diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 3a98dfa1000db7cb47b456b351bc08137e0c7173..132ea32f0f7b1e25e8d7b86b55db0aceaa4f92f3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -5608,7 +5608,9 @@ package android.location {
   }
 
   public final class Country implements android.os.Parcelable {
+    ctor public Country(@NonNull String, int);
     method public int describeContents();
+    method @NonNull public String getCountryCode();
     method public int getSource();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field public static final int COUNTRY_SOURCE_LOCALE = 3; // 0x3
@@ -5618,6 +5620,11 @@ package android.location {
     field @NonNull public static final android.os.Parcelable.Creator<android.location.Country> CREATOR;
   }
 
+  public class CountryDetector {
+    method public void registerCountryDetectorCallback(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.location.Country>);
+    method public void unregisterCountryDetectorCallback(@NonNull java.util.function.Consumer<android.location.Country>);
+  }
+
   public final class GnssCapabilities implements android.os.Parcelable {
     method @Deprecated public boolean hasMeasurementCorrectionsReflectingPane();
     method @Deprecated public boolean hasNavMessages();
diff --git a/location/java/android/location/Country.java b/location/java/android/location/Country.java
index 62f48917f4dc56188ae1d02551bed5a1606502ac..53cc943a7237e92bab61edacd2af3d15d4cc1f16 100644
--- a/location/java/android/location/Country.java
+++ b/location/java/android/location/Country.java
@@ -16,6 +16,7 @@
 
 package android.location;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
@@ -24,6 +25,8 @@ import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.SystemClock;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Locale;
 
 /**
@@ -33,22 +36,48 @@ import java.util.Locale;
  */
 @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
 public final class Country implements Parcelable {
-    /** The country code came from the mobile network */
+    /**
+     * The country code came from the mobile network
+     */
     public static final int COUNTRY_SOURCE_NETWORK = 0;
 
-    /** The country code came from the location service */
+    /**
+     * The country code came from the location service
+     */
     public static final int COUNTRY_SOURCE_LOCATION = 1;
 
-    /** The country code was read from the SIM card */
+    /**
+     * The country code was read from the SIM card
+     */
     public static final int COUNTRY_SOURCE_SIM = 2;
 
-    /** The country code came from the system locale setting */
+    /**
+     * The country code came from the system locale setting
+     */
     public static final int COUNTRY_SOURCE_LOCALE = 3;
 
+    /**
+     * Country source type
+     *
+     * @hide
+     */
+    @IntDef(
+            prefix = {"COUNTRY_SOURCE_"},
+            value = {
+                    COUNTRY_SOURCE_NETWORK,
+                    COUNTRY_SOURCE_LOCATION,
+                    COUNTRY_SOURCE_SIM,
+                    COUNTRY_SOURCE_LOCALE
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CountrySource {}
+
     /** The ISO 3166-1 two letters country code. */
     private final String mCountryIso;
 
-    /** Where the country code came from. */
+    /**
+     * Where the country code came from.
+     */
     private final int mSource;
 
     private int mHashCode;
@@ -69,11 +98,8 @@ public final class Country implements Parcelable {
      *       <li>{@link #COUNTRY_SOURCE_SIM}
      *       <li>{@link #COUNTRY_SOURCE_LOCALE}
      *     </ul>
-     *
-     * @hide
      */
-    @UnsupportedAppUsage
-    public Country(@NonNull final String countryIso, final int source) {
+    public Country(@NonNull final String countryIso, @CountrySource final int source) {
         if (countryIso == null
                 || source < COUNTRY_SOURCE_NETWORK
                 || source > COUNTRY_SOURCE_LOCALE) {
@@ -85,8 +111,7 @@ public final class Country implements Parcelable {
     }
 
     private Country(final String countryIso, final int source, long timestamp) {
-        if (countryIso == null
-                || source < COUNTRY_SOURCE_NETWORK
+        if (countryIso == null || source < COUNTRY_SOURCE_NETWORK
                 || source > COUNTRY_SOURCE_LOCALE) {
             throw new IllegalArgumentException();
         }
@@ -104,23 +129,38 @@ public final class Country implements Parcelable {
 
     /**
      * @return the ISO 3166-1 two letters country code
+     *
      * @hide
+     *
+     * @deprecated clients using getCountryIso should use the {@link #getCountryCode()} API instead.
      */
     @UnsupportedAppUsage
+    @Deprecated
     public String getCountryIso() {
         return mCountryIso;
     }
 
+    /**
+     * Retrieves country code.
+     *
+     * @return country code in ISO 3166-1:alpha2
+     */
+    @NonNull
+    public String getCountryCode() {
+        return mCountryIso;
+    }
+
     /**
      * @return where the country code came from, could be one of below values
-     *     <p>
-     *     <ul>
-     *       <li>{@link #COUNTRY_SOURCE_NETWORK}
-     *       <li>{@link #COUNTRY_SOURCE_LOCATION}
-     *       <li>{@link #COUNTRY_SOURCE_SIM}
-     *       <li>{@link #COUNTRY_SOURCE_LOCALE}
-     *     </ul>
+     *         <p>
+     *         <ul>
+     *         <li>{@link #COUNTRY_SOURCE_NETWORK}</li>
+     *         <li>{@link #COUNTRY_SOURCE_LOCATION}</li>
+     *         <li>{@link #COUNTRY_SOURCE_SIM}</li>
+     *         <li>{@link #COUNTRY_SOURCE_LOCALE}</li>
+     *         </ul>
      */
+    @CountrySource
     public int getSource() {
         return mSource;
     }
@@ -136,16 +176,15 @@ public final class Country implements Parcelable {
     }
 
     @android.annotation.NonNull
-    public static final Parcelable.Creator<Country> CREATOR =
-            new Parcelable.Creator<Country>() {
-                public Country createFromParcel(Parcel in) {
-                    return new Country(in.readString(), in.readInt(), in.readLong());
-                }
+    public static final Parcelable.Creator<Country> CREATOR = new Parcelable.Creator<Country>() {
+        public Country createFromParcel(Parcel in) {
+            return new Country(in.readString(), in.readInt(), in.readLong());
+        }
 
-                public Country[] newArray(int size) {
-                    return new Country[size];
-                }
-            };
+        public Country[] newArray(int size) {
+            return new Country[size];
+        }
+    };
 
     @Override
     public int describeContents() {
@@ -160,9 +199,10 @@ public final class Country implements Parcelable {
     }
 
     /**
-     * Returns true if this {@link Country} is equivalent to the given object. This ignores the
-     * timestamp value and just checks for equivalence of countryIso and source values. Returns
-     * false otherwise.
+     * Returns true if this {@link Country} is equivalent to the given object. This ignores
+     * the timestamp value and just checks for equivalence of countryIso and source values.
+     * Returns false otherwise.
+     *
      */
     @Override
     public boolean equals(@Nullable Object object) {
@@ -190,12 +230,13 @@ public final class Country implements Parcelable {
     }
 
     /**
-     * Compare the specified country to this country object ignoring the source and timestamp
-     * fields, return true if the countryIso fields are equal
+     * Compare the specified country to this country object ignoring the source
+     * and timestamp fields, return true if the countryIso fields are equal
      *
      * @param country the country to compare
-     * @return true if the specified country's countryIso field is equal to this country's, false
-     *     otherwise.
+     * @return true if the specified country's countryIso field is equal to this
+     *         country's, false otherwise.
+     *
      * @hide
      */
     public boolean equalsIgnoreSource(Country country) {
diff --git a/location/java/android/location/CountryDetector.java b/location/java/android/location/CountryDetector.java
index 2592a280af8fe3619d5579c2f8b8a76d3d0b4adf..6abb35020a359b5aae3f27450621ff23031f31c4 100644
--- a/location/java/android/location/CountryDetector.java
+++ b/location/java/android/location/CountryDetector.java
@@ -16,16 +16,22 @@
 
 package android.location;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.Build;
 import android.os.Handler;
+import android.os.HandlerExecutor;
 import android.os.Looper;
 import android.os.RemoteException;
 import android.util.Log;
 
 import java.util.HashMap;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
 
 /**
  * This class provides access to the system country detector service. This service allows
@@ -48,42 +54,38 @@ import java.util.HashMap;
  *
  * @hide
  */
+@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
 @SystemService(Context.COUNTRY_DETECTOR)
 public class CountryDetector {
 
     /**
-     * The class to wrap the ICountryListener.Stub and CountryListener objects together. The
-     * CountryListener will be notified through the specific looper once the country changed and
-     * detected.
+     * The class to wrap the ICountryListener.Stub , CountryListener & {@code Consumer<Country>}
+     * objects together.
+     *
+     * <p>The CountryListener will be notified through the Handler Executor once the country changed
+     * and detected.
+     *
+     * <p>{@code Consumer<Country>} callback interface is notified through the specific executor
+     * once the country changed and detected.
      */
     private static final class ListenerTransport extends ICountryListener.Stub {
 
-        private final CountryListener mListener;
-
-        private final Handler mHandler;
+        private final Consumer<Country> mListener;
+        private final Executor mExecutor;
 
-        public ListenerTransport(CountryListener listener, Looper looper) {
-            mListener = listener;
-            if (looper != null) {
-                mHandler = new Handler(looper);
-            } else {
-                mHandler = new Handler();
-            }
+        ListenerTransport(Consumer<Country> consumer, Executor executor) {
+            mListener = consumer;
+            mExecutor = executor;
         }
 
         public void onCountryDetected(final Country country) {
-            mHandler.post(
-                    new Runnable() {
-                        public void run() {
-                            mListener.onCountryDetected(country);
-                        }
-                    });
+            mExecutor.execute(() -> mListener.accept(country));
         }
     }
 
     private static final String TAG = "CountryDetector";
     private final ICountryDetector mService;
-    private final HashMap<CountryListener, ListenerTransport> mListeners;
+    private final HashMap<Consumer<Country>, ListenerTransport> mListeners;
 
     /**
      * @hide - hide this constructor because it has a parameter of type ICountryDetector, which is a
@@ -93,13 +95,14 @@ public class CountryDetector {
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
     public CountryDetector(ICountryDetector service) {
         mService = service;
-        mListeners = new HashMap<CountryListener, ListenerTransport>();
+        mListeners = new HashMap<>();
     }
 
     /**
      * Start detecting the country that the user is in.
      *
      * @return the country if it is available immediately, otherwise null will be returned.
+     * @hide
      */
     @UnsupportedAppUsage
     public Country detectCountry() {
@@ -117,33 +120,59 @@ public class CountryDetector {
      * @param listener will be called when the country is detected or changed.
      * @param looper a Looper object whose message queue will be used to implement the callback
      *     mechanism. If looper is null then the callbacks will be called on the main thread.
+     * @hide
+     * @deprecated client using this api should use {@link
+     *     #registerCountryDetectorCallback(Executor, Consumer)} }
      */
     @UnsupportedAppUsage
-    public void addCountryListener(CountryListener listener, Looper looper) {
+    @Deprecated
+    public void addCountryListener(@NonNull CountryListener listener, @Nullable Looper looper) {
+        Handler handler = looper != null ? new Handler(looper) : new Handler();
+        registerCountryDetectorCallback(new HandlerExecutor(handler), listener);
+    }
+
+    /**
+     * Remove the listener
+     *
+     * @hide
+     * @deprecated client using this api should use {@link
+     *     #unregisterCountryDetectorCallback(Consumer)}
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    public void removeCountryListener(CountryListener listener) {
+        unregisterCountryDetectorCallback(listener);
+    }
+
+    /**
+     * Add a callback interface, to be notified when country code is added or changes.
+     *
+     * @param executor The callback executor for the response.
+     * @param consumer {@link Consumer} callback to receive the country code when changed/detected
+     */
+    public void registerCountryDetectorCallback(
+            @NonNull Executor executor, @NonNull Consumer<Country> consumer) {
         synchronized (mListeners) {
-            if (!mListeners.containsKey(listener)) {
-                ListenerTransport transport = new ListenerTransport(listener, looper);
-                try {
-                    mService.addCountryListener(transport);
-                    mListeners.put(listener, transport);
-                } catch (RemoteException e) {
-                    Log.e(TAG, "addCountryListener: RemoteException", e);
-                }
+            unregisterCountryDetectorCallback(consumer);
+            ListenerTransport transport = new ListenerTransport(consumer, executor);
+            try {
+                mService.addCountryListener(transport);
+                mListeners.put(consumer, transport);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
             }
         }
     }
 
-    /** Remove the listener */
-    @UnsupportedAppUsage
-    public void removeCountryListener(CountryListener listener) {
+    /** Remove the callback subscribed to Update country code */
+    public void unregisterCountryDetectorCallback(@NonNull Consumer<Country> consumer) {
         synchronized (mListeners) {
-            ListenerTransport transport = mListeners.get(listener);
+            ListenerTransport transport = mListeners.remove(consumer);
             if (transport != null) {
                 try {
-                    mListeners.remove(listener);
                     mService.removeCountryListener(transport);
                 } catch (RemoteException e) {
-                    Log.e(TAG, "removeCountryListener: RemoteException", e);
+                    throw e.rethrowFromSystemServer();
                 }
             }
         }
diff --git a/location/java/android/location/CountryListener.java b/location/java/android/location/CountryListener.java
index eb67205f4de988a3b93a436371cdf9d13d7b3ce9..0ca6962460f8621d47c22631a1d831d08c18fcdd 100644
--- a/location/java/android/location/CountryListener.java
+++ b/location/java/android/location/CountryListener.java
@@ -18,16 +18,25 @@ package android.location;
 
 import android.compat.annotation.UnsupportedAppUsage;
 
+import java.util.function.Consumer;
+
 /**
  * The listener for receiving the notification when the country is detected or
  * changed
  *
  * @hide
  */
-public interface CountryListener {
+public interface CountryListener extends Consumer<Country> {
     /**
      * @param country the changed or detected country.
      */
     @UnsupportedAppUsage
     void onCountryDetected(Country country);
+
+    /**
+     * @param country the changed or detected country.
+     */
+    default void accept(Country country) {
+        onCountryDetected(country);
+    }
 }
diff --git a/services/core/java/com/android/server/CountryDetectorService.java b/services/core/java/com/android/server/CountryDetectorService.java
index a2a7dd35371fc1588a4a4e0b3570bfe7271a5302..a6549253dcab3baa1d8f750444cf84244020b067 100644
--- a/services/core/java/com/android/server/CountryDetectorService.java
+++ b/services/core/java/com/android/server/CountryDetectorService.java
@@ -148,6 +148,10 @@ public class CountryDetectorService extends ICountryDetector.Stub {
             Receiver r = new Receiver(listener);
             try {
                 listener.asBinder().linkToDeath(r, 0);
+                final Country country = detectCountry();
+                if (country != null) {
+                    listener.onCountryDetected(country);
+                }
                 mReceivers.put(listener.asBinder(), r);
                 if (mReceivers.size() == 1) {
                     Slog.d(TAG, "The first listener is added");