Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 32765d94 authored by Nagendra Prasad Nagarle Basavaraju's avatar Nagendra Prasad Nagarle Basavaraju Committed by Android (Google) Code Review
Browse files

Merge changes from topic "COUNTRY_DETECTOR_API_ENHANCEMENT"

* changes:
  API Enhancement CountryDetector
  Revert CountryDetector changes
parents 167ce476 576862f5
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -5804,8 +5804,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 getCountryIso();
    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
@@ -5816,13 +5817,8 @@ package android.location {
  }
  public class CountryDetector {
    method public void addCountryListener(@NonNull android.location.CountryListener, @Nullable android.os.Looper);
    method @Nullable public android.location.Country detectCountry();
    method public void removeCountryListener(@NonNull android.location.CountryListener);
  }
  public interface CountryListener {
    method public void onCountryDetected(@NonNull android.location.Country);
    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 {
+0 −6
Original line number Diff line number Diff line
@@ -3,10 +3,6 @@ ArrayReturn: android.view.contentcapture.ViewNode#getAutofillOptions():
    Method should return Collection<CharSequence> (or subclass) instead of raw array; was `java.lang.CharSequence[]`


ExecutorRegistration: android.location.CountryDetector#addCountryListener(android.location.CountryListener, android.os.Looper):
    Registration methods should have overload that accepts delivery Executor: `addCountryListener`


GenericException: android.app.prediction.AppPredictor#finalize():
    Methods must not throw generic exceptions (`java.lang.Throwable`)
GenericException: android.hardware.location.ContextHubClient#finalize():
@@ -131,8 +127,6 @@ SamShouldBeLast: android.content.pm.PackageItemInfo#dumpFront(android.util.Print
    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.PackageItemInfo.dumpFront) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.content.pm.ResolveInfo#dump(android.util.Printer, String):
    SAM-compatible parameters (such as parameter 1, "pw", in android.content.pm.ResolveInfo.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.location.CountryDetector#addCountryListener(android.location.CountryListener, android.os.Looper):
    SAM-compatible parameters (such as parameter 1, "listener", in android.location.CountryDetector.addCountryListener) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.location.Location#dump(android.util.Printer, String):
    SAM-compatible parameters (such as parameter 1, "pw", in android.location.Location.dump) should be last to improve Kotlin interoperability; see https://kotlinlang.org/docs/reference/java-interop.html#sam-conversions
SamShouldBeLast: android.location.LocationManager#addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler):
+46 −16
Original line number Diff line number Diff line
@@ -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;

/**
@@ -54,8 +57,22 @@ public final class Country implements Parcelable {
    public static final int COUNTRY_SOURCE_LOCALE = 3;

    /**
     * The ISO 3166-1 two letters country code.
     * 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;

    /**
@@ -73,21 +90,18 @@ public final class Country implements Parcelable {

    /**
     * @param countryIso the ISO 3166-1 two letters country code.
     * @param source where the countryIso came from, could be one of below
     *        values
     * @param source where the countryIso came from, could be one of below values
     *     <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>
     *       <li>{@link #COUNTRY_SOURCE_NETWORK}
     *       <li>{@link #COUNTRY_SOURCE_LOCATION}
     *       <li>{@link #COUNTRY_SOURCE_SIM}
     *       <li>{@link #COUNTRY_SOURCE_LOCALE}
     *     </ul>
     *
     * @hide
     */
    @UnsupportedAppUsage
    public Country(final String countryIso, final int source) {
        if (countryIso == null || source < COUNTRY_SOURCE_NETWORK
    public Country(@NonNull final String countryIso, @CountrySource final int source) {
        if (countryIso == null
                || source < COUNTRY_SOURCE_NETWORK
                || source > COUNTRY_SOURCE_LOCALE) {
            throw new IllegalArgumentException();
        }
@@ -115,12 +129,27 @@ 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.
     */
    @NonNull
    @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>
@@ -131,6 +160,7 @@ public final class Country implements Parcelable {
     *         <li>{@link #COUNTRY_SOURCE_LOCALE}</li>
     *         </ul>
     */
    @CountrySource
    public int getSource() {
        return mSource;
    }
+85 −62
Original line number Diff line number Diff line
@@ -24,28 +24,32 @@ 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 applications to obtain the country that the user is in.
 * <p>
 * The country will be detected in order of reliability, like
 * This class provides access to the system country detector service. This service allows
 * applications to obtain the country that the user is in.
 *
 * <p>The country will be detected in order of reliability, like
 *
 * <ul>
 * <li>Mobile network</li>
 * <li>Location</li>
 * <li>SIM's country</li>
 * <li>Phone's locale</li>
 *   <li>Mobile network
 *   <li>Location
 *   <li>SIM's country
 *   <li>Phone's locale
 * </ul>
 * <p>
 * Call the {@link #detectCountry()} to get the available country immediately.
 * <p>
 * To be notified of the future country change, use the
 * {@link #addCountryListener}
 *
 * <p>Call the {@link #detectCountry()} to get the available country immediately.
 *
 * <p>To be notified of the future country change, use the {@link #addCountryListener}
 *
 * <p>
 *
 * @hide
@@ -55,57 +59,52 @@ import java.util.HashMap;
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 final static class ListenerTransport extends ICountryListener.Stub {
    private static final class ListenerTransport extends ICountryListener.Stub {

        private final CountryListener mListener;
        private final Consumer<Country> mListener;
        private final Executor mExecutor;

        private final Handler mHandler;

        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 final static String TAG = "CountryDetector";
    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 system private class. The right way to
     *       create an instance of this class is using the factory
     *       Context.getSystemService.
     * @hide - hide this constructor because it has a parameter of type ICountryDetector, which is a
     *     system private class. The right way to create an instance of this class is using the
     *     factory Context.getSystemService.
     */
    @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.
     * @return the country if it is available immediately, otherwise null will be returned.
     * @hide
     */
    @Nullable
    @UnsupportedAppUsage
    public Country detectCountry() {
        try {
            return mService.detectCountry();
@@ -116,40 +115,64 @@ public class CountryDetector {
    }

    /**
     * Add a listener to receive the notification when the country is detected
     * or changed.
     * Add a listener to receive the notification when the country is detected or changed.
     *
     * @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.
     * @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
    @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);
            unregisterCountryDetectorCallback(consumer);
            ListenerTransport transport = new ListenerTransport(consumer, executor);
            try {
                mService.addCountryListener(transport);
                    mListeners.put(listener, transport);
                mListeners.put(consumer, transport);
            } catch (RemoteException e) {
                    Log.e(TAG, "addCountryListener: RemoteException", e);
                }
                throw e.rethrowFromSystemServer();
            }
        }
    }

    /**
     * Remove the listener
     */
    public void removeCountryListener(@NonNull 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();
                }
            }
        }
+13 −6
Original line number Diff line number Diff line
@@ -16,8 +16,9 @@

package android.location;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.compat.annotation.UnsupportedAppUsage;

import java.util.function.Consumer;

/**
 * The listener for receiving the notification when the country is detected or
@@ -25,11 +26,17 @@ import android.annotation.SystemApi;
 *
 * @hide
 */
@SystemApi(client = SystemApi.Client.PRIVILEGED_APPS)
public interface CountryListener {
public interface CountryListener extends Consumer<Country> {
    /**
     * @param country the changed or detected country.
     *
     */
    void onCountryDetected(@NonNull Country country);
    @UnsupportedAppUsage
    void onCountryDetected(Country country);

    /**
     * @param country the changed or detected country.
     */
    default void accept(Country country) {
        onCountryDetected(country);
    }
}
Loading