Merge "Only call -rerouted callback if displayId changed"
diff --git a/Android.bp b/Android.bp
index 9077344..fb6ff0f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1121,6 +1121,7 @@
"core/java/android/os/HidlSupport.java",
"core/java/android/annotation/IntDef.java",
"core/java/android/annotation/NonNull.java",
+ "core/java/android/annotation/Nullable.java",
"core/java/android/annotation/SystemApi.java",
"core/java/android/annotation/TestApi.java",
"core/java/android/os/HwBinder.java",
diff --git a/api/current.txt b/api/current.txt
index fc51c39..d26bb22 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5266,6 +5266,7 @@
method public String getGroup();
method public int getGroupAlertBehavior();
method public android.graphics.drawable.Icon getLargeIcon();
+ method @Nullable public android.content.LocusId getLocusId();
method public CharSequence getSettingsText();
method public String getShortcutId();
method public android.graphics.drawable.Icon getSmallIcon();
@@ -5545,6 +5546,7 @@
method @NonNull public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
method @Deprecated public android.app.Notification.Builder setLights(@ColorInt int, int, int);
method @NonNull public android.app.Notification.Builder setLocalOnly(boolean);
+ method @NonNull public android.app.Notification.Builder setLocusId(@Nullable android.content.LocusId);
method @NonNull public android.app.Notification.Builder setNumber(int);
method @NonNull public android.app.Notification.Builder setOngoing(boolean);
method @NonNull public android.app.Notification.Builder setOnlyAlertOnce(boolean);
@@ -11974,6 +11976,7 @@
method @Nullable public android.content.Intent getIntent();
method @Nullable public android.content.Intent[] getIntents();
method public long getLastChangedTimestamp();
+ method @Nullable public android.content.LocusId getLocusId();
method @Nullable public CharSequence getLongLabel();
method @NonNull public String getPackage();
method public int getRank();
@@ -12008,6 +12011,7 @@
method @NonNull public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
method @NonNull public android.content.pm.ShortcutInfo.Builder setIntent(@NonNull android.content.Intent);
method @NonNull public android.content.pm.ShortcutInfo.Builder setIntents(@NonNull android.content.Intent[]);
+ method @NonNull public android.content.pm.ShortcutInfo.Builder setLocusId(@NonNull android.content.LocusId);
method @NonNull public android.content.pm.ShortcutInfo.Builder setLongLabel(@NonNull CharSequence);
method @NonNull public android.content.pm.ShortcutInfo.Builder setLongLived();
method @NonNull public android.content.pm.ShortcutInfo.Builder setPerson(@NonNull android.app.Person);
@@ -22828,24 +22832,6 @@
method @Deprecated public boolean usedInFix();
}
- @Deprecated public final class GpsStatus {
- method @Deprecated public int getMaxSatellites();
- method @Deprecated public Iterable<android.location.GpsSatellite> getSatellites();
- method @Deprecated public int getTimeToFirstFix();
- field @Deprecated public static final int GPS_EVENT_FIRST_FIX = 3; // 0x3
- field @Deprecated public static final int GPS_EVENT_SATELLITE_STATUS = 4; // 0x4
- field @Deprecated public static final int GPS_EVENT_STARTED = 1; // 0x1
- field @Deprecated public static final int GPS_EVENT_STOPPED = 2; // 0x2
- }
-
- @Deprecated public static interface GpsStatus.Listener {
- method @Deprecated public void onGpsStatusChanged(int);
- }
-
- @Deprecated public static interface GpsStatus.NmeaListener {
- method @Deprecated public void onNmeaReceived(long, String);
- }
-
public class Location implements android.os.Parcelable {
ctor public Location(String);
ctor public Location(android.location.Location);
@@ -22914,55 +22900,50 @@
}
public class LocationManager {
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.OnNmeaMessageListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
- method public void addTestProvider(String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
- method @Deprecated public void clearTestProviderEnabled(String);
- method @Deprecated public void clearTestProviderLocation(String);
- method @Deprecated public void clearTestProviderStatus(String);
- method public java.util.List<java.lang.String> getAllProviders();
- method public String getBestProvider(android.location.Criteria, boolean);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull android.location.OnNmeaMessageListener);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull android.location.OnNmeaMessageListener, @Nullable android.os.Handler);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void addProximityAlert(double, double, float, long, @NonNull android.app.PendingIntent);
+ method public void addTestProvider(@NonNull String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
+ method @Deprecated public void clearTestProviderEnabled(@NonNull String);
+ method @Deprecated public void clearTestProviderLocation(@NonNull String);
+ method @Deprecated public void clearTestProviderStatus(@NonNull String);
+ method @NonNull public java.util.List<java.lang.String> getAllProviders();
+ method @Nullable public String getBestProvider(@NonNull android.location.Criteria, boolean);
method @Nullable public String getGnssHardwareModelName();
method public int getGnssYearOfHardware();
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(android.location.GpsStatus);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.location.Location getLastKnownLocation(String);
- method public android.location.LocationProvider getProvider(String);
- method public java.util.List<java.lang.String> getProviders(boolean);
- method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) @Nullable public android.location.Location getLastKnownLocation(@NonNull String);
+ method @Nullable public android.location.LocationProvider getProvider(@NonNull String);
+ method @NonNull public java.util.List<java.lang.String> getProviders(boolean);
+ method @NonNull public java.util.List<java.lang.String> getProviders(@NonNull android.location.Criteria, boolean);
method public boolean isLocationEnabled();
- method public boolean isProviderEnabled(String);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
- method @Deprecated public void removeGpsStatusListener(android.location.GpsStatus.Listener);
- method @Deprecated public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
- method public void removeNmeaListener(android.location.OnNmeaMessageListener);
- method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeProximityAlert(android.app.PendingIntent);
- method public void removeTestProvider(String);
- method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeUpdates(android.location.LocationListener);
- method public void removeUpdates(android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(String, long, float, android.location.LocationListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(String, long, float, android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, android.location.Criteria, android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(String, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(String, android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(android.location.Criteria, android.app.PendingIntent);
- method public boolean sendExtraCommand(String, String, android.os.Bundle);
- method public void setTestProviderEnabled(String, boolean);
- method public void setTestProviderLocation(String, android.location.Location);
- method @Deprecated public void setTestProviderStatus(String, int, android.os.Bundle, long);
- method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
- method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
+ method public boolean isProviderEnabled(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback, @Nullable android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback, @Nullable android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(@NonNull android.location.GnssStatus.Callback, @Nullable android.os.Handler);
+ method public void removeNmeaListener(@NonNull android.location.OnNmeaMessageListener);
+ method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeProximityAlert(@NonNull android.app.PendingIntent);
+ method public void removeTestProvider(@NonNull String);
+ method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeUpdates(@NonNull android.location.LocationListener);
+ method public void removeUpdates(@NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.location.LocationListener);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
+ method public boolean sendExtraCommand(@NonNull String, @NonNull String, @Nullable android.os.Bundle);
+ method public void setTestProviderEnabled(@NonNull String, boolean);
+ method public void setTestProviderLocation(@NonNull String, @NonNull android.location.Location);
+ method @Deprecated public void setTestProviderStatus(@NonNull String, int, @Nullable android.os.Bundle, long);
+ method public void unregisterGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
+ method public void unregisterGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback);
+ method public void unregisterGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
field public static final String GPS_PROVIDER = "gps";
field public static final String KEY_LOCATION_CHANGED = "location";
field public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -23021,6 +23002,7 @@
}
public final class AudioAttributes implements android.os.Parcelable {
+ method public boolean areHapticChannelsMuted();
method public int describeContents();
method public int getContentType();
method public int getFlags();
@@ -23062,6 +23044,7 @@
method public android.media.AudioAttributes.Builder setContentType(int);
method public android.media.AudioAttributes.Builder setFlags(int);
method public android.media.AudioAttributes.Builder setLegacyStreamType(int);
+ method public android.media.AudioAttributes.Builder setMuteHapticChannels(boolean);
method public android.media.AudioAttributes.Builder setUsage(int);
}
@@ -30269,7 +30252,7 @@
field public static final int WIFI_AWARE_DATA_PATH_ROLE_RESPONDER = 1; // 0x1
}
- public static class WifiAwareManager.NetworkSpecifierBuilder {
+ public static final class WifiAwareManager.NetworkSpecifierBuilder {
ctor public WifiAwareManager.NetworkSpecifierBuilder();
method @NonNull public android.net.NetworkSpecifier build();
method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setDiscoverySession(@NonNull android.net.wifi.aware.DiscoverySession);
@@ -41872,7 +41855,7 @@
field public static final int STATE_UNSET = 0; // 0x0
}
- public static class ZenPolicy.Builder {
+ public static final class ZenPolicy.Builder {
ctor public ZenPolicy.Builder();
method @NonNull public android.service.notification.ZenPolicy.Builder allowAlarms(boolean);
method @NonNull public android.service.notification.ZenPolicy.Builder allowAllSounds();
@@ -44786,6 +44769,7 @@
public class PhoneStateListener {
ctor public PhoneStateListener();
ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor);
+ method public void onActiveDataSubscriptionIdChanged(int);
method public void onCallForwardingIndicatorChanged(boolean);
method public void onCallStateChanged(int, String);
method public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>);
@@ -44798,6 +44782,7 @@
method @Deprecated public void onSignalStrengthChanged(int);
method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
method public void onUserMobileDataStateChanged(boolean);
+ field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8
field public static final int LISTEN_CALL_STATE = 32; // 0x20
field public static final int LISTEN_CELL_INFO = 1024; // 0x400
@@ -44863,7 +44848,7 @@
method @Deprecated public int getCdmaDbm();
method @Deprecated public int getCdmaEcio();
method @NonNull public java.util.List<android.telephony.CellSignalStrength> getCellSignalStrengths();
- method public <T extends android.telephony.CellSignalStrength> java.util.List<T> getCellSignalStrengths(@NonNull Class<T>);
+ method @NonNull public <T extends android.telephony.CellSignalStrength> java.util.List<T> getCellSignalStrengths(@NonNull Class<T>);
method @Deprecated public int getEvdoDbm();
method @Deprecated public int getEvdoEcio();
method @Deprecated public int getEvdoSnr();
diff --git a/api/removed.txt b/api/removed.txt
index fdfaf91..7a06803 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -282,12 +282,38 @@
package android.location {
+ @Deprecated public final class GpsStatus {
+ method public int getMaxSatellites();
+ method public Iterable<android.location.GpsSatellite> getSatellites();
+ method public int getTimeToFirstFix();
+ field public static final int GPS_EVENT_FIRST_FIX = 3; // 0x3
+ field public static final int GPS_EVENT_SATELLITE_STATUS = 4; // 0x4
+ field public static final int GPS_EVENT_STARTED = 1; // 0x1
+ field public static final int GPS_EVENT_STOPPED = 2; // 0x2
+ }
+
+ @Deprecated public static interface GpsStatus.Listener {
+ method public void onGpsStatusChanged(int);
+ }
+
+ @Deprecated public static interface GpsStatus.NmeaListener {
+ method public void onNmeaReceived(long, String);
+ }
+
public class Location implements android.os.Parcelable {
method @Deprecated public void removeBearingAccuracy();
method @Deprecated public void removeSpeedAccuracy();
method @Deprecated public void removeVerticalAccuracy();
}
+ public class LocationManager {
+ method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
+ method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(@Nullable android.location.GpsStatus);
+ method @Deprecated public void removeGpsStatusListener(android.location.GpsStatus.Listener);
+ method @Deprecated public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
+ }
+
}
package android.media {
diff --git a/api/system-current.txt b/api/system-current.txt
index 70b9618..975e300 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -474,7 +474,7 @@
public class BroadcastOptions {
method public static android.app.BroadcastOptions makeBasic();
- method @RequiresPermission("android.permission.START_ACTIVITIES_FROM_BACKGROUND") public void setAllowBackgroundActivityStarts(boolean);
+ method @RequiresPermission("android.permission.START_ACTIVITIES_FROM_BACKGROUND") public void setBackgroundActivityStartsAllowed(boolean);
method public void setDontSendToRestrictedApps(boolean);
method @RequiresPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST) public void setTemporaryAppWhitelistDuration(long);
method public android.os.Bundle toBundle();
@@ -3056,81 +3056,75 @@
public final class GnssMeasurementCorrections implements android.os.Parcelable {
method public int describeContents();
- method public double getAltitudeMeters();
- method public double getHorizontalPositionUncertaintyMeters();
- method public double getLatitudeDegrees();
- method public double getLongitudeDegrees();
- method @Nullable public java.util.List<android.location.GnssSingleSatCorrection> getSingleSatelliteCorrectionList();
- method public long getToaGpsNanosecondsOfWeek();
- method public double getVerticalPositionUncertaintyMeters();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssMeasurementCorrections> CREATOR;
+ method @FloatRange(from=-1000.0F, to=10000.0f) public double getAltitudeMeters();
+ method @FloatRange(from=0.0f) public double getHorizontalPositionUncertaintyMeters();
+ method @FloatRange(from=-90.0F, to=90.0f) public double getLatitudeDegrees();
+ method @FloatRange(from=-180.0F, to=180.0f) public double getLongitudeDegrees();
+ method @NonNull public java.util.List<android.location.GnssSingleSatCorrection> getSingleSatelliteCorrectionList();
+ method @IntRange(from=0) public long getToaGpsNanosecondsOfWeek();
+ method @FloatRange(from=0.0f) public double getVerticalPositionUncertaintyMeters();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.location.GnssMeasurementCorrections> CREATOR;
}
public static final class GnssMeasurementCorrections.Builder {
ctor public GnssMeasurementCorrections.Builder();
- method public android.location.GnssMeasurementCorrections build();
- method public android.location.GnssMeasurementCorrections.Builder setAltitudeMeters(double);
- method public android.location.GnssMeasurementCorrections.Builder setHorizontalPositionUncertaintyMeters(double);
- method public android.location.GnssMeasurementCorrections.Builder setLatitudeDegrees(double);
- method public android.location.GnssMeasurementCorrections.Builder setLongitudeDegrees(double);
- method public android.location.GnssMeasurementCorrections.Builder setSingleSatelliteCorrectionList(@Nullable java.util.List<android.location.GnssSingleSatCorrection>);
- method public android.location.GnssMeasurementCorrections.Builder setToaGpsNanosecondsOfWeek(long);
- method public android.location.GnssMeasurementCorrections.Builder setVerticalPositionUncertaintyMeters(double);
+ method @NonNull public android.location.GnssMeasurementCorrections build();
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setAltitudeMeters(@FloatRange(from=-1000.0F, to=10000.0f) double);
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setHorizontalPositionUncertaintyMeters(@FloatRange(from=0.0f) double);
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setLatitudeDegrees(@FloatRange(from=-90.0F, to=90.0f) double);
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setLongitudeDegrees(@FloatRange(from=-180.0F, to=180.0f) double);
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setSingleSatelliteCorrectionList(@NonNull java.util.List<android.location.GnssSingleSatCorrection>);
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setToaGpsNanosecondsOfWeek(@IntRange(from=0) long);
+ method @NonNull public android.location.GnssMeasurementCorrections.Builder setVerticalPositionUncertaintyMeters(@FloatRange(from=0.0f) double);
}
public final class GnssReflectingPlane implements android.os.Parcelable {
method public int describeContents();
- method public double getAltitudeMeters();
- method public double getAzimuthDegrees();
- method public double getLatitudeDegrees();
- method public double getLongitudeDegrees();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssReflectingPlane> CREATOR;
+ method @FloatRange(from=-1000.0F, to=10000.0f) public double getAltitudeMeters();
+ method @FloatRange(from=0.0f, to=360.0f) public double getAzimuthDegrees();
+ method @FloatRange(from=-90.0F, to=90.0f) public double getLatitudeDegrees();
+ method @FloatRange(from=-180.0F, to=180.0f) public double getLongitudeDegrees();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.location.GnssReflectingPlane> CREATOR;
}
public static final class GnssReflectingPlane.Builder {
ctor public GnssReflectingPlane.Builder();
- method public android.location.GnssReflectingPlane build();
- method public android.location.GnssReflectingPlane.Builder setAltitudeMeters(double);
- method public android.location.GnssReflectingPlane.Builder setAzimuthDegrees(double);
- method public android.location.GnssReflectingPlane.Builder setLatitudeDegrees(double);
- method public android.location.GnssReflectingPlane.Builder setLongitudeDegrees(double);
+ method @NonNull public android.location.GnssReflectingPlane build();
+ method @NonNull public android.location.GnssReflectingPlane.Builder setAltitudeMeters(@FloatRange(from=-1000.0F, to=10000.0f) double);
+ method @NonNull public android.location.GnssReflectingPlane.Builder setAzimuthDegrees(@FloatRange(from=0.0f, to=360.0f) double);
+ method @NonNull public android.location.GnssReflectingPlane.Builder setLatitudeDegrees(@FloatRange(from=-90.0F, to=90.0f) double);
+ method @NonNull public android.location.GnssReflectingPlane.Builder setLongitudeDegrees(@FloatRange(from=-180.0F, to=180.0f) double);
}
public final class GnssSingleSatCorrection implements android.os.Parcelable {
method public int describeContents();
- method public float getCarrierFrequencyHz();
+ method @FloatRange(from=0.0f, fromInclusive=false) public float getCarrierFrequencyHz();
method public int getConstellationType();
- method public float getExcessPathLengthMeters();
- method public float getExcessPathLengthUncertaintyMeters();
+ method @FloatRange(from=0.0f) public float getExcessPathLengthMeters();
+ method @FloatRange(from=0.0f) public float getExcessPathLengthUncertaintyMeters();
method @FloatRange(from=0.0f, to=1.0f) public float getProbabilityLineOfSight();
method @Nullable public android.location.GnssReflectingPlane getReflectingPlane();
- method public int getSatelliteId();
- method public int getSingleSatelliteCorrectionFlags();
+ method @IntRange(from=0) public int getSatelliteId();
method public boolean hasExcessPathLength();
method public boolean hasExcessPathLengthUncertainty();
method public boolean hasReflectingPlane();
method public boolean hasValidSatelliteLineOfSight();
- method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.location.GnssSingleSatCorrection> CREATOR;
- field public static final int HAS_EXCESS_PATH_LENGTH_MASK = 2; // 0x2
- field public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 4; // 0x4
- field public static final int HAS_PROB_SAT_IS_LOS_MASK = 1; // 0x1
- field public static final int HAS_REFLECTING_PLANE_MASK = 8; // 0x8
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.location.GnssSingleSatCorrection> CREATOR;
}
public static final class GnssSingleSatCorrection.Builder {
ctor public GnssSingleSatCorrection.Builder();
- method public android.location.GnssSingleSatCorrection build();
- method public android.location.GnssSingleSatCorrection.Builder setCarrierFrequencyHz(float);
- method public android.location.GnssSingleSatCorrection.Builder setConstellationType(int);
- method public android.location.GnssSingleSatCorrection.Builder setExcessPathLengthMeters(float);
- method public android.location.GnssSingleSatCorrection.Builder setExcessPathLengthUncertaintyMeters(float);
- method public android.location.GnssSingleSatCorrection.Builder setProbabilityLineOfSight(@FloatRange(from=0.0f, to=1.0f) float);
- method public android.location.GnssSingleSatCorrection.Builder setReflectingPlane(android.location.GnssReflectingPlane);
- method public android.location.GnssSingleSatCorrection.Builder setSatelliteId(int);
- method public android.location.GnssSingleSatCorrection.Builder setSingleSatelliteCorrectionFlags(int);
+ method @NonNull public android.location.GnssSingleSatCorrection build();
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setCarrierFrequencyHz(@FloatRange(from=0.0f, fromInclusive=false) float);
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setConstellationType(int);
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setExcessPathLengthMeters(@FloatRange(from=0.0f) float);
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setExcessPathLengthUncertaintyMeters(@FloatRange(from=0.0f) float);
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setProbabilityLineOfSight(@FloatRange(from=0.0f, to=1.0f) float);
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setReflectingPlane(@Nullable android.location.GnssReflectingPlane);
+ method @NonNull public android.location.GnssSingleSatCorrection.Builder setSatelliteId(@IntRange(from=0) int);
}
public class GpsClock implements android.os.Parcelable {
@@ -3365,57 +3359,53 @@
}
public class LocationManager {
- method @Deprecated public boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
- method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int getGnssBatchSize();
method public int getGnssCapabilities();
method @Nullable public String getLocationControllerExtraPackage();
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
method public boolean isLocationControllerExtraPackageEnabled();
- method public boolean isLocationEnabledForUser(android.os.UserHandle);
- method public boolean isProviderEnabledForUser(String, android.os.UserHandle);
- method public boolean isProviderPackage(String);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, android.location.BatchedLocationCallback, android.os.Handler);
- method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
- method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(String);
+ method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
+ method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle);
+ method public boolean isProviderPackage(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(@NonNull String);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackageEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, android.os.UserHandle);
- method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(String, boolean, android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(android.location.BatchedLocationCallback);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
}
public final class LocationRequest implements android.os.Parcelable {
- method public static android.location.LocationRequest create();
- method public static android.location.LocationRequest createFromDeprecatedCriteria(android.location.Criteria, long, float, boolean);
- method public static android.location.LocationRequest createFromDeprecatedProvider(String, long, float, boolean);
+ method @NonNull public static android.location.LocationRequest create();
+ method @NonNull public static android.location.LocationRequest createFromDeprecatedCriteria(@NonNull android.location.Criteria, long, float, boolean);
+ method @NonNull public static android.location.LocationRequest createFromDeprecatedProvider(@NonNull String, long, float, boolean);
method public int describeContents();
method public long getExpireAt();
method public long getFastestInterval();
method public boolean getHideFromAppOps();
method public long getInterval();
method public int getNumUpdates();
- method public String getProvider();
+ method @NonNull public String getProvider();
method public int getQuality();
method public float getSmallestDisplacement();
- method public android.os.WorkSource getWorkSource();
+ method @Nullable public android.os.WorkSource getWorkSource();
method public boolean isLocationSettingsIgnored();
method public boolean isLowPowerMode();
- method public android.location.LocationRequest setExpireAt(long);
- method public android.location.LocationRequest setExpireIn(long);
- method public android.location.LocationRequest setFastestInterval(long);
+ method @NonNull public android.location.LocationRequest setExpireAt(long);
+ method @NonNull public android.location.LocationRequest setExpireIn(long);
+ method @NonNull public android.location.LocationRequest setFastestInterval(long);
method public void setHideFromAppOps(boolean);
- method public android.location.LocationRequest setInterval(long);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
- method public android.location.LocationRequest setLowPowerMode(boolean);
- method public android.location.LocationRequest setNumUpdates(int);
- method public android.location.LocationRequest setProvider(String);
- method public android.location.LocationRequest setQuality(int);
- method public android.location.LocationRequest setSmallestDisplacement(float);
- method public void setWorkSource(android.os.WorkSource);
+ method @NonNull public android.location.LocationRequest setInterval(long);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull public android.location.LocationRequest setLowPowerMode(boolean);
+ method @NonNull public android.location.LocationRequest setNumUpdates(int);
+ method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
+ method @NonNull public android.location.LocationRequest setQuality(int);
+ method @NonNull public android.location.LocationRequest setSmallestDisplacement(float);
+ method public void setWorkSource(@Nullable android.os.WorkSource);
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACCURACY_BLOCK = 102; // 0x66
field public static final int ACCURACY_CITY = 104; // 0x68
@@ -4969,7 +4959,7 @@
method @Deprecated public android.net.NetworkSpecifier createNetworkSpecifierPmk(@NonNull android.net.wifi.aware.PeerHandle, @NonNull byte[]);
}
- public static class WifiAwareManager.NetworkSpecifierBuilder {
+ public static final class WifiAwareManager.NetworkSpecifierBuilder {
method @NonNull public android.net.wifi.aware.WifiAwareManager.NetworkSpecifierBuilder setPmk(@NonNull byte[]);
}
@@ -5286,7 +5276,7 @@
method public final void putInt64Array(long, long[]);
method public final void putInt8(long, byte);
method public final void putInt8Array(long, byte[]);
- method public final void putNativeHandle(long, android.os.NativeHandle);
+ method public final void putNativeHandle(long, @Nullable android.os.NativeHandle);
method public final void putString(long, String);
method public static Boolean[] wrapArray(@NonNull boolean[]);
method public static Long[] wrapArray(@NonNull long[]);
@@ -5306,7 +5296,7 @@
method public final double readDouble();
method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
- method public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
+ method @Nullable public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
method public final float readFloat();
method public final java.util.ArrayList<java.lang.Float> readFloatVector();
method public final short readInt16();
@@ -5317,8 +5307,8 @@
method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
method public final byte readInt8();
method public final java.util.ArrayList<java.lang.Byte> readInt8Vector();
- method public final android.os.NativeHandle readNativeHandle();
- method public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
+ method @Nullable public final android.os.NativeHandle readNativeHandle();
+ method @NonNull public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
method public final String readString();
method public final java.util.ArrayList<java.lang.String> readStringVector();
method public final android.os.IHwBinder readStrongBinder();
@@ -5342,8 +5332,8 @@
method public final void writeInt8(byte);
method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
method public final void writeInterfaceToken(String);
- method public final void writeNativeHandle(android.os.NativeHandle);
- method public final void writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>);
+ method public final void writeNativeHandle(@Nullable android.os.NativeHandle);
+ method public final void writeNativeHandleVector(@NonNull java.util.ArrayList<android.os.NativeHandle>);
method public final void writeStatus(int);
method public final void writeString(String);
method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
@@ -5435,10 +5425,10 @@
ctor public NativeHandle(@NonNull java.io.FileDescriptor, boolean);
ctor public NativeHandle(@NonNull java.io.FileDescriptor[], @NonNull int[], boolean);
method public void close() throws java.io.IOException;
- method public android.os.NativeHandle dup() throws java.io.IOException;
- method public java.io.FileDescriptor getFileDescriptor();
- method public java.io.FileDescriptor[] getFileDescriptors();
- method public int[] getInts();
+ method @NonNull public android.os.NativeHandle dup() throws java.io.IOException;
+ method @NonNull public java.io.FileDescriptor getFileDescriptor();
+ method @NonNull public java.io.FileDescriptor[] getFileDescriptors();
+ method @NonNull public int[] getInts();
method public boolean hasSingleFileDescriptor();
}
@@ -5605,7 +5595,7 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.graphics.Bitmap getUserIcon();
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.graphics.Bitmap getUserIcon();
method @Deprecated @android.os.UserManager.UserRestrictionSource @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public int getUserRestrictionSource(String, android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(String, android.os.UserHandle);
method public boolean hasRestrictedProfiles();
@@ -5616,8 +5606,8 @@
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isPrimaryUser();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(android.graphics.Bitmap);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(String);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
field @Deprecated public static final String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
@@ -5863,6 +5853,7 @@
field public static final String NAMESPACE_NETD_NATIVE = "netd_native";
field public static final String NAMESPACE_RUNTIME_NATIVE_BOOT = "runtime_native_boot";
field public static final String NAMESPACE_SYSTEMUI = "systemui";
+ field public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
}
public static interface DeviceConfig.AttentionManagerService {
@@ -5884,6 +5875,7 @@
}
public static interface DeviceConfig.OnPropertyChangedListener {
+ method public default void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
method public void onPropertyChanged(String, String, String);
}
@@ -5893,6 +5885,16 @@
field public static final String PROPERTY_PERMISSIONS_HUB_ENABLED = "permissions_hub_enabled";
}
+ public static class DeviceConfig.Properties {
+ method public boolean getBoolean(@NonNull String, boolean);
+ method public float getFloat(@NonNull String, float);
+ method public int getInt(@NonNull String, int);
+ method @NonNull public java.util.Set<java.lang.String> getKeyset();
+ method public long getLong(@NonNull String, long);
+ method @NonNull public String getNamespace();
+ method @Nullable public String getString(@NonNull String, @Nullable String);
+ }
+
public static interface DeviceConfig.Rollback {
field public static final String BOOT_NAMESPACE = "rollback_boot";
field public static final String ENABLE_ROLLBACK_TIMEOUT = "enable_rollback_timeout";
@@ -6224,10 +6226,10 @@
public static class KeyChainProtectionParams.Builder {
ctor public KeyChainProtectionParams.Builder();
method @NonNull public android.security.keystore.recovery.KeyChainProtectionParams build();
- method public android.security.keystore.recovery.KeyChainProtectionParams.Builder setKeyDerivationParams(@NonNull android.security.keystore.recovery.KeyDerivationParams);
- method public android.security.keystore.recovery.KeyChainProtectionParams.Builder setLockScreenUiFormat(int);
- method public android.security.keystore.recovery.KeyChainProtectionParams.Builder setSecret(@NonNull byte[]);
- method public android.security.keystore.recovery.KeyChainProtectionParams.Builder setUserSecretType(int);
+ method @NonNull public android.security.keystore.recovery.KeyChainProtectionParams.Builder setKeyDerivationParams(@NonNull android.security.keystore.recovery.KeyDerivationParams);
+ method @NonNull public android.security.keystore.recovery.KeyChainProtectionParams.Builder setLockScreenUiFormat(int);
+ method @NonNull public android.security.keystore.recovery.KeyChainProtectionParams.Builder setSecret(@NonNull byte[]);
+ method @NonNull public android.security.keystore.recovery.KeyChainProtectionParams.Builder setUserSecretType(int);
}
public final class KeyChainSnapshot implements android.os.Parcelable {
@@ -6308,9 +6310,9 @@
public static class WrappedApplicationKey.Builder {
ctor public WrappedApplicationKey.Builder();
method @NonNull public android.security.keystore.recovery.WrappedApplicationKey build();
- method public android.security.keystore.recovery.WrappedApplicationKey.Builder setAlias(@NonNull String);
- method public android.security.keystore.recovery.WrappedApplicationKey.Builder setEncryptedKeyMaterial(@NonNull byte[]);
- method public android.security.keystore.recovery.WrappedApplicationKey.Builder setMetadata(@Nullable byte[]);
+ method @NonNull public android.security.keystore.recovery.WrappedApplicationKey.Builder setAlias(@NonNull String);
+ method @NonNull public android.security.keystore.recovery.WrappedApplicationKey.Builder setEncryptedKeyMaterial(@NonNull byte[]);
+ method @NonNull public android.security.keystore.recovery.WrappedApplicationKey.Builder setMetadata(@Nullable byte[]);
}
}
@@ -8510,7 +8512,7 @@
public class ImsException extends java.lang.Exception {
ctor public ImsException(@Nullable String);
ctor public ImsException(@Nullable String, int);
- ctor public ImsException(@Nullable String, int, Throwable);
+ ctor public ImsException(@Nullable String, int, @Nullable Throwable);
method public int getCode();
field public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; // 0x1
field public static final int CODE_ERROR_UNSPECIFIED = 0; // 0x0
@@ -8518,13 +8520,13 @@
}
public final class ImsExternalCallState implements android.os.Parcelable {
- ctor public ImsExternalCallState(String, android.net.Uri, android.net.Uri, boolean, int, int, boolean);
+ ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
method public int describeContents();
- method public android.net.Uri getAddress();
+ method @NonNull public android.net.Uri getAddress();
method public int getCallId();
method public int getCallState();
method public int getCallType();
- method public android.net.Uri getLocalAddress();
+ method @Nullable public android.net.Uri getLocalAddress();
method public boolean isCallHeld();
method public boolean isCallPullable();
method public void writeToParcel(android.os.Parcel, int);
@@ -8534,7 +8536,7 @@
}
public class ImsMmTelManager {
- method public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+ method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAdvancedCallingSettingEnabled();
@@ -8543,7 +8545,7 @@
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiRoamingSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVtSettingEnabled();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
@@ -8562,15 +8564,15 @@
public static class ImsMmTelManager.CapabilityCallback {
ctor public ImsMmTelManager.CapabilityCallback();
- method public void onCapabilitiesStatusChanged(android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+ method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
}
public static class ImsMmTelManager.RegistrationCallback {
ctor public ImsMmTelManager.RegistrationCallback();
method public void onRegistered(int);
method public void onRegistering(int);
- method public void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
- method public void onUnregistered(android.telephony.ims.ImsReasonInfo);
+ method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
+ method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
}
public final class ImsReasonInfo implements android.os.Parcelable {
@@ -8979,14 +8981,14 @@
}
public class ProvisioningManager {
- method public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
+ method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getProvisioningIntValue(int);
method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
- method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getProvisioningStringValue(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
method @WorkerThread @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, String);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 22a3fb3..7e04469 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -60,6 +60,17 @@
}
+package android.location {
+
+ public class LocationManager {
+ method @Deprecated public boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
+ method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
+ method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
+ method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
+ }
+
+}
+
package android.media.tv {
public final class TvInputManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index 6d90c4a..9beef29 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -563,11 +563,13 @@
ctor public AutofillOptions(int, boolean);
method public int describeContents();
method public static android.content.AutofillOptions forWhitelistingItself();
+ method public boolean isAugmentedAutofillEnabled(@NonNull android.content.Context);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.AutofillOptions> CREATOR;
- field public boolean augmentedEnabled;
+ field public boolean augmentedAutofillEnabled;
field public final boolean compatModeEnabled;
field public final int loggingLevel;
+ field @Nullable public android.util.ArraySet<android.content.ComponentName> whitelistedActivitiesForAugmentedAutofill;
}
public final class ContentCaptureOptions implements android.os.Parcelable {
@@ -936,16 +938,16 @@
}
public class LocationManager {
- method public String[] getBackgroundThrottlingWhitelist();
- method public String[] getIgnoreSettingsWhitelist();
+ method @NonNull public String[] getBackgroundThrottlingWhitelist();
+ method @NonNull public String[] getIgnoreSettingsWhitelist();
method @NonNull public java.util.List<android.location.LocationRequest> getTestProviderCurrentRequests(String);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, android.os.UserHandle);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
}
public final class LocationRequest implements android.os.Parcelable {
- method public static android.location.LocationRequest create();
+ method @NonNull public static android.location.LocationRequest create();
method public int describeContents();
method public long getExpireAt();
method public long getFastestInterval();
@@ -953,14 +955,14 @@
method public int getNumUpdates();
method public int getQuality();
method public boolean isLocationSettingsIgnored();
- method public android.location.LocationRequest setExpireAt(long);
- method public android.location.LocationRequest setExpireIn(long);
- method public android.location.LocationRequest setFastestInterval(long);
- method public android.location.LocationRequest setInterval(long);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
- method public android.location.LocationRequest setNumUpdates(int);
- method public android.location.LocationRequest setProvider(String);
- method public android.location.LocationRequest setQuality(int);
+ method @NonNull public android.location.LocationRequest setExpireAt(long);
+ method @NonNull public android.location.LocationRequest setExpireIn(long);
+ method @NonNull public android.location.LocationRequest setFastestInterval(long);
+ method @NonNull public android.location.LocationRequest setInterval(long);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull public android.location.LocationRequest setNumUpdates(int);
+ method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
+ method @NonNull public android.location.LocationRequest setQuality(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACCURACY_BLOCK = 102; // 0x66
field public static final int ACCURACY_CITY = 104; // 0x68
@@ -1520,7 +1522,7 @@
method public final void putInt64Array(long, long[]);
method public final void putInt8(long, byte);
method public final void putInt8Array(long, byte[]);
- method public final void putNativeHandle(long, android.os.NativeHandle);
+ method public final void putNativeHandle(long, @Nullable android.os.NativeHandle);
method public final void putString(long, String);
method public static Boolean[] wrapArray(@NonNull boolean[]);
method public static Long[] wrapArray(@NonNull long[]);
@@ -1540,7 +1542,7 @@
method public final double readDouble();
method public final java.util.ArrayList<java.lang.Double> readDoubleVector();
method public final android.os.HwBlob readEmbeddedBuffer(long, long, long, boolean);
- method public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
+ method @Nullable public final android.os.NativeHandle readEmbeddedNativeHandle(long, long);
method public final float readFloat();
method public final java.util.ArrayList<java.lang.Float> readFloatVector();
method public final short readInt16();
@@ -1551,8 +1553,8 @@
method public final java.util.ArrayList<java.lang.Long> readInt64Vector();
method public final byte readInt8();
method public final java.util.ArrayList<java.lang.Byte> readInt8Vector();
- method public final android.os.NativeHandle readNativeHandle();
- method public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
+ method @Nullable public final android.os.NativeHandle readNativeHandle();
+ method @NonNull public final java.util.ArrayList<android.os.NativeHandle> readNativeHandleVector();
method public final String readString();
method public final java.util.ArrayList<java.lang.String> readStringVector();
method public final android.os.IHwBinder readStrongBinder();
@@ -1576,8 +1578,8 @@
method public final void writeInt8(byte);
method public final void writeInt8Vector(java.util.ArrayList<java.lang.Byte>);
method public final void writeInterfaceToken(String);
- method public final void writeNativeHandle(android.os.NativeHandle);
- method public final void writeNativeHandleVector(java.util.ArrayList<android.os.NativeHandle>);
+ method public final void writeNativeHandle(@Nullable android.os.NativeHandle);
+ method public final void writeNativeHandleVector(@NonNull java.util.ArrayList<android.os.NativeHandle>);
method public final void writeStatus(int);
method public final void writeString(String);
method public final void writeStringVector(java.util.ArrayList<java.lang.String>);
@@ -1670,10 +1672,10 @@
ctor public NativeHandle(@NonNull java.io.FileDescriptor, boolean);
ctor public NativeHandle(@NonNull java.io.FileDescriptor[], @NonNull int[], boolean);
method public void close() throws java.io.IOException;
- method public android.os.NativeHandle dup() throws java.io.IOException;
- method public java.io.FileDescriptor getFileDescriptor();
- method public java.io.FileDescriptor[] getFileDescriptors();
- method public int[] getInts();
+ method @NonNull public android.os.NativeHandle dup() throws java.io.IOException;
+ method @NonNull public java.io.FileDescriptor getFileDescriptor();
+ method @NonNull public java.io.FileDescriptor[] getFileDescriptors();
+ method @NonNull public int[] getInts();
method public boolean hasSingleFileDescriptor();
}
@@ -1990,6 +1992,7 @@
}
public static interface DeviceConfig.OnPropertyChangedListener {
+ method public default void onPropertiesChanged(@NonNull android.provider.DeviceConfig.Properties);
method public void onPropertyChanged(String, String, String);
}
@@ -1998,6 +2001,16 @@
field public static final String PROPERTY_LOCATION_ACCESS_CHECK_ENABLED = "location_access_check_enabled";
}
+ public static class DeviceConfig.Properties {
+ method public boolean getBoolean(@NonNull String, boolean);
+ method public float getFloat(@NonNull String, float);
+ method public int getInt(@NonNull String, int);
+ method @NonNull public java.util.Set<java.lang.String> getKeyset();
+ method public long getLong(@NonNull String, long);
+ method @NonNull public String getNamespace();
+ method @Nullable public String getString(@NonNull String, @Nullable String);
+ }
+
public final class MediaStore {
method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static void deleteContributedMedia(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 831cac2..e573279 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -36,6 +36,7 @@
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
import android.view.Window;
+import android.view.inspector.InspectableProperty;
import android.widget.SpinnerAdapter;
import java.lang.annotation.Retention;
@@ -1374,6 +1375,9 @@
@ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity = Gravity.NO_GRAVITY;
public LayoutParams(@NonNull Context c, AttributeSet attrs) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d1d4bd5..56bf8fa 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -127,6 +127,7 @@
import android.view.autofill.IAutofillWindowPresenter;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureManager;
+import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -717,7 +718,7 @@
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback,
- AutofillManager.AutofillClient {
+ AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
private static final String TAG = "Activity";
private static final boolean DEBUG_LIFECYCLE = false;
@@ -1119,6 +1120,12 @@
return this;
}
+ /** @hide */
+ @Override
+ public final ContentCaptureClient getContentCaptureClient() {
+ return this;
+ }
+
/**
* Register an {@link Application.ActivityLifecycleCallbacks} instance that receives
* lifecycle callbacks for only this Activity.
@@ -6464,6 +6471,12 @@
return getComponentName();
}
+ /** @hide */
+ @Override
+ public final ComponentName contentCaptureClientGetComponentName() {
+ return getComponentName();
+ }
+
/**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity. This simply calls the underlying
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 08239a1..c0a702f 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3115,10 +3115,6 @@
if (!r.stopped) {
throw new IllegalStateException("Can't start activity that is not stopped.");
}
- if (r.activity.mFinished) {
- // TODO(lifecycler): How can this happen?
- return;
- }
// Start
activity.performStart("handleStartActivity");
@@ -3241,6 +3237,8 @@
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
+ }
+ if (pendingActions != null) {
pendingActions.setCallOnPostCreate(true);
}
} else {
@@ -3942,7 +3940,7 @@
if (localLOGV) {
Slog.v(TAG, "Performing resume of " + r + " finished=" + r.activity.mFinished);
}
- if (r == null || r.activity.mFinished) {
+ if (r == null) {
return null;
}
if (r.getLifecycleState() == ON_RESUME) {
@@ -4212,12 +4210,6 @@
private Bundle performPauseActivity(ActivityClientRecord r, boolean finished, String reason,
PendingTransactionActions pendingActions) {
if (r.paused) {
- if (r.activity.mFinished) {
- // If we are finishing, we won't call onResume() in certain cases.
- // So here we likewise don't want to call onPause() if the activity
- // isn't resumed.
- return null;
- }
RuntimeException e = new RuntimeException(
"Performing pause of activity that is not resumed: "
+ r.intent.getComponent().toShortString());
@@ -4337,20 +4329,13 @@
boolean saveState, boolean finalStateRequest, String reason) {
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
if (r != null) {
- if (!keepShown && r.stopped) {
- if (r.activity.mFinished) {
- // If we are finishing, we won't call onResume() in certain
- // cases. So here we likewise don't want to call onStop()
- // if the activity isn't resumed.
- return;
- }
- if (!finalStateRequest) {
- final RuntimeException e = new RuntimeException(
- "Performing stop of activity that is already stopped: "
- + r.intent.getComponent().toShortString());
- Slog.e(TAG, e.getMessage(), e);
- Slog.e(TAG, r.getStateString());
- }
+ if (!keepShown && r.stopped && !finalStateRequest) {
+ // Double stop request is possible if activity receives 'sleep' followed by 'stop'.
+ final RuntimeException e = new RuntimeException(
+ "Performing stop of activity that is already stopped: "
+ + r.intent.getComponent().toShortString());
+ Slog.e(TAG, e.getMessage(), e);
+ Slog.e(TAG, r.getStateString());
}
// One must first be paused before stopped...
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index 062a462..161e2ad 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -61,7 +61,7 @@
"android:broadcast.dontSendToRestrictedApps";
/**
- * Corresponds to {@link #setAllowBackgroundActivityStarts}.
+ * Corresponds to {@link #setBackgroundActivityStartsAllowed}.
*/
static final String KEY_ALLOW_BACKGROUND_ACTIVITY_STARTS =
"android:broadcast.allowBackgroundActivityStarts";
@@ -161,7 +161,7 @@
* the broadcast dispatch. Default value is {@code false}
*/
@RequiresPermission(android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND)
- public void setAllowBackgroundActivityStarts(boolean allowBackgroundActivityStarts) {
+ public void setBackgroundActivityStartsAllowed(boolean allowBackgroundActivityStarts) {
mAllowBackgroundActivityStarts = allowBackgroundActivityStarts;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index f690f5d..03806fa 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -31,6 +31,7 @@
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.Intent;
+import android.content.LocusId;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -77,6 +78,7 @@
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
+import android.view.contentcapture.ContentCaptureContext;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
@@ -1271,6 +1273,7 @@
private long mTimeout;
private String mShortcutId;
+ private LocusId mLocusId;
private CharSequence mSettingsText;
private BubbleMetadata mBubbleMetadata;
@@ -2274,6 +2277,10 @@
mShortcutId = parcel.readString();
}
+ if (parcel.readInt() != 0) {
+ mLocusId = LocusId.CREATOR.createFromParcel(parcel);
+ }
+
mBadgeIcon = parcel.readInt();
if (parcel.readInt() != 0) {
@@ -2397,6 +2404,7 @@
that.mChannelId = this.mChannelId;
that.mTimeout = this.mTimeout;
that.mShortcutId = this.mShortcutId;
+ that.mLocusId = this.mLocusId;
that.mBadgeIcon = this.mBadgeIcon;
that.mSettingsText = this.mSettingsText;
that.mGroupAlertBehavior = this.mGroupAlertBehavior;
@@ -2712,6 +2720,13 @@
parcel.writeInt(0);
}
+ if (mLocusId != null) {
+ parcel.writeInt(1);
+ mLocusId.writeToParcel(parcel, 0);
+ } else {
+ parcel.writeInt(0);
+ }
+
parcel.writeInt(mBadgeIcon);
if (mSettingsText != null) {
@@ -3025,6 +3040,10 @@
sb.append(" publicVersion=");
sb.append(publicVersion.toString());
}
+ if (this.mLocusId != null) {
+ sb.append(" locusId=");
+ sb.append(this.mLocusId); // LocusId.toString() is PII safe.
+ }
sb.append(")");
return sb.toString();
}
@@ -3127,6 +3146,16 @@
return mShortcutId;
}
+ /**
+ * Gets the {@link LocusId} associated with this notification.
+ *
+ * <p>Used by the device's intelligence services to correlate objects (such as
+ * {@link ShortcutInfo} and {@link ContentCaptureContext}) that are correlated.
+ */
+ @Nullable
+ public LocusId getLocusId() {
+ return mLocusId;
+ }
/**
* Returns the settings text provided to {@link Builder#setSettingsText(CharSequence)}.
@@ -3485,6 +3514,19 @@
}
/**
+ * Sets the {@link LocusId} associated with this notification.
+ *
+ * <p>This method should be called when the {@link LocusId} is used in other places (such
+ * as {@link ShortcutInfo} and {@link ContentCaptureContext}) so the device's intelligence
+ * services can correlate them.
+ */
+ @NonNull
+ public Builder setLocusId(@Nullable LocusId locusId) {
+ mN.mLocusId = locusId;
+ return this;
+ }
+
+ /**
* Sets which icon to display as a badge for this notification.
*
* Must be one of {@link #BADGE_ICON_NONE}, {@link #BADGE_ICON_SMALL},
diff --git a/core/java/android/content/AutofillOptions.java b/core/java/android/content/AutofillOptions.java
index 0d25f4d..f59bc98 100644
--- a/core/java/android/content/AutofillOptions.java
+++ b/core/java/android/content/AutofillOptions.java
@@ -16,12 +16,15 @@
package android.content;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArraySet;
import android.util.Log;
import android.view.autofill.AutofillManager;
+import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import java.io.PrintWriter;
@@ -51,8 +54,13 @@
/**
* Whether package is whitelisted for augmented autofill.
*/
- public boolean augmentedEnabled;
- // TODO(b/123100824): add (optional) list of activities
+ public boolean augmentedAutofillEnabled;
+
+ /**
+ * List of whitelisted activities.
+ */
+ @Nullable
+ public ArraySet<ComponentName> whitelistedActivitiesForAugmentedAutofill;
public AutofillOptions(int loggingLevel, boolean compatModeEnabled) {
this.loggingLevel = loggingLevel;
@@ -60,6 +68,20 @@
}
/**
+ * Returns whether activity is whitelisted for augmented autofill.
+ */
+ public boolean isAugmentedAutofillEnabled(@NonNull Context context) {
+ if (!augmentedAutofillEnabled) return false;
+
+ final ContentCaptureClient contentCaptureClient = context.getContentCaptureClient();
+ if (contentCaptureClient == null) return false;
+
+ final ComponentName component = contentCaptureClient.contentCaptureClientGetComponentName();
+ return whitelistedActivitiesForAugmentedAutofill == null
+ || whitelistedActivitiesForAugmentedAutofill.contains(component);
+ }
+
+ /**
* @hide
*/
@TestApi
@@ -78,7 +100,7 @@
final AutofillOptions options = new AutofillOptions(
AutofillManager.FLAG_ADD_CLIENT_VERBOSE, /* compatModeAllowed= */ true);
- options.augmentedEnabled = true;
+ options.augmentedAutofillEnabled = true;
// Always log, as it's used by test only
Log.i(TAG, "forWhitelistingItself(" + packageName + "): " + options);
@@ -87,15 +109,19 @@
@Override
public String toString() {
- return "AutofillOptions [loggingLevel=" + loggingLevel + ", compatMode="
- + compatModeEnabled + ", augmentedEnabled=" + augmentedEnabled + "]";
+ return "AutofillOptions [loggingLevel=" + loggingLevel + ", compatMode=" + compatModeEnabled
+ + ", augmentedAutofillEnabled=" + augmentedAutofillEnabled + "]";
}
/** @hide */
public void dumpShort(@NonNull PrintWriter pw) {
pw.print("logLvl="); pw.print(loggingLevel);
pw.print(", compatMode="); pw.print(compatModeEnabled);
- pw.print(", augmented="); pw.print(augmentedEnabled);
+ pw.print(", augmented="); pw.print(augmentedAutofillEnabled);
+ if (whitelistedActivitiesForAugmentedAutofill != null) {
+ pw.print(", whitelistedActivitiesForAugmentedAutofill=");
+ pw.print(whitelistedActivitiesForAugmentedAutofill);
+ }
}
@Override
@@ -107,7 +133,8 @@
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(loggingLevel);
parcel.writeBoolean(compatModeEnabled);
- parcel.writeBoolean(augmentedEnabled);
+ parcel.writeBoolean(augmentedAutofillEnabled);
+ parcel.writeArraySet(whitelistedActivitiesForAugmentedAutofill);
}
public static final @android.annotation.NonNull Parcelable.Creator<AutofillOptions> CREATOR =
@@ -118,7 +145,9 @@
final int loggingLevel = parcel.readInt();
final boolean compatMode = parcel.readBoolean();
final AutofillOptions options = new AutofillOptions(loggingLevel, compatMode);
- options.augmentedEnabled = parcel.readBoolean();
+ options.augmentedAutofillEnabled = parcel.readBoolean();
+ options.whitelistedActivitiesForAugmentedAutofill =
+ (ArraySet<ComponentName>) parcel.readArraySet(null);
return options;
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index beb1fb6..41995288 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -69,6 +69,7 @@
import android.view.ViewDebug;
import android.view.WindowManager;
import android.view.autofill.AutofillManager.AutofillClient;
+import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.view.textclassifier.TextClassificationManager;
import java.io.File;
@@ -5343,6 +5344,14 @@
/**
* @hide
*/
+ @Nullable
+ public ContentCaptureClient getContentCaptureClient() {
+ return null;
+ }
+
+ /**
+ * @hide
+ */
public final boolean isAutofillCompatibilityEnabled() {
final AutofillOptions options = getAutofillOptions();
return options != null && options.compatModeEnabled;
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index d5273db..7b61807 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -22,11 +22,13 @@
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.annotation.UserIdInt;
+import android.app.Notification;
import android.app.Person;
import android.app.TaskStackBuilder;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.LocusId;
import android.content.pm.LauncherApps.ShortcutQuery;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
@@ -41,6 +43,7 @@
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
+import android.view.contentcapture.ContentCaptureContext;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
@@ -354,6 +357,9 @@
@Nullable
private Person[] mPersons;
+ @Nullable
+ private LocusId mLocusId;
+
private int mRank;
/**
@@ -415,6 +421,8 @@
}
mRank = b.mRank;
mExtras = b.mExtras;
+ mLocusId = b.mLocusId;
+
updateTimestamp();
}
@@ -521,6 +529,7 @@
mFlags = source.mFlags;
mLastChangedTimestamp = source.mLastChangedTimestamp;
mDisabledReason = source.mDisabledReason;
+ mLocusId = source.mLocusId;
// Just always keep it since it's cheep.
mIconResId = source.mIconResId;
@@ -876,6 +885,10 @@
if (source.mExtras != null) {
mExtras = source.mExtras;
}
+
+ if (source.mLocusId != null) {
+ mLocusId = source.mLocusId;
+ }
}
/**
@@ -941,6 +954,8 @@
private PersistableBundle mExtras;
+ private LocusId mLocusId;
+
/**
* Old style constructor.
* @hide
@@ -973,6 +988,19 @@
}
/**
+ * Sets the {@link LocusId} associated with this shortcut.
+ *
+ * <p>This method should be called when the {@link LocusId} is used in other places (such
+ * as {@link Notification} and {@link ContentCaptureContext}) so the device's intelligence
+ * services can correlate them.
+ */
+ @NonNull
+ public Builder setLocusId(@NonNull LocusId locusId) {
+ mLocusId = Preconditions.checkNotNull(locusId, "locusId cannot be null");
+ return this;
+ }
+
+ /**
* Sets the target activity. A shortcut will be shown along with this activity's icon
* on the launcher.
*
@@ -1295,6 +1323,17 @@
}
/**
+ * Gets the {@link LocusId} associated with this shortcut.
+ *
+ * <p>Used by the device's intelligence services to correlate objects (such as
+ * {@link Notification} and {@link ContentCaptureContext}) that are correlated.
+ */
+ @Nullable
+ public LocusId getLocusId() {
+ return mLocusId;
+ }
+
+ /**
* Return the package name of the publisher app.
*/
@NonNull
@@ -1999,6 +2038,7 @@
}
mPersons = source.readParcelableArray(cl, Person.class);
+ mLocusId = source.readParcelable(cl);
}
@Override
@@ -2048,6 +2088,7 @@
}
dest.writeParcelableArray(mPersons, flags);
+ dest.writeParcelable(mLocusId, flags);
}
public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR =
@@ -2263,6 +2304,10 @@
sb.append(mBitmapPath);
}
+ if (mLocusId != null) {
+ sb.append("locusId="); sb.append(mLocusId); // LocusId.toString() is PII-safe.
+ }
+
sb.append("}");
return sb.toString();
}
@@ -2276,7 +2321,7 @@
Set<String> categories, Intent[] intentsWithExtras, int rank, PersistableBundle extras,
long lastChangedTimestamp,
int flags, int iconResId, String iconResName, String bitmapPath, int disabledReason,
- Person[] persons) {
+ Person[] persons, LocusId locusId) {
mUserId = userId;
mId = id;
mPackageName = packageName;
@@ -2303,5 +2348,6 @@
mBitmapPath = bitmapPath;
mDisabledReason = disabledReason;
mPersons = persons;
+ mLocusId = locusId;
}
}
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 55b340f..139a5ee 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -286,14 +286,15 @@
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public void setFeature(int feature, boolean enabled, byte[] token) {
+ public boolean setFeature(int feature, boolean enabled, byte[] token) {
if (mService != null) {
try {
- mService.setFeature(feature, enabled, token);
+ return mService.setFeature(feature, enabled, token);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
+ return false;
}
/**
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 9609e99..5043d4c 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -98,7 +98,7 @@
// Enumerate all faces
void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver);
- int setFeature(int feature, boolean enabled, in byte [] token);
+ boolean setFeature(int feature, boolean enabled, in byte [] token);
boolean getFeature(int feature);
diff --git a/core/java/android/os/HwBlob.java b/core/java/android/os/HwBlob.java
index 0ec63b5..2c453bf 100644
--- a/core/java/android/os/HwBlob.java
+++ b/core/java/android/os/HwBlob.java
@@ -17,6 +17,7 @@
package android.os;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -241,7 +242,7 @@
* @param x a {@link NativeHandle} instance to write
* @throws IndexOutOfBoundsException when [offset, offset + sizeof(jobject)] is out of range
*/
- public native final void putNativeHandle(long offset, NativeHandle x);
+ public native final void putNativeHandle(long offset, @Nullable NativeHandle x);
/**
* Put a boolean array contiguously at an offset in the blob.
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 7919a00..dc640c9 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -17,6 +17,8 @@
package android.os;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -123,7 +125,7 @@
*
* @param val to write
*/
- public native final void writeNativeHandle(NativeHandle val);
+ public native final void writeNativeHandle(@Nullable NativeHandle val);
/**
* Writes an array of boolean values to the end of the parcel.
@@ -170,6 +172,9 @@
private native final void writeStringVector(String[] val);
/**
* Writes an array of native handles to the end of the parcel.
+ *
+ * Individual elements may be null but not the whole array.
+ *
* @param val array of {@link NativeHandle} objects to write
*/
private native final void writeNativeHandleVector(NativeHandle[] val);
@@ -284,7 +289,7 @@
* Helper method to write a list of native handles to the end of the parcel.
* @param val list of {@link NativeHandle} objects to write
*/
- public final void writeNativeHandleVector(ArrayList<NativeHandle> val) {
+ public final void writeNativeHandleVector(@NonNull ArrayList<NativeHandle> val) {
writeNativeHandleVector(val.toArray(new NativeHandle[val.size()]));
}
@@ -359,7 +364,7 @@
* @return a {@link NativeHandle} instance parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
- public native final NativeHandle readNativeHandle();
+ public native final @Nullable NativeHandle readNativeHandle();
/**
* Reads an embedded native handle (without duplicating the underlying
* file descriptors) from the parcel. These file descriptors will only
@@ -372,7 +377,7 @@
* @return a {@link NativeHandle} instance parsed from the parcel
* @throws IllegalArgumentException if the parcel has no more data
*/
- public native final NativeHandle readEmbeddedNativeHandle(
+ public native final @Nullable NativeHandle readEmbeddedNativeHandle(
long parentHandle, long offset);
/**
@@ -521,7 +526,7 @@
* @return array of {@link NativeHandle} objects.
* @throws IllegalArgumentException if the parcel has no more data
*/
- public final ArrayList<NativeHandle> readNativeHandleVector() {
+ public final @NonNull ArrayList<NativeHandle> readNativeHandleVector() {
return new ArrayList<NativeHandle>(Arrays.asList(readNativeHandleAsArray()));
}
diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java
index f13bf5f..8d341b6 100644
--- a/core/java/android/os/NativeHandle.java
+++ b/core/java/android/os/NativeHandle.java
@@ -99,6 +99,8 @@
* @return a boolean value
*/
public boolean hasSingleFileDescriptor() {
+ checkOpen();
+
return mFds.length == 1 && mInts.length == 0;
}
@@ -108,7 +110,7 @@
* If this method is called, this must also be explicitly closed with
* {@link #close()}.
*/
- public NativeHandle dup() throws java.io.IOException {
+ public @NonNull NativeHandle dup() throws java.io.IOException {
FileDescriptor[] fds = new FileDescriptor[mFds.length];
try {
for (int i = 0; i < mFds.length; i++) {
@@ -123,6 +125,12 @@
return new NativeHandle(fds, mInts, true /*own*/);
}
+ private void checkOpen() {
+ if (mFds == null) {
+ throw new IllegalStateException("NativeHandle is invalidated after close.");
+ }
+ }
+
/**
* Closes the file descriptors if they are owned by this object.
*
@@ -130,19 +138,20 @@
*/
@Override
public void close() throws java.io.IOException {
- if (!mOwn) {
- return;
- }
+ checkOpen();
- try {
- for (FileDescriptor fd : mFds) {
- Os.close(fd);
+ if (mOwn) {
+ try {
+ for (FileDescriptor fd : mFds) {
+ Os.close(fd);
+ }
+ } catch (ErrnoException e) {
+ e.rethrowAsIOException();
}
- } catch (ErrnoException e) {
- e.rethrowAsIOException();
+
+ mOwn = false;
}
- mOwn = false;
mFds = null;
mInts = null;
}
@@ -154,7 +163,9 @@
* @throws IllegalStateException if this object contains either zero or
* more than one file descriptor, or a non-empty data stream.
*/
- public FileDescriptor getFileDescriptor() {
+ public @NonNull FileDescriptor getFileDescriptor() {
+ checkOpen();
+
if (!hasSingleFileDescriptor()) {
throw new IllegalStateException(
"NativeHandle is not single file descriptor. Contents must"
@@ -171,6 +182,8 @@
* @hide
*/
private int[] getFdsAsIntArray() {
+ checkOpen();
+
int numFds = mFds.length;
int[] fds = new int[numFds];
@@ -182,11 +195,13 @@
}
/**
- * Fetch file descriptors.
+ * Fetch file descriptors
*
* @return the fds.
*/
- public FileDescriptor[] getFileDescriptors() {
+ public @NonNull FileDescriptor[] getFileDescriptors() {
+ checkOpen();
+
return mFds;
}
@@ -195,7 +210,9 @@
*
* @return the opaque data stream.
*/
- public int[] getInts() {
+ public @NonNull int[] getInts() {
+ checkOpen();
+
return mInts;
}
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7f73dab..4263377 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2705,7 +2705,7 @@
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public void setUserName(String name) {
+ public void setUserName(@Nullable String name) {
setUserName(getUserHandle(), name);
}
@@ -2732,7 +2732,7 @@
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public void setUserIcon(Bitmap icon) {
+ public void setUserIcon(@NonNull Bitmap icon) {
setUserIcon(getUserHandle(), icon);
}
@@ -2772,7 +2772,7 @@
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public Bitmap getUserIcon() {
+ public @Nullable Bitmap getUserIcon() {
return getUserIcon(getUserHandle());
}
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 5d4539c..ba54bd2 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -33,10 +33,12 @@
import android.util.Pair;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executor;
/**
@@ -144,6 +146,14 @@
public static final String NAMESPACE_SYSTEMUI = "systemui";
/**
+ * Namespace for TextClassifier related features.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
+
+ /**
* Namespace for all runtime related features.
*
* @hide
@@ -656,16 +666,18 @@
private static void handleChange(Uri uri) {
List<String> pathSegments = uri.getPathSegments();
// pathSegments(0) is "config"
- String namespace = pathSegments.get(1);
- String name = pathSegments.get(2);
- String value = getProperty(namespace, name);
+ final String namespace = pathSegments.get(1);
+ final String name = pathSegments.get(2);
+ final String value = getProperty(namespace, name);
synchronized (sLock) {
- for (OnPropertyChangedListener listener : sListeners.keySet()) {
+ for (final OnPropertyChangedListener listener : sListeners.keySet()) {
if (namespace.equals(sListeners.get(listener).first)) {
sListeners.get(listener).second.execute(new Runnable() {
@Override
public void run() {
- listener.onPropertyChanged(namespace, name, value);
+ Map<String, String> propertyMap = new HashMap(1);
+ propertyMap.put(name, value);
+ listener.onPropertiesChanged(new Properties(namespace, propertyMap));
}
});
@@ -692,5 +704,147 @@
* @param value The new value of the property which has changed.
*/
void onPropertyChanged(String namespace, String name, String value);
+
+ /**
+ * Called when one or more properties have changed.
+ *
+ * @param properties Contains the complete collection of properties which have changed for a
+ * single namespace.
+ */
+ default void onPropertiesChanged(@NonNull Properties properties) {
+ // During the transitional period, this method calls the old one to ensure legacy
+ // callers continue to function as expected. Ignore this if you are implementing it for
+ // yourself.
+ String namespace = properties.getNamespace();
+ for (String name : properties.getKeyset()) {
+ onPropertyChanged(namespace, name, properties.getString(name, null));
+ }
+ }
+ }
+
+ /**
+ * A mapping of properties to values, as well as a single namespace which they all belong to.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static class Properties {
+ private final String mNamespace;
+ private final HashMap<String, String> mMap;
+
+ /**
+ * Create a mapping of properties to values and the namespace they belong to.
+ *
+ * @param namespace The namespace these properties belong to.
+ * @param keyValueMap A map between property names and property values.
+ */
+ Properties(@NonNull String namespace, @Nullable Map<String, String> keyValueMap) {
+ Preconditions.checkNotNull(namespace);
+ mNamespace = namespace;
+ mMap = new HashMap();
+ if (keyValueMap != null) {
+ mMap.putAll(keyValueMap);
+ }
+ }
+
+ /**
+ * @return the namespace all properties within this instance belong to.
+ */
+ @NonNull
+ public String getNamespace() {
+ return mNamespace;
+ }
+
+ /**
+ * @return the non-null set of property names.
+ */
+ @NonNull
+ public Set<String> getKeyset() {
+ return mMap.keySet();
+ }
+
+ /**
+ * Look up the String value of a property.
+ *
+ * @param name The name of the property to look up.
+ * @param defaultValue The value to return if the property has not been defined.
+ * @return the corresponding value, or defaultValue if none exists.
+ */
+ @Nullable
+ public String getString(@NonNull String name, @Nullable String defaultValue) {
+ Preconditions.checkNotNull(name);
+ String value = mMap.get(name);
+ return value != null ? value : defaultValue;
+ }
+
+ /**
+ * Look up the boolean value of a property.
+ *
+ * @param name The name of the property to look up.
+ * @param defaultValue The value to return if the property has not been defined.
+ * @return the corresponding value, or defaultValue if none exists.
+ */
+ public boolean getBoolean(@NonNull String name, boolean defaultValue) {
+ Preconditions.checkNotNull(name);
+ String value = mMap.get(name);
+ return value != null ? Boolean.parseBoolean(value) : defaultValue;
+ }
+
+ /**
+ * Look up the int value of a property.
+ *
+ * @param name The name of the property to look up.
+ * @param defaultValue The value to return if the property has not been defined or fails to
+ * parse into an int.
+ * @return the corresponding value, or defaultValue if no valid int is available.
+ */
+ public int getInt(@NonNull String name, int defaultValue) {
+ Preconditions.checkNotNull(name);
+ String value = mMap.get(name);
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Look up the long value of a property.
+ *
+ * @param name The name of the property to look up.
+ * @param defaultValue The value to return if the property has not been defined. or fails to
+ * parse into a long.
+ * @return the corresponding value, or defaultValue if no valid long is available.
+ */
+ public long getLong(@NonNull String name, long defaultValue) {
+ Preconditions.checkNotNull(name);
+ String value = mMap.get(name);
+ try {
+ return Long.parseLong(value);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ }
+ }
+
+ /**
+ * Look up the int value of a property.
+ *
+ * @param name The name of the property to look up.
+ * @param defaultValue The value to return if the property has not been defined. or fails to
+ * parse into a float.
+ * @return the corresponding value, or defaultValue if no valid float is available.
+ */
+ public float getFloat(@NonNull String name, float defaultValue) {
+ Preconditions.checkNotNull(name);
+ String value = mMap.get(name);
+ try {
+ return Float.parseFloat(value);
+ } catch (NumberFormatException e) {
+ return defaultValue;
+ } catch (NullPointerException e) {
+ return defaultValue;
+ }
+ }
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f2bb87d..7a16742 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10684,7 +10684,7 @@
/**
* Setting to enable the Wi-Fi link probing.
- * Disabled by default, and setting it to 1 will enable it.
+ * Enabled by default, and setting it to 0 will disable it.
* The value is boolean (0 or 1).
* @hide
*/
@@ -11917,22 +11917,24 @@
* entity_list_default use ":" as delimiter for values. Ex:
*
* <pre>
- * smart_linkify_enabled (boolean)
- * system_textclassifier_enabled (boolean)
- * model_dark_launch_enabled (boolean)
- * smart_selection_enabled (boolean)
- * smart_text_share_enabled (boolean)
- * smart_linkify_enabled (boolean)
- * smart_select_animation_enabled (boolean)
- * suggest_selection_max_range_length (int)
- * classify_text_max_range_length (int)
- * generate_links_max_text_length (int)
- * generate_links_log_sample_rate (int)
- * entity_list_default (String[])
- * entity_list_not_editable (String[])
- * entity_list_editable (String[])
- * lang_id_threshold_override (float)
- * template_intent_factory_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * system_textclassifier_enabled (boolean)
+ * model_dark_launch_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * smart_select_animation_enabled (boolean)
+ * suggest_selection_max_range_length (int)
+ * classify_text_max_range_length (int)
+ * generate_links_max_text_length (int)
+ * generate_links_log_sample_rate (int)
+ * entity_list_default (String[])
+ * entity_list_not_editable (String[])
+ * entity_list_editable (String[])
+ * in_app_conversation_action_types_default (String[])
+ * notification_conversation_action_types_default (String[])
+ * lang_id_threshold_override (float)
+ * template_intent_factory_enabled (boolean)
* </pre>
*
* <p>
@@ -14587,6 +14589,14 @@
*/
public static final String BATTERY_CHARGING_STATE_UPDATE_DELAY =
"battery_charging_state_update_delay";
+
+ /**
+ * A serialized string of params that will be loaded into a text classifier action model.
+ *
+ * @hide
+ */
+ public static final String TEXT_CLASSIFIER_ACTION_MODEL_PARAMS =
+ "text_classifier_action_model_params";
}
/**
diff --git a/core/java/android/security/keystore/recovery/KeyChainProtectionParams.java b/core/java/android/security/keystore/recovery/KeyChainProtectionParams.java
index 8f6b6ec..8801217 100644
--- a/core/java/android/security/keystore/recovery/KeyChainProtectionParams.java
+++ b/core/java/android/security/keystore/recovery/KeyChainProtectionParams.java
@@ -165,7 +165,7 @@
* @param userSecretType The secret type
* @return This builder.
*/
- public Builder setUserSecretType(@UserSecretType int userSecretType) {
+ public @NonNull Builder setUserSecretType(@UserSecretType int userSecretType) {
mInstance.mUserSecretType = userSecretType;
return this;
}
@@ -179,7 +179,7 @@
* @param lockScreenUiFormat The UI format
* @return This builder.
*/
- public Builder setLockScreenUiFormat(@LockScreenUiFormat int lockScreenUiFormat) {
+ public @NonNull Builder setLockScreenUiFormat(@LockScreenUiFormat int lockScreenUiFormat) {
mInstance.mLockScreenUiFormat = lockScreenUiFormat;
return this;
}
@@ -190,7 +190,7 @@
* @param keyDerivationParams Key derivation parameters
* @return This builder.
*/
- public Builder setKeyDerivationParams(@NonNull KeyDerivationParams
+ public @NonNull Builder setKeyDerivationParams(@NonNull KeyDerivationParams
keyDerivationParams) {
mInstance.mKeyDerivationParams = keyDerivationParams;
return this;
@@ -202,7 +202,7 @@
* @param secret The secret.
* @return This builder.
*/
- public Builder setSecret(@NonNull byte[] secret) {
+ public @NonNull Builder setSecret(@NonNull byte[] secret) {
mInstance.mSecret = secret;
return this;
}
@@ -216,7 +216,7 @@
* @return new instance
* @throws NullPointerException if some required fields were not set.
*/
- @NonNull public KeyChainProtectionParams build() {
+ public @NonNull KeyChainProtectionParams build() {
if (mInstance.mUserSecretType == null) {
mInstance.mUserSecretType = TYPE_LOCKSCREEN;
}
@@ -236,7 +236,7 @@
Arrays.fill(mSecret, (byte) 0);
}
- public static final @android.annotation.NonNull Parcelable.Creator<KeyChainProtectionParams> CREATOR =
+ public static final @NonNull Parcelable.Creator<KeyChainProtectionParams> CREATOR =
new Parcelable.Creator<KeyChainProtectionParams>() {
public KeyChainProtectionParams createFromParcel(Parcel in) {
return new KeyChainProtectionParams(in);
diff --git a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
index 18517aa..2f58471 100644
--- a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
+++ b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java
@@ -147,7 +147,7 @@
return mEncryptedRecoveryKeyBlob;
}
- public static final @android.annotation.NonNull Creator<KeyChainSnapshot> CREATOR =
+ public static final @NonNull Creator<KeyChainSnapshot> CREATOR =
new Creator<KeyChainSnapshot>() {
public KeyChainSnapshot createFromParcel(Parcel in) {
return new KeyChainSnapshot(in);
@@ -171,7 +171,7 @@
* @param snapshotVersion The snapshot version
* @return This builder.
*/
- public Builder setSnapshotVersion(int snapshotVersion) {
+ public @NonNull Builder setSnapshotVersion(int snapshotVersion) {
mInstance.mSnapshotVersion = snapshotVersion;
return this;
}
@@ -182,7 +182,7 @@
* @param maxAttempts The maximum number of guesses.
* @return This builder.
*/
- public Builder setMaxAttempts(int maxAttempts) {
+ public @NonNull Builder setMaxAttempts(int maxAttempts) {
mInstance.mMaxAttempts = maxAttempts;
return this;
}
@@ -193,7 +193,7 @@
* @param counterId The counter id.
* @return This builder.
*/
- public Builder setCounterId(long counterId) {
+ public @NonNull Builder setCounterId(long counterId) {
mInstance.mCounterId = counterId;
return this;
}
@@ -204,7 +204,7 @@
* @param serverParams The server parameters
* @return This builder.
*/
- public Builder setServerParams(byte[] serverParams) {
+ public @NonNull Builder setServerParams(byte[] serverParams) {
mInstance.mServerParams = serverParams;
return this;
}
@@ -218,7 +218,7 @@
* @throws CertificateException if the given certificate path cannot be encoded properly
* @return This builder.
*/
- public Builder setTrustedHardwareCertPath(@NonNull CertPath certPath)
+ public @NonNull Builder setTrustedHardwareCertPath(@NonNull CertPath certPath)
throws CertificateException {
mInstance.mCertPath = RecoveryCertPath.createRecoveryCertPath(certPath);
return this;
@@ -230,7 +230,7 @@
* @param keyChainProtectionParams The UI and key derivation parameters
* @return This builder.
*/
- public Builder setKeyChainProtectionParams(
+ public @NonNull Builder setKeyChainProtectionParams(
@NonNull List<KeyChainProtectionParams> keyChainProtectionParams) {
mInstance.mKeyChainProtectionParams = keyChainProtectionParams;
return this;
@@ -242,7 +242,8 @@
* @param entryRecoveryData List of application keys
* @return This builder.
*/
- public Builder setWrappedApplicationKeys(List<WrappedApplicationKey> entryRecoveryData) {
+ public @NonNull Builder setWrappedApplicationKeys(
+ @NonNull List<WrappedApplicationKey> entryRecoveryData) {
mInstance.mEntryRecoveryData = entryRecoveryData;
return this;
}
@@ -253,7 +254,8 @@
* @param encryptedRecoveryKeyBlob The recovery key blob.
* @return This builder.
*/
- public Builder setEncryptedRecoveryKeyBlob(@NonNull byte[] encryptedRecoveryKeyBlob) {
+ public @NonNull Builder setEncryptedRecoveryKeyBlob(
+ @NonNull byte[] encryptedRecoveryKeyBlob) {
mInstance.mEncryptedRecoveryKeyBlob = encryptedRecoveryKeyBlob;
return this;
}
@@ -265,7 +267,7 @@
* @return new instance
* @throws NullPointerException if some of the required fields were not set.
*/
- @NonNull public KeyChainSnapshot build() {
+ public @NonNull KeyChainSnapshot build() {
Preconditions.checkCollectionElementsNotNull(mInstance.mKeyChainProtectionParams,
"keyChainProtectionParams");
Preconditions.checkCollectionElementsNotNull(mInstance.mEntryRecoveryData,
diff --git a/core/java/android/security/keystore/recovery/KeyDerivationParams.java b/core/java/android/security/keystore/recovery/KeyDerivationParams.java
index 6d1533e..d036d14 100644
--- a/core/java/android/security/keystore/recovery/KeyDerivationParams.java
+++ b/core/java/android/security/keystore/recovery/KeyDerivationParams.java
@@ -140,7 +140,7 @@
return mMemoryDifficulty;
}
- public static final @android.annotation.NonNull Parcelable.Creator<KeyDerivationParams> CREATOR =
+ public static final @NonNull Parcelable.Creator<KeyDerivationParams> CREATOR =
new Parcelable.Creator<KeyDerivationParams>() {
public KeyDerivationParams createFromParcel(Parcel in) {
return new KeyDerivationParams(in);
diff --git a/core/java/android/security/keystore/recovery/RecoveryCertPath.java b/core/java/android/security/keystore/recovery/RecoveryCertPath.java
index 04e965f..51bd2ae 100644
--- a/core/java/android/security/keystore/recovery/RecoveryCertPath.java
+++ b/core/java/android/security/keystore/recovery/RecoveryCertPath.java
@@ -74,7 +74,7 @@
mEncodedCertPath = in.createByteArray();
}
- public static final @android.annotation.NonNull Parcelable.Creator<RecoveryCertPath> CREATOR =
+ public static final @NonNull Parcelable.Creator<RecoveryCertPath> CREATOR =
new Parcelable.Creator<RecoveryCertPath>() {
public RecoveryCertPath createFromParcel(Parcel in) {
return new RecoveryCertPath(in);
diff --git a/core/java/android/security/keystore/recovery/RecoveryController.java b/core/java/android/security/keystore/recovery/RecoveryController.java
index a88aa8c..cc3e578 100644
--- a/core/java/android/security/keystore/recovery/RecoveryController.java
+++ b/core/java/android/security/keystore/recovery/RecoveryController.java
@@ -283,6 +283,7 @@
*/
@RequiresPermission(android.Manifest.permission.RECOVER_KEYSTORE)
@NonNull public static RecoveryController getInstance(@NonNull Context context) {
+ // lockSettings may be null.
ILockSettings lockSettings =
ILockSettings.Stub.asInterface(ServiceManager.getService("lock_settings"));
return new RecoveryController(lockSettings, KeyStore.getInstance());
diff --git a/core/java/android/security/keystore/recovery/RecoverySession.java b/core/java/android/security/keystore/recovery/RecoverySession.java
index 2b2438a..3e595e0 100644
--- a/core/java/android/security/keystore/recovery/RecoverySession.java
+++ b/core/java/android/security/keystore/recovery/RecoverySession.java
@@ -193,7 +193,7 @@
*
* @hide
*/
- String getSessionId() {
+ @NonNull String getSessionId() {
return mSessionId;
}
diff --git a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
index c6e6272..665c937 100644
--- a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
+++ b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java
@@ -72,7 +72,7 @@
* @param alias The alias.
* @return This builder.
*/
- public Builder setAlias(@NonNull String alias) {
+ public @NonNull Builder setAlias(@NonNull String alias) {
mInstance.mAlias = alias;
return this;
}
@@ -83,7 +83,7 @@
* @param encryptedKeyMaterial The key material
* @return This builder
*/
- public Builder setEncryptedKeyMaterial(@NonNull byte[] encryptedKeyMaterial) {
+ public @NonNull Builder setEncryptedKeyMaterial(@NonNull byte[] encryptedKeyMaterial) {
mInstance.mEncryptedKeyMaterial = encryptedKeyMaterial;
return this;
}
@@ -94,7 +94,7 @@
* @param metadata The metadata
* @return This builder
*/
- public Builder setMetadata(@Nullable byte[] metadata) {
+ public @NonNull Builder setMetadata(@Nullable byte[] metadata) {
mInstance.mMetadata = metadata;
return this;
}
@@ -105,7 +105,7 @@
* @return new instance
* @throws NullPointerException if some required fields were not set.
*/
- @NonNull public WrappedApplicationKey build() {
+ public @NonNull WrappedApplicationKey build() {
Preconditions.checkNotNull(mInstance.mAlias);
Preconditions.checkNotNull(mInstance.mEncryptedKeyMaterial);
return mInstance;
@@ -143,7 +143,7 @@
return mMetadata;
}
- public static final @android.annotation.NonNull Parcelable.Creator<WrappedApplicationKey> CREATOR =
+ public static final @NonNull Parcelable.Creator<WrappedApplicationKey> CREATOR =
new Parcelable.Creator<WrappedApplicationKey>() {
public WrappedApplicationKey createFromParcel(Parcel in) {
return new WrappedApplicationKey(in);
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 7ef40cd..9694998 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -358,7 +358,7 @@
* Provides a convenient way to set the various fields of a {@link ZenPolicy}. If a field
* is not set, it is (@link STATE_UNSET} and will not change the current set policy.
*/
- public static class Builder {
+ public static final class Builder {
private ZenPolicy mZenPolicy;
public Builder() {
diff --git a/core/java/android/util/ArrayMap.java b/core/java/android/util/ArrayMap.java
index 436cb4f..e2af6f5 100644
--- a/core/java/android/util/ArrayMap.java
+++ b/core/java/android/util/ArrayMap.java
@@ -16,12 +16,12 @@
package android.util;
-import libcore.util.EmptyArray;
-
import android.annotation.UnsupportedAppUsage;
import com.android.internal.util.ArrayUtils;
+import libcore.util.EmptyArray;
+
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Map;
@@ -453,6 +453,10 @@
* @return Returns the key stored at the given index.
*/
public K keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return (K)mArray[index << 1];
}
@@ -462,6 +466,10 @@
* @return Returns the value stored at the given index.
*/
public V valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return (V)mArray[(index << 1) + 1];
}
@@ -472,6 +480,10 @@
* @return Returns the previous value at the given index.
*/
public V setValueAt(int index, V value) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
index = (index << 1) + 1;
V old = (V)mArray[index];
mArray[index] = value;
@@ -665,6 +677,11 @@
* @return Returns the value that was stored at this index.
*/
public V removeAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+
final Object old = mArray[(index << 1) + 1];
final int osize = mSize;
final int nsize;
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 43786f7..b99336b 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -39,6 +39,8 @@
public static final String SAFETY_HUB = "settings_safety_hub";
public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
public static final String GLOBAL_ACTIONS_GRID_ENABLED = "settings_global_actions_grid_enabled";
+ public static final String GLOBAL_ACTIONS_PANEL_ENABLED =
+ "settings_global_actions_panel_enabled";
private static final Map<String, String> DEFAULT_FLAGS;
@@ -46,7 +48,7 @@
DEFAULT_FLAGS = new HashMap<>();
DEFAULT_FLAGS.put("settings_audio_switcher", "true");
DEFAULT_FLAGS.put("settings_mobile_network_v2", "true");
- DEFAULT_FLAGS.put("settings_network_and_internet_v2", "true");
+ DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
DEFAULT_FLAGS.put("settings_slice_injection", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put("settings_wifi_mac_randomization", "true");
@@ -56,7 +58,8 @@
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
DEFAULT_FLAGS.put(SAFETY_HUB, "false");
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
- DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "false");
+ DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true");
+ DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
}
/**
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index cf49803..e4de704 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -21,9 +21,6 @@
import libcore.util.EmptyArray;
-import java.util.Arrays;
-import java.util.Objects;
-
/**
* SparseArray mapping longs to Objects. Unlike a normal array of Objects,
* there can be gaps in the indices. It is intended to be more memory efficient
@@ -147,6 +144,10 @@
* Removes the mapping at the specified index.
*/
public void removeAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mValues[index] != DELETED) {
mValues[index] = DELETED;
mGarbage = true;
@@ -236,6 +237,10 @@
* key.</p>
*/
public long keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mGarbage) {
gc();
}
@@ -256,6 +261,10 @@
*/
@SuppressWarnings("unchecked")
public E valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mGarbage) {
gc();
}
@@ -269,6 +278,10 @@
* LongSparseArray stores.
*/
public void setValueAt(int index, E value) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mGarbage) {
gc();
}
diff --git a/core/java/android/util/LongSparseLongArray.java b/core/java/android/util/LongSparseLongArray.java
index 8dcdb40..f167f00 100644
--- a/core/java/android/util/LongSparseLongArray.java
+++ b/core/java/android/util/LongSparseLongArray.java
@@ -16,14 +16,13 @@
package android.util;
+import android.annotation.UnsupportedAppUsage;
+
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
-import android.annotation.UnsupportedAppUsage;
import libcore.util.EmptyArray;
-import java.util.Arrays;
-
/**
* Map of {@code long} to {@code long}. Unlike a normal array of longs, there
* can be gaps in the indices. It is intended to be more memory efficient than using a
@@ -173,6 +172,10 @@
* key.</p>
*/
public long keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mKeys[index];
}
@@ -188,6 +191,10 @@
* associated with the largest key.</p>
*/
public long valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mValues[index];
}
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 89ea2d3..67dfb02 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -16,10 +16,11 @@
package android.util;
+import android.annotation.UnsupportedAppUsage;
+
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
-import android.annotation.UnsupportedAppUsage;
import libcore.util.EmptyArray;
/**
@@ -171,6 +172,10 @@
* the behavior is undefined.</p>
*/
public void removeAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mValues[index] != DELETED) {
mValues[index] = DELETED;
mGarbage = true;
@@ -279,6 +284,10 @@
* the behavior is undefined.</p>
*/
public int keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mGarbage) {
gc();
}
@@ -302,6 +311,10 @@
*/
@SuppressWarnings("unchecked")
public E valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mGarbage) {
gc();
}
@@ -317,6 +330,10 @@
* <p>For indices outside of the range <code>0...size()-1</code>, the behavior is undefined.</p>
*/
public void setValueAt(int index, E value) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
if (mGarbage) {
gc();
}
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index d4c4095..03fa1c9 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -16,10 +16,11 @@
package android.util;
+import android.annotation.UnsupportedAppUsage;
+
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
-import android.annotation.UnsupportedAppUsage;
import libcore.util.EmptyArray;
/**
@@ -167,6 +168,10 @@
* key.</p>
*/
public int keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mKeys[index];
}
@@ -182,6 +187,10 @@
* associated with the largest key.</p>
*/
public boolean valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mValues[index];
}
@@ -189,11 +198,19 @@
* Directly set the value at a particular index.
*/
public void setValueAt(int index, boolean value) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
mValues[index] = value;
}
/** @hide */
public void setKeyAt(int index, int key) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
mKeys[index] = key;
}
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index 9e6bad1..c68dc4e 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -16,14 +16,15 @@
package android.util;
+import android.annotation.UnsupportedAppUsage;
+
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.GrowingArrayUtils;
-import java.util.Arrays;
-
-import android.annotation.UnsupportedAppUsage;
import libcore.util.EmptyArray;
+import java.util.Arrays;
+
/**
* SparseIntArrays map integers to integers. Unlike a normal array of integers,
* there can be gaps in the indices. It is intended to be more memory efficient
@@ -171,6 +172,10 @@
* key.</p>
*/
public int keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mKeys[index];
}
@@ -186,6 +191,10 @@
* associated with the largest key.</p>
*/
public int valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mValues[index];
}
@@ -193,6 +202,10 @@
* Directly set the value at a particular index.
*/
public void setValueAt(int index, int value) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
mValues[index] = value;
}
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index 81db2b7..37a9202 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -182,6 +182,10 @@
* key.</p>
*/
public int keyAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mKeys[index];
}
@@ -197,6 +201,10 @@
* associated with the largest key.</p>
*/
public long valueAt(int index) {
+ if (index >= mSize) {
+ // The array might be slightly bigger than mSize, in which case, indexing won't fail.
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
return mValues[index];
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 874be81..287365f7 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9530,8 +9530,7 @@
// View is not important for "regular" autofill, so we must check if Augmented Autofill
// is enabled for the activity
final AutofillOptions options = mContext.getAutofillOptions();
- if (options == null || !options.augmentedEnabled) {
- // TODO(b/123100824): should also check if activity is whitelisted
+ if (options == null || !options.isAugmentedAutofillEnabled(mContext)) {
return false;
}
final AutofillManager afm = getAutofillManager();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f2474a5..4dc20d4 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7845,6 +7845,10 @@
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
})
+ @InspectableProperty(name = "layout_width", enumMapping = {
+ @InspectableProperty.EnumMap(name = "match_parent", value = MATCH_PARENT),
+ @InspectableProperty.EnumMap(name = "wrap_content", value = WRAP_CONTENT)
+ })
public int width;
/**
@@ -7856,6 +7860,10 @@
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
})
+ @InspectableProperty(name = "layout_height", enumMapping = {
+ @InspectableProperty.EnumMap(name = "match_parent", value = MATCH_PARENT),
+ @InspectableProperty.EnumMap(name = "wrap_content", value = WRAP_CONTENT)
+ })
public int height;
/**
@@ -8028,6 +8036,7 @@
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginLeft")
public int leftMargin;
/**
@@ -8036,6 +8045,7 @@
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginTop")
public int topMargin;
/**
@@ -8044,6 +8054,7 @@
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginRight")
public int rightMargin;
/**
@@ -8052,6 +8063,7 @@
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginBottom")
public int bottomMargin;
/**
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 885bd2a..a3e6549 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -193,6 +193,15 @@
private MainContentCaptureSession mMainSession;
/** @hide */
+ public interface ContentCaptureClient {
+ /**
+ * Gets the component name of the client.
+ */
+ @NonNull
+ ComponentName contentCaptureClientGetComponentName();
+ }
+
+ /** @hide */
public ContentCaptureManager(@NonNull Context context,
@NonNull IContentCaptureManager service, @NonNull ContentCaptureOptions options) {
mContext = Preconditions.checkNotNull(context, "context cannot be null");
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 6bf1eba..1f0971e 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -121,11 +121,11 @@
public static final int STATE_INTERNAL_ERROR = 0x100;
/**
- * Session is disabled because service didn't whitelist package.
+ * Session is disabled because service didn't whitelist package or activity.
*
* @hide
*/
- public static final int STATE_PACKAGE_NOT_WHITELISTED = 0x200;
+ public static final int STATE_NOT_WHITELISTED = 0x200;
private static final int INITIAL_CHILDREN_CAPACITY = 5;
diff --git a/core/java/android/view/textclassifier/ConfigParser.java b/core/java/android/view/textclassifier/ConfigParser.java
new file mode 100644
index 0000000..8e0bdf9
--- /dev/null
+++ b/core/java/android/view/textclassifier/ConfigParser.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.textclassifier;
+
+import android.annotation.Nullable;
+import android.provider.DeviceConfig;
+import android.util.KeyValueListParser;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/**
+ * Retrieves settings from {@link DeviceConfig} and {@link android.provider.Settings}.
+ * It will try DeviceConfig first and then Settings.
+ *
+ * @hide
+ */
+@VisibleForTesting
+public final class ConfigParser {
+ private static final String TAG = "ConfigParser";
+
+ private final KeyValueListParser mParser;
+
+ public ConfigParser(@Nullable String textClassifierConstants) {
+ final KeyValueListParser parser = new KeyValueListParser(',');
+ try {
+ parser.setString(textClassifierConstants);
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on with defaults.
+ Log.w(TAG, "Bad text_classifier_constants: " + textClassifierConstants);
+ }
+ mParser = parser;
+ }
+
+ /**
+ * Reads a boolean flag.
+ */
+ public boolean getBoolean(String key, boolean defaultValue) {
+ return DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getBoolean(key, defaultValue));
+ }
+
+ /**
+ * Reads an integer flag.
+ */
+ public int getInt(String key, int defaultValue) {
+ return DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getInt(key, defaultValue));
+ }
+
+ /**
+ * Reads a float flag.
+ */
+ public float getFloat(String key, float defaultValue) {
+ return DeviceConfig.getFloat(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getFloat(key, defaultValue));
+ }
+
+ /**
+ * Reads a string flag.
+ */
+ public String getString(String key, String defaultValue) {
+ return DeviceConfig.getString(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ key,
+ mParser.getString(key, defaultValue));
+ }
+}
diff --git a/core/java/android/view/textclassifier/TextClassificationConstants.java b/core/java/android/view/textclassifier/TextClassificationConstants.java
index 2ef8d04..125b0d3 100644
--- a/core/java/android/view/textclassifier/TextClassificationConstants.java
+++ b/core/java/android/view/textclassifier/TextClassificationConstants.java
@@ -17,8 +17,6 @@
package android.view.textclassifier;
import android.annotation.Nullable;
-import android.util.KeyValueListParser;
-import android.util.Slog;
import com.android.internal.util.IndentingPrintWriter;
@@ -32,22 +30,24 @@
* This is encoded as a key=value list, separated by commas. Ex:
*
* <pre>
- * smart_linkify_enabled (boolean)
- * system_textclassifier_enabled (boolean)
- * model_dark_launch_enabled (boolean)
- * smart_selection_enabled (boolean)
- * smart_text_share_enabled (boolean)
- * smart_linkify_enabled (boolean)
- * smart_select_animation_enabled (boolean)
- * suggest_selection_max_range_length (int)
- * classify_text_max_range_length (int)
- * generate_links_max_text_length (int)
- * generate_links_log_sample_rate (int)
- * entity_list_default (String[])
- * entity_list_not_editable (String[])
- * entity_list_editable (String[])
- * lang_id_threshold_override (float)
- * template_intent_factory_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * system_textclassifier_enabled (boolean)
+ * model_dark_launch_enabled (boolean)
+ * smart_selection_enabled (boolean)
+ * smart_text_share_enabled (boolean)
+ * smart_linkify_enabled (boolean)
+ * smart_select_animation_enabled (boolean)
+ * suggest_selection_max_range_length (int)
+ * classify_text_max_range_length (int)
+ * generate_links_max_text_length (int)
+ * generate_links_log_sample_rate (int)
+ * entity_list_default (String[])
+ * entity_list_not_editable (String[])
+ * entity_list_editable (String[])
+ * in_app_conversation_action_types_default (String[])
+ * notification_conversation_action_types_default (String[])
+ * lang_id_threshold_override (float)
+ * template_intent_factory_enabled (boolean)
* </pre>
*
* <p>
@@ -61,43 +61,90 @@
* @hide
*/
public final class TextClassificationConstants {
-
private static final String LOG_TAG = "TextClassificationConstants";
- private static final String LOCAL_TEXT_CLASSIFIER_ENABLED =
- "local_textclassifier_enabled";
- private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED =
- "system_textclassifier_enabled";
- private static final String MODEL_DARK_LAUNCH_ENABLED =
- "model_dark_launch_enabled";
- private static final String SMART_SELECTION_ENABLED =
- "smart_selection_enabled";
- private static final String SMART_TEXT_SHARE_ENABLED =
- "smart_text_share_enabled";
- private static final String SMART_LINKIFY_ENABLED =
- "smart_linkify_enabled";
+ /**
+ * Whether the smart linkify feature is enabled.
+ */
+ private static final String SMART_LINKIFY_ENABLED = "smart_linkify_enabled";
+ /**
+ * Whether SystemTextClassifier is enabled.
+ */
+ private static final String SYSTEM_TEXT_CLASSIFIER_ENABLED = "system_textclassifier_enabled";
+ /**
+ * Whether TextClassifierImpl is enabled.
+ */
+ private static final String LOCAL_TEXT_CLASSIFIER_ENABLED = "local_textclassifier_enabled";
+ /**
+ * Enable smart selection without a visible UI changes.
+ */
+ private static final String MODEL_DARK_LAUNCH_ENABLED = "model_dark_launch_enabled";
+
+ /**
+ * Whether the smart selection feature is enabled.
+ */
+ private static final String SMART_SELECTION_ENABLED = "smart_selection_enabled";
+ /**
+ * Whether the smart text share feature is enabled.
+ */
+ private static final String SMART_TEXT_SHARE_ENABLED = "smart_text_share_enabled";
+ /**
+ * Whether animation for smart selection is enabled.
+ */
private static final String SMART_SELECT_ANIMATION_ENABLED =
"smart_select_animation_enabled";
+ /**
+ * Max length of text that suggestSelection can accept.
+ */
private static final String SUGGEST_SELECTION_MAX_RANGE_LENGTH =
"suggest_selection_max_range_length";
- private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH =
- "classify_text_max_range_length";
- private static final String GENERATE_LINKS_MAX_TEXT_LENGTH =
- "generate_links_max_text_length";
+ /**
+ * Max length of text that classifyText can accept.
+ */
+ private static final String CLASSIFY_TEXT_MAX_RANGE_LENGTH = "classify_text_max_range_length";
+ /**
+ * Max length of text that generateLinks can accept.
+ */
+ private static final String GENERATE_LINKS_MAX_TEXT_LENGTH = "generate_links_max_text_length";
+ /**
+ * Sampling rate for generateLinks logging.
+ */
private static final String GENERATE_LINKS_LOG_SAMPLE_RATE =
"generate_links_log_sample_rate";
- private static final String ENTITY_LIST_DEFAULT =
- "entity_list_default";
- private static final String ENTITY_LIST_NOT_EDITABLE =
- "entity_list_not_editable";
- private static final String ENTITY_LIST_EDITABLE =
- "entity_list_editable";
+ /**
+ * A colon(:) separated string that specifies the default entities types for
+ * generateLinks when hint is not given.
+ */
+ private static final String ENTITY_LIST_DEFAULT = "entity_list_default";
+ /**
+ * A colon(:) separated string that specifies the default entities types for
+ * generateLinks when the text is in a not editable UI widget.
+ */
+ private static final String ENTITY_LIST_NOT_EDITABLE = "entity_list_not_editable";
+ /**
+ * A colon(:) separated string that specifies the default entities types for
+ * generateLinks when the text is in an editable UI widget.
+ */
+ private static final String ENTITY_LIST_EDITABLE = "entity_list_editable";
+ /**
+ * A colon(:) separated string that specifies the default action types for
+ * suggestConversationActions when the suggestions are used in an app.
+ */
private static final String IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT =
"in_app_conversation_action_types_default";
+ /**
+ * A colon(:) separated string that specifies the default action types for
+ * suggestConversationActions when the suggestions are used in a notification.
+ */
private static final String NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT =
"notification_conversation_action_types_default";
- private static final String LANG_ID_THRESHOLD_OVERRIDE =
- "lang_id_threshold_override";
+ /**
+ * Threshold in classifyText to consider a text is in a foreign language.
+ */
+ private static final String LANG_ID_THRESHOLD_OVERRIDE = "lang_id_threshold_override";
+ /**
+ * Whether to enable {@link android.view.textclassifier.TemplateIntentFactory}.
+ */
private static final String TEMPLATE_INTENT_FACTORY_ENABLED = "template_intent_factory_enabled";
private static final boolean LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT = true;
@@ -162,66 +209,77 @@
private final boolean mTemplateIntentFactoryEnabled;
private TextClassificationConstants(@Nullable String settings) {
- final KeyValueListParser parser = new KeyValueListParser(',');
- try {
- parser.setString(settings);
- } catch (IllegalArgumentException e) {
- // Failed to parse the settings string, log this and move on with defaults.
- Slog.e(LOG_TAG, "Bad TextClassifier settings: " + settings);
- }
- mSystemTextClassifierEnabled = parser.getBoolean(
- SYSTEM_TEXT_CLASSIFIER_ENABLED,
- SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
- mLocalTextClassifierEnabled = parser.getBoolean(
- LOCAL_TEXT_CLASSIFIER_ENABLED,
- LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
- mModelDarkLaunchEnabled = parser.getBoolean(
- MODEL_DARK_LAUNCH_ENABLED,
- MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
- mSmartSelectionEnabled = parser.getBoolean(
- SMART_SELECTION_ENABLED,
- SMART_SELECTION_ENABLED_DEFAULT);
- mSmartTextShareEnabled = parser.getBoolean(
- SMART_TEXT_SHARE_ENABLED,
- SMART_TEXT_SHARE_ENABLED_DEFAULT);
- mSmartLinkifyEnabled = parser.getBoolean(
- SMART_LINKIFY_ENABLED,
- SMART_LINKIFY_ENABLED_DEFAULT);
- mSmartSelectionAnimationEnabled = parser.getBoolean(
- SMART_SELECT_ANIMATION_ENABLED,
- SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
- mSuggestSelectionMaxRangeLength = parser.getInt(
- SUGGEST_SELECTION_MAX_RANGE_LENGTH,
- SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
- mClassifyTextMaxRangeLength = parser.getInt(
- CLASSIFY_TEXT_MAX_RANGE_LENGTH,
- CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
- mGenerateLinksMaxTextLength = parser.getInt(
- GENERATE_LINKS_MAX_TEXT_LENGTH,
- GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
- mGenerateLinksLogSampleRate = parser.getInt(
- GENERATE_LINKS_LOG_SAMPLE_RATE,
- GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
- mEntityListDefault = parseStringList(parser.getString(
+ ConfigParser configParser = new ConfigParser(settings);
+ mSystemTextClassifierEnabled =
+ configParser.getBoolean(
+ SYSTEM_TEXT_CLASSIFIER_ENABLED,
+ SYSTEM_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+ mLocalTextClassifierEnabled =
+ configParser.getBoolean(
+ LOCAL_TEXT_CLASSIFIER_ENABLED,
+ LOCAL_TEXT_CLASSIFIER_ENABLED_DEFAULT);
+ mModelDarkLaunchEnabled =
+ configParser.getBoolean(
+ MODEL_DARK_LAUNCH_ENABLED,
+ MODEL_DARK_LAUNCH_ENABLED_DEFAULT);
+ mSmartSelectionEnabled =
+ configParser.getBoolean(
+ SMART_SELECTION_ENABLED,
+ SMART_SELECTION_ENABLED_DEFAULT);
+ mSmartTextShareEnabled =
+ configParser.getBoolean(
+ SMART_TEXT_SHARE_ENABLED,
+ SMART_TEXT_SHARE_ENABLED_DEFAULT);
+ mSmartLinkifyEnabled =
+ configParser.getBoolean(
+ SMART_LINKIFY_ENABLED,
+ SMART_LINKIFY_ENABLED_DEFAULT);
+ mSmartSelectionAnimationEnabled =
+ configParser.getBoolean(
+ SMART_SELECT_ANIMATION_ENABLED,
+ SMART_SELECT_ANIMATION_ENABLED_DEFAULT);
+ mSuggestSelectionMaxRangeLength =
+ configParser.getInt(
+ SUGGEST_SELECTION_MAX_RANGE_LENGTH,
+ SUGGEST_SELECTION_MAX_RANGE_LENGTH_DEFAULT);
+ mClassifyTextMaxRangeLength =
+ configParser.getInt(
+ CLASSIFY_TEXT_MAX_RANGE_LENGTH,
+ CLASSIFY_TEXT_MAX_RANGE_LENGTH_DEFAULT);
+ mGenerateLinksMaxTextLength =
+ configParser.getInt(
+ GENERATE_LINKS_MAX_TEXT_LENGTH,
+ GENERATE_LINKS_MAX_TEXT_LENGTH_DEFAULT);
+ mGenerateLinksLogSampleRate =
+ configParser.getInt(
+ GENERATE_LINKS_LOG_SAMPLE_RATE,
+ GENERATE_LINKS_LOG_SAMPLE_RATE_DEFAULT);
+ mEntityListDefault = parseStringList(configParser.getString(
ENTITY_LIST_DEFAULT,
ENTITY_LIST_DEFAULT_VALUE));
- mEntityListNotEditable = parseStringList(parser.getString(
- ENTITY_LIST_NOT_EDITABLE,
- ENTITY_LIST_DEFAULT_VALUE));
- mEntityListEditable = parseStringList(parser.getString(
- ENTITY_LIST_EDITABLE,
- ENTITY_LIST_DEFAULT_VALUE));
- mInAppConversationActionTypesDefault = parseStringList(parser.getString(
- IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
- CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
- mNotificationConversationActionTypesDefault = parseStringList(parser.getString(
- NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
- CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
- mLangIdThresholdOverride = parser.getFloat(
- LANG_ID_THRESHOLD_OVERRIDE,
- LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
- mTemplateIntentFactoryEnabled = parser.getBoolean(
- TEMPLATE_INTENT_FACTORY_ENABLED, TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
+ mEntityListNotEditable = parseStringList(
+ configParser.getString(
+ ENTITY_LIST_NOT_EDITABLE,
+ ENTITY_LIST_DEFAULT_VALUE));
+ mEntityListEditable = parseStringList(
+ configParser.getString(
+ ENTITY_LIST_EDITABLE,
+ ENTITY_LIST_DEFAULT_VALUE));
+ mInAppConversationActionTypesDefault = parseStringList(
+ configParser.getString(
+ IN_APP_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
+ mNotificationConversationActionTypesDefault = parseStringList(
+ configParser.getString(
+ NOTIFICATION_CONVERSATION_ACTION_TYPES_DEFAULT,
+ CONVERSATION_ACTIONS_TYPES_DEFAULT_VALUES));
+ mLangIdThresholdOverride =
+ configParser.getFloat(
+ LANG_ID_THRESHOLD_OVERRIDE,
+ LANG_ID_THRESHOLD_OVERRIDE_DEFAULT);
+ mTemplateIntentFactoryEnabled = configParser.getBoolean(
+ TEMPLATE_INTENT_FACTORY_ENABLED,
+ TEMPLATE_INTENT_FACTORY_ENABLED_DEFAULT);
}
/** Load from a settings string. */
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index d047c55..868cbb1 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -20,9 +20,11 @@
import android.annotation.Nullable;
import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
+import android.app.ActivityThread;
import android.content.Context;
import android.database.ContentObserver;
import android.os.ServiceManager;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.textclassifier.TextClassifierService;
import android.view.textclassifier.TextClassifier.TextClassifierType;
@@ -195,6 +197,7 @@
if (mSettingsObserver != null) {
getApplicationContext().getContentResolver()
.unregisterContentObserver(mSettingsObserver);
+ DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver);
}
} finally {
super.finalize();
@@ -277,7 +280,8 @@
}
}
- private static final class SettingsObserver extends ContentObserver {
+ private static final class SettingsObserver extends ContentObserver
+ implements DeviceConfig.OnPropertyChangedListener {
private final WeakReference<TextClassificationManager> mTcm;
@@ -288,10 +292,23 @@
Settings.Global.getUriFor(Settings.Global.TEXT_CLASSIFIER_CONSTANTS),
false /* notifyForDescendants */,
this);
+ DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ ActivityThread.currentApplication().getMainExecutor(),
+ this);
}
@Override
public void onChange(boolean selfChange) {
+ invalidateSettings();
+ }
+
+ @Override
+ public void onPropertyChanged(String namespace, String name, String value) {
+ invalidateSettings();
+ }
+
+ private void invalidateSettings() {
final TextClassificationManager tcm = mTcm.get();
if (tcm != null) {
tcm.invalidate();
diff --git a/core/java/android/widget/AbsoluteLayout.java b/core/java/android/widget/AbsoluteLayout.java
index 4ce0d5d..e3499f9 100644
--- a/core/java/android/widget/AbsoluteLayout.java
+++ b/core/java/android/widget/AbsoluteLayout.java
@@ -21,6 +21,7 @@
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
@@ -159,10 +160,12 @@
/**
* The horizontal, or X, location of the child within the view group.
*/
+ @InspectableProperty(name = "layout_x")
public int x;
/**
* The vertical, or Y, location of the child within the view group.
*/
+ @InspectableProperty(name = "layout_y")
public int y;
/**
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 3570c79..69da911 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -443,6 +443,9 @@
* @see android.view.Gravity
* @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
*/
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity = UNSPECIFIED_GRAVITY;
public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index e833df9..bdde435 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -1987,6 +1987,7 @@
* will be pro-rated among all views whose weight is greater than 0.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_weight")
public float weight;
/**
@@ -2010,6 +2011,9 @@
@ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity = -1;
/**
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 109c0a4..8ee31e2 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1286,6 +1286,7 @@
* the anchor's visibility is GONE.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_alignWithParentIfMissing")
public boolean alignWithParent;
public LayoutParams(Context c, AttributeSet attrs) {
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index 22931fc..ac23093 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -26,6 +26,7 @@
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
+import android.view.inspector.InspectableProperty;
/**
* <p>A layout that arranges its children horizontally. A TableRow should
@@ -398,12 +399,14 @@
* <p>The column index of the cell represented by the widget.</p>
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_column")
public int column;
/**
* <p>The number of columns the widgets spans over.</p>
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_span")
public int span;
private static final int LOCATION = 0;
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 67e0446..fd978f5 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -18,6 +18,11 @@
import static java.lang.annotation.RetentionPolicy.SOURCE;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.app.Activity;
import android.app.ActivityManager;
@@ -90,6 +95,8 @@
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
@@ -135,7 +142,7 @@
* {@link AppPredictionManager} will be queried for direct share targets.
*/
// TODO(b/123089490): Replace with system flag
- private static final boolean USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS = true;
+ private static final boolean USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS = false;
// TODO(b/123088566) Share these in a better way.
private static final String APP_PREDICTION_SHARE_UI_SURFACE = "share";
public static final String LAUNCH_LOCATON_DIRECT_SHARE = "direct_share";
@@ -152,11 +159,17 @@
private static final boolean USE_SHORTCUT_MANAGER_FOR_DIRECT_TARGETS = true;
private static final boolean USE_CHOOSER_TARGET_SERVICE_FOR_DIRECT_TARGETS = true;
+ /**
+ * The transition time between placeholders for direct share to a message
+ * indicating that non are available.
+ */
+ private static final int NO_DIRECT_SHARE_ANIM_IN_MILLIS = 200;
+
// TODO(b/121287224): Re-evaluate this limit
private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
private static final int QUERY_TARGET_SERVICE_LIMIT = 5;
- private static final int WATCHDOG_TIMEOUT_MILLIS = 2000;
+ private static final int WATCHDOG_TIMEOUT_MILLIS = 3000;
private Bundle mReplacementExtras;
private IntentSender mChosenComponentSender;
@@ -172,6 +185,8 @@
private ChooserListAdapter mChooserListAdapter;
private ChooserRowAdapter mChooserRowAdapter;
+ private Drawable mChooserRowLayer;
+ private int mChooserRowServiceSpacing;
private SharedPreferences mPinnedSharedPrefs;
private static final float PINNED_TARGET_SCORE_BOOST = 1000.f;
@@ -220,7 +235,6 @@
sri.connection.destroy();
mServiceConnections.remove(sri.connection);
if (mServiceConnections.isEmpty()) {
- mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
sendVoiceChoicesIfNeeded();
mChooserListAdapter.setShowServiceTargets(true);
}
@@ -230,8 +244,12 @@
if (DEBUG) {
Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
}
+ if (isDestroyed()) {
+ break;
+ }
unbindRemainingServices();
sendVoiceChoicesIfNeeded();
+ mChooserListAdapter.completeServiceTargetLoading();
mChooserListAdapter.setShowServiceTargets(true);
break;
@@ -399,11 +417,17 @@
.setExtras(extras)
.build());
mAppPredictorCallback = resultList -> {
+ if (isFinishing() || isDestroyed()) {
+ return;
+ }
final List<DisplayResolveInfo> driList =
getDisplayResolveInfos(mChooserListAdapter);
final List<ShortcutManager.ShareShortcutInfo> shareShortcutInfos =
new ArrayList<>();
for (AppTarget appTarget : resultList) {
+ if (appTarget.getShortcutInfo() == null) {
+ continue;
+ }
shareShortcutInfos.add(new ShortcutManager.ShareShortcutInfo(
appTarget.getShortcutInfo(),
new ComponentName(
@@ -414,6 +438,10 @@
mAppPredictor.registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback);
}
+ mChooserRowLayer = getResources().getDrawable(R.drawable.chooser_row_layer_list, null);
+ mChooserRowServiceSpacing = getResources()
+ .getDimensionPixelSize(R.dimen.chooser_service_spacing);
+
if (DEBUG) {
Log.d(TAG, "System Time Cost is " + systemCost);
}
@@ -919,6 +947,10 @@
@Override
protected boolean onTargetSelected(TargetInfo target, boolean alwaysCheck) {
+ if (target instanceof NotSelectableTargetInfo) {
+ return false;
+ }
+
if (mRefinementIntentSender != null) {
final Intent fillIn = new Intent();
final List<Intent> sourceIntents = target.getAllSourceIntents();
@@ -1064,14 +1096,14 @@
}
}
- if (!mServiceConnections.isEmpty()) {
- if (DEBUG) {
- Log.d(TAG, "queryTargets setting watchdog timer for "
- + WATCHDOG_TIMEOUT_MILLIS + "ms");
- }
- mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
- WATCHDOG_TIMEOUT_MILLIS);
- } else {
+ if (DEBUG) {
+ Log.d(TAG, "queryTargets setting watchdog timer for "
+ + WATCHDOG_TIMEOUT_MILLIS + "ms");
+ }
+ mChooserHandler.sendEmptyMessageDelayed(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT,
+ WATCHDOG_TIMEOUT_MILLIS);
+
+ if (mServiceConnections.isEmpty()) {
sendVoiceChoicesIfNeeded();
}
}
@@ -1213,7 +1245,6 @@
conn.destroy();
}
mServiceConnections.clear();
- mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
}
public void onSetupVoiceInteraction() {
@@ -1420,7 +1451,93 @@
return null;
}
- final class ChooserTargetInfo implements TargetInfo {
+ interface ChooserTargetInfo extends TargetInfo {
+ float getModifiedScore();
+
+ ChooserTarget getChooserTarget();
+ }
+
+ /**
+ * Distinguish between targets that selectable by the user, vs those that are
+ * placeholders for the system while information is loading in an async manner.
+ */
+ abstract class NotSelectableTargetInfo implements ChooserTargetInfo {
+
+ public Intent getResolvedIntent() {
+ return null;
+ }
+
+ public ComponentName getResolvedComponentName() {
+ return null;
+ }
+
+ public boolean start(Activity activity, Bundle options) {
+ return false;
+ }
+
+ public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) {
+ return false;
+ }
+
+ public boolean startAsUser(Activity activity, Bundle options, UserHandle user) {
+ return false;
+ }
+
+ public ResolveInfo getResolveInfo() {
+ return null;
+ }
+
+ public CharSequence getDisplayLabel() {
+ return null;
+ }
+
+ public CharSequence getExtendedInfo() {
+ return null;
+ }
+
+ public Drawable getBadgeIcon() {
+ return null;
+ }
+
+ public CharSequence getBadgeContentDescription() {
+ return null;
+ }
+
+ public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
+ return null;
+ }
+
+ public List<Intent> getAllSourceIntents() {
+ return null;
+ }
+
+ public boolean isPinned() {
+ return false;
+ }
+
+ public float getModifiedScore() {
+ return 0.1f;
+ }
+
+ public ChooserTarget getChooserTarget() {
+ return null;
+ }
+ }
+
+ final class PlaceHolderTargetInfo extends NotSelectableTargetInfo {
+ public Drawable getDisplayIcon() {
+ return getDrawable(R.drawable.resolver_icon_placeholder);
+ }
+ }
+
+
+ final class EmptyTargetInfo extends NotSelectableTargetInfo {
+ public Drawable getDisplayIcon() {
+ return null;
+ }
+ }
+
+ final class SelectableTargetInfo implements ChooserTargetInfo {
private final DisplayResolveInfo mSourceInfo;
private final ResolveInfo mBackupResolveInfo;
private final ChooserTarget mChooserTarget;
@@ -1431,7 +1548,7 @@
private final int mFillInFlags;
private final float mModifiedScore;
- public ChooserTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget,
+ SelectableTargetInfo(DisplayResolveInfo sourceInfo, ChooserTarget chooserTarget,
float modifiedScore) {
mSourceInfo = sourceInfo;
mChooserTarget = chooserTarget;
@@ -1460,7 +1577,7 @@
mFillInFlags = 0;
}
- private ChooserTargetInfo(ChooserTargetInfo other, Intent fillInIntent, int flags) {
+ private SelectableTargetInfo(SelectableTargetInfo other, Intent fillInIntent, int flags) {
mSourceInfo = other.mSourceInfo;
mBackupResolveInfo = other.mBackupResolveInfo;
mChooserTarget = other.mChooserTarget;
@@ -1616,7 +1733,7 @@
@Override
public TargetInfo cloneFilledIn(Intent fillInIntent, int flags) {
- return new ChooserTargetInfo(this, fillInIntent, flags);
+ return new SelectableTargetInfo(this, fillInIntent, flags);
}
@Override
@@ -1644,7 +1761,9 @@
private static final int MAX_SERVICE_TARGETS = 4;
private static final int MAX_TARGETS_PER_SERVICE = 2;
- private final List<ChooserTargetInfo> mServiceTargets = new ArrayList<>();
+ // Reserve spots for incoming direct share targets by adding placeholders
+ private ChooserTargetInfo mPlaceHolderTargetInfo = new PlaceHolderTargetInfo();
+ private List<ChooserTargetInfo> mServiceTargets;
private final List<TargetInfo> mCallerTargets = new ArrayList<>();
private boolean mShowServiceTargets;
@@ -1663,6 +1782,8 @@
super(context, payloadIntents, null, rList, launchedFromUid, filterLastUsed,
resolverListController);
+ mServiceTargets = createPlaceHolders();
+
if (initialIntents != null) {
final PackageManager pm = getPackageManager();
for (int i = 0; i < initialIntents.length; i++) {
@@ -1715,6 +1836,14 @@
}
}
+ private List<ChooserTargetInfo> createPlaceHolders() {
+ List<ChooserTargetInfo> list = new ArrayList<>();
+ for (int i = 0; i < MAX_SERVICE_TARGETS; i++) {
+ list.add(mPlaceHolderTargetInfo);
+ }
+ return list;
+ }
+
@Override
public boolean showsExtendedInfo(TargetInfo info) {
// We have badges so we don't need this text shown.
@@ -1770,22 +1899,33 @@
@Override
public int getCount() {
- return super.getCount() + getServiceTargetCount() + getCallerTargetCount();
+ return super.getCount() + getSelectableServiceTargetCount() + getCallerTargetCount();
}
@Override
public int getUnfilteredCount() {
- return super.getUnfilteredCount() + getServiceTargetCount() + getCallerTargetCount();
+ return super.getUnfilteredCount() + getSelectableServiceTargetCount()
+ + getCallerTargetCount();
}
public int getCallerTargetCount() {
return mCallerTargets.size();
}
- public int getServiceTargetCount() {
- if (!mShowServiceTargets) {
- return 0;
+ /**
+ * Filter out placeholders and non-selectable service targets
+ */
+ public int getSelectableServiceTargetCount() {
+ int count = 0;
+ for (ChooserTargetInfo info : mServiceTargets) {
+ if (info instanceof SelectableTargetInfo) {
+ count++;
+ }
}
+ return count;
+ }
+
+ public int getServiceTargetCount() {
return Math.min(mServiceTargets.size(), MAX_SERVICE_TARGETS);
}
@@ -1831,7 +1971,8 @@
}
offset += callerTargetCount;
- final int serviceTargetCount = getServiceTargetCount();
+ final int serviceTargetCount = filtered ? getServiceTargetCount() :
+ getSelectableServiceTargetCount();
if (position - offset < serviceTargetCount) {
return mServiceTargets.get(position - offset);
}
@@ -1850,8 +1991,14 @@
if (mTargetsNeedPruning && targets.size() > 0) {
// First proper update since we got an onListRebuilt() with (transient) 0 items.
// Clear out the target list and rebuild.
- mServiceTargets.clear();
+ mServiceTargets = createPlaceHolders();
mTargetsNeedPruning = false;
+
+ // Add back any app-supplied direct share targets that may have been
+ // wiped by this clear
+ if (mCallerChooserTargets != null) {
+ addServiceResults(null, Lists.newArrayList(mCallerChooserTargets));
+ }
}
final float parentScore = getScore(origTarget);
@@ -1867,7 +2014,7 @@
// This incents ChooserTargetServices to define what's truly better.
targetScore = lastScore * 0.95f;
}
- insertServiceTarget(new ChooserTargetInfo(origTarget, target, targetScore));
+ insertServiceTarget(new SelectableTargetInfo(origTarget, target, targetScore));
if (DEBUG) {
Log.d(TAG, " => " + target.toString() + " score=" + targetScore
@@ -1905,11 +2052,33 @@
}
}
+ /**
+ * Calling this marks service target loading complete, and will attempt to no longer
+ * update the direct share area.
+ */
+ public void completeServiceTargetLoading() {
+ mServiceTargets.removeIf(o -> o instanceof PlaceHolderTargetInfo);
+
+ if (mServiceTargets.isEmpty()) {
+ mServiceTargets.add(new EmptyTargetInfo());
+ }
+ notifyDataSetChanged();
+ }
+
private void insertServiceTarget(ChooserTargetInfo chooserTargetInfo) {
+ // Avoid inserting any potentially late results
+ if (mServiceTargets.size() == 1
+ && mServiceTargets.get(0) instanceof EmptyTargetInfo) {
+ return;
+ }
+
final float newScore = chooserTargetInfo.getModifiedScore();
for (int i = 0, N = mServiceTargets.size(); i < N; i++) {
final ChooserTargetInfo serviceTarget = mServiceTargets.get(i);
- if (newScore > serviceTarget.getModifiedScore()) {
+ if (serviceTarget == null) {
+ mServiceTargets.set(i, chooserTargetInfo);
+ return;
+ } else if (newScore > serviceTarget.getModifiedScore()) {
mServiceTargets.add(i, chooserTargetInfo);
return;
}
@@ -1968,7 +2137,7 @@
// There can be at most one row of service targets.
public int getServiceTargetRowCount() {
- return (int) mChooserListAdapter.getServiceTargetCount() == 0 ? 0 : 1;
+ return 1;
}
@Override
@@ -2054,58 +2223,81 @@
final int start = getFirstRowPosition(rowPosition);
final int startType = mChooserListAdapter.getPositionTargetType(start);
+ final int lastStartType = mChooserListAdapter.getPositionTargetType(
+ getFirstRowPosition(rowPosition - 1));
+
+ if (startType != lastStartType || rowPosition == 0) {
+ holder.row.setBackground(mChooserRowLayer);
+ setVertPadding(holder, mChooserRowServiceSpacing, 0);
+ } else {
+ holder.row.setBackground(null);
+ setVertPadding(holder, 0, 0);
+ }
+
int end = start + mColumnCount - 1;
while (mChooserListAdapter.getPositionTargetType(end) != startType && end >= start) {
end--;
}
- if (startType == ChooserListAdapter.TARGET_SERVICE) {
- int nextStartType = mChooserListAdapter.getPositionTargetType(
- getFirstRowPosition(rowPosition + 1));
- int serviceSpacing = holder.row.getContext().getResources()
- .getDimensionPixelSize(R.dimen.chooser_service_spacing);
- if (rowPosition == 0 && nextStartType != ChooserListAdapter.TARGET_SERVICE) {
- // if the row is the only row for target service
- setVertPadding(holder, 0, 0);
- } else {
- int top = rowPosition == 0 ? serviceSpacing : 0;
- if (nextStartType != ChooserListAdapter.TARGET_SERVICE) {
- setVertPadding(holder, top, serviceSpacing);
- } else {
- setVertPadding(holder, top, 0);
- }
- }
- } else {
- holder.row.setBackgroundColor(Color.TRANSPARENT);
- int lastStartType = mChooserListAdapter.getPositionTargetType(
- getFirstRowPosition(rowPosition - 1));
- if (lastStartType == ChooserListAdapter.TARGET_SERVICE || rowPosition == 0) {
- int serviceSpacing = holder.row.getContext().getResources()
- .getDimensionPixelSize(R.dimen.chooser_service_spacing);
- setVertPadding(holder, serviceSpacing, 0);
- } else {
- setVertPadding(holder, 0, 0);
- }
- }
+ if (end == start && mChooserListAdapter.getItem(start) instanceof EmptyTargetInfo) {
+ final TextView textView = holder.row.findViewById(R.id.chooser_row_text_option);
- final int oldHeight = holder.row.getLayoutParams().height;
- holder.row.getLayoutParams().height = Math.max(1, holder.measuredRowHeight);
- if (holder.row.getLayoutParams().height != oldHeight) {
- holder.row.requestLayout();
+ if (textView.getVisibility() != View.VISIBLE) {
+ textView.setAlpha(0.0f);
+ textView.setVisibility(View.VISIBLE);
+ textView.setText(R.string.chooser_no_direct_share_targets);
+
+ ValueAnimator fadeAnim = ObjectAnimator.ofFloat(textView, "alpha", 0.0f, 1.0f);
+ fadeAnim.setInterpolator(new DecelerateInterpolator(1.0f));
+
+ float translationInPx = getResources().getDimensionPixelSize(
+ R.dimen.chooser_row_text_option_translate);
+ textView.setTranslationY(translationInPx);
+ ValueAnimator translateAnim = ObjectAnimator.ofFloat(textView, "translationY",
+ 0.0f);
+ translateAnim.setInterpolator(new DecelerateInterpolator(1.0f));
+
+ AnimatorSet animSet = new AnimatorSet();
+ animSet.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS);
+ animSet.setStartDelay(NO_DIRECT_SHARE_ANIM_IN_MILLIS);
+ animSet.playTogether(fadeAnim, translateAnim);
+ animSet.start();
+ }
}
for (int i = 0; i < mColumnCount; i++) {
final View v = holder.cells[i];
if (start + i <= end) {
- v.setVisibility(View.VISIBLE);
+ setCellVisibility(holder, i, View.VISIBLE);
holder.itemIndices[i] = start + i;
mChooserListAdapter.bindView(holder.itemIndices[i], v);
} else {
- v.setVisibility(View.INVISIBLE);
+ setCellVisibility(holder, i, View.INVISIBLE);
}
}
}
+ private void setCellVisibility(RowViewHolder holder, int i, int visibility) {
+ final View v = holder.cells[i];
+ if (visibility == View.VISIBLE) {
+ holder.cellVisibility[i] = true;
+ v.setVisibility(visibility);
+ v.setAlpha(1.0f);
+ } else if (visibility == View.INVISIBLE && holder.cellVisibility[i]) {
+ holder.cellVisibility[i] = false;
+
+ ValueAnimator fadeAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0f);
+ fadeAnim.setDuration(NO_DIRECT_SHARE_ANIM_IN_MILLIS);
+ fadeAnim.setInterpolator(new AccelerateInterpolator(1.0f));
+ fadeAnim.addListener(new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ v.setVisibility(View.INVISIBLE);
+ }
+ });
+ fadeAnim.start();
+ }
+ }
+
private void setVertPadding(RowViewHolder holder, int top, int bottom) {
holder.row.setPadding(holder.row.getPaddingLeft(), top,
holder.row.getPaddingRight(), bottom);
@@ -2132,14 +2324,16 @@
}
static class RowViewHolder {
- final View[] cells;
- final ViewGroup row;
+ public final View[] cells;
+ public final boolean [] cellVisibility;
+ public final ViewGroup row;
int measuredRowHeight;
int[] itemIndices;
public RowViewHolder(ViewGroup row, int cellCount) {
this.row = row;
this.cells = new View[cellCount];
+ this.cellVisibility = new boolean[cellCount];
this.itemIndices = new int[cellCount];
}
@@ -2217,8 +2411,6 @@
mChooserActivity.unbindService(this);
mChooserActivity.mServiceConnections.remove(this);
if (mChooserActivity.mServiceConnections.isEmpty()) {
- mChooserActivity.mChooserHandler.removeMessages(
- CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
mChooserActivity.sendVoiceChoicesIfNeeded();
}
mConnectedComponent = null;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 0919911..011cc04 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -28,6 +28,7 @@
import android.app.VoiceInteractor.PickOptionRequest;
import android.app.VoiceInteractor.PickOptionRequest.Option;
import android.app.VoiceInteractor.Prompt;
+import android.app.role.RoleManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -194,7 +195,7 @@
com.android.internal.R.string.whichHomeApplicationNamed,
com.android.internal.R.string.whichHomeApplicationLabel);
- // SpR.id.buttonecial titles for BROWSABLE components
+ // titles for layout that deals with http(s) intents
public static final int BROWSABLE_TITLE_RES =
com.android.internal.R.string.whichGiveAccessToApplication;
public static final int BROWSABLE_NAMED_TITLE_RES =
@@ -302,7 +303,7 @@
mUseLayoutForBrowsables = getTargetIntent() == null
? false
- : getTargetIntent().hasCategory(Intent.CATEGORY_BROWSABLE);
+ : isHttpSchemeAndViewAction(getTargetIntent());
// We don't want to support Always Use if browsable layout is being used,
// as to mitigate Intent Capturing vulnerability
@@ -473,8 +474,8 @@
final boolean named = mAdapter.getFilteredPosition() >= 0;
if (title == ActionTitle.DEFAULT && defaultTitleRes != 0) {
return getString(defaultTitleRes);
- } else if (intent.hasCategory(Intent.CATEGORY_BROWSABLE)) {
- // If the Intent is BROWSABLE then we need to warn the user that
+ } else if (isHttpSchemeAndViewAction(intent)) {
+ // If the Intent's scheme is http(s) then we need to warn the user that
// they're giving access for the activity to open URLs from this specific host
return named
? getString(ActionTitle.BROWSABLE_NAMED_TITLE_RES, intent.getData().getHost(),
@@ -583,6 +584,12 @@
resetButtonBar();
}
+ private boolean isHttpSchemeAndViewAction(Intent intent) {
+ return (IntentFilter.SCHEME_HTTP.equals(intent.getScheme())
+ || IntentFilter.SCHEME_HTTPS.equals(intent.getScheme()))
+ && Intent.ACTION_VIEW.equals(intent.getAction());
+ }
+
private boolean hasManagedProfile() {
UserManager userManager = (UserManager) getSystemService(Context.USER_SERVICE);
if (userManager == null) {
@@ -645,10 +652,18 @@
private void showSettingsForSelected(int which, boolean hasIndexBeenFiltered) {
ResolveInfo ri = mAdapter.resolveInfoForPosition(which, hasIndexBeenFiltered);
- Intent in = new Intent().setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
- .setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
- .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
- startActivity(in);
+ Intent intent = new Intent();
+ // For browsers, we open the Default Browser page
+ // For regular apps, we open the Open by Default page
+ if (ri.handleAllWebDataURI) {
+ intent.setAction(Intent.ACTION_MANAGE_DEFAULT_APP)
+ .putExtra(Intent.EXTRA_ROLE_NAME, RoleManager.ROLE_BROWSER);
+ } else {
+ intent.setAction(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS)
+ .setData(Uri.fromParts("package", ri.activityInfo.packageName, null))
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
+ }
+ startActivity(intent);
}
public void startSelected(int which, boolean always, boolean hasIndexBeenFiltered) {
diff --git a/core/java/com/android/internal/infra/WhitelistHelper.java b/core/java/com/android/internal/infra/WhitelistHelper.java
new file mode 100644
index 0000000..eec82bc
--- /dev/null
+++ b/core/java/com/android/internal/infra/WhitelistHelper.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.infra;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+
+/**
+ * Helper class for keeping track of whitelisted packages/activities.
+ *
+ * @hide
+ */
+public final class WhitelistHelper {
+
+ private static final String TAG = "WhitelistHelper";
+
+ /**
+ * Map of whitelisted packages/activities. The whole package is whitelisted if its
+ * corresponding value is {@code null}.
+ */
+ @Nullable
+ private ArrayMap<String, ArraySet<ComponentName>> mWhitelistedPackages;
+
+ /**
+ * Sets the whitelist with the given packages and activities. The list is cleared if both
+ * packageNames and components are {@code null}.
+ *
+ * @param packageNames packages to be whitelisted.
+ * @param components activities to be whitelisted.
+ *
+ * @throws IllegalArgumentException if packages or components are empty.
+ */
+ public void setWhitelist(@Nullable ArraySet<String> packageNames,
+ @Nullable ArraySet<ComponentName> components) {
+ mWhitelistedPackages = null;
+ if (packageNames == null && components == null) return;
+
+ if ((packageNames != null && packageNames.isEmpty())
+ || (components != null && components.isEmpty())) {
+ throw new IllegalArgumentException("Packages or Components cannot be empty.");
+ }
+
+ mWhitelistedPackages = new ArrayMap<>();
+
+ if (packageNames != null) {
+ for (int i = 0; i < packageNames.size(); i++) {
+ mWhitelistedPackages.put(packageNames.valueAt(i), null);
+ }
+ }
+
+ if (components != null) {
+ for (int i = 0; i < components.size(); i++) {
+ final ComponentName component = components.valueAt(i);
+ if (component == null) {
+ Log.w(TAG, "setWhitelist(): component is null");
+ continue;
+ }
+
+ final String packageName = component.getPackageName();
+ ArraySet<ComponentName> set = mWhitelistedPackages.get(packageName);
+ if (set == null) {
+ set = new ArraySet<>();
+ mWhitelistedPackages.put(packageName, set);
+ }
+ set.add(component);
+ }
+ }
+ }
+
+ /**
+ * Returns {@code true} if the entire package is whitelisted.
+ */
+ public boolean isWhitelisted(@NonNull String packageName) {
+ Preconditions.checkNotNull(packageName);
+
+ if (mWhitelistedPackages == null) return false;
+
+ return mWhitelistedPackages.containsKey(packageName)
+ && mWhitelistedPackages.get(packageName) == null;
+ }
+
+ /**
+ * Returns {@code true} if the specified activity is whitelisted.
+ */
+ public boolean isWhitelisted(@NonNull ComponentName componentName) {
+ Preconditions.checkNotNull(componentName);
+
+ final String packageName = componentName.getPackageName();
+ final ArraySet<ComponentName> whitelistedComponents = getWhitelistedComponents(packageName);
+ if (whitelistedComponents != null) {
+ return whitelistedComponents.contains(componentName);
+ }
+
+ return isWhitelisted(packageName);
+ }
+
+ /**
+ * Returns a set of whitelisted components with the given package, or null if nothing is
+ * whitelisted.
+ */
+ @Nullable
+ public ArraySet<ComponentName> getWhitelistedComponents(@NonNull String packageName) {
+ Preconditions.checkNotNull(packageName);
+
+ return mWhitelistedPackages == null ? null : mWhitelistedPackages.get(packageName);
+ }
+
+ @Override
+ public String toString() {
+ return "WhitelistHelper[" + mWhitelistedPackages + ']';
+ }
+
+ /**
+ * Dumps it!
+ */
+ public void dump(@NonNull String prefix, @NonNull String message, @NonNull PrintWriter pw) {
+ if (mWhitelistedPackages == null || mWhitelistedPackages.size() == 0) {
+ pw.print(prefix); pw.print(message); pw.println(": (no whitelisted packages)");
+ return;
+ }
+
+ final int size = mWhitelistedPackages.size();
+ pw.print(prefix); pw.print(message); pw.print(": "); pw.print(size);
+ pw.println(" packages");
+ for (int i = 0; i < mWhitelistedPackages.size(); i++) {
+ final String packageName = mWhitelistedPackages.keyAt(i);
+ final ArraySet<ComponentName> components = mWhitelistedPackages.valueAt(i);
+ pw.print(prefix); pw.print(i); pw.print("."); pw.print(packageName); pw.print(": ");
+ if (components == null) {
+ pw.println("(whole package)");
+ continue;
+ }
+
+ pw.print("["); pw.print(components.valueAt(0));
+ for (int j = 1; j < components.size(); j++) {
+ pw.print(", "); pw.print(components.valueAt(i));
+ }
+ pw.println("]");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 64bdc6e..f48b56d7 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -46,6 +46,7 @@
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.Interpolator;
+import android.view.inspector.InspectableProperty;
import android.widget.EdgeEffect;
import android.widget.Scroller;
@@ -2779,6 +2780,9 @@
* Where to position the view page within the overall ViewPager
* container; constants are defined in {@link android.view.Gravity}.
*/
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity;
/**
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index c1cbd52..62df6e7 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -1043,7 +1043,9 @@
optional SettingProto app_ops_constants = 148 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto text_classifier_action_model_params = 145 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 145 then 149; // (145 was removed)
+ // Next tag = 149;
}
diff --git a/core/res/res/drawable/chooser_row_layer_list.xml b/core/res/res/drawable/chooser_row_layer_list.xml
new file mode 100644
index 0000000..0fb26e1
--- /dev/null
+++ b/core/res/res/drawable/chooser_row_layer_list.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:bottom="-2dp" android:left="-2dp" android:right="-2dp">
+ <shape android:shape="rectangle">
+ <stroke android:width="1dp" android:color="@color/chooser_row_divider"/>
+ </shape>
+ </item>
+</layer-list>
diff --git a/core/res/res/layout/chooser_row.xml b/core/res/res/layout/chooser_row.xml
index cf81260..d4585eb 100644
--- a/core/res/res/layout/chooser_row.xml
+++ b/core/res/res/layout/chooser_row.xml
@@ -23,6 +23,12 @@
android:gravity="start|top"
android:paddingStart="@dimen/chooser_grid_padding"
android:paddingEnd="@dimen/chooser_grid_padding">
-
+ <TextView
+ android:id="@+id/chooser_row_text_option"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:layout_gravity="center"
+ android:visibility="gone" />
</LinearLayout>
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 02fae4a..e9b1bd3 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -215,4 +215,6 @@
<!-- Magnifier -->
<color name="default_magnifier_color_overlay">#00FFFFFF</color>
+ <color name="chooser_row_divider">#1f000000</color>
+
</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 818caa8..ccd35cd 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -706,6 +706,9 @@
<!-- Indicates that connected MAC randomization is supported on this device -->
<bool translatable="false" name="config_wifi_connected_mac_randomization_supported">false</bool>
+ <!-- Indicates that p2p MAC randomization is supported on this device -->
+ <bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">false</bool>
+
<!-- Indicates that wifi link probing is supported on this device -->
<bool translatable="false" name="config_wifi_link_probing_supported">false</bool>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 39cbd26..fafd8fe 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -717,6 +717,7 @@
<!-- chooser (sharesheet) spacing -->
<dimen name="chooser_corner_radius">8dp</dimen>
+ <dimen name="chooser_row_text_option_translate">25dp</dimen>
<dimen name="chooser_view_spacing">18dp</dimen>
<dimen name="chooser_edge_margin_thin">16dp</dimen>
<dimen name="chooser_edge_margin_normal">24dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4e47b1f..5b658b7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -5340,4 +5340,8 @@
<item quantity="one"><xliff:g id="file_name">%s</xliff:g> + <xliff:g id="count">%d</xliff:g> file</item>
<item quantity="other"><xliff:g id="file_name">%s</xliff:g> + <xliff:g id="count">%d</xliff:g> files</item>
</plurals>
+
+ <!-- ChooserActivity - No direct share targets are available. [CHAR LIMIT=NONE] -->
+ <string name="chooser_no_direct_share_targets">Direct share not available</string>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3ea9070..e01f421 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1939,6 +1939,7 @@
<java-symbol type="bool" name="config_wifi_convert_apband_5ghz_to_any" />
<java-symbol type="bool" name="config_wifi_local_only_hotspot_5ghz" />
<java-symbol type="bool" name="config_wifi_connected_mac_randomization_supported" />
+ <java-symbol type="bool" name="config_wifi_p2p_mac_randomization_supported" />
<java-symbol type="bool" name="config_wifi_link_probing_supported" />
<java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
<java-symbol type="bool" name="config_wimaxEnabled" />
@@ -2751,12 +2752,16 @@
<java-symbol type="id" name="month_view" />
<java-symbol type="integer" name="config_zen_repeat_callers_threshold" />
<java-symbol type="dimen" name="chooser_corner_radius" />
+ <java-symbol type="string" name="chooser_no_direct_share_targets" />
+ <java-symbol type="drawable" name="chooser_row_layer_list" />
<java-symbol type="dimen" name="chooser_view_spacing" />
<java-symbol type="dimen" name="chooser_edge_margin_thin" />
<java-symbol type="dimen" name="chooser_edge_margin_normal" />
<java-symbol type="dimen" name="chooser_preview_image_font_size"/>
<java-symbol type="dimen" name="chooser_preview_width" />
<java-symbol type="layout" name="chooser_grid" />
+ <java-symbol type="id" name="chooser_row_text_option" />
+ <java-symbol type="dimen" name="chooser_row_text_option_translate" />
<java-symbol type="layout" name="resolve_grid_item" />
<java-symbol type="id" name="day_picker_view_pager" />
<java-symbol type="layout" name="day_picker_content_material" />
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index c17aa92..109cff9 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -21,12 +21,14 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
+import android.content.LocusId;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.media.session.MediaSession;
@@ -320,6 +322,27 @@
action.clone().getSemanticAction());
}
+ @Test
+ public void testBuilder_setLocusId() {
+ LocusId locusId = new LocusId("4815162342");
+ Notification notification = new Notification.Builder(mContext, "whatever")
+ .setLocusId(locusId).build();
+ assertEquals(locusId, notification.getLocusId());
+
+ Notification clone = writeAndReadParcelable(notification);
+ assertEquals(locusId, clone.getLocusId());
+ }
+
+ @Test
+ public void testBuilder_setLocusId_null() {
+ Notification notification = new Notification.Builder(mContext, "whatever")
+ .setLocusId(null).build();
+ assertNull(notification.getLocusId());
+
+ Notification clone = writeAndReadParcelable(notification);
+ assertNull(clone.getLocusId());
+ }
+
private Notification.Builder getMediaNotification() {
MediaSession session = new MediaSession(mContext, "test");
return new Notification.Builder(mContext, "color")
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index de1453a..d100f40 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -30,6 +30,7 @@
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
+import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -223,7 +224,29 @@
}
@Test
- public void testListener() throws InterruptedException {
+ public void testListener_propertiesCallback() throws InterruptedException {
+ final CountDownLatch countDownLatch = new CountDownLatch(1);
+
+ OnPropertyChangedListener changeListener = new OnPropertyChangedListener() {
+ public void onPropertyChanged(String namespace, String name, String value) {
+ // ignore legacy callback
+ }
+
+ @Override
+ public void onPropertiesChanged(DeviceConfig.Properties properties) {
+ assertThat(properties.getNamespace()).isEqualTo(sNamespace);
+ assertThat(properties.getKeyset().size()).isEqualTo(1);
+ assertThat(properties.getKeyset()).contains(sKey);
+ assertThat(properties.getString(sKey, "default_value")).isEqualTo(sValue);
+ countDownLatch.countDown();
+ }
+ };
+
+ testListener(countDownLatch, changeListener);
+ }
+
+ @Test
+ public void testListener_legacyCallback() throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(1);
OnPropertyChangedListener changeListener = (namespace, name, value) -> {
@@ -233,16 +256,23 @@
countDownLatch.countDown();
};
+ testListener(countDownLatch, changeListener);
+
+ }
+
+ private void testListener(CountDownLatch countDownLatch,
+ OnPropertyChangedListener changeListener) {
try {
DeviceConfig.addOnPropertyChangedListener(sNamespace,
ActivityThread.currentApplication().getMainExecutor(), changeListener);
DeviceConfig.setProperty(sNamespace, sKey, sValue, false);
assertThat(countDownLatch.await(
WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue();
+ } catch (InterruptedException e) {
+ Assert.fail(e.getMessage());
} finally {
DeviceConfig.removeOnPropertyChangedListener(changeListener);
}
-
}
private static boolean deleteViaContentProvider(String namespace, String key) {
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ad1403d..2beff66 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -468,6 +468,7 @@
Settings.Global.TETHER_SUPPORTED,
Settings.Global.TETHER_ENABLE_LEGACY_DHCP_SERVER,
Settings.Global.TEXT_CLASSIFIER_CONSTANTS,
+ Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS,
Settings.Global.THEATER_MODE_ON,
Settings.Global.TIME_ONLY_MODE_CONSTANTS,
Settings.Global.TRANSITION_ANIMATION_SCALE,
diff --git a/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
new file mode 100644
index 0000000..1b3c724
--- /dev/null
+++ b/core/tests/coretests/src/android/view/textclassifier/ConfigParserTest.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.view.textclassifier;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.provider.DeviceConfig;
+import android.support.test.uiautomator.UiDevice;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ConfigParserTest {
+ private static final String SETTINGS = "int=42,float=12.3,boolean=true,string=abc";
+ private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
+ "device_config delete " + DeviceConfig.NAMESPACE_TEXTCLASSIFIER;
+ private static final String[] DEVICE_CONFIG_KEYS = new String[]{
+ "boolean",
+ "string",
+ "int",
+ "float"
+ };
+
+ private ConfigParser mConfigParser;
+
+ @Before
+ public void setup() throws IOException {
+ mConfigParser = new ConfigParser(SETTINGS);
+ clearDeviceConfig();
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ clearDeviceConfig();
+ }
+
+ @Test
+ public void getBoolean_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "boolean",
+ "false",
+ false);
+ boolean value = mConfigParser.getBoolean("boolean", true);
+ assertThat(value).isFalse();
+ }
+
+ @Test
+ public void getBoolean_settings() {
+ boolean value = mConfigParser.getBoolean(
+ "boolean",
+ false);
+ assertThat(value).isTrue();
+ }
+
+ @Test
+ public void getInt_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "int",
+ "1",
+ false);
+ int value = mConfigParser.getInt("int", 0);
+ assertThat(value).isEqualTo(1);
+ }
+
+ @Test
+ public void getInt_settings() {
+ int value = mConfigParser.getInt("int", 0);
+ assertThat(value).isEqualTo(42);
+ }
+
+ @Test
+ public void getFloat_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "float",
+ "3.14",
+ false);
+ float value = mConfigParser.getFloat("float", 0);
+ assertThat(value).isWithin(0.0001f).of(3.14f);
+ }
+
+ @Test
+ public void getFloat_settings() {
+ float value = mConfigParser.getFloat("float", 0);
+ assertThat(value).isWithin(0.0001f).of(12.3f);
+ }
+
+ @Test
+ public void getString_deviceConfig() {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_TEXTCLASSIFIER,
+ "string",
+ "hello",
+ false);
+ String value = mConfigParser.getString("string", "");
+ assertThat(value).isEqualTo("hello");
+ }
+
+ @Test
+ public void getString_settings() {
+ String value = mConfigParser.getString("string", "");
+ assertThat(value).isEqualTo("abc");
+ }
+
+ private static void clearDeviceConfig() throws IOException {
+ UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+ for (String key : DEVICE_CONFIG_KEYS) {
+ uiDevice.executeShellCommand(CLEAR_DEVICE_CONFIG_KEY_CMD + " " + key);
+ }
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index 9fbc166..3578bc0 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -740,6 +740,7 @@
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "testing intent sending");
+ sendIntent.setType("text/plain");
return sendIntent;
}
diff --git a/core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java b/core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java
new file mode 100644
index 0000000..ab6830b
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.infra;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.ComponentName;
+import android.util.ArraySet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/**
+ * Unit test for {@link WhitelistHelper}.
+ *
+ * <p>To run it:
+ * {@code atest FrameworksCoreTests:com.android.internal.infra.WhitelistHelperTest}
+ */
+
+@RunWith(MockitoJUnitRunner.class)
+public class WhitelistHelperTest {
+ private WhitelistHelper mWhitelistHelper = new WhitelistHelper();
+
+ private String mPackage1 = "com.example";
+ private String mPackage2 = "com.example2";
+
+ private ComponentName mComponent1 = new ComponentName(mPackage1, "class1");
+ private ComponentName mComponent2 = new ComponentName(mPackage1, "class2");
+ private ComponentName mComponentDifferentPkg = new ComponentName(mPackage2, "class3");
+
+ @Test
+ public void testSetWhitelist_emptyArguments() {
+ assertThrows(IllegalArgumentException.class,
+ () -> mWhitelistHelper.setWhitelist(new ArraySet<>(), null));
+ assertThrows(IllegalArgumentException.class,
+ () -> mWhitelistHelper.setWhitelist(null, new ArraySet<>()));
+ assertThrows(IllegalArgumentException.class,
+ () -> mWhitelistHelper.setWhitelist(new ArraySet<>(), new ArraySet<>()));
+ }
+
+ @Test
+ public void testWhitelistHelper_nullArguments() {
+ assertThrows(NullPointerException.class,
+ () -> mWhitelistHelper.isWhitelisted((String) null));
+ assertThrows(NullPointerException.class,
+ () -> mWhitelistHelper.isWhitelisted((ComponentName) null));
+ assertThrows(NullPointerException.class,
+ () -> mWhitelistHelper.getWhitelistedComponents(null));
+ }
+
+ @Test
+ public void testSetWhitelist_nullPackage() {
+ final ArraySet<String> packages = new ArraySet<>();
+ packages.add(null);
+ mWhitelistHelper.setWhitelist(packages, null);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+
+ @Test
+ public void testSetWhitelist_nullActivity() {
+ final ArraySet<ComponentName> components = new ArraySet<>();
+ components.add(null);
+ mWhitelistHelper.setWhitelist(null, components);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+
+ @Test
+ public void testSetWhitelist_replaceWhitelist() {
+ final ArraySet<ComponentName> components = new ArraySet<>();
+ components.add(mComponent1);
+ mWhitelistHelper.setWhitelist(null, components);
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+
+ final ArraySet<ComponentName> components2 = new ArraySet<>();
+ components2.add(mComponent2);
+ mWhitelistHelper.setWhitelist(null, components2);
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isTrue();
+ }
+
+ @Test
+ public void testIsWhitelisted_packageWhitelisted() {
+ final ArraySet<String> packages = new ArraySet<>();
+ packages.add(mPackage1);
+ mWhitelistHelper.setWhitelist(packages, null);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+
+ @Test
+ public void testIsWhitelisted_activityWhitelisted() {
+ final ArraySet<ComponentName> components = new ArraySet<>();
+ components.add(mComponent1);
+ mWhitelistHelper.setWhitelist(null, components);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+}
diff --git a/location/java/android/location/GnssMeasurementCorrections.java b/location/java/android/location/GnssMeasurementCorrections.java
index fdbc3dd..3e32c21 100644
--- a/location/java/android/location/GnssMeasurementCorrections.java
+++ b/location/java/android/location/GnssMeasurementCorrections.java
@@ -16,11 +16,16 @@
package android.location;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
+import com.android.internal.util.Preconditions;
+
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -35,37 +40,44 @@
public final class GnssMeasurementCorrections implements Parcelable {
/** Represents latitude in degrees at which the corrections are computed. */
- private double mLatitudeDegrees;
+ @FloatRange(from = -90.0f, to = 90.0f)
+ private final double mLatitudeDegrees;
/** Represents longitude in degrees at which the corrections are computed. */
- private double mLongitudeDegrees;
+ @FloatRange(from = -180.0f, to = 180.0f)
+ private final double mLongitudeDegrees;
/**
* Represents altitude in meters above the WGS 84 reference ellipsoid at which the corrections
* are computed.
*/
- private double mAltitudeMeters;
+ @FloatRange(from = -1000.0, to = 10000.0f)
+ private final double mAltitudeMeters;
/**
* Represents the horizontal uncertainty (68% confidence) in meters on the device position at
* which the corrections are provided.
*
* <p> This value is useful for example to judge how accurate the provided corrections are.
*/
- private double mHorizontalPositionUncertaintyMeters;
+ @FloatRange(from = 0.0f)
+ private final double mHorizontalPositionUncertaintyMeters;
/**
* Represents the vertical uncertainty (68% confidence) in meters on the device position at
* which the corrections are provided.
*
* <p> This value is useful for example to judge how accurate the provided corrections are.
*/
- private double mVerticalPositionUncertaintyMeters;
+ @FloatRange(from = 0.0f)
+ private final double mVerticalPositionUncertaintyMeters;
/** Time Of Applicability, GPS time of week in nanoseconds. */
- private long mToaGpsNanosecondsOfWeek;
+ @IntRange(from = 0)
+ private final long mToaGpsNanosecondsOfWeek;
/**
* A set of {@link GnssSingleSatCorrection} each containing measurement corrections for a
* satellite in view.
*/
- private @Nullable List<GnssSingleSatCorrection> mSingleSatCorrectionList;
+ @NonNull
+ private final List<GnssSingleSatCorrection> mSingleSatCorrectionList;
private GnssMeasurementCorrections(Builder builder) {
mLatitudeDegrees = builder.mLatitudeDegrees;
@@ -74,19 +86,19 @@
mHorizontalPositionUncertaintyMeters = builder.mHorizontalPositionUncertaintyMeters;
mVerticalPositionUncertaintyMeters = builder.mVerticalPositionUncertaintyMeters;
mToaGpsNanosecondsOfWeek = builder.mToaGpsNanosecondsOfWeek;
- mSingleSatCorrectionList =
- builder.mSingleSatCorrectionList == null
- ? null
- : Collections.unmodifiableList(
- new ArrayList<>(builder.mSingleSatCorrectionList));
+ final List<GnssSingleSatCorrection> singleSatCorrList = builder.mSingleSatCorrectionList;
+ Preconditions.checkArgument(singleSatCorrList != null && !singleSatCorrList.isEmpty());
+ mSingleSatCorrectionList = Collections.unmodifiableList(new ArrayList<>(singleSatCorrList));
}
/** Gets the latitude in degrees at which the corrections are computed. */
+ @FloatRange(from = -90.0f, to = 90.0f)
public double getLatitudeDegrees() {
return mLatitudeDegrees;
}
/** Gets the longitude in degrees at which the corrections are computed. */
+ @FloatRange(from = -180.0f, to = 180.0f)
public double getLongitudeDegrees() {
return mLongitudeDegrees;
}
@@ -95,6 +107,7 @@
* Gets the altitude in meters above the WGS 84 reference ellipsoid at which the corrections are
* computed.
*/
+ @FloatRange(from = -1000.0f, to = 10000.0f)
public double getAltitudeMeters() {
return mAltitudeMeters;
}
@@ -103,6 +116,7 @@
* Gets the horizontal uncertainty (68% confidence) in meters on the device position at
* which the corrections are provided.
*/
+ @FloatRange(from = 0.0f)
public double getHorizontalPositionUncertaintyMeters() {
return mHorizontalPositionUncertaintyMeters;
}
@@ -111,11 +125,13 @@
* Gets the vertical uncertainty (68% confidence) in meters on the device position at
* which the corrections are provided.
*/
+ @FloatRange(from = 0.0f)
public double getVerticalPositionUncertaintyMeters() {
return mVerticalPositionUncertaintyMeters;
}
/** Gets the time of applicability, GPS time of week in nanoseconds. */
+ @IntRange(from = 0)
public long getToaGpsNanosecondsOfWeek() {
return mToaGpsNanosecondsOfWeek;
}
@@ -124,7 +140,8 @@
* Gets a set of {@link GnssSingleSatCorrection} each containing measurement corrections for a
* satellite in view
*/
- public @Nullable List<GnssSingleSatCorrection> getSingleSatelliteCorrectionList() {
+ @NonNull
+ public List<GnssSingleSatCorrection> getSingleSatelliteCorrectionList() {
return mSingleSatCorrectionList;
}
@@ -133,10 +150,11 @@
return 0;
}
- public static final @android.annotation.NonNull Creator<GnssMeasurementCorrections> CREATOR =
+ public static final Creator<GnssMeasurementCorrections> CREATOR =
new Creator<GnssMeasurementCorrections>() {
@Override
- public GnssMeasurementCorrections createFromParcel(Parcel parcel) {
+ @NonNull
+ public GnssMeasurementCorrections createFromParcel(@NonNull Parcel parcel) {
final GnssMeasurementCorrections.Builder gnssMeasurementCorrectons =
new Builder()
.setLatitudeDegrees(parcel.readDouble())
@@ -148,7 +166,7 @@
List<GnssSingleSatCorrection> singleSatCorrectionList = new ArrayList<>();
parcel.readTypedList(singleSatCorrectionList, GnssSingleSatCorrection.CREATOR);
gnssMeasurementCorrectons.setSingleSatelliteCorrectionList(
- singleSatCorrectionList.isEmpty() ? null : singleSatCorrectionList);
+ singleSatCorrectionList);
return gnssMeasurementCorrectons.build();
}
@@ -177,7 +195,7 @@
}
@Override
- public void writeToParcel(Parcel parcel, int flags) {
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeDouble(mLatitudeDegrees);
parcel.writeDouble(mLongitudeDegrees);
parcel.writeDouble(mAltitudeMeters);
@@ -199,16 +217,18 @@
private double mHorizontalPositionUncertaintyMeters;
private double mVerticalPositionUncertaintyMeters;
private long mToaGpsNanosecondsOfWeek;
- private List<GnssSingleSatCorrection> mSingleSatCorrectionList;
+ @Nullable private List<GnssSingleSatCorrection> mSingleSatCorrectionList;
/** Sets the latitude in degrees at which the corrections are computed. */
- public Builder setLatitudeDegrees(double latitudeDegrees) {
+ @NonNull public Builder setLatitudeDegrees(
+ @FloatRange(from = -90.0f, to = 90.0f) double latitudeDegrees) {
mLatitudeDegrees = latitudeDegrees;
return this;
}
/** Sets the longitude in degrees at which the corrections are computed. */
- public Builder setLongitudeDegrees(double longitudeDegrees) {
+ @NonNull public Builder setLongitudeDegrees(
+ @FloatRange(from = -180.0f, to = 180.0f) double longitudeDegrees) {
mLongitudeDegrees = longitudeDegrees;
return this;
}
@@ -217,7 +237,8 @@
* Sets the altitude in meters above the WGS 84 reference ellipsoid at which the corrections
* are computed.
*/
- public Builder setAltitudeMeters(double altitudeMeters) {
+ @NonNull public Builder setAltitudeMeters(
+ @FloatRange(from = -1000.0f, to = 10000.0f) double altitudeMeters) {
mAltitudeMeters = altitudeMeters;
return this;
}
@@ -227,8 +248,8 @@
* Sets the horizontal uncertainty (68% confidence) in meters on the device position at
* which the corrections are provided.
*/
- public Builder setHorizontalPositionUncertaintyMeters(
- double horizontalPositionUncertaintyMeters) {
+ @NonNull public Builder setHorizontalPositionUncertaintyMeters(
+ @FloatRange(from = 0.0f) double horizontalPositionUncertaintyMeters) {
mHorizontalPositionUncertaintyMeters = horizontalPositionUncertaintyMeters;
return this;
}
@@ -237,14 +258,15 @@
* Sets the vertical uncertainty (68% confidence) in meters on the device position at which
* the corrections are provided.
*/
- public Builder setVerticalPositionUncertaintyMeters(
- double verticalPositionUncertaintyMeters) {
+ @NonNull public Builder setVerticalPositionUncertaintyMeters(
+ @FloatRange(from = 0.0f) double verticalPositionUncertaintyMeters) {
mVerticalPositionUncertaintyMeters = verticalPositionUncertaintyMeters;
return this;
}
/** Sets the time of applicability, GPS time of week in nanoseconds. */
- public Builder setToaGpsNanosecondsOfWeek(long toaGpsNanosecondsOfWeek) {
+ @NonNull public Builder setToaGpsNanosecondsOfWeek(
+ @IntRange(from = 0) long toaGpsNanosecondsOfWeek) {
mToaGpsNanosecondsOfWeek = toaGpsNanosecondsOfWeek;
return this;
}
@@ -253,19 +275,14 @@
* Sets a the list of {@link GnssSingleSatCorrection} containing measurement corrections for
* a satellite in view
*/
- public Builder setSingleSatelliteCorrectionList(
- @Nullable List<GnssSingleSatCorrection> singleSatCorrectionList) {
- if (singleSatCorrectionList == null) {
- mSingleSatCorrectionList = null;
- } else {
- mSingleSatCorrectionList =
- Collections.unmodifiableList(new ArrayList<>(singleSatCorrectionList));
- }
+ @NonNull public Builder setSingleSatelliteCorrectionList(
+ @NonNull List<GnssSingleSatCorrection> singleSatCorrectionList) {
+ mSingleSatCorrectionList = singleSatCorrectionList;
return this;
}
/** Builds a {@link GnssMeasurementCorrections} instance as specified by this builder. */
- public GnssMeasurementCorrections build() {
+ @NonNull public GnssMeasurementCorrections build() {
return new GnssMeasurementCorrections(this);
}
}
diff --git a/location/java/android/location/GnssReflectingPlane.java b/location/java/android/location/GnssReflectingPlane.java
index c5095d7..9d05287 100644
--- a/location/java/android/location/GnssReflectingPlane.java
+++ b/location/java/android/location/GnssReflectingPlane.java
@@ -16,6 +16,8 @@
package android.location;
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -29,17 +31,21 @@
public final class GnssReflectingPlane implements Parcelable {
/** Represents latitude in degrees of the reflecting plane */
- private double mLatitudeDegrees;
+ @FloatRange(from = -90.0f, to = 90.0f)
+ private final double mLatitudeDegrees;
/** Represents longitude in degrees of the reflecting plane. */
- private double mLongitudeDegrees;
+ @FloatRange(from = -180.0f, to = 180.0f)
+ private final double mLongitudeDegrees;
/**
* Represents altitude in meters above the WGS 84 reference ellipsoid of the reflection point in
* the plane
*/
- private double mAltitudeMeters;
+ @FloatRange(from = -1000.0f, to = 10000.0f)
+ private final double mAltitudeMeters;
/** Represents azimuth clockwise from north of the reflecting plane in degrees. */
- private double mAzimuthDegrees;
+ @FloatRange(from = 0.0f, to = 360.0f)
+ private final double mAzimuthDegrees;
private GnssReflectingPlane(Builder builder) {
mLatitudeDegrees = builder.mLatitudeDegrees;
@@ -49,11 +55,13 @@
}
/** Gets the latitude in degrees of the reflecting plane. */
+ @FloatRange(from = -90.0f, to = 90.0f)
public double getLatitudeDegrees() {
return mLatitudeDegrees;
}
/** Gets the longitude in degrees of the reflecting plane. */
+ @FloatRange(from = -180.0f, to = 180.0f)
public double getLongitudeDegrees() {
return mLongitudeDegrees;
}
@@ -62,11 +70,13 @@
* Gets the altitude in meters above the WGS 84 reference ellipsoid of the reflecting point
* within the plane
*/
+ @FloatRange(from = -1000.0f, to = 10000.0f)
public double getAltitudeMeters() {
return mAltitudeMeters;
}
/** Gets the azimuth clockwise from north of the reflecting plane in degrees. */
+ @FloatRange(from = 0.0f, to = 360.0f)
public double getAzimuthDegrees() {
return mAzimuthDegrees;
}
@@ -76,10 +86,11 @@
return 0;
}
- public static final @android.annotation.NonNull Creator<GnssReflectingPlane> CREATOR =
+ public static final Creator<GnssReflectingPlane> CREATOR =
new Creator<GnssReflectingPlane>() {
@Override
- public GnssReflectingPlane createFromParcel(Parcel parcel) {
+ @NonNull
+ public GnssReflectingPlane createFromParcel(@NonNull Parcel parcel) {
GnssReflectingPlane reflectingPlane =
new Builder()
.setLatitudeDegrees(parcel.readDouble())
@@ -108,7 +119,7 @@
}
@Override
- public void writeToParcel(Parcel parcel, int flags) {
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeDouble(mLatitudeDegrees);
parcel.writeDouble(mLongitudeDegrees);
parcel.writeDouble(mAltitudeMeters);
@@ -119,19 +130,20 @@
public static final class Builder {
/** For documentation, see corresponding fields in {@link GnssReflectingPlane}. */
private double mLatitudeDegrees;
-
private double mLongitudeDegrees;
private double mAltitudeMeters;
private double mAzimuthDegrees;
/** Sets the latitude in degrees of the reflecting plane. */
- public Builder setLatitudeDegrees(double latitudeDegrees) {
+ @NonNull public Builder setLatitudeDegrees(
+ @FloatRange(from = -90.0f, to = 90.0f) double latitudeDegrees) {
mLatitudeDegrees = latitudeDegrees;
return this;
}
/** Sets the longitude in degrees of the reflecting plane. */
- public Builder setLongitudeDegrees(double longitudeDegrees) {
+ @NonNull public Builder setLongitudeDegrees(
+ @FloatRange(from = -180.0f, to = 180.0f) double longitudeDegrees) {
mLongitudeDegrees = longitudeDegrees;
return this;
}
@@ -140,19 +152,21 @@
* Sets the altitude in meters above the WGS 84 reference ellipsoid of the reflecting point
* within the plane
*/
- public Builder setAltitudeMeters(double altitudeMeters) {
+ @NonNull public Builder setAltitudeMeters(
+ @FloatRange(from = -1000.0f, to = 10000.0f) double altitudeMeters) {
mAltitudeMeters = altitudeMeters;
return this;
}
/** Sets the azimuth clockwise from north of the reflecting plane in degrees. */
- public Builder setAzimuthDegrees(double azimuthDegrees) {
+ @NonNull public Builder setAzimuthDegrees(
+ @FloatRange(from = 0.0f, to = 360.0f) double azimuthDegrees) {
mAzimuthDegrees = azimuthDegrees;
return this;
}
/** Builds a {@link GnssReflectingPlane} object as specified by this builder. */
- public GnssReflectingPlane build() {
+ @NonNull public GnssReflectingPlane build() {
return new GnssReflectingPlane(this);
}
}
diff --git a/location/java/android/location/GnssSingleSatCorrection.java b/location/java/android/location/GnssSingleSatCorrection.java
index dbf3fd9..e901909 100644
--- a/location/java/android/location/GnssSingleSatCorrection.java
+++ b/location/java/android/location/GnssSingleSatCorrection.java
@@ -17,6 +17,8 @@
package android.location;
import android.annotation.FloatRange;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
@@ -35,40 +37,49 @@
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mProbSatIsLos}.
+ *
+ * @hide
*/
public static final int HAS_PROB_SAT_IS_LOS_MASK = 1 << 0;
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mExcessPathLengthMeters}.
+ *
+ * @hide
*/
public static final int HAS_EXCESS_PATH_LENGTH_MASK = 1 << 1;
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mExcessPathLengthUncertaintyMeters}.
+ *
+ * @hide
*/
public static final int HAS_EXCESS_PATH_LENGTH_UNC_MASK = 1 << 2;
/**
* Bit mask for {@link #mSingleSatCorrectionFlags} indicating the presence of {@link
* #mReflectingPlane}.
+ *
+ * @hide
*/
public static final int HAS_REFLECTING_PLANE_MASK = 1 << 3;
/** A bitmask of fields present in this object (see HAS_* constants defined above) */
- private int mSingleSatCorrectionFlags;
+ private final int mSingleSatCorrectionFlags;
/** Defines the constellation of the given satellite as defined in {@link GnssStatus}. */
@GnssStatus.ConstellationType
- private int mConstellationType;
+ private final int mConstellationType;
/**
* Satellite vehicle ID number
*
* <p>Interpretation depends on {@link GnssStatus#getSvid(int)}.
*/
- private int mSatId;
+ @IntRange(from = 0)
+ private final int mSatId;
/**
* Carrier frequency of the signal to be corrected, for example it can be the GPS center
@@ -79,22 +90,25 @@
* values related to L1 will be filled, and in the other all of the values related to L5 will be
* filled.
*/
- private float mCarrierFrequencyHz;
+ @FloatRange(from = 0.0f, fromInclusive = false)
+ private final float mCarrierFrequencyHz;
/**
* The probability that the satellite is estimated to be in Line-of-Sight condition at the given
* location.
*/
- @FloatRange(from = 0f, to = 1f)
- private float mProbSatIsLos;
+ @FloatRange(from = 0.0f, to = 1.0f)
+ private final float mProbSatIsLos;
/**
* Excess path length to be subtracted from pseudorange before using it in calculating location.
*/
- private float mExcessPathLengthMeters;
+ @FloatRange(from = 0.0f)
+ private final float mExcessPathLengthMeters;
/** Error estimate (1-sigma) for the Excess path length estimate */
- private float mExcessPathLengthUncertaintyMeters;
+ @FloatRange(from = 0.0f)
+ private final float mExcessPathLengthUncertaintyMeters;
/**
* Defines the reflecting plane location and azimuth information
@@ -102,7 +116,8 @@
* <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
* signal goes through multiple reflections or if reflection plane serving is not supported.
*/
- private @Nullable GnssReflectingPlane mReflectingPlane;
+ @Nullable
+ private final GnssReflectingPlane mReflectingPlane;
private GnssSingleSatCorrection(Builder builder) {
mSingleSatCorrectionFlags = builder.mSingleSatCorrectionFlags;
@@ -115,7 +130,11 @@
mReflectingPlane = builder.mReflectingPlane;
}
- /** Gets a bitmask of fields present in this object */
+ /**
+ * Gets a bitmask of fields present in this object
+ *
+ * @hide
+ */
public int getSingleSatelliteCorrectionFlags() {
return mSingleSatCorrectionFlags;
}
@@ -137,6 +156,7 @@
* <p>Interpretation depends on {@link #getConstellationType()}. See {@link
* GnssStatus#getSvid(int)}.
*/
+ @IntRange(from = 0)
public int getSatelliteId() {
return mSatId;
}
@@ -154,6 +174,7 @@
*
* @return the carrier frequency of the signal tracked in Hz.
*/
+ @FloatRange(from = 0.0f, fromInclusive = false)
public float getCarrierFrequencyHz() {
return mCarrierFrequencyHz;
}
@@ -162,7 +183,7 @@
* Returns the probability that the satellite is in line-of-sight condition at the given
* location.
*/
- @FloatRange(from = 0f, to = 1f)
+ @FloatRange(from = 0.0f, to = 1.0f)
public float getProbabilityLineOfSight() {
return mProbSatIsLos;
}
@@ -171,11 +192,13 @@
* Returns the Excess path length to be subtracted from pseudorange before using it in
* calculating location.
*/
+ @FloatRange(from = 0.0f)
public float getExcessPathLengthMeters() {
return mExcessPathLengthMeters;
}
/** Returns the error estimate (1-sigma) for the Excess path length estimate */
+ @FloatRange(from = 0.0f)
public float getExcessPathLengthUncertaintyMeters() {
return mExcessPathLengthUncertaintyMeters;
}
@@ -186,7 +209,8 @@
* <p>The flag HAS_REFLECTING_PLANE will be used to set this value to invalid if the satellite
* signal goes through multiple reflections or if reflection plane serving is not supported
*/
- public @Nullable GnssReflectingPlane getReflectingPlane() {
+ @Nullable
+ public GnssReflectingPlane getReflectingPlane() {
return mReflectingPlane;
}
@@ -215,23 +239,27 @@
return 0;
}
- public static final @android.annotation.NonNull Creator<GnssSingleSatCorrection> CREATOR =
+ public static final Creator<GnssSingleSatCorrection> CREATOR =
new Creator<GnssSingleSatCorrection>() {
@Override
- public GnssSingleSatCorrection createFromParcel(Parcel parcel) {
- GnssSingleSatCorrection singleSatCorrection =
+ @NonNull
+ public GnssSingleSatCorrection createFromParcel(@NonNull Parcel parcel) {
+ int mSingleSatCorrectionFlags = parcel.readInt();
+ boolean hasReflectingPlane =
+ (mSingleSatCorrectionFlags & HAS_REFLECTING_PLANE_MASK) != 0;
+ final GnssSingleSatCorrection.Builder singleSatCorrectionBuilder =
new Builder()
- .setSingleSatelliteCorrectionFlags(parcel.readInt())
.setConstellationType(parcel.readInt())
.setSatelliteId(parcel.readInt())
.setCarrierFrequencyHz(parcel.readFloat())
.setProbabilityLineOfSight(parcel.readFloat())
.setExcessPathLengthMeters(parcel.readFloat())
- .setExcessPathLengthUncertaintyMeters(parcel.readFloat())
- .setReflectingPlane(
- GnssReflectingPlane.CREATOR.createFromParcel(parcel))
- .build();
- return singleSatCorrection;
+ .setExcessPathLengthUncertaintyMeters(parcel.readFloat());
+ if (hasReflectingPlane) {
+ singleSatCorrectionBuilder.setReflectingPlane(
+ GnssReflectingPlane.CREATOR.createFromParcel(parcel));
+ }
+ return singleSatCorrectionBuilder.build();
}
@Override
@@ -256,12 +284,14 @@
format,
"ExcessPathLengthUncertaintyMeters = ",
mExcessPathLengthUncertaintyMeters));
- builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane));
+ if (hasReflectingPlane()) {
+ builder.append(String.format(format, "ReflectingPlane = ", mReflectingPlane));
+ }
return builder.toString();
}
@Override
- public void writeToParcel(Parcel parcel, int flags) {
+ public void writeToParcel(@NonNull Parcel parcel, int flags) {
parcel.writeInt(mSingleSatCorrectionFlags);
parcel.writeInt(mConstellationType);
parcel.writeInt(mSatId);
@@ -269,7 +299,9 @@
parcel.writeFloat(mProbSatIsLos);
parcel.writeFloat(mExcessPathLengthMeters);
parcel.writeFloat(mExcessPathLengthUncertaintyMeters);
- mReflectingPlane.writeToParcel(parcel, flags);
+ if (hasReflectingPlane()) {
+ mReflectingPlane.writeToParcel(parcel, flags);
+ }
}
/** Builder for {@link GnssSingleSatCorrection} */
@@ -287,28 +319,25 @@
private float mProbSatIsLos;
private float mExcessPathLengthMeters;
private float mExcessPathLengthUncertaintyMeters;
+ @Nullable
private GnssReflectingPlane mReflectingPlane;
- /** Sets a bitmask of fields present in this object */
- public Builder setSingleSatelliteCorrectionFlags(int singleSatCorrectionFlags) {
- mSingleSatCorrectionFlags = singleSatCorrectionFlags;
- return this;
- }
-
/** Sets the constellation type. */
- public Builder setConstellationType(@GnssStatus.ConstellationType int constellationType) {
+ @NonNull public Builder setConstellationType(
+ @GnssStatus.ConstellationType int constellationType) {
mConstellationType = constellationType;
return this;
}
/** Sets the Satellite ID defined in the ICD of the given constellation. */
- public Builder setSatelliteId(int satId) {
+ @NonNull public Builder setSatelliteId(@IntRange(from = 0) int satId) {
mSatId = satId;
return this;
}
/** Sets the Carrier frequency in Hz. */
- public Builder setCarrierFrequencyHz(float carrierFrequencyHz) {
+ @NonNull public Builder setCarrierFrequencyHz(
+ @FloatRange(from = 0.0f, fromInclusive = false) float carrierFrequencyHz) {
mCarrierFrequencyHz = carrierFrequencyHz;
return this;
}
@@ -317,8 +346,8 @@
* Sets the line-of-sight probability of the satellite at the given location in the range
* between 0 and 1.
*/
- public Builder setProbabilityLineOfSight(
- @FloatRange(from = 0f, to = 1f) float probSatIsLos) {
+ @NonNull public Builder setProbabilityLineOfSight(
+ @FloatRange(from = 0.0f, to = 1.0f) float probSatIsLos) {
Preconditions.checkArgumentInRange(
probSatIsLos, 0, 1, "probSatIsLos should be between 0 and 1.");
mProbSatIsLos = probSatIsLos;
@@ -331,7 +360,8 @@
* Sets the Excess path length to be subtracted from pseudorange before using it in
* calculating location.
*/
- public Builder setExcessPathLengthMeters(float excessPathLengthMeters) {
+ @NonNull public Builder setExcessPathLengthMeters(
+ @FloatRange(from = 0.0f) float excessPathLengthMeters) {
mExcessPathLengthMeters = excessPathLengthMeters;
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_MASK);
@@ -339,8 +369,8 @@
}
/** Sets the error estimate (1-sigma) for the Excess path length estimate */
- public Builder setExcessPathLengthUncertaintyMeters(
- float excessPathLengthUncertaintyMeters) {
+ @NonNull public Builder setExcessPathLengthUncertaintyMeters(
+ @FloatRange(from = 0.0f) float excessPathLengthUncertaintyMeters) {
mExcessPathLengthUncertaintyMeters = excessPathLengthUncertaintyMeters;
mSingleSatCorrectionFlags =
(byte) (mSingleSatCorrectionFlags | HAS_EXCESS_PATH_LENGTH_UNC_MASK);
@@ -348,15 +378,20 @@
}
/** Sets the reflecting plane information */
- public Builder setReflectingPlane(GnssReflectingPlane reflectingPlane) {
+ @NonNull public Builder setReflectingPlane(@Nullable GnssReflectingPlane reflectingPlane) {
mReflectingPlane = reflectingPlane;
- mSingleSatCorrectionFlags =
- (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK);
+ if (reflectingPlane != null) {
+ mSingleSatCorrectionFlags =
+ (byte) (mSingleSatCorrectionFlags | HAS_REFLECTING_PLANE_MASK);
+ } else {
+ mSingleSatCorrectionFlags =
+ (byte) (mSingleSatCorrectionFlags & ~HAS_REFLECTING_PLANE_MASK);
+ }
return this;
}
/** Builds a {@link GnssSingleSatCorrection} instance as specified by this builder. */
- public GnssSingleSatCorrection build() {
+ @NonNull public GnssSingleSatCorrection build() {
return new GnssSingleSatCorrection(this);
}
}
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 609a15e..4e37654 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -30,6 +30,7 @@
* <p>This class is used in conjunction with the {@link Listener} interface.
*
* @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
+ * @removed
*/
@Deprecated
public final class GpsStatus {
@@ -112,6 +113,7 @@
/**
* Used for receiving notifications when GPS status has changed.
* @deprecated use {@link GnssStatus.Callback} instead.
+ * @removed
*/
@Deprecated
public interface Listener {
@@ -142,6 +144,7 @@
* You can implement this interface and call {@link LocationManager#addNmeaListener}
* to receive NMEA data from the GPS engine.
* @deprecated use {@link OnNmeaMessageListener} instead.
+ * @removed
*/
@Deprecated
public interface NmeaListener {
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 6828c59..8af1532 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -44,12 +44,12 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.location.ProviderProperties;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
/**
@@ -78,14 +78,10 @@
private final GnssMeasurementCallbackTransport mGnssMeasurementCallbackTransport;
private final GnssNavigationMessageCallbackTransport mGnssNavigationMessageCallbackTransport;
private final BatchedLocationCallbackTransport mBatchedLocationCallbackTransport;
- private final HashMap<GpsStatus.Listener, GnssStatusListenerTransport> mGpsStatusListeners =
- new HashMap<>();
- private final HashMap<GpsStatus.NmeaListener, GnssStatusListenerTransport> mGpsNmeaListeners =
- new HashMap<>();
- private final HashMap<GnssStatus.Callback, GnssStatusListenerTransport> mGnssStatusListeners =
- new HashMap<>();
- private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
- new HashMap<>();
+ private final ArrayMap<GnssStatus.Callback, GnssStatusListenerTransport> mGnssStatusListeners =
+ new ArrayMap<>();
+ private final ArrayMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
+ new ArrayMap<>();
// volatile + GnssStatus final-fields pattern to avoid a partially published object
private volatile GnssStatus mGnssStatus;
private int mTimeToFirstFix;
@@ -293,8 +289,7 @@
"com.android.settings.location.FOOTER_STRING";
// Map from LocationListeners to their associated ListenerTransport objects
- private final HashMap<LocationListener, ListenerTransport> mListeners =
- new HashMap<LocationListener,ListenerTransport>();
+ private final ArrayMap<LocationListener, ListenerTransport> mListeners = new ArrayMap<>();
private class ListenerTransport extends ILocationListener.Stub {
private static final int TYPE_LOCATION_CHANGED = 1;
@@ -405,7 +400,7 @@
* @hide
*/
@TestApi
- public String[] getBackgroundThrottlingWhitelist() {
+ public @NonNull String[] getBackgroundThrottlingWhitelist() {
try {
return mService.getBackgroundThrottlingWhitelist();
} catch (RemoteException e) {
@@ -417,7 +412,7 @@
* @hide
*/
@TestApi
- public String[] getIgnoreSettingsWhitelist() {
+ public @NonNull String[] getIgnoreSettingsWhitelist() {
try {
return mService.getIgnoreSettingsWhitelist();
} catch (RemoteException e) {
@@ -431,7 +426,7 @@
* right way to create an instance of this class is using the
* factory Context.getSystemService.
*/
- public LocationManager(Context context, ILocationManager service) {
+ public LocationManager(@NonNull Context context, @NonNull ILocationManager service) {
mService = service;
mContext = context;
mGnssMeasurementCallbackTransport =
@@ -454,7 +449,7 @@
*
* @return list of Strings containing names of the provider
*/
- public List<String> getAllProviders() {
+ public @NonNull List<String> getAllProviders() {
try {
return mService.getAllProviders();
} catch (RemoteException e) {
@@ -469,7 +464,7 @@
* enabled are returned.
* @return list of Strings containing names of the providers
*/
- public List<String> getProviders(boolean enabledOnly) {
+ public @NonNull List<String> getProviders(boolean enabledOnly) {
try {
return mService.getProviders(null, enabledOnly);
} catch (RemoteException e) {
@@ -488,7 +483,7 @@
* @throws SecurityException if the caller is not permitted to access the
* given provider.
*/
- public LocationProvider getProvider(String name) {
+ public @Nullable LocationProvider getProvider(@NonNull String name) {
checkProvider(name);
try {
ProviderProperties properties = mService.getProviderProperties(name);
@@ -511,7 +506,7 @@
* enabled are returned.
* @return list of Strings containing names of the providers
*/
- public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
+ public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) {
checkCriteria(criteria);
try {
return mService.getProviders(criteria, enabledOnly);
@@ -542,7 +537,7 @@
* @param enabledOnly if true then only a provider that is currently enabled is returned
* @return name of the provider that best matches the requirements
*/
- public String getBestProvider(Criteria criteria, boolean enabledOnly) {
+ public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) {
checkCriteria(criteria);
try {
return mService.getBestProvider(criteria, enabledOnly);
@@ -572,8 +567,8 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- LocationListener listener) {
+ public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ @NonNull LocationListener listener) {
checkProvider(provider);
checkListener(listener);
@@ -604,8 +599,8 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- LocationListener listener, Looper looper) {
+ public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ @NonNull LocationListener listener, @Nullable Looper looper) {
checkProvider(provider);
checkListener(listener);
@@ -637,8 +632,8 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
- LocationListener listener, Looper looper) {
+ public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria,
+ @NonNull LocationListener listener, @Nullable Looper looper) {
checkCriteria(criteria);
checkListener(listener);
@@ -665,8 +660,8 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- PendingIntent intent) {
+ public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ @NonNull PendingIntent intent) {
checkProvider(provider);
checkPendingIntent(intent);
@@ -772,8 +767,8 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
- PendingIntent intent) {
+ public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria,
+ @NonNull PendingIntent intent) {
checkCriteria(criteria);
checkPendingIntent(intent);
@@ -802,7 +797,8 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(String provider, LocationListener listener, Looper looper) {
+ public void requestSingleUpdate(
+ @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) {
checkProvider(provider);
checkListener(listener);
@@ -832,7 +828,10 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper) {
+ public void requestSingleUpdate(
+ @NonNull Criteria criteria,
+ @NonNull LocationListener listener,
+ @Nullable Looper looper) {
checkCriteria(criteria);
checkListener(listener);
@@ -855,7 +854,7 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(String provider, PendingIntent intent) {
+ public void requestSingleUpdate(@NonNull String provider, @NonNull PendingIntent intent) {
checkProvider(provider);
checkPendingIntent(intent);
@@ -879,7 +878,7 @@
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(Criteria criteria, PendingIntent intent) {
+ public void requestSingleUpdate(@NonNull Criteria criteria, @NonNull PendingIntent intent) {
checkCriteria(criteria);
checkPendingIntent(intent);
@@ -948,8 +947,10 @@
@SystemApi
@TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(LocationRequest request, LocationListener listener,
- Looper looper) {
+ public void requestLocationUpdates(
+ @NonNull LocationRequest request,
+ @NonNull LocationListener listener,
+ @Nullable Looper looper) {
checkListener(listener);
requestLocationUpdates(request, listener, looper, null);
}
@@ -978,7 +979,8 @@
@SystemApi
@TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
+ public void requestLocationUpdates(
+ @NonNull LocationRequest request, @NonNull PendingIntent intent) {
checkPendingIntent(intent);
requestLocationUpdates(request, null, null, intent);
}
@@ -1003,7 +1005,7 @@
* @hide
*/
@RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION})
- public boolean injectLocation(Location newLocation) {
+ public boolean injectLocation(@NonNull Location newLocation) {
try {
return mService.injectLocation(newLocation);
} catch (RemoteException e) {
@@ -1048,7 +1050,7 @@
* @param listener listener object that no longer needs location updates
* @throws IllegalArgumentException if listener is null
*/
- public void removeUpdates(LocationListener listener) {
+ public void removeUpdates(@NonNull LocationListener listener) {
checkListener(listener);
String packageName = mContext.getPackageName();
@@ -1073,7 +1075,7 @@
* @param intent pending intent object that no longer needs location updates
* @throws IllegalArgumentException if intent is null
*/
- public void removeUpdates(PendingIntent intent) {
+ public void removeUpdates(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1133,7 +1135,7 @@
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void addProximityAlert(double latitude, double longitude, float radius, long expiration,
- PendingIntent intent) {
+ @NonNull PendingIntent intent) {
checkPendingIntent(intent);
if (expiration < 0) expiration = Long.MAX_VALUE;
@@ -1183,7 +1185,10 @@
* @hide
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void addGeofence(LocationRequest request, Geofence fence, PendingIntent intent) {
+ public void addGeofence(
+ @NonNull LocationRequest request,
+ @NonNull Geofence fence,
+ @NonNull PendingIntent intent) {
checkPendingIntent(intent);
checkGeofence(fence);
@@ -1210,7 +1215,7 @@
* @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
* permission is not present
*/
- public void removeProximityAlert(PendingIntent intent) {
+ public void removeProximityAlert(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1237,7 +1242,7 @@
*
* @hide
*/
- public void removeGeofence(Geofence fence, PendingIntent intent) {
+ public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) {
checkPendingIntent(intent);
checkGeofence(fence);
String packageName = mContext.getPackageName();
@@ -1260,7 +1265,7 @@
*
* @hide
*/
- public void removeAllGeofences(PendingIntent intent) {
+ public void removeAllGeofences(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1290,7 +1295,7 @@
* @hide
*/
@SystemApi
- public boolean isLocationEnabledForUser(UserHandle userHandle) {
+ public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) {
try {
return mService.isLocationEnabledForUser(userHandle.getIdentifier());
} catch (RemoteException e) {
@@ -1309,7 +1314,7 @@
@SystemApi
@TestApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
- public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
+ public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) {
Settings.Secure.putIntForUser(
mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE,
@@ -1332,7 +1337,7 @@
*
* @throws IllegalArgumentException if provider is null
*/
- public boolean isProviderEnabled(String provider) {
+ public boolean isProviderEnabled(@NonNull String provider) {
return isProviderEnabledForUser(provider, Process.myUserHandle());
}
@@ -1353,7 +1358,8 @@
* @hide
*/
@SystemApi
- public boolean isProviderEnabledForUser(String provider, UserHandle userHandle) {
+ public boolean isProviderEnabledForUser(
+ @NonNull String provider, @NonNull UserHandle userHandle) {
checkProvider(provider);
try {
@@ -1382,7 +1388,7 @@
@SystemApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
public boolean setProviderEnabledForUser(
- String provider, boolean enabled, UserHandle userHandle) {
+ @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) {
checkProvider(provider);
return Settings.Secure.setLocationProviderEnabledForUser(
@@ -1406,6 +1412,7 @@
*
* @hide
*/
+ @Nullable
public Location getLastLocation() {
String packageName = mContext.getPackageName();
@@ -1434,7 +1441,8 @@
* @throws IllegalArgumentException if provider is null or doesn't exist
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public Location getLastKnownLocation(String provider) {
+ @Nullable
+ public Location getLastKnownLocation(@NonNull String provider) {
checkProvider(provider);
String packageName = mContext.getPackageName();
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
@@ -1447,10 +1455,6 @@
}
}
- // --- Mock provider support ---
- // TODO: It would be fantastic to deprecate mock providers entirely, and replace
- // with something closer to LocationProviderBase.java
-
/**
* Creates a mock location provider and adds it to the set of active providers.
*
@@ -1461,7 +1465,8 @@
* allowed} for your app.
* @throws IllegalArgumentException if a provider with the given name already exists
*/
- public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
+ public void addTestProvider(
+ @NonNull String name, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
ProviderProperties properties = new ProviderProperties(requiresNetwork,
@@ -1488,7 +1493,7 @@
* allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- public void removeTestProvider(String provider) {
+ public void removeTestProvider(@NonNull String provider) {
try {
mService.removeTestProvider(provider, mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1512,7 +1517,7 @@
* @throws IllegalArgumentException if no provider with the given name exists
* @throws IllegalArgumentException if the location is incomplete
*/
- public void setTestProviderLocation(String provider, Location loc) {
+ public void setTestProviderLocation(@NonNull String provider, @NonNull Location loc) {
if (!loc.isComplete()) {
IllegalArgumentException e = new IllegalArgumentException(
"Incomplete location object, missing timestamp or accuracy? " + loc);
@@ -1546,7 +1551,7 @@
* @deprecated This function has always been a no-op, and may be removed in the future.
*/
@Deprecated
- public void clearTestProviderLocation(String provider) {}
+ public void clearTestProviderLocation(@NonNull String provider) {}
/**
* Sets a mock enabled value for the given provider. This value will be used in place
@@ -1560,7 +1565,7 @@
* allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- public void setTestProviderEnabled(String provider, boolean enabled) {
+ public void setTestProviderEnabled(@NonNull String provider, boolean enabled) {
try {
mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1581,7 +1586,7 @@
* @deprecated Use {@link #setTestProviderEnabled(String, boolean)} instead.
*/
@Deprecated
- public void clearTestProviderEnabled(String provider) {
+ public void clearTestProviderEnabled(@NonNull String provider) {
setTestProviderEnabled(provider, false);
}
@@ -1601,7 +1606,8 @@
* @deprecated This method has no effect.
*/
@Deprecated
- public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
+ public void setTestProviderStatus(
+ @NonNull String provider, int status, @Nullable Bundle extras, long updateTime) {
try {
mService.setTestProviderStatus(provider, status, extras, updateTime,
mContext.getOpPackageName());
@@ -1622,7 +1628,7 @@
* @deprecated This method has no effect.
*/
@Deprecated
- public void clearTestProviderStatus(String provider) {
+ public void clearTestProviderStatus(@NonNull String provider) {
setTestProviderStatus(provider, LocationProvider.AVAILABLE, null, 0L);
}
@@ -1648,13 +1654,11 @@
// This class is used to send Gnss status events to the client's specific thread.
private class GnssStatusListenerTransport extends IGnssStatusListener.Stub {
- private final GpsStatus.Listener mGpsListener;
- private final GpsStatus.NmeaListener mGpsNmeaListener;
private final GnssStatus.Callback mGnssCallback;
private final OnNmeaMessageListener mGnssNmeaListener;
private class GnssHandler extends Handler {
- public GnssHandler(Handler handler) {
+ GnssHandler(Handler handler) {
super(handler != null ? handler.getLooper() : Looper.myLooper());
}
@@ -1663,24 +1667,22 @@
switch (msg.what) {
case NMEA_RECEIVED:
synchronized (mNmeaBuffer) {
- int length = mNmeaBuffer.size();
- for (int i = 0; i < length; i++) {
- Nmea nmea = mNmeaBuffer.get(i);
+ for (Nmea nmea : mNmeaBuffer) {
mGnssNmeaListener.onNmeaMessage(nmea.mNmea, nmea.mTimestamp);
}
mNmeaBuffer.clear();
}
break;
- case GpsStatus.GPS_EVENT_STARTED:
+ case GNSS_EVENT_STARTED:
mGnssCallback.onStarted();
break;
- case GpsStatus.GPS_EVENT_STOPPED:
+ case GNSS_EVENT_STOPPED:
mGnssCallback.onStopped();
break;
- case GpsStatus.GPS_EVENT_FIRST_FIX:
+ case GNSS_EVENT_FIRST_FIX:
mGnssCallback.onFirstFix(mTimeToFirstFix);
break;
- case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
+ case GNSS_EVENT_SATELLITE_STATUS:
mGnssCallback.onSatelliteStatusChanged(mGnssStatus);
break;
default:
@@ -1691,8 +1693,11 @@
private final Handler mGnssHandler;
- // This must not equal any of the GpsStatus event IDs
- private static final int NMEA_RECEIVED = 1000;
+ private static final int NMEA_RECEIVED = 1;
+ private static final int GNSS_EVENT_STARTED = 2;
+ private static final int GNSS_EVENT_STOPPED = 3;
+ private static final int GNSS_EVENT_FIRST_FIX = 4;
+ private static final int GNSS_EVENT_SATELLITE_STATUS = 5;
private class Nmea {
long mTimestamp;
@@ -1705,98 +1710,31 @@
}
private final ArrayList<Nmea> mNmeaBuffer;
- GnssStatusListenerTransport(GpsStatus.Listener listener) {
- this(listener, null);
- }
-
- GnssStatusListenerTransport(GpsStatus.Listener listener, Handler handler) {
- mGpsListener = listener;
- mGnssHandler = new GnssHandler(handler);
- mGpsNmeaListener = null;
- mNmeaBuffer = null;
- mGnssCallback = mGpsListener != null ? new GnssStatus.Callback() {
- @Override
- public void onStarted() {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
- }
-
- @Override
- public void onStopped() {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED);
- }
-
- @Override
- public void onFirstFix(int ttff) {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX);
- }
-
- @Override
- public void onSatelliteStatusChanged(GnssStatus status) {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
- }
- } : null;
- mGnssNmeaListener = null;
- }
-
- GnssStatusListenerTransport(GpsStatus.NmeaListener listener) {
- this(listener, null);
- }
-
- GnssStatusListenerTransport(GpsStatus.NmeaListener listener, Handler handler) {
- mGpsListener = null;
- mGnssHandler = new GnssHandler(handler);
- mGpsNmeaListener = listener;
- mNmeaBuffer = new ArrayList<Nmea>();
- mGnssCallback = null;
- mGnssNmeaListener = mGpsNmeaListener != null ? new OnNmeaMessageListener() {
- @Override
- public void onNmeaMessage(String nmea, long timestamp) {
- mGpsNmeaListener.onNmeaReceived(timestamp, nmea);
- }
- } : null;
- }
-
- GnssStatusListenerTransport(GnssStatus.Callback callback) {
- this(callback, null);
- }
-
GnssStatusListenerTransport(GnssStatus.Callback callback, Handler handler) {
mGnssCallback = callback;
mGnssHandler = new GnssHandler(handler);
mGnssNmeaListener = null;
mNmeaBuffer = null;
- mGpsListener = null;
- mGpsNmeaListener = null;
- }
-
- GnssStatusListenerTransport(OnNmeaMessageListener listener) {
- this(listener, null);
}
GnssStatusListenerTransport(OnNmeaMessageListener listener, Handler handler) {
mGnssCallback = null;
mGnssHandler = new GnssHandler(handler);
mGnssNmeaListener = listener;
- mGpsListener = null;
- mGpsNmeaListener = null;
- mNmeaBuffer = new ArrayList<Nmea>();
+ mNmeaBuffer = new ArrayList<>();
}
@Override
public void onGnssStarted() {
if (mGnssCallback != null) {
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_STARTED;
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(GNSS_EVENT_STARTED).sendToTarget();
}
}
@Override
public void onGnssStopped() {
if (mGnssCallback != null) {
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_STOPPED;
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(GNSS_EVENT_STOPPED).sendToTarget();
}
}
@@ -1804,9 +1742,7 @@
public void onFirstFix(int ttff) {
if (mGnssCallback != null) {
mTimeToFirstFix = ttff;
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_FIRST_FIX;
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(GNSS_EVENT_FIRST_FIX).sendToTarget();
}
}
@@ -1817,11 +1753,8 @@
mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths,
carrierFreqs);
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
- // remove any SV status messages already in the queue
- mGnssHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.removeMessages(GNSS_EVENT_SATELLITE_STATUS);
+ mGnssHandler.obtainMessage(GNSS_EVENT_SATELLITE_STATUS).sendToTarget();
}
}
@@ -1831,11 +1764,9 @@
synchronized (mNmeaBuffer) {
mNmeaBuffer.add(new Nmea(timestamp, nmea));
}
- Message msg = Message.obtain();
- msg.what = NMEA_RECEIVED;
- // remove any NMEA_RECEIVED messages already in the queue
+
mGnssHandler.removeMessages(NMEA_RECEIVED);
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(NMEA_RECEIVED).sendToTarget();
}
}
}
@@ -1849,27 +1780,12 @@
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
* @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead.
+ * @removed
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addGpsStatusListener(GpsStatus.Listener listener) {
- boolean result;
-
- if (mGpsStatusListeners.get(listener) != null) {
- // listener is already registered
- return true;
- }
- try {
- GnssStatusListenerTransport transport = new GnssStatusListenerTransport(listener);
- result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
- if (result) {
- mGpsStatusListeners.put(listener, transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- return result;
+ return false;
}
/**
@@ -1877,18 +1793,10 @@
*
* @param listener GPS status listener object to remove
* @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead.
+ * @removed
*/
@Deprecated
- public void removeGpsStatusListener(GpsStatus.Listener listener) {
- try {
- GnssStatusListenerTransport transport = mGpsStatusListeners.remove(listener);
- if (transport != null) {
- mService.unregisterGnssStatusCallback(transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ public void removeGpsStatusListener(GpsStatus.Listener listener) {}
/**
* Registers a GNSS status callback.
@@ -1900,7 +1808,7 @@
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssStatusCallback(GnssStatus.Callback callback) {
+ public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
return registerGnssStatusCallback(callback, null);
}
@@ -1915,7 +1823,8 @@
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssStatusCallback(GnssStatus.Callback callback, Handler handler) {
+ public boolean registerGnssStatusCallback(
+ @NonNull GnssStatus.Callback callback, @Nullable Handler handler) {
boolean result;
if (mGnssStatusListeners.get(callback) != null) {
// listener is already registered
@@ -1940,7 +1849,7 @@
*
* @param callback GNSS status callback object to remove
*/
- public void unregisterGnssStatusCallback(GnssStatus.Callback callback) {
+ public void unregisterGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
try {
GnssStatusListenerTransport transport = mGnssStatusListeners.remove(callback);
if (transport != null) {
@@ -1960,27 +1869,12 @@
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
* @deprecated use {@link #addNmeaListener(OnNmeaMessageListener)} instead.
+ * @removed
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addNmeaListener(GpsStatus.NmeaListener listener) {
- boolean result;
-
- if (mGpsNmeaListeners.get(listener) != null) {
- // listener is already registered
- return true;
- }
- try {
- GnssStatusListenerTransport transport = new GnssStatusListenerTransport(listener);
- result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
- if (result) {
- mGpsNmeaListeners.put(listener, transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- return result;
+ return false;
}
/**
@@ -1988,18 +1882,10 @@
*
* @param listener a {@link GpsStatus.NmeaListener} object to remove
* @deprecated use {@link #removeNmeaListener(OnNmeaMessageListener)} instead.
+ * @removed
*/
@Deprecated
- public void removeNmeaListener(GpsStatus.NmeaListener listener) {
- try {
- GnssStatusListenerTransport transport = mGpsNmeaListeners.remove(listener);
- if (transport != null) {
- mService.unregisterGnssStatusCallback(transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ public void removeNmeaListener(GpsStatus.NmeaListener listener) {}
/**
* Adds an NMEA listener.
@@ -2011,7 +1897,7 @@
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean addNmeaListener(OnNmeaMessageListener listener) {
+ public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) {
return addNmeaListener(listener, null);
}
@@ -2026,10 +1912,11 @@
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean addNmeaListener(OnNmeaMessageListener listener, Handler handler) {
+ public boolean addNmeaListener(
+ @NonNull OnNmeaMessageListener listener, @Nullable Handler handler) {
boolean result;
- if (mGpsNmeaListeners.get(listener) != null) {
+ if (mGnssNmeaListeners.get(listener) != null) {
// listener is already registered
return true;
}
@@ -2052,7 +1939,7 @@
*
* @param listener a {@link OnNmeaMessageListener} object to remove
*/
- public void removeNmeaListener(OnNmeaMessageListener listener) {
+ public void removeNmeaListener(@NonNull OnNmeaMessageListener listener) {
try {
GnssStatusListenerTransport transport = mGnssNmeaListeners.remove(listener);
if (transport != null) {
@@ -2068,6 +1955,7 @@
* Don't use it. Use {@link #registerGnssMeasurementsCallback} instead.
* @hide
* @deprecated Not supported anymore.
+ * @removed
*/
@Deprecated
@SystemApi
@@ -2083,7 +1971,8 @@
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback) {
+ public boolean registerGnssMeasurementsCallback(
+ @NonNull GnssMeasurementsEvent.Callback callback) {
return registerGnssMeasurementsCallback(callback, null);
}
@@ -2095,8 +1984,8 @@
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback,
- Handler handler) {
+ public boolean registerGnssMeasurementsCallback(
+ @NonNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler) {
return mGnssMeasurementCallbackTransport.add(callback, handler);
}
@@ -2120,15 +2009,12 @@
}
/**
- * Returns an integer with flags representing the capabilities of the GNSS chipset.
+ * Returns the integer capability flags of the GNSS chipset as defined in {@code
+ * IGnssCallback.hal}
*
* @hide
*/
@SystemApi
- /**
- * Returns the integer capability flags of the GNSS chipset as defined in {@code
- * IGnssCallback.hal}
- */
public int getGnssCapabilities() {
try {
return mGnssMeasurementCallbackTransport.getGnssCapabilities();
@@ -2144,6 +2030,7 @@
* @hide
* @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)}
* instead.
+ * @removed
*/
@Deprecated
@SystemApi
@@ -2155,7 +2042,8 @@
*
* @param callback a {@link GnssMeasurementsEvent.Callback} object to remove.
*/
- public void unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback) {
+ public void unregisterGnssMeasurementsCallback(
+ @NonNull GnssMeasurementsEvent.Callback callback) {
mGnssMeasurementCallbackTransport.remove(callback);
}
@@ -2164,6 +2052,7 @@
* Don't use it. Use {@link #registerGnssNavigationMessageCallback} instead.
* @hide
* @deprecated Not supported anymore.
+ * @removed
*/
@Deprecated
@SystemApi
@@ -2179,12 +2068,12 @@
* @deprecated use
* {@link #unregisterGnssNavigationMessageCallback(GnssNavigationMessage.Callback)}
* instead
+ * @removed
*/
@Deprecated
@SystemApi
@SuppressLint("Doclava125")
- public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
- }
+ public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {}
/**
* Registers a GNSS Navigation Message callback.
@@ -2193,7 +2082,7 @@
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
public boolean registerGnssNavigationMessageCallback(
- GnssNavigationMessage.Callback callback) {
+ @NonNull GnssNavigationMessage.Callback callback) {
return registerGnssNavigationMessageCallback(callback, null);
}
@@ -2206,7 +2095,7 @@
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean registerGnssNavigationMessageCallback(
- GnssNavigationMessage.Callback callback, Handler handler) {
+ @NonNull GnssNavigationMessage.Callback callback, @Nullable Handler handler) {
return mGnssNavigationMessageCallbackTransport.add(callback, handler);
}
@@ -2216,7 +2105,7 @@
* @param callback a {@link GnssNavigationMessage.Callback} object to remove.
*/
public void unregisterGnssNavigationMessageCallback(
- GnssNavigationMessage.Callback callback) {
+ @NonNull GnssNavigationMessage.Callback callback) {
mGnssNavigationMessageCallbackTransport.remove(callback);
}
@@ -2230,19 +2119,12 @@
*
* @param status object containing GPS status details, or null.
* @return status object containing updated GPS status.
+ * @removed
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
- public GpsStatus getGpsStatus(GpsStatus status) {
- if (status == null) {
- status = new GpsStatus();
- }
- // When mGnssStatus is null, that means that this method is called outside
- // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility.
- if (mGnssStatus != null) {
- status.setStatus(mGnssStatus, mTimeToFirstFix);
- }
- return status;
+ public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) {
+ return null;
}
/**
@@ -2319,7 +2201,7 @@
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
public boolean registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull,
- BatchedLocationCallback callback, Handler handler) {
+ @NonNull BatchedLocationCallback callback, @Nullable Handler handler) {
mBatchedLocationCallbackTransport.add(callback, handler);
try {
@@ -2357,7 +2239,8 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
- public boolean unregisterGnssBatchedLocationCallback(BatchedLocationCallback callback) {
+ public boolean unregisterGnssBatchedLocationCallback(
+ @NonNull BatchedLocationCallback callback) {
mBatchedLocationCallbackTransport.remove(callback);
@@ -2379,7 +2262,8 @@
*
* @return true if the command succeeds.
*/
- public boolean sendExtraCommand(String provider, String command, Bundle extras) {
+ public boolean sendExtraCommand(
+ @NonNull String provider, @NonNull String command, @Nullable Bundle extras) {
try {
return mService.sendExtraCommand(provider, command, extras);
} catch (RemoteException e) {
@@ -2448,7 +2332,7 @@
* @hide
*/
@SystemApi
- public boolean isProviderPackage(String packageName) {
+ public boolean isProviderPackage(@NonNull String packageName) {
try {
return mService.isProviderPackage(packageName);
} catch (RemoteException e) {
@@ -2464,7 +2348,7 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
- public void setLocationControllerExtraPackage(String packageName) {
+ public void setLocationControllerExtraPackage(@NonNull String packageName) {
try {
mService.setLocationControllerExtraPackage(packageName);
} catch (RemoteException e) {
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 6fd063e..a05d850 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -17,6 +17,8 @@
package android.location;
import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -183,14 +185,16 @@
*
* @return a new location request
*/
+ @NonNull
public static LocationRequest create() {
return new LocationRequest();
}
/** @hide */
@SystemApi
- public static LocationRequest createFromDeprecatedProvider(String provider, long minTime,
- float minDistance, boolean singleShot) {
+ @NonNull
+ public static LocationRequest createFromDeprecatedProvider(
+ @NonNull String provider, long minTime, float minDistance, boolean singleShot) {
if (minTime < 0) minTime = 0;
if (minDistance < 0) minDistance = 0;
@@ -215,8 +219,9 @@
/** @hide */
@SystemApi
- public static LocationRequest createFromDeprecatedCriteria(Criteria criteria, long minTime,
- float minDistance, boolean singleShot) {
+ @NonNull
+ public static LocationRequest createFromDeprecatedCriteria(
+ @NonNull Criteria criteria, long minTime, float minDistance, boolean singleShot) {
if (minTime < 0) minTime = 0;
if (minDistance < 0) minDistance = 0;
@@ -287,7 +292,7 @@
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the quality constant is not valid
*/
- public LocationRequest setQuality(int quality) {
+ public @NonNull LocationRequest setQuality(int quality) {
checkQuality(quality);
mQuality = quality;
return this;
@@ -330,7 +335,7 @@
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the interval is less than zero
*/
- public LocationRequest setInterval(long millis) {
+ public @NonNull LocationRequest setInterval(long millis) {
checkInterval(millis);
mInterval = millis;
if (!mExplicitFastestInterval) {
@@ -362,7 +367,7 @@
* @hide
*/
@SystemApi
- public LocationRequest setLowPowerMode(boolean enabled) {
+ public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
mLowPowerMode = enabled;
return this;
}
@@ -386,7 +391,7 @@
* @return the same object, so that setters can be chained
*/
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
+ public @NonNull LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
mLocationSettingsIgnored = locationSettingsIgnored;
return this;
}
@@ -427,7 +432,7 @@
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the interval is less than zero
*/
- public LocationRequest setFastestInterval(long millis) {
+ public @NonNull LocationRequest setFastestInterval(long millis) {
checkInterval(millis);
mExplicitFastestInterval = true;
mFastestInterval = millis;
@@ -463,7 +468,7 @@
* @param millis duration of request in milliseconds
* @return the same object, so that setters can be chained
*/
- public LocationRequest setExpireIn(long millis) {
+ public @NonNull LocationRequest setExpireIn(long millis) {
long elapsedRealtime = SystemClock.elapsedRealtime();
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
@@ -491,7 +496,7 @@
* @param millis expiration time of request, in milliseconds since boot including suspend
* @return the same object, so that setters can be chained
*/
- public LocationRequest setExpireAt(long millis) {
+ public @NonNull LocationRequest setExpireAt(long millis) {
mExpireAt = millis;
if (mExpireAt < 0) mExpireAt = 0;
return this;
@@ -522,7 +527,7 @@
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if numUpdates is 0 or less
*/
- public LocationRequest setNumUpdates(int numUpdates) {
+ public @NonNull LocationRequest setNumUpdates(int numUpdates) {
if (numUpdates <= 0) {
throw new IllegalArgumentException(
"invalid numUpdates: " + numUpdates);
@@ -553,7 +558,8 @@
}
}
- public LocationRequest setProvider(String provider) {
+ /** Sets the provider to use for this location request. */
+ public @NonNull LocationRequest setProvider(@NonNull String provider) {
checkProvider(provider);
mProvider = provider;
return this;
@@ -561,13 +567,13 @@
/** @hide */
@SystemApi
- public String getProvider() {
+ public @NonNull String getProvider() {
return mProvider;
}
/** @hide */
@SystemApi
- public LocationRequest setSmallestDisplacement(float meters) {
+ public @NonNull LocationRequest setSmallestDisplacement(float meters) {
checkDisplacement(meters);
mSmallestDisplacement = meters;
return this;
@@ -590,13 +596,13 @@
* @hide
*/
@SystemApi
- public void setWorkSource(WorkSource workSource) {
+ public void setWorkSource(@Nullable WorkSource workSource) {
mWorkSource = workSource;
}
/** @hide */
@SystemApi
- public WorkSource getWorkSource() {
+ public @Nullable WorkSource getWorkSource() {
return mWorkSource;
}
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index aed8e4e..c2f29bc 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -374,9 +374,15 @@
*/
public static final int FLAG_NO_CAPTURE = 0x1 << 10;
+ /**
+ * @hide
+ * Flag indicating force muting haptic channels.
+ */
+ public static final int FLAG_MUTE_HAPTIC = 0x1 << 11;
+
private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO |
FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY |
- FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER;
+ FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_MUTE_HAPTIC;
private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
@@ -467,6 +473,14 @@
}
/**
+ * Return if haptic channels are muted.
+ * @return {@code true} if haptic channels are muted, {@code false} otherwise.
+ */
+ public boolean areHapticChannelsMuted() {
+ return (mFlags & FLAG_MUTE_HAPTIC) != 0;
+ }
+
+ /**
* Builder class for {@link AudioAttributes} objects.
* <p> Here is an example where <code>Builder</code> is used to define the
* {@link AudioAttributes} to be used by a new <code>AudioTrack</code> instance:
@@ -490,6 +504,7 @@
private int mContentType = CONTENT_TYPE_UNKNOWN;
private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
private int mFlags = 0x0;
+ private boolean mMuteHapticChannels = false;
private HashSet<String> mTags = new HashSet<String>();
private Bundle mBundle;
@@ -528,6 +543,9 @@
aa.mUsage = mUsage;
aa.mSource = mSource;
aa.mFlags = mFlags;
+ if (mMuteHapticChannels) {
+ aa.mFlags |= FLAG_MUTE_HAPTIC;
+ }
aa.mTags = (HashSet<String>) mTags.clone();
aa.mFormattedTags = TextUtils.join(";", mTags);
if (mBundle != null) {
@@ -803,6 +821,17 @@
}
return this;
}
+
+ /**
+ * Specifying if haptic should be muted or not when playing audio-haptic coupled data.
+ * By default, haptic channels are enabled.
+ * @param muted true to force muting haptic channels.
+ * @return the same Builder instance.
+ */
+ public Builder setMuteHapticChannels(boolean muted) {
+ mMuteHapticChannels = muted;
+ return this;
+ }
};
@Override
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
index 3ef0235..03dfd3e 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarView.java
@@ -74,6 +74,7 @@
// For now, we use the bar number as title.
mBarTitle.setText(Integer.toString(barViewInfo.getHeight()));
mBarSummary.setText(barViewInfo.getSummary());
+ mIcon.setContentDescription(barViewInfo.getContentDescription());
}
@VisibleForTesting
diff --git a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
index 409f9ea..1ef36a2 100644
--- a/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
+++ b/packages/SettingsLib/BarChartPreference/src/com/android/settingslib/widget/BarViewInfo.java
@@ -34,6 +34,7 @@
private View.OnClickListener mClickListener;
@StringRes
private int mSummary;
+ private @Nullable CharSequence mContentDescription;
// A number indicates this bar's height. The larger number shows a higher bar view.
private int mHeight;
// A real height of bar view.
@@ -45,11 +46,14 @@
* @param icon The icon of bar view.
* @param barHeight The height of bar view. Larger number shows a higher bar view.
* @param summary The string resource id for summary.
+ * @param contentDescription Optional text that briefly describes the contents of the icon.
*/
- public BarViewInfo(Drawable icon, @IntRange(from = 0) int barHeight, @StringRes int summary) {
+ public BarViewInfo(Drawable icon, @IntRange(from = 0) int barHeight, @StringRes int summary,
+ @Nullable CharSequence contentDescription) {
mIcon = icon;
mHeight = barHeight;
mSummary = summary;
+ mContentDescription = contentDescription;
}
/**
@@ -91,6 +95,10 @@
return mSummary;
}
+ public @Nullable CharSequence getContentDescription() {
+ return mContentDescription;
+ }
+
void setNormalizedHeight(@IntRange(from = 0) int barHeight) {
mNormalizedHeight = barHeight;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
index a6b2410..bee1b3c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/Tile.java
@@ -41,6 +41,8 @@
import android.text.TextUtils;
import android.util.Log;
+import androidx.annotation.VisibleForTesting;
+
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@@ -58,6 +60,8 @@
*/
public ArrayList<UserHandle> userHandle = new ArrayList<>();
+ @VisibleForTesting
+ long mLastUpdateTime;
private final String mActivityPackage;
private final String mActivityName;
private final Intent mIntent;
@@ -157,6 +161,7 @@
*/
public CharSequence getTitle(Context context) {
CharSequence title = null;
+ ensureMetadataNotStale(context);
final PackageManager packageManager = context.getPackageManager();
if (mMetaData.containsKey(META_DATA_PREFERENCE_TITLE)) {
if (mMetaData.get(META_DATA_PREFERENCE_TITLE) instanceof Integer) {
@@ -207,6 +212,7 @@
if (mSummaryOverride != null) {
return mSummaryOverride;
}
+ ensureMetadataNotStale(context);
CharSequence summary = null;
final PackageManager packageManager = context.getPackageManager();
if (mMetaData != null) {
@@ -248,6 +254,7 @@
if (!hasKey()) {
return null;
}
+ ensureMetadataNotStale(context);
if (mMetaData.get(META_DATA_PREFERENCE_KEYHINT) instanceof Integer) {
return context.getResources().getString(mMetaData.getInt(META_DATA_PREFERENCE_KEYHINT));
} else {
@@ -268,7 +275,7 @@
if (context == null || mMetaData == null) {
return null;
}
-
+ ensureMetadataNotStale(context);
int iconResId = mMetaData.getInt(META_DATA_PREFERENCE_ICON);
// Set the icon
if (iconResId == 0) {
@@ -294,6 +301,7 @@
&& mMetaData.containsKey(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE)) {
return mMetaData.getBoolean(TileUtils.META_DATA_PREFERENCE_ICON_TINTABLE);
}
+ ensureMetadataNotStale(context);
final String pkgName = context.getPackageName();
// If this drawable is coming from outside Settings, tint it to match the color.
final ActivityInfo activityInfo = getActivityInfo(context);
@@ -301,6 +309,28 @@
&& !TextUtils.equals(pkgName, activityInfo.packageName);
}
+ /**
+ * Ensures metadata is not stale for this tile.
+ */
+ private void ensureMetadataNotStale(Context context) {
+ final PackageManager pm = context.getApplicationContext().getPackageManager();
+
+ try {
+ final long lastUpdateTime = pm.getPackageInfo(mActivityPackage,
+ PackageManager.GET_META_DATA).lastUpdateTime;
+ if (lastUpdateTime == mLastUpdateTime) {
+ // All good. Do nothing
+ return;
+ }
+ // App has been updated since we load metadata last time. Reload metadata.
+ mActivityInfo = null;
+ getActivityInfo(context);
+ mLastUpdateTime = lastUpdateTime;
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.d(TAG, "Can't find package, probably uninstalled.");
+ }
+ }
+
private ActivityInfo getActivityInfo(Context context) {
if (mActivityInfo == null) {
final PackageManager pm = context.getApplicationContext().getPackageManager();
@@ -309,6 +339,7 @@
pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
if (infoList != null && !infoList.isEmpty()) {
mActivityInfo = infoList.get(0).activityInfo;
+ mMetaData = mActivityInfo.metaData;
}
}
return mActivityInfo;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 3d38837..4fc62bb 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -57,6 +57,7 @@
import androidx.annotation.NonNull;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.CollectionUtils;
import com.android.settingslib.R;
import com.android.settingslib.utils.ThreadUtils;
@@ -133,6 +134,12 @@
private final ArraySet<ScanResult> mScanResults = new ArraySet<>();
/**
+ * Extra set of unused scan results corresponding to this AccessPoint for verbose logging
+ * purposes, such as a set of Passpoint roaming scan results when home scans are available.
+ */
+ private final ArraySet<ScanResult> mExtraScanResults = new ArraySet<>();
+
+ /**
* Map of BSSIDs to scored networks for individual bssids.
*
* <p>This cache should not be evicted with scan results, as the values here are used to
@@ -216,6 +223,7 @@
*/
private String mFqdn;
private String mProviderFriendlyName;
+ private boolean mIsRoaming = false;
private boolean mIsCarrierAp = false;
@@ -289,15 +297,12 @@
// Calculate required fields
updateKey();
- updateRssi();
+ updateBestRssiInfo();
}
/**
* Creates an AccessPoint with only a WifiConfiguration. This is used for the saved networks
* page.
- *
- * Passpoint Credential AccessPoints should be created with this.
- * Make sure to call setScanResults after constructing with this.
*/
public AccessPoint(Context context, WifiConfiguration config) {
mContext = context;
@@ -315,39 +320,33 @@
}
/**
- * Initialize an AccessPoint object for a Passpoint OSU Provider.
- * Make sure to call setScanResults after constructing with this.
+ * Initialize an AccessPoint object for a Passpoint network.
*/
- public AccessPoint(Context context, OsuProvider provider) {
+ public AccessPoint(@NonNull Context context, @NonNull WifiConfiguration config,
+ @Nullable Collection<ScanResult> homeScans,
+ @Nullable Collection<ScanResult> roamingScans) {
+ mContext = context;
+ networkId = config.networkId;
+ mConfig = config;
+ setScanResultsPasspoint(homeScans, roamingScans);
+ updateKey();
+ }
+
+ /**
+ * Initialize an AccessPoint object for a Passpoint OSU Provider.
+ */
+ public AccessPoint(@NonNull Context context, @NonNull OsuProvider provider,
+ @NonNull Collection<ScanResult> results) {
mContext = context;
mOsuProvider = provider;
- ssid = provider.getFriendlyName();
+ setScanResults(results);
updateKey();
}
AccessPoint(Context context, Collection<ScanResult> results) {
mContext = context;
-
- if (results.isEmpty()) {
- throw new IllegalArgumentException("Cannot construct with an empty ScanResult list");
- }
- mScanResults.addAll(results);
-
- // Information derived from scan results
- ScanResult firstResult = results.iterator().next();
- ssid = firstResult.SSID;
- bssid = firstResult.BSSID;
- security = getSecurity(firstResult);
- if (security == SECURITY_PSK) {
- pskType = getPskType(firstResult);
- }
+ setScanResults(results);
updateKey();
- updateRssi();
-
- // Passpoint Info
- mIsCarrierAp = firstResult.isCarrierAp;
- mCarrierApEapType = firstResult.carrierApEapType;
- mCarrierName = firstResult.carrierName;
}
@VisibleForTesting void loadConfig(WifiConfiguration config) {
@@ -468,7 +467,8 @@
if (isVerboseLoggingEnabled()) {
builder.append(",rssi=").append(mRssi);
- builder.append(",scan cache size=").append(mScanResults.size());
+ builder.append(",scan cache size=").append(mScanResults.size()
+ + mExtraScanResults.size());
}
return builder.append(')').toString();
@@ -703,14 +703,19 @@
*
* <p>Callers should not modify this set.
*/
- public Set<ScanResult> getScanResults() { return mScanResults; }
+ public Set<ScanResult> getScanResults() {
+ Set<ScanResult> allScans = new ArraySet<>();
+ allScans.addAll(mScanResults);
+ allScans.addAll(mExtraScanResults);
+ return allScans;
+ }
public Map<String, TimestampedScoredNetwork> getScoredNetworkCache() {
return mScoredNetworkCache;
}
/**
- * Updates {@link #mRssi}.
+ * Updates {@link #mRssi} and sets scan result information to that of the best RSSI scan result.
*
* <p>If the given connection is active, the existing value of {@link #mRssi} will be returned.
* If the given AccessPoint is not active, a value will be calculated from previous scan
@@ -718,22 +723,41 @@
* value. If the access point is not connected and there are no scan results, the rssi will be
* set to {@link #UNREACHABLE_RSSI}.
*/
- private void updateRssi() {
+ private void updateBestRssiInfo() {
if (this.isActive()) {
return;
}
- int rssi = UNREACHABLE_RSSI;
+ ScanResult bestResult = null;
+ int bestRssi = UNREACHABLE_RSSI;
for (ScanResult result : mScanResults) {
- if (result.level > rssi) {
- rssi = result.level;
+ if (result.level > bestRssi) {
+ bestRssi = result.level;
+ bestResult = result;
}
}
- if (rssi != UNREACHABLE_RSSI && mRssi != UNREACHABLE_RSSI) {
- mRssi = (mRssi + rssi) / 2; // half-life previous value
+ // Set the rssi to the average of the current rssi and the previous rssi.
+ if (bestRssi != UNREACHABLE_RSSI && mRssi != UNREACHABLE_RSSI) {
+ mRssi = (mRssi + bestRssi) / 2;
} else {
- mRssi = rssi;
+ mRssi = bestRssi;
+ }
+
+ if (bestResult != null) {
+ ssid = bestResult.SSID;
+ bssid = bestResult.BSSID;
+ security = getSecurity(bestResult);
+ if (security == SECURITY_PSK) {
+ pskType = getPskType(bestResult);
+ }
+ mIsCarrierAp = bestResult.isCarrierAp;
+ mCarrierApEapType = bestResult.carrierApEapType;
+ mCarrierName = bestResult.carrierName;
+ }
+ // Update the config SSID of a Passpoint network to that of the best RSSI
+ if (isPasspoint()) {
+ mConfig.SSID = convertToQuotedString(ssid);
}
}
@@ -897,18 +921,12 @@
summary.append(mContext.getString(R.string.tap_to_sign_up));
}
} else if (isActive()) {
- if (isPasspoint()) {
- // This is the active connection on passpoint
- summary.append(getSummary(mContext, /* ssid */ null, getDetailedState(),
- /* isEphemeral */ false,
- /* suggestionOrSpecifierPackageName */ null));
- } else if (mConfig != null && getDetailedState() == DetailedState.CONNECTED
+ if (mConfig != null && getDetailedState() == DetailedState.CONNECTED
&& mIsCarrierAp) {
// This is the active connection on a carrier AP
summary.append(String.format(mContext.getString(R.string.connected_via_carrier),
mCarrierName));
} else {
- // This is the active connection on non-passpoint network
summary.append(getSummary(mContext, /* ssid */ null, getDetailedState(),
mInfo != null && mInfo.isEphemeral(),
mInfo != null ? mInfo.getNetworkSuggestionOrSpecifierPackageName() : null));
@@ -1107,7 +1125,8 @@
if (mConfig != null) savedState.putParcelable(KEY_CONFIG, mConfig);
savedState.putParcelable(KEY_WIFIINFO, mInfo);
savedState.putParcelableArray(KEY_SCANRESULTS,
- mScanResults.toArray(new Parcelable[mScanResults.size()]));
+ mScanResults.toArray(new Parcelable[mScanResults.size()
+ + mExtraScanResults.size()]));
savedState.putParcelableArrayList(KEY_SCOREDNETWORKCACHE,
new ArrayList<>(mScoredNetworkCache.values()));
if (mNetworkInfo != null) {
@@ -1129,24 +1148,27 @@
}
/**
- * Sets {@link #mScanResults} to the given collection.
+ * Sets {@link #mScanResults} to the given collection and updates info based on the best RSSI
+ * scan result.
*
* @param scanResults a collection of scan results to add to the internal set
- * @throws IllegalArgumentException if any of the given ScanResults did not belong to this AP
*/
void setScanResults(Collection<ScanResult> scanResults) {
+ if (CollectionUtils.isEmpty(scanResults)) {
+ Log.d(TAG, "Cannot set scan results to empty list");
+ return;
+ }
// Validate scan results are for current AP only by matching SSID/BSSID
// Passpoint networks are not bound to a specific SSID/BSSID, so skip this for passpoint.
- if (!isPasspoint() && !isOsuProvider()) {
- String key = getKey();
+ if (mKey != null && !isPasspoint() && !isOsuProvider()) {
for (ScanResult result : scanResults) {
String scanResultKey = AccessPoint.getKey(result);
- if (!mKey.equals(scanResultKey)) {
- throw new IllegalArgumentException(
- String.format(
+ if (mKey != null && !mKey.equals(scanResultKey)) {
+ Log.d(TAG, String.format(
"ScanResult %s\nkey of %s did not match current AP key %s",
- result, scanResultKey, key));
+ result, scanResultKey, mKey));
+ return;
}
}
}
@@ -1154,7 +1176,7 @@
int oldLevel = getLevel();
mScanResults.clear();
mScanResults.addAll(scanResults);
- updateRssi();
+ updateBestRssiInfo();
int newLevel = getLevel();
// If newLevel is 0, there will be no displayed Preference since the AP is unreachable
@@ -1174,20 +1196,26 @@
mAccessPointListener.onAccessPointChanged(this);
}
});
+ }
- if (!scanResults.isEmpty()) {
- ScanResult result = scanResults.iterator().next();
-
- // This flag only comes from scans, is not easily saved in config
- if (security == SECURITY_PSK) {
- pskType = getPskType(result);
+ /**
+ * Sets the internal scan result cache to the list of home scans.
+ * If there are no home scans, then the roaming scan list is used, and the AccessPoint is
+ * marked as roaming.
+ */
+ void setScanResultsPasspoint(
+ @Nullable Collection<ScanResult> homeScans,
+ @Nullable Collection<ScanResult> roamingScans) {
+ mExtraScanResults.clear();
+ if (!CollectionUtils.isEmpty(homeScans)) {
+ if (!CollectionUtils.isEmpty(roamingScans)) {
+ mExtraScanResults.addAll(roamingScans);
}
-
- // The carrier info in the ScanResult is set by the platform based on the SSID and will
- // always be the same for all matching scan results.
- mIsCarrierAp = result.isCarrierAp;
- mCarrierApEapType = result.carrierApEapType;
- mCarrierName = result.carrierName;
+ mIsRoaming = false;
+ setScanResults(homeScans);
+ } else if (!CollectionUtils.isEmpty(roamingScans)) {
+ mIsRoaming = true;
+ setScanResults(roamingScans);
}
}
@@ -1204,7 +1232,6 @@
*/
public boolean update(
@Nullable WifiConfiguration config, WifiInfo info, NetworkInfo networkInfo) {
-
boolean updated = false;
final int oldLevel = getLevel();
if (info != null && isInfoForThisAccessPoint(config, info)) {
@@ -1538,7 +1565,8 @@
*
* All methods are invoked on the Main Thread
*/
- private class AccessPointProvisioningCallback extends ProvisioningCallback {
+ @VisibleForTesting
+ class AccessPointProvisioningCallback extends ProvisioningCallback {
@Override
@MainThread public void onProvisioningFailure(int status) {
if (TextUtils.equals(mOsuStatus, mContext.getString(R.string.osu_completing_sign_up))) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 871e248..3c10688 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -117,7 +117,11 @@
if (connected) {
mWifiInfo = mWifiManager.getConnectionInfo();
if (mWifiInfo != null) {
- ssid = getValidSsid(mWifiInfo);
+ if (mWifiInfo.isPasspointAp() || mWifiInfo.isOsuAp()) {
+ ssid = mWifiInfo.getProviderFriendlyName();
+ } else {
+ ssid = getValidSsid(mWifiInfo);
+ }
updateRssi(mWifiInfo.getRssi());
maybeRequestNetworkScore();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
index 9ce6b34..a31d64c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java
@@ -53,7 +53,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.internal.util.CollectionUtils;
import com.android.settingslib.R;
import com.android.settingslib.core.lifecycle.Lifecycle;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -646,30 +645,14 @@
Map<Integer, List<ScanResult>>> pairing : passpointConfigsAndScans) {
WifiConfiguration config = pairing.first;
if (seenFQDNs.add(config.FQDN)) {
- List<ScanResult> apScanResults = new ArrayList<>();
-
List<ScanResult> homeScans =
pairing.second.get(WifiManager.PASSPOINT_HOME_NETWORK);
List<ScanResult> roamingScans =
pairing.second.get(WifiManager.PASSPOINT_ROAMING_NETWORK);
- // TODO(b/118705403): Differentiate home network vs roaming network for summary info
- if (!CollectionUtils.isEmpty(homeScans)) {
- apScanResults.addAll(homeScans);
- } else if (!CollectionUtils.isEmpty(roamingScans)) {
- apScanResults.addAll(roamingScans);
- }
-
- int bestRssi = Integer.MIN_VALUE;
- for (ScanResult result : apScanResults) {
- if (result.level >= bestRssi) {
- bestRssi = result.level;
- config.SSID = AccessPoint.convertToQuotedString(result.SSID);
- }
- }
-
AccessPoint accessPoint =
- getCachedOrCreatePasspoint(apScanResults, accessPointCache, config);
+ getCachedOrCreatePasspoint(config, homeScans, roamingScans,
+ accessPointCache);
accessPoints.add(accessPoint);
}
}
@@ -688,8 +671,8 @@
for (OsuProvider provider : providersAndScans.keySet()) {
if (!alreadyProvisioned.contains(provider)) {
AccessPoint accessPointOsu =
- getCachedOrCreateOsu(providersAndScans.get(provider),
- accessPointCache, provider);
+ getCachedOrCreateOsu(provider, providersAndScans.get(provider),
+ accessPointCache);
accessPoints.add(accessPointOsu);
}
}
@@ -709,26 +692,29 @@
}
private AccessPoint getCachedOrCreatePasspoint(
- List<ScanResult> scanResults,
- List<AccessPoint> cache,
- WifiConfiguration config) {
+ WifiConfiguration config,
+ List<ScanResult> homeScans,
+ List<ScanResult> roamingScans,
+ List<AccessPoint> cache) {
AccessPoint accessPoint = getCachedByKey(cache, AccessPoint.getKey(config));
if (accessPoint == null) {
- accessPoint = new AccessPoint(mContext, config);
+ accessPoint = new AccessPoint(mContext, config, homeScans, roamingScans);
+ } else {
+ accessPoint.setScanResultsPasspoint(homeScans, roamingScans);
}
- accessPoint.setScanResults(scanResults);
return accessPoint;
}
private AccessPoint getCachedOrCreateOsu(
+ OsuProvider provider,
List<ScanResult> scanResults,
- List<AccessPoint> cache,
- OsuProvider provider) {
+ List<AccessPoint> cache) {
AccessPoint accessPoint = getCachedByKey(cache, AccessPoint.getKey(provider));
if (accessPoint == null) {
- accessPoint = new AccessPoint(mContext, provider);
+ accessPoint = new AccessPoint(mContext, provider, scanResults);
+ } else {
+ accessPoint.setScanResults(scanResults);
}
- accessPoint.setScanResults(scanResults);
return accessPoint;
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
index f5ead0c..06f5fde 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/AccessPointTest.java
@@ -43,13 +43,16 @@
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiSsid;
+import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
+import android.net.wifi.hotspot2.ProvisioningCallback;
import android.net.wifi.hotspot2.pps.HomeSp;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.SystemClock;
import android.text.SpannableString;
import android.text.format.DateUtils;
+import android.util.ArraySet;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -68,6 +71,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
import java.util.concurrent.CountDownLatch;
@SmallTest
@@ -75,8 +81,11 @@
public class AccessPointTest {
private static final String TEST_SSID = "\"test_ssid\"";
+ private static final String ROAMING_SSID = "\"roaming_ssid\"";
+ private static final String OSU_FRIENDLY_NAME = "osu_friendly_name";
- private static final ArrayList<ScanResult> SCAN_RESULTS = buildScanResultCache();
+ private ArrayList<ScanResult> mScanResults;
+ private ArrayList<ScanResult> mRoamingScans;
private static final RssiCurve FAST_BADGE_CURVE =
new RssiCurve(-150, 10, new byte[]{Speed.FAST});
@@ -88,10 +97,11 @@
private WifiInfo mWifiInfo;
@Mock private RssiCurve mockBadgeCurve;
@Mock private WifiNetworkScoreCache mockWifiNetworkScoreCache;
- public static final int NETWORK_ID = 123;
- public static final int DEFAULT_RSSI = -55;
+ @Mock private AccessPoint.AccessPointListener mMockAccessPointListener;
+ private static final int NETWORK_ID = 123;
+ private static final int DEFAULT_RSSI = -55;
- private static ScanResult createScanResult(String ssid, String bssid, int rssi) {
+ private ScanResult createScanResult(String ssid, String bssid, int rssi) {
ScanResult scanResult = new ScanResult();
scanResult.SSID = ssid;
scanResult.level = rssi;
@@ -101,6 +111,12 @@
return scanResult;
}
+ private OsuProvider createOsuProvider() {
+ Map<String, String> friendlyNames = new HashMap<>();
+ friendlyNames.put("en", OSU_FRIENDLY_NAME);
+ return new OsuProvider(null, friendlyNames, null, null, null, null, null);
+ }
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
@@ -108,6 +124,8 @@
mWifiInfo = new WifiInfo();
mWifiInfo.setSSID(WifiSsid.createFromAsciiEncoded(TEST_SSID));
mWifiInfo.setBSSID(TEST_BSSID);
+ mScanResults = buildScanResultCache(TEST_SSID);
+ mRoamingScans = buildScanResultCache(ROAMING_SSID);
WifiTracker.sVerboseLogging = false;
}
@@ -573,14 +591,14 @@
Bundle bundle = new Bundle();
bundle.putParcelableArray(
AccessPoint.KEY_SCANRESULTS,
- SCAN_RESULTS.toArray(new Parcelable[SCAN_RESULTS.size()]));
+ mScanResults.toArray(new Parcelable[mScanResults.size()]));
return new AccessPoint(mContext, bundle);
}
- private static ArrayList<ScanResult> buildScanResultCache() {
+ private ArrayList<ScanResult> buildScanResultCache(String ssid) {
ArrayList<ScanResult> scanResults = new ArrayList<>();
for (int i = 0; i < 5; i++) {
- ScanResult scanResult = createScanResult(TEST_SSID, "bssid-" + i, i);
+ ScanResult scanResult = createScanResult(ssid, "bssid-" + i, i);
scanResults.add(scanResult);
}
return scanResults;
@@ -975,12 +993,12 @@
int speed1 = Speed.MODERATE;
RssiCurve badgeCurve1 = mock(RssiCurve.class);
when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1);
- when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(0)))
+ when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(0)))
.thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1));
int speed2 = Speed.VERY_FAST;
RssiCurve badgeCurve2 = mock(RssiCurve.class);
when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2);
- when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(1)))
+ when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(1)))
.thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2));
int expectedSpeed = (speed1 + speed2) / 2;
@@ -998,12 +1016,12 @@
int speed1 = Speed.VERY_FAST;
RssiCurve badgeCurve1 = mock(RssiCurve.class);
when(badgeCurve1.lookupScore(anyInt())).thenReturn((byte) speed1);
- when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(0)))
+ when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(0)))
.thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve1));
int speed2 = Speed.NONE;
RssiCurve badgeCurve2 = mock(RssiCurve.class);
when(badgeCurve2.lookupScore(anyInt())).thenReturn((byte) speed2);
- when(mockWifiNetworkScoreCache.getScoredNetwork(SCAN_RESULTS.get(1)))
+ when(mockWifiNetworkScoreCache.getScoredNetwork(mScanResults.get(1)))
.thenReturn(buildScoredNetworkWithGivenBadgeCurve(badgeCurve2));
ap.update(
@@ -1123,7 +1141,7 @@
.setActive(true)
.setScoredNetworkCache(
new ArrayList(Arrays.asList(recentScore)))
- .setScanResults(SCAN_RESULTS)
+ .setScanResults(mScanResults)
.build();
when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class)))
@@ -1151,7 +1169,7 @@
.setActive(true)
.setScoredNetworkCache(
new ArrayList(Arrays.asList(recentScore)))
- .setScanResults(SCAN_RESULTS)
+ .setScanResults(mScanResults)
.build();
int newSpeed = Speed.MODERATE;
@@ -1196,7 +1214,7 @@
AccessPoint ap = new TestAccessPointBuilder(mContext)
.setSsid(TEST_SSID)
.setBssid(TEST_BSSID)
- .setScanResults(SCAN_RESULTS)
+ .setScanResults(mScanResults)
.build();
assertThat(ap.update(null, mWifiInfo, null)).isFalse();
@@ -1217,4 +1235,172 @@
assertThat(passpointAp.update(null, mWifiInfo, null)).isFalse();
}
+
+ /**
+ * Verifies that an AccessPoint's getKey() is consistent with the overloaded static getKey().
+ */
+ @Test
+ public void testGetKey_matchesKeysCorrectly() {
+ AccessPoint ap = new AccessPoint(mContext, mScanResults);
+ assertThat(ap.getKey()).isEqualTo(AccessPoint.getKey(mScanResults.get(0)));
+
+ WifiConfiguration spyConfig = spy(new WifiConfiguration());
+ when(spyConfig.isPasspoint()).thenReturn(true);
+ spyConfig.FQDN = "fqdn";
+ AccessPoint passpointAp = new AccessPoint(mContext, spyConfig, mScanResults, null);
+ assertThat(passpointAp.getKey()).isEqualTo(AccessPoint.getKey(spyConfig));
+
+ OsuProvider provider = createOsuProvider();
+ AccessPoint osuAp = new AccessPoint(mContext, provider, mScanResults);
+ assertThat(osuAp.getKey()).isEqualTo(AccessPoint.getKey(provider));
+ }
+
+ /**
+ * Verifies that the Passpoint AccessPoint constructor creates AccessPoints whose isPasspoint()
+ * returns true.
+ */
+ @Test
+ public void testPasspointAccessPointConstructor_createdAccessPointIsPasspoint() {
+ WifiConfiguration spyConfig = spy(new WifiConfiguration());
+ when(spyConfig.isPasspoint()).thenReturn(true);
+ AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig,
+ mScanResults, mRoamingScans);
+
+ assertThat(passpointAccessPoint.isPasspoint()).isTrue();
+ }
+
+ /**
+ * Verifies that Passpoint AccessPoints set their config's SSID to the home scans', and to the
+ * roaming scans' if no home scans are available.
+ */
+ @Test
+ public void testSetScanResultsPasspoint_differentiatesHomeAndRoaming() {
+ WifiConfiguration spyConfig = spy(new WifiConfiguration());
+ when(spyConfig.isPasspoint()).thenReturn(true);
+ AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig,
+ mScanResults, mRoamingScans);
+ assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(TEST_SSID);
+
+ passpointAccessPoint.setScanResultsPasspoint(null, mRoamingScans);
+ assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(ROAMING_SSID);
+
+ passpointAccessPoint.setScanResultsPasspoint(mScanResults, null);
+ assertThat(AccessPoint.removeDoubleQuotes(spyConfig.SSID)).isEqualTo(TEST_SSID);
+ }
+
+ /**
+ * Verifies that getScanResults returns both home and roaming scans.
+ */
+ @Test
+ public void testGetScanResults_showsHomeAndRoamingScans() {
+ WifiConfiguration spyConfig = spy(new WifiConfiguration());
+ when(spyConfig.isPasspoint()).thenReturn(true);
+ AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig,
+ mScanResults, mRoamingScans);
+ Set<ScanResult> fullSet = new ArraySet<>();
+ fullSet.addAll(mScanResults);
+ fullSet.addAll(mRoamingScans);
+ assertThat(passpointAccessPoint.getScanResults()).isEqualTo(fullSet);
+ }
+
+ /**
+ * Verifies that the Passpoint AccessPoint takes the ssid of the strongest scan result.
+ */
+ @Test
+ public void testPasspointAccessPoint_setsBestSsid() {
+ WifiConfiguration spyConfig = spy(new WifiConfiguration());
+ when(spyConfig.isPasspoint()).thenReturn(true);
+
+ String badSsid = "badSsid";
+ String goodSsid = "goodSsid";
+ String bestSsid = "bestSsid";
+ ScanResult badScanResult = createScanResult(badSsid, TEST_BSSID, -100);
+ ScanResult goodScanResult = createScanResult(goodSsid, TEST_BSSID, -10);
+ ScanResult bestScanResult = createScanResult(bestSsid, TEST_BSSID, -1);
+
+ AccessPoint passpointAccessPoint = new AccessPoint(mContext, spyConfig,
+ Arrays.asList(badScanResult, goodScanResult), null);
+ assertThat(passpointAccessPoint.getConfig().SSID)
+ .isEqualTo(AccessPoint.convertToQuotedString(goodSsid));
+ passpointAccessPoint.setScanResultsPasspoint(
+ Arrays.asList(badScanResult, goodScanResult, bestScanResult), null);
+ assertThat(passpointAccessPoint.getConfig().SSID)
+ .isEqualTo(AccessPoint.convertToQuotedString(bestSsid));
+ }
+
+ /**
+ * Verifies that the OSU AccessPoint constructor creates AccessPoints whose isOsuProvider()
+ * returns true.
+ */
+ @Test
+ public void testOsuAccessPointConstructor_createdAccessPointIsOsuProvider() {
+ AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(),
+ mScanResults);
+
+ assertThat(osuAccessPoint.isOsuProvider()).isTrue();
+ }
+
+ /**
+ * Verifies that the summary of an OSU entry only shows the tap_to_sign_up string.
+ */
+ @Test
+ public void testOsuAccessPointSummary_showsTapToSignUp() {
+ AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(),
+ mScanResults);
+
+ assertThat(osuAccessPoint.getSummary())
+ .isEqualTo(mContext.getString(R.string.tap_to_sign_up));
+ }
+
+ @Test
+ public void testOsuAccessPointSummary_showsProvisioningUpdates() {
+ AccessPoint osuAccessPoint = new AccessPoint(mContext, createOsuProvider(),
+ mScanResults);
+
+ osuAccessPoint.setListener(mMockAccessPointListener);
+
+ AccessPoint.AccessPointProvisioningCallback provisioningCallback =
+ osuAccessPoint.new AccessPointProvisioningCallback();
+
+ int[] openingProviderStatuses = {
+ ProvisioningCallback.OSU_STATUS_AP_CONNECTING,
+ ProvisioningCallback.OSU_STATUS_AP_CONNECTED,
+ ProvisioningCallback.OSU_STATUS_SERVER_CONNECTING,
+ ProvisioningCallback.OSU_STATUS_SERVER_VALIDATED,
+ ProvisioningCallback.OSU_STATUS_SERVER_CONNECTED,
+ ProvisioningCallback.OSU_STATUS_INIT_SOAP_EXCHANGE,
+ ProvisioningCallback.OSU_STATUS_WAITING_FOR_REDIRECT_RESPONSE
+ };
+ int[] completingSignUpStatuses = {
+ ProvisioningCallback.OSU_STATUS_REDIRECT_RESPONSE_RECEIVED,
+ ProvisioningCallback.OSU_STATUS_SECOND_SOAP_EXCHANGE,
+ ProvisioningCallback.OSU_STATUS_THIRD_SOAP_EXCHANGE,
+ ProvisioningCallback.OSU_STATUS_RETRIEVING_TRUST_ROOT_CERTS,
+ };
+
+ for (int status : openingProviderStatuses) {
+ provisioningCallback.onProvisioningStatus(status);
+ assertThat(osuAccessPoint.getSummary())
+ .isEqualTo(String.format(mContext.getString(R.string.osu_opening_provider),
+ OSU_FRIENDLY_NAME));
+ }
+
+ provisioningCallback.onProvisioningFailure(0);
+ assertThat(osuAccessPoint.getSummary())
+ .isEqualTo(mContext.getString(R.string.osu_connect_failed));
+
+ for (int status : completingSignUpStatuses) {
+ provisioningCallback.onProvisioningStatus(status);
+ assertThat(osuAccessPoint.getSummary())
+ .isEqualTo(mContext.getString(R.string.osu_completing_sign_up));
+ }
+
+ provisioningCallback.onProvisioningFailure(0);
+ assertThat(osuAccessPoint.getSummary())
+ .isEqualTo(mContext.getString(R.string.osu_sign_up_failed));
+
+ provisioningCallback.onProvisioningComplete();
+ assertThat(osuAccessPoint.getSummary())
+ .isEqualTo(mContext.getString(R.string.osu_sign_up_complete));
+ }
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
index 7d22788..edf414d 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/wifi/WifiTrackerTest.java
@@ -1155,8 +1155,7 @@
providersAndScans, cachedAccessPoints);
// Verify second update AP is the same object as the first update AP
- assertTrue(osuAccessPointsFirstUpdate.get(0)
- == osuAccessPointsSecondUpdate.get(0));
+ assertThat(osuAccessPointsFirstUpdate.get(0)).isSameAs(osuAccessPointsSecondUpdate.get(0));
// Verify second update AP has the average of the first and second update RSSIs
assertThat(osuAccessPointsSecondUpdate.get(0).getRssi())
.isEqualTo((prevRssi + newRssi) / 2);
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
index 491f32d..bfda888 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileTest.java
@@ -9,7 +9,11 @@
import static com.google.common.truth.Truth.assertThat;
+import android.content.Context;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ResolveInfo;
import android.os.Bundle;
import org.junit.Before;
@@ -17,17 +21,22 @@
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.ShadowPackageManager;
@RunWith(RobolectricTestRunner.class)
public class TileTest {
+ private Context mContext;
private ActivityInfo mActivityInfo;
private Tile mTile;
@Before
public void setUp() {
+ mContext = RuntimeEnvironment.application;
mActivityInfo = new ActivityInfo();
- mActivityInfo.packageName = RuntimeEnvironment.application.getPackageName();
+ mActivityInfo.applicationInfo = new ApplicationInfo();
+ mActivityInfo.packageName = mContext.getPackageName();
mActivityInfo.name = "abc";
mActivityInfo.icon = com.android.internal.R.drawable.ic_plus;
mActivityInfo.metaData = new Bundle();
@@ -143,4 +152,21 @@
assertThat(tile.getOrder()).isEqualTo(1);
}
+
+ @Test
+ public void getTitle_shouldEnsureMetadataNotStale() {
+ final ResolveInfo info = new ResolveInfo();
+ info.activityInfo = mActivityInfo;
+ final ShadowPackageManager spm = Shadow.extract(mContext.getPackageManager());
+ spm.addResolveInfoForIntent(
+ new Intent().setClassName(mActivityInfo.packageName, mActivityInfo.name), info);
+
+ final Tile tile = new Tile(mActivityInfo, "category");
+ final long staleTimeStamp = -10000;
+ tile.mLastUpdateTime = staleTimeStamp;
+
+ tile.getTitle(RuntimeEnvironment.application);
+
+ assertThat(tile.mLastUpdateTime).isNotEqualTo(staleTimeStamp);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java
index 29d57b7..2b27248 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartInfoTest.java
@@ -72,7 +72,8 @@
final BarViewInfo barViewInfo = new BarViewInfo(
null /* icon */,
50,
- mTitle);
+ mTitle,
+ null);
final BarChartInfo mBarChartInfo = new BarChartInfo.Builder()
.setTitle(mTitle)
@@ -91,7 +92,8 @@
final BarViewInfo barViewInfo = new BarViewInfo(
null /* icon */,
50,
- mTitle);
+ mTitle,
+ null);
final BarChartInfo mBarChartInfo = new BarChartInfo.Builder()
.setTitle(mTitle)
.setDetails(mDetails)
@@ -113,7 +115,8 @@
final BarViewInfo barViewInfo = new BarViewInfo(
null /* icon */,
50,
- mTitle);
+ mTitle,
+ null);
new BarChartInfo.Builder()
.setTitle(mTitle)
.setDetails(mDetails)
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
index 3acca2a..266554b 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/BarChartPreferenceTest.java
@@ -113,7 +113,8 @@
final BarChartInfo barChartInfo = new BarChartInfo.Builder()
.setTitle(R.string.debug_app)
.setDetails(R.string.debug_app)
- .addBarViewInfo(new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app))
+ .addBarViewInfo(
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null))
.build();
mPreference.initializeBarChart(barChartInfo);
@@ -128,7 +129,8 @@
// We don't call BarChartInfo.Builder#setDetails yet.
final BarChartInfo barChartInfo = new BarChartInfo.Builder()
.setTitle(R.string.debug_app)
- .addBarViewInfo(new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app))
+ .addBarViewInfo(
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null))
.build();
mPreference.initializeBarChart(barChartInfo);
@@ -144,7 +146,8 @@
.setDetails(R.string.debug_app)
.setDetailsOnClickListener(v -> {
})
- .addBarViewInfo(new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app))
+ .addBarViewInfo(
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null))
.build();
mPreference.initializeBarChart(barChartInfo);
@@ -157,7 +160,7 @@
@Test
public void setBarViewInfos_oneBarViewInfoSet_shouldShowOneBarView() {
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app)
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null)
};
mPreference.initializeBarChart(mBarChartInfo);
@@ -175,8 +178,8 @@
@Test
public void setBarViewInfos_twoBarViewInfosSet_shouldShowTwoBarViews() {
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app)
+ new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null)
};
mPreference.initializeBarChart(mBarChartInfo);
@@ -195,9 +198,9 @@
@Test
public void setBarViewInfos_threeBarViewInfosSet_shouldShowThreeBarViews() {
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app)
+ new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null)
};
mPreference.initializeBarChart(mBarChartInfo);
@@ -217,10 +220,10 @@
@Test
public void setBarViewInfos_fourBarViewInfosSet_shouldShowFourBarViews() {
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 2 /* barNumber */, R.string.debug_app),
+ new BarViewInfo(mIcon, 20 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 2 /* barNumber */, R.string.debug_app, null),
};
mPreference.initializeBarChart(mBarChartInfo);
@@ -242,11 +245,11 @@
thrown.expect(IllegalStateException.class);
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 70 /* barNumber */, R.string.debug_app),
+ new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 70 /* barNumber */, R.string.debug_app, null),
};
mPreference.setBarViewInfos(barViewsInfo);
@@ -255,10 +258,10 @@
@Test
public void setBarViewInfos_barViewInfosSet_shouldBeSortedInDescending() {
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app),
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app),
+ new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 50 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 5 /* barNumber */, R.string.debug_app, null),
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
};
mPreference.initializeBarChart(mBarChartInfo);
@@ -278,7 +281,7 @@
@Test
public void setBarViewInfos_validBarViewSummarySet_barViewShouldShowSummary() {
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{
- new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app),
+ new BarViewInfo(mIcon, 10 /* barNumber */, R.string.debug_app, null),
};
mPreference.initializeBarChart(mBarChartInfo);
@@ -291,7 +294,8 @@
@Test
public void setBarViewInfos_clickListenerForBarViewSet_barViewShouldHaveClickListener() {
- final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app);
+ final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app,
+ null);
viewInfo.setClickListener(v -> {
});
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{viewInfo};
@@ -306,7 +310,8 @@
@Test
public void onBindViewHolder_loadingStateIsTrue_shouldHideAllViews() {
- final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app);
+ final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app,
+ null);
viewInfo.setClickListener(v -> {
});
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{viewInfo};
@@ -322,7 +327,8 @@
@Test
public void onBindViewHolder_loadingStateIsFalse_shouldInitAnyView() {
- final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app);
+ final BarViewInfo viewInfo = new BarViewInfo(mIcon, 30 /* barNumber */, R.string.debug_app,
+ null);
viewInfo.setClickListener(v -> {
});
final BarViewInfo[] barViewsInfo = new BarViewInfo[]{viewInfo};
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 0f8fd92..f7f34f6 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1382,6 +1382,9 @@
Settings.Global.TEXT_CLASSIFIER_CONSTANTS,
GlobalSettingsProto.TEXT_CLASSIFIER_CONSTANTS);
dumpSetting(s, p,
+ Settings.Global.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS,
+ GlobalSettingsProto.TEXT_CLASSIFIER_ACTION_MODEL_PARAMS);
+ dumpSetting(s, p,
Settings.Global.THEATER_MODE_ON,
GlobalSettingsProto.THEATER_MODE_ON);
dumpSetting(s, p,
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
new file mode 100644
index 0000000..7c72688
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.view.View;
+
+import com.android.systemui.plugins.annotations.DependsOn;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Plugin which provides a "Panel" {@link View} to be rendered inside of the GlobalActions menu.
+ *
+ * Implementations should construct a new {@link PanelViewController} with the given
+ * {@link Callbacks} instance inside of {@link #onPanelShown(Callbacks)}, and should not hold onto
+ * a reference, instead allowing Global Actions to manage the lifetime of the object.
+ *
+ * Under this assumption, {@link PanelViewController} represents the lifetime of a single invocation
+ * of the Global Actions menu. The {@link View} for the Panel is generated when the
+ * {@link PanelViewController} is constructed, and {@link PanelViewController#getPanelContent()}
+ * serves as a simple getter. When Global Actions is dismissed,
+ * {@link PanelViewController#onDismissed()} can be used to cleanup any resources allocated when
+ * constructed. Global Actions will then release the reference, and the {@link PanelViewController}
+ * will be garbage-collected.
+ */
+@ProvidesInterface(
+ action = GlobalActionsPanelPlugin.ACTION, version = GlobalActionsPanelPlugin.VERSION)
+@DependsOn(target = GlobalActionsPanelPlugin.Callbacks.class)
+@DependsOn(target = GlobalActionsPanelPlugin.PanelViewController.class)
+public interface GlobalActionsPanelPlugin extends Plugin {
+ String ACTION = "com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS_PANEL";
+ int VERSION = 0;
+
+ /**
+ * Invoked when the GlobalActions menu is shown.
+ *
+ * @param callbacks {@link Callbacks} instance that can be used by the Panel to interact with
+ * the Global Actions menu.
+ * @return A {@link PanelViewController} instance used to receive Global Actions events.
+ */
+ PanelViewController onPanelShown(Callbacks callbacks);
+
+ /**
+ * Provides methods to interact with the Global Actions menu.
+ */
+ @ProvidesInterface(version = Callbacks.VERSION)
+ interface Callbacks {
+ int VERSION = 0;
+
+ /** Dismisses the Global Actions menu. */
+ void dismissGlobalActionsMenu();
+ }
+
+ /**
+ * Receives Global Actions events, and provides the Panel {@link View}.
+ */
+ @ProvidesInterface(version = PanelViewController.VERSION)
+ interface PanelViewController {
+ int VERSION = 0;
+
+ /**
+ * Returns the {@link View} for the Panel to be rendered in Global Actions. This View can be
+ * any size, and will be rendered above the Global Actions menu when z-ordered.
+ */
+ View getPanelContent();
+
+ /**
+ * Invoked when the Global Actions menu (containing the View returned from
+ * {@link #getPanelContent()}) is dismissed.
+ */
+ void onDismissed();
+ }
+}
diff --git a/packages/SystemUI/res/drawable/global_action_panel_scrim.xml b/packages/SystemUI/res/drawable/global_action_panel_scrim.xml
new file mode 100644
index 0000000..177b8d2
--- /dev/null
+++ b/packages/SystemUI/res/drawable/global_action_panel_scrim.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <gradient
+ android:centerY="0.45"
+ android:startColor="#be3c4043"
+ android:centerColor="#be3c4043"
+ android:endColor="#4d3c4043"
+ android:angle="270" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 50cf37b..a40a14a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -856,6 +856,9 @@
<!-- Global actions grid layout -->
<dimen name="global_actions_grid_side_margin">4dp</dimen>
+ <!-- Global actions panel -->
+ <dimen name="global_actions_panel_top_margin">85dp</dimen>
+
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_x">8dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index c16c91b..8a95cc49 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -67,6 +67,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
@@ -88,8 +89,10 @@
import com.android.systemui.MultiListLayout;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
-import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.ExtensionController.Extension;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.leak.RotationUtils;
import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
@@ -161,6 +164,8 @@
private final ScreenshotHelper mScreenshotHelper;
private final ScreenRecordHelper mScreenRecordHelper;
+ private final Extension<GlobalActionsPanelPlugin> mPanelExtension;
+
/**
* @param context everything needs a context :(
*/
@@ -204,6 +209,11 @@
mScreenRecordHelper = new ScreenRecordHelper(context);
Dependency.get(ConfigurationController.class).addCallback(this);
+
+ mPanelExtension = Dependency.get(ExtensionController.class)
+ .newExtension(GlobalActionsPanelPlugin.class)
+ .withPlugin(GlobalActionsPanelPlugin.class)
+ .build();
}
/**
@@ -399,8 +409,16 @@
}
return false;
};
+ GlobalActionsPanelPlugin.PanelViewController panelViewController =
+ mPanelExtension.get() != null
+ ? mPanelExtension.get().onPanelShown(() -> {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
+ })
+ : null;
ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener,
- mSeparatedEmergencyButtonEnabled);
+ mSeparatedEmergencyButtonEnabled, panelViewController);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.setKeyguardShowing(mKeyguardShowing);
@@ -1470,20 +1488,22 @@
private MultiListLayout mGlobalActionsLayout;
private final OnClickListener mClickListener;
private final OnItemLongClickListener mLongClickListener;
- private final GradientDrawable mGradientDrawable;
+ private final Drawable mBackgroundDrawable;
private final ColorExtractor mColorExtractor;
+ private final GlobalActionsPanelPlugin.PanelViewController mPanelController;
private boolean mKeyguardShowing;
private boolean mShouldDisplaySeparatedButton;
private boolean mShowing;
+ private final float mScrimAlpha;
public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
- OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton) {
+ OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton,
+ GlobalActionsPanelPlugin.PanelViewController plugin) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
mContext = context;
mAdapter = adapter;
mClickListener = clickListener;
mLongClickListener = longClickListener;
- mGradientDrawable = new GradientDrawable(mContext);
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton;
@@ -1504,12 +1524,46 @@
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
- window.setBackgroundDrawable(mGradientDrawable);
window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
initializeLayout();
setTitle(R.string.global_actions);
+
+ mPanelController = plugin;
+ View panelView = initializePanel();
+ if (panelView == null) {
+ mBackgroundDrawable = new GradientDrawable(context);
+ mScrimAlpha = 0.7f;
+ } else {
+ mBackgroundDrawable = context.getDrawable(
+ com.android.systemui.R.drawable.global_action_panel_scrim);
+ mScrimAlpha = 1f;
+ addContentView(
+ panelView,
+ new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ }
+ window.setBackgroundDrawable(mBackgroundDrawable);
+ }
+
+ private View initializePanel() {
+ if (isPanelEnabled(mContext) && mPanelController != null) {
+ View panelView = mPanelController.getPanelContent();
+ if (panelView != null) {
+ FrameLayout panelContainer = new FrameLayout(mContext);
+ FrameLayout.LayoutParams panelParams =
+ new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT);
+ panelParams.topMargin = mContext.getResources().getDimensionPixelSize(
+ com.android.systemui.R.dimen.global_actions_panel_top_margin);
+ panelContainer.addView(panelView, panelParams);
+ return panelContainer;
+ }
+ }
+ return null;
}
private void initializeLayout() {
@@ -1530,6 +1584,11 @@
mGlobalActionsLayout.setRotationListener(this::onRotate);
}
+ private boolean isPanelEnabled(Context context) {
+ return FeatureFlagUtils.isEnabled(
+ context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);
+ }
+
private int getGlobalActionsLayoutId(Context context) {
if (isGridEnabled(context)) {
if (RotationUtils.getRotation(context) == RotationUtils.ROTATION_SEASCAPE) {
@@ -1590,13 +1649,18 @@
super.onStart();
updateList();
- Point displaySize = new Point();
- mContext.getDisplay().getRealSize(displaySize);
- mColorExtractor.addOnColorsChangedListener(this);
- mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
- GradientColors colors = mColorExtractor.getColors(mKeyguardShowing ?
- WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
- updateColors(colors, false /* animate */);
+ if (mBackgroundDrawable instanceof GradientDrawable) {
+ Point displaySize = new Point();
+ mContext.getDisplay().getRealSize(displaySize);
+ mColorExtractor.addOnColorsChangedListener(this);
+ ((GradientDrawable) mBackgroundDrawable)
+ .setScreenSize(displaySize.x, displaySize.y);
+ GradientColors colors = mColorExtractor.getColors(
+ mKeyguardShowing
+ ? WallpaperManager.FLAG_LOCK
+ : WallpaperManager.FLAG_SYSTEM);
+ updateColors(colors, false /* animate */);
+ }
}
/**
@@ -1605,11 +1669,14 @@
* @param animate Interpolates gradient if true, just sets otherwise.
*/
private void updateColors(GradientColors colors, boolean animate) {
- mGradientDrawable.setColors(colors, animate);
+ if (!(mBackgroundDrawable instanceof GradientDrawable)) {
+ return;
+ }
+ ((GradientDrawable) mBackgroundDrawable).setColors(colors, animate);
View decorView = getWindow().getDecorView();
if (colors.supportsDarkText()) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
- View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decorView.setSystemUiVisibility(0);
}
@@ -1625,7 +1692,7 @@
public void show() {
super.show();
mShowing = true;
- mGradientDrawable.setAlpha(0);
+ mBackgroundDrawable.setAlpha(0);
mGlobalActionsLayout.setTranslationX(getAnimTranslation());
mGlobalActionsLayout.setAlpha(0);
mGlobalActionsLayout.animate()
@@ -1635,8 +1702,8 @@
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setUpdateListener(animation -> {
int alpha = (int) ((Float) animation.getAnimatedValue()
- * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
- mGradientDrawable.setAlpha(alpha);
+ * mScrimAlpha * 255);
+ mBackgroundDrawable.setAlpha(alpha);
})
.start();
}
@@ -1653,14 +1720,17 @@
.alpha(0)
.translationX(getAnimTranslation())
.setDuration(300)
- .withEndAction(() -> super.dismiss())
+ .withEndAction(super::dismiss)
.setInterpolator(new LogAccelerateInterpolator())
.setUpdateListener(animation -> {
int alpha = (int) ((1f - (Float) animation.getAnimatedValue())
- * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
- mGradientDrawable.setAlpha(alpha);
+ * mScrimAlpha * 255);
+ mBackgroundDrawable.setAlpha(alpha);
})
.start();
+ if (mPanelController != null) {
+ mPanelController.onDismissed();
+ }
}
void dismissImmediately() {
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index 7ce13c2..a15e89c 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -25,12 +25,15 @@
DisplayCutoutEmulationTallOverlay \
FontNotoSerifSourceOverlay \
IconPackCircularAndroidOverlay \
+ IconPackCircularLauncherOverlay \
IconPackCircularSettingsOverlay \
IconPackCircularSystemUIOverlay \
IconPackFilledAndroidOverlay \
+ IconPackFilledLauncherOverlay \
IconPackFilledSettingsOverlay \
IconPackFilledSystemUIOverlay \
IconPackRoundedAndroidOverlay \
+ IconPackRoundedLauncherOverlay \
IconPackRoundedSettingsOverlay \
IconPackRoundedSystemUIOverlay \
IconShapeRoundedRectOverlay \
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/Android.mk b/packages/overlays/IconPackCircularLauncherOverlay/Android.mk
new file mode 100644
index 0000000..a5277fa
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := IconPackCircularLauncher
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := IconPackCircularLauncherOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml b/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..0b69eca
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon_pack.circular.launcher"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="com.android.launcher3" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
+ <application android:label="Circular" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml
new file mode 100644
index 0000000..74ed9ed
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_clear.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
new file mode 100644
index 0000000..6c4e1de
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_corp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M16,4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H2v12c0,1.66,1.34,3,3,3h14c1.66,0,3-1.34,3-3V6h-6V4z M9.5,4 c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,7.5V18c0,0.83-0.67,1.5-1.5,1.5H5c-0.83,0-1.5-0.67-1.5-1.5V7.5 H20.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_empty_recents.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_empty_recents.xml
new file mode 100644
index 0000000..7e363f6
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_empty_recents.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M17,18V6c0-1.1-0.9-2-2-2H9C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6C16.1,20,17,19.1,17,18z M8.5,18V6 c0-0.28,0.22-0.5,0.5-0.5h6c0.28,0,0.5,0.22,0.5,0.5v12c0,0.28-0.22,0.5-0.5,0.5H9C8.72,18.5,8.5,18.28,8.5,18z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21,7h-2c-0.55,0-1,0.45-1,1v8c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1V8C22,7.45,21.55,7,21,7z M20.5,15.5h-1v-7h1V15.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M5,17c0.55,0,1-0.45,1-1V8c0-0.55-0.45-1-1-1H3C2.45,7,2,7.45,2,8v8c0,0.55,0.45,1,1,1H5z M3.5,8.5h1v7h-1V8.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
new file mode 100644
index 0000000..e4bc8e6
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M11.99,20.5 c-4.68,0-8.49-3.81-8.49-8.5c0-4.69,3.81-8.5,8.49-8.5c4.69,0,8.51,3.81,8.51,8.5C20.5,16.69,16.68,20.5,11.99,20.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
new file mode 100644
index 0000000..c104e3e
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M3.97,20.03c0.15,0.15,0.34,0.22,0.53,0.22s0.38-0.07,0.53-0.22L12,13.06l6.97,6.97c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l6.97-6.97c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L5.03,3.97c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-6.97,6.97C3.68,19.26,3.68,19.74,3.97,20.03z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
new file mode 100644
index 0000000..e526329
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,8.5c-1.93,0-3.5,1.57-3.5,3.5s1.57,3.5,3.5,3.5c1.93,0,3.5-1.57,3.5-3.5S13.93,8.5,12,8.5z M12,14c-1.1,0-2-0.9-2-2 s0.9-2,2-2c1.1,0,2,0.9,2,2S13.1,14,12,14z M21.29,13.9l-1.83-1.05c-0.3-0.17-0.49-0.49-0.48-0.84v-0.01 c0-0.35,0.18-0.67,0.48-0.84l1.83-1.05c0.48-0.28,0.64-0.89,0.37-1.37l-2-3.46c-0.19-0.32-0.52-0.5-0.87-0.5 c-0.17,0-0.34,0.04-0.5,0.13l-1.84,1.06c-0.14,0.08-0.29,0.12-0.45,0.12c-0.17,0-0.35-0.05-0.5-0.14c0,0-0.01,0-0.01-0.01 C15.2,5.77,15,5.47,15,5.12V3c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v2.12c0,0.34-0.2,0.65-0.5,0.82c0,0-0.01,0-0.01,0.01 c-0.16,0.09-0.33,0.14-0.5,0.14c-0.15,0-0.31-0.04-0.45-0.12L5.71,4.9c-0.16-0.09-0.33-0.13-0.5-0.13c-0.35,0-0.68,0.18-0.87,0.5 l-2,3.46C2.06,9.21,2.23,9.82,2.71,10.1l1.83,1.05c0.3,0.17,0.49,0.49,0.48,0.84v0.01c0,0.35-0.18,0.67-0.48,0.84L2.71,13.9 c-0.48,0.28-0.64,0.89-0.37,1.37l2,3.46c0.19,0.32,0.52,0.5,0.87,0.5c0.17,0,0.34-0.04,0.5-0.13l1.84-1.06 c0.14-0.08,0.29-0.12,0.45-0.12c0.17,0,0.35,0.05,0.5,0.14c0,0,0.01,0,0.01,0.01C8.8,18.23,9,18.53,9,18.88V21c0,0.55,0.45,1,1,1h4 c0.55,0,1-0.45,1-1v-2.12c0-0.34,0.2-0.65,0.5-0.82c0,0,0.01,0,0.01-0.01c0.16-0.09,0.33-0.14,0.5-0.14c0.15,0,0.31,0.04,0.45,0.12 l1.84,1.06c0.16,0.09,0.33,0.13,0.5,0.13c0.35,0,0.68-0.18,0.87-0.5l2-3.46C21.94,14.79,21.77,14.18,21.29,13.9z M18.61,17.55 l-1.41-0.81c-0.36-0.21-0.78-0.32-1.2-0.32c-0.43,0-0.86,0.12-1.25,0.34c-0.77,0.44-1.25,1.25-1.25,2.12v1.62h-3v-1.62 c0-0.87-0.48-1.68-1.26-2.12c-0.38-0.22-0.81-0.33-1.25-0.33c-0.42,0-0.84,0.11-1.2,0.32l-1.41,0.81l-1.5-2.6l1.39-0.8 c0.76-0.44,1.24-1.26,1.23-2.15c0-0.88-0.47-1.7-1.23-2.14l-1.39-0.8l1.5-2.6L6.8,7.26c0.36,0.21,0.78,0.32,1.2,0.32 c0.43,0,0.86-0.12,1.25-0.34c0.77-0.44,1.25-1.25,1.25-2.12V3.5h3v1.62c0,0.87,0.48,1.68,1.26,2.12c0.38,0.22,0.81,0.33,1.25,0.33 c0.42,0,0.84-0.11,1.2-0.32l1.41-0.81l1.5,2.6l-1.39,0.8c-0.76,0.44-1.24,1.26-1.23,2.15c0,0.88,0.47,1.7,1.23,2.14l1.39,0.8 L18.61,17.55z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
new file mode 100644
index 0000000..78de832
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M15.08,8.01c-0.39-0.39-0.91-0.59-1.42-0.59c-0.51,0-1.02,0.2-1.41,0.59L0.59,19.67l3.75,3.75l11.66-11.66 c0.78-0.78,0.78-2.04,0.01-2.82L15.08,8.01z M4.34,21.29l-1.63-1.63l7.45-7.45l1.63,1.63L4.34,21.29z M14.93,10.7l-2.09,2.09 l-1.63-1.63l2.09-2.09c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.36,0.15l0.92,0.93C15.13,10.18,15.13,10.5,14.93,10.7z M17.67,5.25h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V5.25h1.08c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.08V2.67c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.08h-1.08c-0.41,0-0.75,0.34-0.75,0.75 S17.26,5.25,17.67,5.25z M5.67,5.25h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75V5.25h1.08 c0.41,0,0.75-0.34,0.75-0.75S9.74,3.75,9.33,3.75H8.25V2.67c0-0.41-0.34-0.75-0.75-0.75S6.75,2.26,6.75,2.67v1.08H5.67 c-0.41,0-0.75,0.34-0.75,0.75S5.26,5.25,5.67,5.25z M21.33,15.75h-1.08v-1.08c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75 v1.08h-1.08c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1.08v1.08c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.08 h1.08c0.41,0,0.75-0.34,0.75-0.75S21.74,15.75,21.33,15.75z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
new file mode 100644
index 0000000..11f0b4b
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4,6v3c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V6c0-1.1-0.9-2-2-2H6C4.9,4,4,4.9,4,6z M18.5,6v3c0,0.28-0.22,0.5-0.5,0.5H6 C5.72,9.5,5.5,9.28,5.5,9V6c0-0.28,0.22-0.5,0.5-0.5h12C18.28,5.5,18.5,5.72,18.5,6z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4,18c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-3c0-1.1-0.9-2-2-2H6c-1.1,0-2,0.9-2,2V18z M5.5,15c0-0.28,0.22-0.5,0.5-0.5h12 c0.28,0,0.5,0.22,0.5,0.5v3c0,0.28-0.22,0.5-0.5,0.5H6c-0.28,0-0.5-0.22-0.5-0.5V15z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
new file mode 100644
index 0000000..3834fb6
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_wallpaper.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <group
+ android:translateX="119.000000"
+ android:translateY="358.000000">
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
+ </group>
+ </group>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
new file mode 100644
index 0000000..f73a9cc
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_warning.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,14.75c0.41,0,0.75-0.34,0.75-0.75V9.75C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75V14 C11.25,14.41,11.59,14.75,12,14.75z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
new file mode 100644
index 0000000..1c2470e
--- /dev/null
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_widget.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M11,5c0-1.1-0.9-2-2-2H5C3.9,3,3,3.9,3,5v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2V5z M9.5,9c0,0.28-0.22,0.5-0.5,0.5H5 C4.72,9.5,4.5,9.28,4.5,9V5c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V9z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9,13H5c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C11,13.9,10.1,13,9,13z M9.5,19c0,0.28-0.22,0.5-0.5,0.5 H5c-0.28,0-0.5-0.22-0.5-0.5v-4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V19z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M19,13h-4c-1.1,0-2,0.9-2,2v4c0,1.1,0.9,2,2,2h4c1.1,0,2-0.9,2-2v-4C21,13.9,20.1,13,19,13z M19.5,19 c0,0.28-0.22,0.5-0.5,0.5h-4c-0.28,0-0.5-0.22-0.5-0.5v-4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5V19z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18.41,2.76c-0.39-0.39-0.9-0.59-1.41-0.59s-1.02,0.2-1.41,0.59l-2.83,2.83c-0.78,0.78-0.78,2.05,0,2.83l2.83,2.83 c0.39,0.39,0.9,0.59,1.41,0.59s1.02-0.2,1.41-0.59l2.83-2.83c0.78-0.78,0.78-2.05,0-2.83L18.41,2.76z M20.18,7.35l-2.83,2.83 c-0.13,0.13-0.28,0.15-0.35,0.15s-0.23-0.02-0.35-0.15l-2.83-2.83C13.69,7.23,13.67,7.08,13.67,7s0.02-0.23,0.15-0.35l2.83-2.83 c0.13-0.13,0.28-0.15,0.35-0.15s0.23,0.02,0.35,0.15l2.83,2.83c0.13,0.13,0.15,0.28,0.15,0.35S20.31,7.23,20.18,7.35z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/Android.mk b/packages/overlays/IconPackFilledLauncherOverlay/Android.mk
new file mode 100644
index 0000000..d2e5b60
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := IconPackFilledLauncher
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := IconPackFilledLauncherOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml b/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..0b9f636
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon_pack.filled.launcher"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="com.android.launcher3" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
+ <application android:label="Filled" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml
new file mode 100644
index 0000000..1a2f778
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_clear.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
new file mode 100644
index 0000000..8910308
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_corp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20,6h-4V4c0-1.1-0.9-2-2-2h-4C8.9,2,8,2.9,8,4v2H4C2.9,6,2,6.9,2,8v11c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V8 C22,6.9,21.1,6,20,6z M9.5,4c0-0.28,0.22-0.5,0.5-0.5h4c0.28,0,0.5,0.22,0.5,0.5v2h-5V4z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4 c-0.28,0-0.5-0.22-0.5-0.5V8c0-0.28,0.22-0.5,0.5-0.5h16c0.28,0,0.5,0.22,0.5,0.5V19z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_empty_recents.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_empty_recents.xml
new file mode 100644
index 0000000..1d4c8d7
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_empty_recents.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M17,18V6c0-1.1-0.9-2-2-2H9C7.9,4,7,4.9,7,6v12c0,1.1,0.9,2,2,2h6C16.1,20,17,19.1,17,18z M8.5,18V6 c0-0.28,0.22-0.5,0.5-0.5h6c0.28,0,0.5,0.22,0.5,0.5v12c0,0.28-0.22,0.5-0.5,0.5H9C8.72,18.5,8.5,18.28,8.5,18z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21,17c0.55,0,1-0.45,1-1V8c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1v8c0,0.55,0.45,1,1,1H21z M19.5,8.5h1v7h-1V8.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M5,7H3C2.45,7,2,7.45,2,8v8c0,0.55,0.45,1,1,1h2c0.55,0,1-0.45,1-1V8C6,7.45,5.55,7,5,7z M4.5,15.5h-1v-7h1V15.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
new file mode 100644
index 0000000..a90141d
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4.92,4.94c-3.9,3.91-3.9,10.24,0.01,14.14s10.24,3.9,14.14-0.01C20.95,17.2,22,14.65,22,12c0-2.65-1.06-5.19-2.93-7.07 C15.16,1.03,8.83,1.03,4.92,4.94z M18,18c-1.6,1.59-3.76,2.48-6.02,2.48c-4.69-0.01-8.49-3.83-8.48-8.52 c0.01-4.69,3.83-8.49,8.52-8.48c4.69,0.01,8.49,3.83,8.48,8.52C20.49,14.25,19.6,16.41,18,18z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 12 7 C 12.5522847498 7 13 7.44771525017 13 8 C 13 8.55228474983 12.5522847498 9 12 9 C 11.4477152502 9 11 8.55228474983 11 8 C 11 7.44771525017 11.4477152502 7 12 7 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,10.5c-0.41,0-0.75,0.34-0.75,0.75v5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-5 C12.75,10.84,12.41,10.5,12,10.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
new file mode 100644
index 0000000..d31b6a1
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M5.22,18.78C5.37,18.93,5.56,19,5.75,19s0.38-0.07,0.53-0.22L12,13.06l5.72,5.72c0.15,0.15,0.34,0.22,0.53,0.22 s0.38-0.07,0.53-0.22c0.29-0.29,0.29-0.77,0-1.06L13.06,12l5.72-5.72c0.29-0.29,0.29-0.77,0-1.06s-0.77-0.29-1.06,0L12,10.94 L6.28,5.22c-0.29-0.29-0.77-0.29-1.06,0s-0.29,0.77,0,1.06L10.94,12l-5.72,5.72C4.93,18.01,4.93,18.49,5.22,18.78z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
new file mode 100644
index 0000000..70dc701
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M2.43,15.45l1.79,3.09c0.25,0.45,0.74,0.73,1.25,0.73c0.17,0,0.35-0.03,0.52-0.09l1.76-0.7c0.25,0.17,0.51,0.31,0.77,0.45 l0.26,1.84c0.09,0.71,0.69,1.24,1.42,1.24h3.61c0.72,0,1.33-0.53,1.43-1.19l0.26-1.86c0.25-0.14,0.51-0.28,0.76-0.45l1.76,0.7 c0.17,0.07,0.35,0.1,0.53,0.1c0.5,0,0.98-0.27,1.23-0.72l1.82-3.14c0.34-0.61,0.19-1.38-0.36-1.82l-1.48-1.16 c0.01-0.15,0.02-0.29,0.02-0.45s-0.01-0.3-0.02-0.45l1.48-1.16c0.55-0.43,0.7-1.19,0.35-1.84l-1.8-3.1 c-0.25-0.45-0.74-0.73-1.26-0.73c-0.17,0-0.35,0.03-0.52,0.09l-1.76,0.7c-0.25-0.17-0.51-0.31-0.77-0.45l-0.26-1.84 c-0.09-0.71-0.69-1.24-1.42-1.24h-3.61c-0.71,0-1.32,0.54-1.41,1.22L8.52,5.09C8.26,5.23,8.01,5.37,7.75,5.54L5.99,4.83 c-0.17-0.07-0.35-0.1-0.52-0.1c-0.5,0-0.98,0.27-1.22,0.72L2.43,8.55c-0.36,0.61-0.21,1.4,0.36,1.84l1.48,1.16 C4.27,11.7,4.26,11.85,4.26,12c0,0.16,0.01,0.3,0.02,0.45l-1.49,1.16C2.24,14.04,2.09,14.8,2.43,15.45z M5.2,13.63l0.63-0.49 l-0.05-0.79c-0.01-0.11-0.01-0.58,0-0.7l0.05-0.79L5.2,10.37L3.77,9.25l1.74-3l1.69,0.68l0.73,0.29l0.66-0.43 c0.19-0.13,0.4-0.25,0.65-0.38l0.67-0.36L10,5.3l0.25-1.79h3.48l0.26,1.8l0.11,0.76l0.69,0.36c0.23,0.12,0.44,0.24,0.64,0.37 l0.65,0.43l0.72-0.29l1.7-0.68l1.75,3.02l-1.43,1.12l-0.62,0.49l0.05,0.79c0.01,0.11,0.01,0.58,0,0.7l-0.05,0.79l0.62,0.49 l1.43,1.12l-1.74,3.02l-1.69-0.68l-0.72-0.29l-0.65,0.43c-0.19,0.13-0.4,0.25-0.65,0.38l-0.67,0.36l-0.11,0.75l-0.25,1.77h-3.5 L10,18.71l-0.11-0.76l-0.69-0.36c-0.23-0.12-0.44-0.24-0.64-0.37l-0.65-0.43l-0.72,0.29L5.5,17.76l-1.73-3.01L5.2,13.63z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,16c2.21,0,4-1.79,4-4s-1.79-4-4-4c-2.21,0-4,1.79-4,4S9.79,16,12,16z M12,9.5c1.38,0,2.5,1.12,2.5,2.5 s-1.12,2.5-2.5,2.5c-1.38,0-2.5-1.12-2.5-2.5S10.62,9.5,12,9.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
new file mode 100644
index 0000000..d754cbe
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M14.38,7.3C14.18,7.1,13.92,7,13.66,7c-0.26,0-0.51,0.1-0.71,0.29L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34 C3.82,22.9,4.08,23,4.34,23s0.51-0.1,0.71-0.29L16.7,11.05c0.39-0.39,0.39-1.02,0-1.41L14.38,7.3z M4.34,21.29l-1.63-1.63 l7.45-7.45l1.63,1.63L4.34,21.29z M12.84,12.78l-1.63-1.63l2.45-2.45l1.62,1.64L12.84,12.78z M17.75,5.25h1v1 C18.75,6.66,19.09,7,19.5,7s0.75-0.34,0.75-0.75v-1h1C21.66,5.25,22,4.91,22,4.5s-0.34-0.75-0.75-0.75h-1v-1 C20.25,2.34,19.91,2,19.5,2s-0.75,0.34-0.75,0.75v1h-1C17.34,3.75,17,4.09,17,4.5S17.34,5.25,17.75,5.25z M5.75,5.25h1v1 C6.75,6.66,7.09,7,7.5,7s0.75-0.34,0.75-0.75v-1h1C9.66,5.25,10,4.91,10,4.5S9.66,3.75,9.25,3.75h-1v-1C8.25,2.34,7.91,2,7.5,2 S6.75,2.34,6.75,2.75v1h-1C5.34,3.75,5,4.09,5,4.5S5.34,5.25,5.75,5.25z M21.25,15.75h-1v-1c0-0.41-0.34-0.75-0.75-0.75 s-0.75,0.34-0.75,0.75v1h-1c-0.41,0-0.75,0.34-0.75,0.75s0.34,0.75,0.75,0.75h1v1c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75 v-1h1c0.41,0,0.75-0.34,0.75-0.75S21.66,15.75,21.25,15.75z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
new file mode 100644
index 0000000..87a9546
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M5,11h14c0.55,0,1-0.45,1-1V4c0-0.55-0.45-1-1-1H5C4.45,3,4,3.45,4,4v6C4,10.55,4.45,11,5,11z M5.5,4.5h13v5h-13V4.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4,20c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1v-6c0-0.55-0.45-1-1-1H5c-0.55,0-1,0.45-1,1V20z M5.5,14.5h13v5h-13V14.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml
new file mode 100644
index 0000000..3834fb6
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_wallpaper.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <group
+ android:translateX="119.000000"
+ android:translateY="358.000000">
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000">
+ <path
+ android:fillColor="#000000"
+ android:pathData="M-109-356.5c4.69,0,8.5,3.36,8.5,7.5c0,2.48-2.02,4.5-4.5,4.5h-1.77c-1.1,0-2,0.9-2,2 c0,0.45,0.16,0.89,0.46,1.27l0.02,0.02l0.02,0.02c0.17,0.2,0.27,0.44,0.27,0.68c0,0.55-0.45,1-1,1c-4.69,0-8.5-3.81-8.5-8.5 S-113.69-356.5-109-356.5 M-109-358c-5.51,0-10,4.49-10,10s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67 c-0.08-0.1-0.13-0.21-0.13-0.33c0-0.28,0.22-0.5,0.5-0.5h1.77c3.31,0,6-2.69,6-6C-99-353.96-103.49-358-109-358L-109-358z" />
+ </group>
+ </group>
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 6.5 10 C 7.32842712475 10 8 10.6715728753 8 11.5 C 8 12.3284271247 7.32842712475 13 6.5 13 C 5.67157287525 13 5 12.3284271247 5 11.5 C 5 10.6715728753 5.67157287525 10 6.5 10 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 9.5 6 C 10.3284271247 6 11 6.67157287525 11 7.5 C 11 8.32842712475 10.3284271247 9 9.5 9 C 8.67157287525 9 8 8.32842712475 8 7.5 C 8 6.67157287525 8.67157287525 6 9.5 6 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 14.5 6 C 15.3284271247 6 16 6.67157287525 16 7.5 C 16 8.32842712475 15.3284271247 9 14.5 9 C 13.6715728753 9 13 8.32842712475 13 7.5 C 13 6.67157287525 13.6715728753 6 14.5 6 Z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 17.5 10 C 18.3284271247 10 19 10.6715728753 19 11.5 C 19 12.3284271247 18.3284271247 13 17.5 13 C 16.6715728753 13 16 12.3284271247 16 11.5 C 16 10.6715728753 16.6715728753 10 17.5 10 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
new file mode 100644
index 0000000..614828c
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_warning.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M4.47,21h15.06c1.54,0,2.5-1.67,1.73-3L13.73,4.99c-0.39-0.67-1.06-1-1.73-1s-1.35,0.33-1.73,1L2.74,18 C1.97,19.33,2.93,21,4.47,21z M4.04,18.75l7.53-13.01c0.13-0.22,0.33-0.25,0.43-0.25s0.31,0.03,0.43,0.25l7.53,13.01 c0.13,0.22,0.05,0.41,0,0.5c-0.05,0.09-0.18,0.25-0.43,0.25H4.47c-0.25,0-0.38-0.16-0.43-0.25C3.98,19.16,3.91,18.97,4.04,18.75z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,14.5c0.41,0,0.75-0.34,0.75-0.75v-4C12.75,9.33,12.41,9,12,9s-0.75,0.34-0.75,0.75v4C11.25,14.16,11.59,14.5,12,14.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M 12 16 C 12.5522847498 16 13 16.4477152502 13 17 C 13 17.5522847498 12.5522847498 18 12 18 C 11.4477152502 18 11 17.5522847498 11 17 C 11 16.4477152502 11.4477152502 16 12 16 Z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
new file mode 100644
index 0000000..a8aeaf2
--- /dev/null
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_widget.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M10,3H4C3.45,3,3,3.45,3,4v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1V4C11,3.45,10.55,3,10,3z M9.5,9.5h-5v-5h5V9.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M10,13H4c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C11,13.45,10.55,13,10,13z M9.5,19.5h-5v-5h5 V19.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20,13h-6c-0.55,0-1,0.45-1,1v6c0,0.55,0.45,1,1,1h6c0.55,0,1-0.45,1-1v-6C21,13.45,20.55,13,20,13z M19.5,19.5h-5v-5h5 V19.5z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21.95,6.29l-4.24-4.24c-0.2-0.2-0.45-0.29-0.71-0.29s-0.51,0.1-0.71,0.29l-4.24,4.24c-0.39,0.39-0.39,1.02,0,1.41 l4.24,4.24c0.2,0.2,0.45,0.29,0.71,0.29s0.51-0.1,0.71-0.29l4.24-4.24C22.34,7.32,22.34,6.68,21.95,6.29z M17,10.54L13.46,7 L17,3.46L20.54,7L17,10.54z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk b/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk
new file mode 100644
index 0000000..7adfe3b
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/Android.mk
@@ -0,0 +1,31 @@
+#
+# Copyright 2019, The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_RRO_THEME := IconPackRoundedLauncher
+LOCAL_CERTIFICATE := platform
+LOCAL_PRODUCT_MODULE := true
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := IconPackRoundedLauncherOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml b/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..8406f42
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.theme.icon_pack.rounded.launcher"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="com.android.launcher3" android:category="android.theme.customization.icon_pack.launcher" android:priority="1"/>
+ <application android:label="Rounded" android:hasCode="false"/>
+</manifest>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml
new file mode 100644
index 0000000..919e93e
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_clear.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
new file mode 100644
index 0000000..5a14373
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_corp.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20,6h-4V4c0-1.11-0.89-2-2-2h-4C8.89,2,8,2.89,8,4v2H4C2.89,6,2.01,6.89,2.01,8L2,19c0,1.11,0.89,2,2,2h16 c1.11,0,2-0.89,2-2V8C22,6.89,21.11,6,20,6z M14,6h-4V4h4V6z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_empty_recents.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_empty_recents.xml
new file mode 100644
index 0000000..76f8831
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_empty_recents.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M3,6h2c0.55,0,1,0.45,1,1v9c0,0.55-0.45,1-1,1H3c-0.55,0-1-0.45-1-1V7C2,6.45,2.45,6,3,6z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M8,19h8c0.55,0,1-0.45,1-1V5c0-0.55-0.45-1-1-1H8C7.45,4,7,4.45,7,5v13C7,18.55,7.45,19,8,19z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M19,6h2c0.55,0,1,0.45,1,1v9c0,0.55-0.45,1-1,1h-2c-0.55,0-1-0.45-1-1V7C18,6.45,18.45,6,19,6z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
new file mode 100644
index 0000000..6a4e448
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_info_no_shadow.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10s10-4.48,10-10C22,6.48,17.52,2,12,2z M13,17c0,0.55-0.45,1-1,1s-1-0.45-1-1 v-5c0-0.55,0.45-1,1-1s1,0.45,1,1V17z M12,9.25c-0.69,0-1.25-0.56-1.25-1.25S11.31,6.75,12,6.75S13.25,7.31,13.25,8 S12.69,9.25,12,9.25z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
new file mode 100644
index 0000000..08ae89f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_remove_no_shadow.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M5.7,18.3c0.39,0.39,1.02,0.39,1.41,0L12,13.41l4.89,4.89c0.39,0.39,1.02,0.39,1.41,0s0.39-1.02,0-1.41L13.41,12l4.89-4.89 c0.38-0.38,0.38-1.02,0-1.4c-0.39-0.39-1.02-0.39-1.41,0c0,0,0,0,0,0L12,10.59L7.11,5.7c-0.39-0.39-1.02-0.39-1.41,0 s-0.39,1.02,0,1.41L10.59,12L5.7,16.89C5.31,17.28,5.31,17.91,5.7,18.3z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
new file mode 100644
index 0000000..842b687
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21.64,8.39l-1.6-2.76c-0.28-0.48-0.88-0.7-1.36-0.5l-2.14,0.91c-0.48-0.37-1.01-0.68-1.57-0.92l-0.27-2.2 C14.64,2.4,14.14,2,13.59,2h-3.18C9.86,2,9.36,2.4,9.3,2.92L9.04,5.11c-0.57,0.24-1.1,0.55-1.58,0.92L5.32,5.12 c-0.48-0.2-1.08,0.02-1.36,0.5l-1.6,2.76C2.08,8.86,2.18,9.48,2.6,9.8l1.94,1.45C4.51,11.49,4.5,11.74,4.5,12s0.01,0.51,0.04,0.76 L2.6,14.2c-0.42,0.31-0.52,0.94-0.24,1.41l1.6,2.76c0.28,0.48,0.88,0.7,1.36,0.5l2.14-0.91c0.48,0.37,1.01,0.68,1.57,0.92 l0.27,2.19C9.36,21.6,9.86,22,10.41,22h3.18c0.55,0,1.04-0.4,1.11-0.92l0.27-2.19c0.56-0.24,1.09-0.55,1.57-0.92l2.14,0.91 c0.48,0.2,1.08-0.02,1.36-0.5l1.6-2.76c0.28-0.48,0.18-1.1-0.24-1.42l-1.94-1.45c0.03-0.25,0.04-0.5,0.04-0.76 s-0.01-0.51-0.04-0.76L21.4,9.8C21.82,9.49,21.92,8.86,21.64,8.39z M12,15.5c-1.93,0-3.5-1.57-3.5-3.5s1.57-3.5,3.5-3.5 s3.5,1.57,3.5,3.5S13.93,15.5,12,15.5z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
new file mode 100644
index 0000000..8950fbd
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_smartspace_preferences.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21.23,2.43L19.5,3.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34L18.4,4.5l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 L19.5,5.6l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,4.5l0.97-1.73C21.69,2.55,21.45,2.31,21.23,2.43z M14.37,7.29 c-0.39-0.39-1.02-0.39-1.41,0L1.29,18.96c-0.39,0.39-0.39,1.02,0,1.41l2.34,2.34c0.39,0.39,1.02,0.39,1.41,0L16.7,11.05 c0.39-0.39,0.39-1.02,0-1.41L14.37,7.29z M13.34,12.78l-2.12-2.12l2.44-2.44l2.12,2.12L13.34,12.78z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M21.23,14.43L19.5,15.4l-1.73-0.97c-0.22-0.12-0.46,0.12-0.34,0.34l0.97,1.73l-0.97,1.73c-0.12,0.22,0.12,0.46,0.34,0.34 l1.73-0.97l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L20.6,16.5l0.97-1.73C21.69,14.55,21.45,14.31,21.23,14.43z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M9.23,2.43L7.5,3.4L5.77,2.43C5.55,2.31,5.31,2.55,5.43,2.77L6.4,4.5L5.43,6.23C5.31,6.45,5.55,6.69,5.77,6.57L7.5,5.6 l1.73,0.97c0.22,0.12,0.46-0.12,0.34-0.34L8.6,4.5l0.97-1.73C9.69,2.55,9.45,2.31,9.23,2.43z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
new file mode 100644
index 0000000..30478b3
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_split_screen.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18,2H6C4.9,2,4,2.9,4,4v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M18,13H6c-1.1,0-2,0.9-2,2v5c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2v-5C20,13.9,19.1,13,18,13z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml
new file mode 100644
index 0000000..72d1d31
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_wallpaper.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12,2C6.49,2,2,6.49,2,12s4.49,10,10,10c1.38,0,2.5-1.12,2.5-2.5c0-0.61-0.23-1.2-0.64-1.67c-0.08-0.1-0.13-0.21-0.13-0.33 c0-0.28,0.22-0.5,0.5-0.5H16c3.31,0,6-2.69,6-6C22,6.04,17.51,2,12,2z M6.5,13C5.67,13,5,12.33,5,11.5S5.67,10,6.5,10 S8,10.67,8,11.5S7.33,13,6.5,13z M9.5,9C8.67,9,8,8.33,8,7.5S8.67,6,9.5,6S11,6.67,11,7.5S10.33,9,9.5,9z M14.5,9 C13.67,9,13,8.33,13,7.5S13.67,6,14.5,6S16,6.67,16,7.5S15.33,9,14.5,9z M17.5,13c-0.83,0-1.5-0.67-1.5-1.5s0.67-1.5,1.5-1.5 s1.5,0.67,1.5,1.5S18.33,13,17.5,13z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
new file mode 100644
index 0000000..f92842a
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_warning.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M12.87,3.49c-0.39-0.67-1.35-0.67-1.73,0l-9.27,16C1.48,20.17,1.96,21,2.73,21h18.53c0.77,0,1.25-0.83,0.87-1.5L12.87,3.49 z M11,10c0-0.55,0.45-1,1-1s1,0.45,1,1v3c0,0.55-0.45,1-1,1s-1-0.45-1-1V10z M12,18.25c-0.69,0-1.25-0.56-1.25-1.25 s0.56-1.25,1.25-1.25s1.25,0.56,1.25,1.25S12.69,18.25,12,18.25z" />
+</vector>
\ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
new file mode 100644
index 0000000..511757f
--- /dev/null
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_widget.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+
+ <path
+ android:fillColor="#000000"
+ android:pathData="M17.7,2.3c-0.4-0.4-1-0.4-1.4,0l-4,4c-0.4,0.4-0.4,1,0,1.4l4,4c0.4,0.4,1,0.4,1.4,0l4-4c0.4-0.4,0.4-1,0-1.4L17.7,2.3z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M11,4c0-0.5-0.4-1-1-1H4C3.5,3,3,3.5,3,4v6c0,0.6,0.5,1,1,1h6c0.6,0,1-0.4,1-1V4z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M20,21c0.5,0,1-0.5,1-1v-6c0-0.6-0.5-1-1-1h-6c-0.6,0-1,0.4-1,1v6c0,0.5,0.4,1,1,1H20z" />
+ <path
+ android:fillColor="#000000"
+ android:pathData="M10,13H4c-0.5,0-1,0.4-1,1v6c0,0.5,0.5,1,1,1h6c0.6,0,1-0.5,1-1v-6C11,13.4,10.6,13,10,13z" />
+</vector>
\ No newline at end of file
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 3f33813..62deaff 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -72,6 +72,7 @@
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.WhitelistHelper;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.server.LocalServices;
@@ -173,10 +174,10 @@
private ServiceInfo mRemoteAugmentedAutofillServiceInfo;
/**
- * List of packages that are whitelisted to be trigger augmented autofill.
+ * List of packages/activities that are whitelisted to be trigger augmented autofill.
*/
@GuardedBy("mLock")
- private final ArraySet<String> mWhitelistedAugmentAutofillPackages = new ArraySet<>();
+ private final WhitelistHelper mAugmentedWhitelistHelper = new WhitelistHelper();
AutofillManagerServiceImpl(AutofillManagerService master, Object lock,
LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui,
@@ -905,13 +906,8 @@
pw.println(mRemoteAugmentedAutofillServiceInfo);
}
- final int whitelistSize = mWhitelistedAugmentAutofillPackages.size();
- pw.print(prefix); pw.print("Packages whitelisted for augmented autofill: ");
- pw.println(whitelistSize);
- for (int i = 0; i < whitelistSize; i++) {
- final String whitelistedPkg = mWhitelistedAugmentAutofillPackages.valueAt(i);
- pw.print(prefix2); pw.print(i + 1); pw.print(": "); pw.println(whitelistedPkg);
- }
+ pw.print(prefix); pw.print("augmented autofill whitelist: ");
+ mAugmentedWhitelistHelper.dump(prefix2, "Whitelist", pw);
pw.print(prefix); pw.print("Field classification enabled: ");
pw.println(isFieldClassificationEnabledLocked());
@@ -1129,9 +1125,8 @@
Slog.v(TAG, "setAugmentedAutofillWhitelistLocked(packages=" + packages + ", activities="
+ activities + ")");
}
- whitelistForAugmentedAutofillPackages(packages);
+ whitelistForAugmentedAutofillPackages(packages, activities);
- // TODO(b/123100824): whitelist activities as well
// TODO(b/122858578): log metrics
return true;
}
@@ -1171,28 +1166,30 @@
@GuardedBy("mLock")
boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) {
- // TODO(b/122595322): need to check whitelisted activities as well.
- final String packageName = componentName.getPackageName();
- return mWhitelistedAugmentAutofillPackages.contains(packageName);
+ return mAugmentedWhitelistHelper.isWhitelisted(componentName);
}
@GuardedBy("mLock")
void setAugmentedAutofillWhitelistLocked(@NonNull AutofillOptions options,
@NonNull String packageName) {
- // TODO(b/122595322): need to setwhitelisted activities as well.
- options.augmentedEnabled = mWhitelistedAugmentAutofillPackages.contains(packageName);
+ options.augmentedAutofillEnabled = mAugmentedWhitelistHelper.isWhitelisted(packageName);
+ options.whitelistedActivitiesForAugmentedAutofill = mAugmentedWhitelistHelper
+ .getWhitelistedComponents(packageName);
}
- private void whitelistForAugmentedAutofillPackages(@NonNull List<String> packages) {
+ /**
+ *
+ * @throws IllegalArgumentException if packages or components are empty.
+ */
+ private void whitelistForAugmentedAutofillPackages(@Nullable List<String> packages,
+ @Nullable List<ComponentName> components) {
// TODO(b/123100824): add CTS test for when it's null
synchronized (mLock) {
- if (packages == null) {
- if (mMaster.verbose) Slog.v(TAG, "clearing all whitelisted augmented packages");
- mWhitelistedAugmentAutofillPackages.clear();
- } else {
- if (mMaster.verbose) Slog.v(TAG, "whitelisting augmented packages: " + packages);
- mWhitelistedAugmentAutofillPackages.addAll(packages);
+ if (mMaster.verbose) {
+ Slog.v(TAG, "whitelisting packages: " + packages + "and activities: " + components);
}
+ mAugmentedWhitelistHelper.setWhitelist(new ArraySet<>(packages),
+ new ArraySet<>(components));
mRemoteAugmentedAutofillService = getRemoteAugmentedAutofillServiceLocked();
}
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index b33259d..955d764 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -20,8 +20,8 @@
import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
import static android.view.contentcapture.ContentCaptureSession.STATE_DUPLICATED_ID;
import static android.view.contentcapture.ContentCaptureSession.STATE_INTERNAL_ERROR;
+import static android.view.contentcapture.ContentCaptureSession.STATE_NOT_WHITELISTED;
import static android.view.contentcapture.ContentCaptureSession.STATE_NO_SERVICE;
-import static android.view.contentcapture.ContentCaptureSession.STATE_PACKAGE_NOT_WHITELISTED;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
@@ -29,6 +29,7 @@
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
@@ -55,6 +56,7 @@
import android.view.contentcapture.UserDataRemovalRequest;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.WhitelistHelper;
import com.android.internal.os.IResultReceiver;
import com.android.server.LocalServices;
import com.android.server.contentcapture.RemoteContentCaptureService.ContentCaptureServiceCallbacks;
@@ -94,7 +96,7 @@
* List of packages that are whitelisted to be content captured.
*/
@GuardedBy("mLock")
- private final ArraySet<String> mWhitelistedPackages = new ArraySet<>();
+ private final WhitelistHelper mWhitelistHelper = new WhitelistHelper();
// TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's
@@ -194,7 +196,7 @@
final int taskId = activityPresentationInfo.taskId;
final int displayId = activityPresentationInfo.displayId;
final ComponentName componentName = activityPresentationInfo.componentName;
- final boolean whitelisted = isWhitelistedLocked(componentName);
+ final boolean whiteListed = isWhitelistedLocked(componentName);
final ComponentName serviceComponentName = getServiceComponentName();
final boolean enabled = isEnabledLocked();
if (mMaster.mRequestsHistory != null) {
@@ -204,7 +206,7 @@
+ " t=" + taskId + " d=" + displayId
+ " s=" + ComponentName.flattenToShortString(serviceComponentName)
+ " u=" + mUserId + " f=" + flags + (enabled ? "" : " (disabled)")
- + " w=" + whitelisted;
+ + " w=" + whiteListed;
mMaster.mRequestsHistory.log(historyItem);
}
@@ -225,12 +227,12 @@
return;
}
- if (!whitelisted) {
+ if (!whiteListed) {
if (mMaster.debug) {
- Slog.d(TAG, "startSession(" + componentName + "): not whitelisted");
+ Slog.d(TAG, "startSession(" + componentName + "): package or component "
+ + "not whitelisted");
}
- // TODO(b/122595322): need to return STATE_ACTIVITY_NOT_WHITELISTED as well
- setClientState(clientReceiver, STATE_DISABLED | STATE_PACKAGE_NOT_WHITELISTED,
+ setClientState(clientReceiver, STATE_DISABLED | STATE_NOT_WHITELISTED,
/* binder= */ null);
return;
}
@@ -270,21 +272,20 @@
@GuardedBy("mLock")
private boolean isWhitelistedLocked(@NonNull ComponentName componentName) {
- // TODO(b/122595322): need to check whitelisted activities as well.
- final String packageName = componentName.getPackageName();
- return mWhitelistedPackages.contains(packageName);
+ return mWhitelistHelper.isWhitelisted(componentName);
}
- private void whitelistPackages(@NonNull List<String> packages) {
+ /**
+ * @throws IllegalArgumentException if packages or components are empty.
+ */
+ private void setWhitelist(@Nullable List<String> packages,
+ @Nullable List<ComponentName> components) {
// TODO(b/122595322): add CTS test for when it's null
synchronized (mLock) {
- if (packages == null) {
- if (mMaster.verbose) Slog.v(TAG, "clearing all whitelisted packages");
- mWhitelistedPackages.clear();
- } else {
- if (mMaster.verbose) Slog.v(TAG, "whitelisting packages: " + packages);
- mWhitelistedPackages.addAll(packages);
+ if (mMaster.verbose) {
+ Slog.v(TAG, "whitelisting packages: " + packages + "and activities: " + components);
}
+ mWhitelistHelper.setWhitelist(new ArraySet<>(packages), new ArraySet<>(components));
}
}
@@ -411,15 +412,15 @@
@GuardedBy("mLock")
ContentCaptureOptions getOptionsForPackageLocked(@NonNull String packageName) {
- if (!mWhitelistedPackages.contains(packageName)) {
+ if (!mWhitelistHelper.isWhitelisted(packageName)) {
if (mMaster.verbose) {
Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted");
}
return null;
}
- // TODO(b/122595322): need to check whitelisted activities as well.
- final ArraySet<ComponentName> whitelistedComponents = null;
+ final ArraySet<ComponentName> whitelistedComponents = mWhitelistHelper
+ .getWhitelistedComponents(packageName);
ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel,
mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs,
mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize,
@@ -440,12 +441,7 @@
mRemoteService.dump(prefix2, pw);
}
- final int whitelistSize = mWhitelistedPackages.size();
- pw.print(prefix); pw.print("Whitelisted packages: "); pw.println(whitelistSize);
- for (int i = 0; i < whitelistSize; i++) {
- final String whitelistedPkg = mWhitelistedPackages.valueAt(i);
- pw.print(prefix2); pw.print(i + 1); pw.print(": "); pw.println(whitelistedPkg);
- }
+ pw.print(prefix); pw.print("Whitelist: "); pw.println(mWhitelistHelper);
if (mSessions.isEmpty()) {
pw.print(prefix); pw.println("no sessions");
@@ -485,9 +481,8 @@
Slog.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities="
+ activities + ")");
}
- whitelistPackages(packages);
+ setWhitelist(packages, activities);
- // TODO(b/122595322): whitelist activities as well
// TODO(b/119613670): log metrics
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 0955cc5..1a70582 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -259,7 +259,7 @@
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
| PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
| PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
- | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE;
+ | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
@@ -819,7 +819,8 @@
remove(r.binder);
}
}
- if ((events & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE) != 0) {
+ if ((events & PhoneStateListener
+ .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
try {
r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
} catch (RemoteException ex) {
@@ -1748,7 +1749,7 @@
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE)) {
+ PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)) {
try {
r.callback.onActiveDataSubIdChanged(activeDataSubId);
} catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index d2d1482..feeb16b 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -32,6 +32,7 @@
import android.hardware.biometrics.IBiometricServiceReceiverInternal;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback;
+import android.hardware.biometrics.face.V1_0.OptionalBool;
import android.hardware.biometrics.face.V1_0.Status;
import android.hardware.face.Face;
import android.hardware.face.FaceManager;
@@ -54,7 +55,6 @@
import com.android.server.biometrics.AuthenticationClient;
import com.android.server.biometrics.BiometricServiceBase;
import com.android.server.biometrics.BiometricUtils;
-import com.android.server.biometrics.ClientMonitor;
import com.android.server.biometrics.EnumerateClient;
import com.android.server.biometrics.Metrics;
import com.android.server.biometrics.RemovalClient;
@@ -385,38 +385,61 @@
}
@Override
- public int setFeature(int feature, boolean enabled, final byte[] token) {
+ public boolean setFeature(int feature, boolean enabled, final byte[] token) {
checkPermission(MANAGE_BIOMETRIC);
+ if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+ Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
+ return false;
+ }
+
final ArrayList<Byte> byteToken = new ArrayList<>();
for (int i = 0; i < token.length; i++) {
byteToken.add(token[i]);
}
- int result;
- try {
- result = mDaemon != null ? mDaemon.setFeature(feature, enabled, byteToken)
- : Status.INTERNAL_ERROR;
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled,
- e);
- result = Status.INTERNAL_ERROR;
- }
+ // TODO: Support multiple faces
+ final int faceId = getFirstTemplateForUser(mCurrentUserId);
- return result;
+ if (mDaemon != null) {
+ try {
+ return mDaemon.setFeature(feature, enabled, byteToken, faceId) == Status.OK;
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "Unable to set feature: " + feature + " to enabled:" + enabled,
+ e);
+ }
+ }
+ return false;
}
@Override
public boolean getFeature(int feature) {
checkPermission(MANAGE_BIOMETRIC);
- boolean result = true;
- try {
- result = mDaemon != null ? mDaemon.getFeature(feature) : true;
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to getRequireAttention", e);
+ // This should ideally return tri-state, but the user isn't shown settings unless
+ // they are enrolled so it's fine for now.
+ if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+ Slog.e(TAG, "No enrolled biometrics while getting feature: " + feature);
+ return false;
}
- return result;
+
+ // TODO: Support multiple faces
+ final int faceId = getFirstTemplateForUser(mCurrentUserId);
+
+ if (mDaemon != null) {
+ try {
+ OptionalBool result = mDaemon.getFeature(feature, faceId);
+ if (result.status == Status.OK) {
+ return result.value;
+ } else {
+ // Same tri-state comment applies here.
+ return false;
+ }
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "Unable to getRequireAttention", e);
+ }
+ }
+ return false;
}
@Override
@@ -431,6 +454,15 @@
}
}
}
+
+ // TODO: Support multiple faces
+ private int getFirstTemplateForUser(int user) {
+ final List<Face> faces = FaceService.this.getEnrolledTemplates(user);
+ if (!faces.isEmpty()) {
+ return faces.get(0).getBiometricId();
+ }
+ return 0;
+ }
}
/**
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ee968c8..0bc46f1 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1973,8 +1973,7 @@
} catch (RemoteException ex) {
Slog.w(TAG, "unable to clear GK secure user id");
}
- UserInfo userInfo = mUserManager.getUserInfo(userId);
- if (unknownUser || userInfo == null || userInfo.isManagedProfile()) {
+ if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
removeKeystoreProfileKey(userId);
}
}
diff --git a/services/core/java/com/android/server/pm/OWNERS b/services/core/java/com/android/server/pm/OWNERS
index 8ce2568..3c1ee3e 100644
--- a/services/core/java/com/android/server/pm/OWNERS
+++ b/services/core/java/com/android/server/pm/OWNERS
@@ -14,72 +14,72 @@
per-file StagingManager.java = dariofreni@google.com, narayan@google.com, toddke@android.com, toddke@google.com
# dex
-per-file AbstractStatsBase.java = agampe@google.com
-per-file AbstractStatsBase.java = calin@google.com
-per-file AbstractStatsBase.java = ngeoffray@google.com
-per-file BackgroundDexOptService.java = agampe@google.com
-per-file BackgroundDexOptService.java = calin@google.com
-per-file BackgroundDexOptService.java = ngeoffray@google.com
-per-file CompilerStats.java = agampe@google.com
-per-file CompilerStats.java = calin@google.com
-per-file CompilerStats.java = ngeoffray@google.com
-per-file DynamicCodeLoggingService.java = agampe@google.com
-per-file DynamicCodeLoggingService.java = calin@google.com
-per-file DynamicCodeLoggingService.java = ngeoffray@google.com
-per-file InstructionSets.java = agampe@google.com
-per-file InstructionSets.java = calin@google.com
-per-file InstructionSets.java = ngeoffray@google.com
-per-file OtaDexoptService.java = agampe@google.com
-per-file OtaDexoptService.java = calin@google.com
-per-file OtaDexoptService.java = ngeoffray@google.com
-per-file OtaDexoptShellCommand.java = agampe@google.com
-per-file OtaDexoptShellCommand.java = calin@google.com
-per-file OtaDexoptShellCommand.java = ngeoffray@google.com
-per-file PackageDexOptimizer.java = agampe@google.com
-per-file PackageDexOptimizer.java = calin@google.com
-per-file PackageDexOptimizer.java = ngeoffray@google.com
-per-file PackageManagerServiceCompilerMapping.java = agampe@google.com
-per-file PackageManagerServiceCompilerMapping.java = calin@google.com
-per-file PackageManagerServiceCompilerMapping.java = ngeoffray@google.com
-per-file PackageUsage.java = agampe@google.com
-per-file PackageUsage.java = calin@google.com
-per-file PackageUsage.java = ngeoffray@google.com
+per-file AbstractStatsBase.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file AbstractStatsBase.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file AbstractStatsBase.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file BackgroundDexOptService.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file BackgroundDexOptService.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file BackgroundDexOptService.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file CompilerStats.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file CompilerStats.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file CompilerStats.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file DynamicCodeLoggingService.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file DynamicCodeLoggingService.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file DynamicCodeLoggingService.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file InstructionSets.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file InstructionSets.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file InstructionSets.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file OtaDexoptService.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file OtaDexoptService.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file OtaDexoptService.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file OtaDexoptShellCommand.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file OtaDexoptShellCommand.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file OtaDexoptShellCommand.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageDexOptimizer.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageDexOptimizer.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageDexOptimizer.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageManagerServiceCompilerMapping.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageManagerServiceCompilerMapping.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageManagerServiceCompilerMapping.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageUsage.java = agampe@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageUsage.java = calin@google.com, toddke@google.com, svetoslavganov@google.com
+per-file PackageUsage.java = ngeoffray@google.com, toddke@google.com, svetoslavganov@google.com
# multi user / cross profile
-per-file CrossProfileAppsServiceImpl.java = omakoto@google.com
-per-file CrossProfileAppsServiceImpl.java = yamasani@google.com
-per-file CrossProfileAppsService.java = omakoto@google.com
-per-file CrossProfileAppsService.java = yamasani@google.com
-per-file CrossProfileIntentFilter.java = omakoto@google.com
-per-file CrossProfileIntentFilter.java = yamasani@google.com
-per-file CrossProfileIntentResolver.java = omakoto@google.com
-per-file CrossProfileIntentResolver.java = yamasani@google.com
-per-file UserManagerService.java = omakoto@google.com
-per-file UserManagerService.java = yamasani@google.com
-per-file UserRestrictionsUtils.java = omakoto@google.com
-per-file UserRestrictionsUtils.java = yamasani@google.com
-per-file UserRestrictionsUtils.java = rubinxu@google.com
-per-file UserRestrictionsUtils.java = sandness@google.com
+per-file CrossProfileAppsServiceImpl.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file CrossProfileAppsServiceImpl.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
+per-file CrossProfileAppsService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file CrossProfileAppsService.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
+per-file CrossProfileIntentFilter.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file CrossProfileIntentFilter.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
+per-file CrossProfileIntentResolver.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file CrossProfileIntentResolver.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
+per-file UserManagerService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file UserManagerService.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
+per-file UserRestrictionsUtils.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file UserRestrictionsUtils.java = yamasani@google.com, omakoto@google.com, hackbod@google.com
+per-file UserRestrictionsUtils.java = rubinxu@google.com, yamasani@google.com, hackbod@google.com
+per-file UserRestrictionsUtils.java = sandness@google.com, yamasani@google.com, hackbod@google.com
# security
-per-file KeySetHandle.java = cbrubaker@google.com
-per-file KeySetManagerService.java = cbrubaker@google.com
-per-file PackageKeySetData.java = cbrubaker@google.com
-per-file PackageSignatures.java = cbrubaker@google.com
-per-file SELinuxMMAC.java = cbrubaker@google.com
+per-file KeySetHandle.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
+per-file KeySetManagerService.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
+per-file PackageKeySetData.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
+per-file PackageSignatures.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
+per-file SELinuxMMAC.java = cbrubaker@google.com, svetoslavganov@google.com, hackbod@google.com
# shortcuts
-per-file LauncherAppsService.java = omakoto@google.com
-per-file ShareTargetInfo.java = omakoto@google.com
-per-file ShortcutBitmapSaver.java = omakoto@google.com
-per-file ShortcutDumpFiles.java = omakoto@google.com
-per-file ShortcutLauncher.java = omakoto@google.com
-per-file ShortcutNonPersistentUser.java = omakoto@google.com
-per-file ShortcutPackage.java = omakoto@google.com
-per-file ShortcutPackageInfo.java = omakoto@google.com
-per-file ShortcutPackageItem.java = omakoto@google.com
-per-file ShortcutParser.java = omakoto@google.com
-per-file ShortcutRequestPinProcessor.java = omakoto@google.com
-per-file ShortcutService.java = omakoto@google.com
-per-file ShortcutUser.java = omakoto@google.com
+per-file LauncherAppsService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShareTargetInfo.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutBitmapSaver.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutDumpFiles.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutLauncher.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutNonPersistentUser.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutPackage.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutPackageInfo.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutPackageItem.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutParser.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutRequestPinProcessor.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutService.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
+per-file ShortcutUser.java = omakoto@google.com, yamasani@google.com, hackbod@google.com
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index d9a5eb9..eced165 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -22,6 +22,7 @@
import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.LocusId;
import android.content.pm.PackageInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
@@ -1702,15 +1703,17 @@
flags |= ShortcutInfo.FLAG_SHADOW;
}
+ LocusId locusId = null; // LocusId is not set on XML.
+
return new ShortcutInfo(
- userId, id, packageName, activityComponent, /* icon =*/ null,
+ userId, id, packageName, activityComponent, /* icon= */ null,
title, titleResId, titleResName, text, textResId, textResName,
disabledMessage, disabledMessageResId, disabledMessageResName,
categories,
intents.toArray(new Intent[intents.size()]),
rank, extras, lastChangedTimestamp, flags,
iconResId, iconResName, bitmapPath, disabledReason,
- persons.toArray(new Person[persons.size()]));
+ persons.toArray(new Person[persons.size()]), locusId);
}
private static Intent parseIntent(XmlPullParser parser)
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index 668fc88..f9c0db0 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -450,7 +450,8 @@
null, // icon res name
null, // bitmap path
disabledReason,
- null /* persons */);
+ null /* persons */,
+ null /* locusId */);
}
private static String parseCategory(ShortcutService service, AttributeSet attrs) {
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 1392762..4fd8489 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -202,13 +202,6 @@
// Do not move the stack as a part of reparenting
static final int REPARENT_LEAVE_STACK_IN_PLACE = 2;
- // The height/width divide used when fitting a task within a bounds with method
- // {@link #fitWithinBounds}.
- // We always want the task to to be visible in the bounds without affecting its size when
- // fitting. To make sure this is the case, we don't adjust the task left or top side pass
- // the input bounds right or bottom side minus the width or height divided by this value.
- private static final int FIT_WITHIN_BOUNDS_DIVIDER = 3;
-
/**
* The factory used to create {@link TaskRecord}. This allows OEM subclass {@link TaskRecord}.
*/
@@ -1932,35 +1925,33 @@
*
* @param bounds Bounds to be adjusted.
* @param stackBounds Bounds within which the other bounds should remain.
+ * @param overlapPxX The amount of px required to be visible in the X dimension.
+ * @param overlapPxY The amount of px required to be visible in the Y dimension.
*/
- private static void fitWithinBounds(Rect bounds, Rect stackBounds) {
+ private static void fitWithinBounds(Rect bounds, Rect stackBounds, int overlapPxX,
+ int overlapPxY) {
if (stackBounds == null || stackBounds.isEmpty() || stackBounds.contains(bounds)) {
return;
}
- if (bounds.left < stackBounds.left || bounds.right > stackBounds.right) {
- final int maxRight = stackBounds.right
- - (stackBounds.width() / FIT_WITHIN_BOUNDS_DIVIDER);
- int horizontalDiff = stackBounds.left - bounds.left;
- if ((horizontalDiff < 0 && bounds.left >= maxRight)
- || (bounds.left + horizontalDiff >= maxRight)) {
- horizontalDiff = maxRight - bounds.left;
- }
- bounds.left += horizontalDiff;
- bounds.right += horizontalDiff;
+ // For each side of the parent (eg. left), check if the opposing side of the window (eg.
+ // right) is at least overlap pixels away. If less, offset the window by that difference.
+ int horizontalDiff = 0;
+ // If window is smaller than overlap, use it's smallest dimension instead
+ int overlapLR = Math.min(overlapPxX, bounds.width());
+ if (bounds.right < (stackBounds.left + overlapLR)) {
+ horizontalDiff = overlapLR - (bounds.right - stackBounds.left);
+ } else if (bounds.left > (stackBounds.right - overlapLR)) {
+ horizontalDiff = -(overlapLR - (stackBounds.right - bounds.left));
}
-
- if (bounds.top < stackBounds.top || bounds.bottom > stackBounds.bottom) {
- final int maxBottom = stackBounds.bottom
- - (stackBounds.height() / FIT_WITHIN_BOUNDS_DIVIDER);
- int verticalDiff = stackBounds.top - bounds.top;
- if ((verticalDiff < 0 && bounds.top >= maxBottom)
- || (bounds.top + verticalDiff >= maxBottom)) {
- verticalDiff = maxBottom - bounds.top;
- }
- bounds.top += verticalDiff;
- bounds.bottom += verticalDiff;
+ int verticalDiff = 0;
+ int overlapTB = Math.min(overlapPxY, bounds.width());
+ if (bounds.bottom < (stackBounds.top + overlapTB)) {
+ verticalDiff = overlapTB - (bounds.bottom - stackBounds.top);
+ } else if (bounds.top > (stackBounds.bottom - overlapTB)) {
+ verticalDiff = -(overlapTB - (stackBounds.bottom - bounds.top));
}
+ bounds.offset(horizontalDiff, verticalDiff);
}
/**
@@ -2230,7 +2221,11 @@
adjustForMinimalTaskDimensions(outOverrideBounds, mTmpBounds);
if (windowingMode == WINDOWING_MODE_FREEFORM) {
// by policy, make sure the window remains within parent somewhere
- fitWithinBounds(outOverrideBounds, newParentConfig.windowConfiguration.getBounds());
+ final float density =
+ ((float) newParentConfig.densityDpi) / DisplayMetrics.DENSITY_DEFAULT;
+ fitWithinBounds(outOverrideBounds, newParentConfig.windowConfiguration.getBounds(),
+ (int) (density * WindowState.MINIMUM_VISIBLE_WIDTH_IN_DP),
+ (int) (density * WindowState.MINIMUM_VISIBLE_HEIGHT_IN_DP));
}
computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d5a6f00..20cca66 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -942,29 +942,9 @@
// Make sure the content and visible frames are inside of the
// final window frame.
if (windowsAreFloating && !mWindowFrames.mFrame.isEmpty()) {
- // For pinned workspace the frame isn't limited in any particular
- // way since SystemUI controls the bounds. For freeform however
- // we want to keep things inside the content frame.
- final Rect limitFrame = task.inPinnedWindowingMode() ? mWindowFrames.mFrame
- : mWindowFrames.mContentFrame;
- // Keep the frame out of the blocked system area, limit it in size to the content area
- // and make sure that there is always a minimum visible so that the user can drag it
- // into a usable area..
- final int height = Math.min(mWindowFrames.mFrame.height(), limitFrame.height());
- final int width = Math.min(limitFrame.width(), mWindowFrames.mFrame.width());
- final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
- final int minVisibleHeight = Math.min(height, WindowManagerService.dipToPixel(
- MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics));
- final int minVisibleWidth = Math.min(width, WindowManagerService.dipToPixel(
- MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics));
- final int top = Math.max(limitFrame.top,
- Math.min( mWindowFrames.mFrame.top, limitFrame.bottom - minVisibleHeight));
- final int left = Math.max(limitFrame.left + minVisibleWidth - width,
- Math.min( mWindowFrames.mFrame.left, limitFrame.right - minVisibleWidth));
- mWindowFrames.mFrame.set(left, top, left + width, top + height);
final int visBottom = mWindowFrames.mVisibleFrame.bottom;
final int contentBottom = mWindowFrames.mContentFrame.bottom;
- mWindowFrames.mContentFrame.set( mWindowFrames.mFrame);
+ mWindowFrames.mContentFrame.set(mWindowFrames.mFrame);
mWindowFrames.mVisibleFrame.set(mWindowFrames.mContentFrame);
mWindowFrames.mStableFrame.set(mWindowFrames.mContentFrame);
if (isImeTarget && inFreeformWindowingMode()) {
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 298b664..bce3e98 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -160,6 +160,8 @@
using IMeasurementCorrections =
android::hardware::gnss::measurement_corrections::V1_0::IMeasurementCorrections;
+using GnssSingleSatCorrectionFlags =
+ android::hardware::gnss::measurement_corrections::V1_0::GnssSingleSatCorrectionFlags;
using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControl;
using android::hardware::gnss::visibility_control::V1_0::IGnssVisibilityControlCallback;
@@ -199,9 +201,7 @@
sp<IGnssMeasurement_V2_0> gnssMeasurementIface_V2_0 = nullptr;
sp<IGnssNavigationMessage> gnssNavigationMessageIface = nullptr;
sp<IMeasurementCorrections> gnssCorrectionsIface = nullptr;
-// This boolean is needed to ensure that Gnsss Measurement Corrections related method are only
-// initalized when needed which will be few devices initially
-bool firstGnssMeasurementCorrectionInjected = false;
+
sp<IGnssVisibilityControl> gnssVisibilityControlIface = nullptr;
#define WAKE_LOCK_NAME "GPS"
@@ -1471,6 +1471,51 @@
"(Ljava/lang/String;BLjava/lang/String;BLjava/lang/String;BZZ)V");
method_isInEmergencySession = env->GetMethodID(clazz, "isInEmergencySession", "()Z");
+ jclass measCorrClass = env->FindClass("android/location/GnssMeasurementCorrections");
+ method_correctionsGetLatitudeDegrees = env->GetMethodID(
+ measCorrClass,"getLatitudeDegrees", "()D");
+ method_correctionsGetLongitudeDegrees = env->GetMethodID(
+ measCorrClass, "getLongitudeDegrees", "()D");
+ method_correctionsGetAltitudeMeters = env->GetMethodID(
+ measCorrClass, "getAltitudeMeters", "()D");
+ method_correctionsGetHorPosUncMeters = env->GetMethodID(
+ measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
+ method_correctionsGetVerPosUncMeters = env->GetMethodID(
+ measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
+ method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
+ measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");
+
+ method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
+ measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava/util/List;");
+
+ jclass corrListClass = env->FindClass("java/util/List");
+ method_listSize = env->GetMethodID(corrListClass, "size", "()I");
+ method_correctionListGet = env->GetMethodID(corrListClass, "get", "(I)Ljava/lang/Object;");
+
+ jclass singleSatCorrClass = env->FindClass("android/location/GnssSingleSatCorrection");
+ method_correctionSatFlags = env->GetMethodID(
+ singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
+ method_correctionSatConstType = env->GetMethodID(
+ singleSatCorrClass, "getConstellationType", "()I");
+ method_correctionSatId= env->GetMethodID(
+ singleSatCorrClass, "getSatelliteId", "()I");
+ method_correctionSatCarrierFreq = env->GetMethodID(
+ singleSatCorrClass, "getCarrierFrequencyHz", "()F");
+ method_correctionSatIsLosProb = env->GetMethodID(
+ singleSatCorrClass,"getProbabilityLineOfSight", "()F");
+ method_correctionSatEpl = env->GetMethodID(
+ singleSatCorrClass, "getExcessPathLengthMeters", "()F");
+ method_correctionSatEplUnc = env->GetMethodID(
+ singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
+ method_correctionSatRefPlane = env->GetMethodID(
+ singleSatCorrClass, "getReflectingPlane", "()Landroid/location/GnssReflectingPlane;");
+
+ jclass refPlaneClass = env->FindClass("android/location/GnssReflectingPlane");
+ method_correctionPlaneLatDeg = env->GetMethodID(refPlaneClass, "getLatitudeDegrees", "()D");
+ method_correctionPlaneLngDeg = env->GetMethodID(refPlaneClass, "getLongitudeDegrees", "()D");
+ method_correctionPlaneAltDeg = env->GetMethodID(refPlaneClass, "getAltitudeMeters", "()D");
+ method_correctionPlaneAzimDeg = env->GetMethodID(refPlaneClass, "getAzimuthDegrees", "()D");
+
/*
* Save a pointer to JVM.
*/
@@ -2341,29 +2386,6 @@
ALOGW("Trying to inject GNSS corrections on a chipset that does not support them.");
return JNI_FALSE;
}
- if (firstGnssMeasurementCorrectionInjected == false) {
- jclass measCorrClass = env->GetObjectClass(correctionsObj);
- method_correctionsGetLatitudeDegrees = env->GetMethodID(
- measCorrClass,"getLatitudeDegrees", "()D");
-
- method_correctionsGetLongitudeDegrees = env->GetMethodID(
- measCorrClass, "getLongitudeDegrees", "()D");
-
- method_correctionsGetAltitudeMeters = env->GetMethodID(
- measCorrClass, "getAltitudeMeters", "()D");
-
- method_correctionsGetHorPosUncMeters = env->GetMethodID(
- measCorrClass, "getHorizontalPositionUncertaintyMeters", "()D");
-
- method_correctionsGetVerPosUncMeters = env->GetMethodID(
- measCorrClass, "getVerticalPositionUncertaintyMeters", "()D");
-
- method_correctionsGetToaGpsNanosecondsOfWeek = env->GetMethodID(
- measCorrClass, "getToaGpsNanosecondsOfWeek", "()J");
-
- method_correctionsGetSingleSatCorrectionList = env->GetMethodID(
- measCorrClass, "getSingleSatelliteCorrectionList", "()Ljava.util.List;");
- }
jdouble latitudeDegreesCorr = env->CallDoubleMethod(
correctionsObj, method_correctionsGetLatitudeDegrees);
@@ -2380,42 +2402,18 @@
jobject singleSatCorrectionList = env->CallObjectMethod(correctionsObj,
method_correctionsGetSingleSatCorrectionList);
- if (firstGnssMeasurementCorrectionInjected == false) {
- jclass corrListClass = env->GetObjectClass(singleSatCorrectionList);
- method_listSize = env->GetMethodID(corrListClass, "size", "()I");
- method_correctionListGet = env->GetMethodID(
- corrListClass, "get", "(I)Landroid/location/GnssSingleSatCorrection;");
- }
-
auto len = (singleSatCorrectionList == nullptr)
? 0
: env->CallIntMethod(singleSatCorrectionList, method_listSize);
+ if (len == 0) {
+ ALOGI("Empty correction list injected....Returning with no HAL injection");
+ return JNI_TRUE;
+ }
hidl_vec<SingleSatCorrection> list(len);
for (uint16_t i = 0; i < len; ++i) {
jobject singleSatCorrectionObj = env->CallObjectMethod(
- singleSatCorrectionList, method_correctionListGet, i);
-
- if (firstGnssMeasurementCorrectionInjected == false) {
- jclass singleSatCorrClass = env->GetObjectClass(singleSatCorrectionObj);
- method_correctionSatFlags = env->GetMethodID(
- singleSatCorrClass, "getSingleSatelliteCorrectionFlags", "()I");
- method_correctionSatConstType = env->GetMethodID(
- singleSatCorrClass, "getConstellationType", "()I");
- method_correctionSatId= env->GetMethodID(
- singleSatCorrClass, "getSatelliteId", "()I");
- method_correctionSatCarrierFreq = env->GetMethodID(
- singleSatCorrClass, "getCarrierFrequencyHz", "()F");
- method_correctionSatIsLosProb = env->GetMethodID(
- singleSatCorrClass,"getProbabilityLineOfSight", "()F");
- method_correctionSatEpl = env->GetMethodID(
- singleSatCorrClass, "getExcessPathLengthMeters", "()F");
- method_correctionSatEplUnc = env->GetMethodID(
- singleSatCorrClass, "getExcessPathLengthUncertaintyMeters", "()F");
- method_correctionSatRefPlane = env->GetMethodID(
- singleSatCorrClass, "getReflectingPlane",
- "()Landroid/location/GnssReflectingPlane;");
- }
+ singleSatCorrectionList, method_correctionListGet, i);
jint correctionFlags =
env->CallIntMethod(singleSatCorrectionObj, method_correctionSatFlags);
@@ -2431,38 +2429,34 @@
env->CallFloatMethod(singleSatCorrectionObj, method_correctionSatEpl);
jfloat eplUncMeters = env->CallFloatMethod(singleSatCorrectionObj,
method_correctionSatEplUnc);
- jobject reflectingPlaneObj = env->CallObjectMethod(
- singleSatCorrectionObj, method_correctionSatRefPlane);
-
- if (firstGnssMeasurementCorrectionInjected == false) {
- jclass refPlaneClass = env->GetObjectClass(reflectingPlaneObj);
- method_correctionPlaneLatDeg = env->GetMethodID(
- refPlaneClass, "getLatitudeDegrees", "()D");
- method_correctionPlaneLngDeg = env->GetMethodID(
- refPlaneClass, "getLongitudeDegrees", "()D");
- method_correctionPlaneAltDeg = env->GetMethodID(
- refPlaneClass, "getAltitudeMeters", "()D");
- method_correctionPlaneAzimDeg = env->GetMethodID(
- refPlaneClass, "getAzimuthDegrees", "()D");
+ uint16_t corrFlags = static_cast<uint16_t>(correctionFlags);
+ jobject reflectingPlaneObj;
+ bool has_ref_plane = (corrFlags & GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE) != 0;
+ if (has_ref_plane) {
+ reflectingPlaneObj = env->CallObjectMethod(
+ singleSatCorrectionObj, method_correctionSatRefPlane);
}
- jdouble latitudeDegreesRefPlane = env->CallDoubleMethod(
- reflectingPlaneObj, method_correctionPlaneLatDeg);
- jdouble longitudeDegreesRefPlane = env->CallDoubleMethod(
- reflectingPlaneObj, method_correctionPlaneLngDeg);
- jdouble altitudeDegreesRefPlane = env->CallDoubleMethod(
- reflectingPlaneObj, method_correctionPlaneAltDeg);
- jdouble azimuthDegreeRefPlane = env->CallDoubleMethod(
- reflectingPlaneObj, method_correctionPlaneAzimDeg);
- ReflectingPlane reflectingPlane = {
- .latitudeDegrees = latitudeDegreesRefPlane,
- .longitudeDegrees = longitudeDegreesRefPlane,
- .altitudeMeters = altitudeDegreesRefPlane,
- .azimuthDegrees = azimuthDegreeRefPlane,
- };
+ ReflectingPlane reflectingPlane;
+ if (has_ref_plane) {
+ jdouble latitudeDegreesRefPlane = env->CallDoubleMethod(
+ reflectingPlaneObj, method_correctionPlaneLatDeg);
+ jdouble longitudeDegreesRefPlane = env->CallDoubleMethod(
+ reflectingPlaneObj, method_correctionPlaneLngDeg);
+ jdouble altitudeDegreesRefPlane = env->CallDoubleMethod(
+ reflectingPlaneObj, method_correctionPlaneAltDeg);
+ jdouble azimuthDegreeRefPlane = env->CallDoubleMethod(
+ reflectingPlaneObj, method_correctionPlaneAzimDeg);
+ reflectingPlane = {
+ .latitudeDegrees = latitudeDegreesRefPlane,
+ .longitudeDegrees = longitudeDegreesRefPlane,
+ .altitudeMeters = altitudeDegreesRefPlane,
+ .azimuthDegrees = azimuthDegreeRefPlane,
+ };
+ }
SingleSatCorrection singleSatCorrection = {
- .singleSatCorrectionFlags = static_cast<uint16_t>(correctionFlags),
+ .singleSatCorrectionFlags = corrFlags,
.constellation = static_cast<GnssConstellationType>(constType),
.svid = static_cast<uint16_t>(satId),
.carrierFrequencyHz = carrierFreqHz,
@@ -2484,7 +2478,6 @@
};
gnssCorrectionsIface->setCorrections(measurementCorrections);
- firstGnssMeasurementCorrectionInjected = true;
return JNI_TRUE;
}
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index e36586e..2077ecb 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -36,6 +36,7 @@
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.Context;
+import android.content.LocusId;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.Callback;
import android.content.pm.ShortcutInfo;
@@ -369,6 +370,10 @@
return ret;
}
+ public static LocusId locusId(String id) {
+ return new LocusId(id);
+ }
+
public static void resetAll(Collection<?> mocks) {
for (Object o : mocks) {
reset(o);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 5d07888..dc307b5 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -47,6 +47,7 @@
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.service.voice.IVoiceInteractionSession;
+import android.util.DisplayMetrics;
import android.util.Xml;
import android.view.DisplayInfo;
@@ -166,6 +167,44 @@
WINDOWING_MODE_FREEFORM, mParentBounds, insetBounds, insetBounds);
}
+ @Test
+ public void testFitWithinBounds() {
+ final Rect parentBounds = new Rect(10, 10, 200, 200);
+ ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay();
+ ActivityStack stack = display.createStack(WINDOWING_MODE_FREEFORM, ACTIVITY_TYPE_STANDARD,
+ true /* onTop */);
+ TaskRecord task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Configuration parentConfig = stack.getConfiguration();
+ parentConfig.windowConfiguration.setBounds(parentBounds);
+ parentConfig.densityDpi = DisplayMetrics.DENSITY_DEFAULT;
+
+ // check top and left
+ Rect reqBounds = new Rect(-190, -190, 0, 0);
+ task.setBounds(reqBounds);
+ // Make sure part of it is exposed
+ assertTrue(task.getBounds().right > parentBounds.left);
+ assertTrue(task.getBounds().bottom > parentBounds.top);
+ // Should still be more-or-less in that corner
+ assertTrue(task.getBounds().left <= parentBounds.left);
+ assertTrue(task.getBounds().top <= parentBounds.top);
+
+ assertEquals(reqBounds.width(), task.getBounds().width());
+ assertEquals(reqBounds.height(), task.getBounds().height());
+
+ // check bottom and right
+ reqBounds = new Rect(210, 210, 400, 400);
+ task.setBounds(reqBounds);
+ // Make sure part of it is exposed
+ assertTrue(task.getBounds().left < parentBounds.right);
+ assertTrue(task.getBounds().top < parentBounds.bottom);
+ // Should still be more-or-less in that corner
+ assertTrue(task.getBounds().right >= parentBounds.right);
+ assertTrue(task.getBounds().bottom >= parentBounds.bottom);
+
+ assertEquals(reqBounds.width(), task.getBounds().width());
+ assertEquals(reqBounds.height(), task.getBounds().height());
+ }
+
/** Tests that the task bounds adjust properly to changes between FULLSCREEN and FREEFORM */
@Test
public void testBoundsOnModeChangeFreeformToFullscreen() {
diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java
index d98f37d..b9d8eb6 100644
--- a/telephony/java/android/telephony/LocationAccessPolicy.java
+++ b/telephony/java/android/telephony/LocationAccessPolicy.java
@@ -174,22 +174,22 @@
boolean hasManifestPermission = checkManifestPermission(context, query.callingPid,
query.callingUid, permissionToCheck);
- int appOpMode = context.getSystemService(AppOpsManager.class)
- .noteOpNoThrow(AppOpsManager.permissionToOpCode(permissionToCheck),
- query.callingUid, query.callingPackage);
-
- if (hasManifestPermission && appOpMode == AppOpsManager.MODE_ALLOWED) {
- // If the app did everything right, return without logging.
- return LocationPermissionResult.ALLOWED;
- }
-
- // If the app has the manifest permission but not the app-op permission, it means that
- // it's aware of the requirement and the user denied permission explicitly. If we see
- // this, don't let any of the overrides happen.
if (hasManifestPermission) {
- Log.i(TAG, query.callingPackage + " is aware of " + locationTypeForLog + " but the"
- + " app-ops permission is specifically denied.");
- return appOpsModeToPermissionResult(appOpMode);
+ // Only check the app op if the app has the permission.
+ int appOpMode = context.getSystemService(AppOpsManager.class)
+ .noteOpNoThrow(AppOpsManager.permissionToOpCode(permissionToCheck),
+ query.callingUid, query.callingPackage);
+ if (appOpMode == AppOpsManager.MODE_ALLOWED) {
+ // If the app did everything right, return without logging.
+ return LocationPermissionResult.ALLOWED;
+ } else {
+ // If the app has the manifest permission but not the app-op permission, it means
+ // that it's aware of the requirement and the user denied permission explicitly.
+ // If we see this, don't let any of the overrides happen.
+ Log.i(TAG, query.callingPackage + " is aware of " + locationTypeForLog + " but the"
+ + " app-ops permission is specifically denied.");
+ return appOpsModeToPermissionResult(appOpMode);
+ }
}
int minSdkVersion = Manifest.permission.ACCESS_FINE_LOCATION.equals(permissionToCheck)
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 5fd36f4..918bf60 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -292,17 +292,16 @@
public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000;
/**
- * Listen for changes to active data subId. Active data subscription
- * is whichever is being used for Internet data. For most of the case, it's
- * default data subscription but it could be others. For example, when data is
- * switched to opportunistic subscription, that becomes the active data sub.
+ * Listen for changes to active data subId. Active data subscription is
+ * the current subscription used to setup Cellular Internet data. For example,
+ * it could be the current active opportunistic subscription in use, or the
+ * subscription user selected as default data subscription in DSDS mode.
*
* Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
* READ_PHONE_STATE}
- * @see #onActiveDataSubIdChanged
- * @hide
+ * @see #onActiveDataSubscriptionIdChanged
*/
- public static final int LISTEN_ACTIVE_DATA_SUBID_CHANGE = 0x00400000;
+ public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000;
/**
* Listen for changes to the radio power state.
@@ -709,12 +708,11 @@
/**
* Callback invoked when active data subId changes. Requires
* the READ_PHONE_STATE permission.
- * @param subId current data subId used for Internet data. It will be default data subscription
- * most cases. And it could be other subscriptions for example opportunistic
- * subscription if data is switched onto it.
- * @hide
+ * @param subId current subscription used to setup Cellular Internet data.
+ * For example, it could be the current active opportunistic subscription in use,
+ * or the subscription user selected as default data subscription in DSDS mode.
*/
- public void onActiveDataSubIdChanged(int subId) {
+ public void onActiveDataSubscriptionIdChanged(int subId) {
// default implementation empty
}
@@ -1003,7 +1001,7 @@
if (psl == null) return;
Binder.withCleanCallingIdentity(
- () -> mExecutor.execute(() -> psl.onActiveDataSubIdChanged(subId)));
+ () -> mExecutor.execute(() -> psl.onActiveDataSubscriptionIdChanged(subId)));
}
public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) {
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index c516d97..480c9d9 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -214,7 +214,7 @@
* @see android.telephony#CellSignalStrengthCdma
* @see android.telephony#CellSignalStrengthGsm
*/
- public @NonNull List<CellSignalStrength> getCellSignalStrengths() {
+ @NonNull public List<CellSignalStrength> getCellSignalStrengths() {
return getCellSignalStrengths(CellSignalStrength.class);
}
@@ -240,7 +240,7 @@
* @see android.telephony#CellSignalStrengthCdma
* @see android.telephony#CellSignalStrengthGsm
*/
- public <T extends CellSignalStrength> @NonNull List<T> getCellSignalStrengths(
+ @NonNull public <T extends CellSignalStrength> List<T> getCellSignalStrengths(
@NonNull Class<T> clazz) {
List<T> cssList = new ArrayList<>(2); // Usually have 2 or fewer elems
if (mLte.isValid() && clazz.isAssignableFrom(CellSignalStrengthLte.class)) {
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index ac4d17a..bdaad5b 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -86,7 +86,8 @@
* @param message an optional message to detail the error condition more specifically.
* @param cause the {@link Throwable} that caused this {@link ImsException} to be created.
*/
- public ImsException(@Nullable String message, @ImsErrorCode int code, Throwable cause) {
+ public ImsException(@Nullable String message, @ImsErrorCode int code,
+ @Nullable Throwable cause) {
super(getMessage(message, code), cause);
mCode = code;
}
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index a58f361..37b11ed 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -17,6 +17,8 @@
package android.telephony.ims;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.Uri;
import android.os.Parcel;
@@ -124,9 +126,9 @@
* @param callType The type of external call.
* @param isCallheld A flag determining if the external connection is currently held.
*/
- public ImsExternalCallState(String callId, Uri address, Uri localAddress,
- boolean isPullable, @ExternalCallState int callState, @ExternalCallType int callType,
- boolean isCallheld) {
+ public ImsExternalCallState(@NonNull String callId, @NonNull Uri address,
+ @Nullable Uri localAddress, boolean isPullable, @ExternalCallState int callState,
+ @ExternalCallType int callType, boolean isCallheld) {
mCallId = getIdForString(callId);
mAddress = address;
mLocalAddress = localAddress;
@@ -184,14 +186,14 @@
return mCallId;
}
- public Uri getAddress() {
+ public @NonNull Uri getAddress() {
return mAddress;
}
/**
* @return A {@link Uri} containing the local address from the Multiendpoint Dialog Information.
*/
- public Uri getLocalAddress() {
+ public @Nullable Uri getLocalAddress() {
return mLocalAddress;
}
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index bb85be1..58ddf21 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -21,6 +21,7 @@
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
@@ -199,7 +200,7 @@
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
- public void onUnregistered(ImsReasonInfo info) {
+ public void onUnregistered(@Nullable ImsReasonInfo info) {
}
/**
@@ -211,7 +212,7 @@
* transport type that has failed to handover registration to.
* @param info A {@link ImsReasonInfo} that identifies the reason for failure.
*/
- public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
+ public void onTechnologyChangeFailed(int imsTransportType, @Nullable ImsReasonInfo info) {
}
/**
@@ -223,7 +224,7 @@
* subscription.
* @hide
*/
- public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+ public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
}
/**@hide*/
@@ -294,7 +295,7 @@
* @param capabilities The new availability of the capabilities.
*/
public void onCapabilitiesStatusChanged(
- MmTelFeature.MmTelCapabilities capabilities) {
+ @NonNull MmTelFeature.MmTelCapabilities capabilities) {
}
/**@hide*/
@@ -319,7 +320,7 @@
* @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
* @throws IllegalArgumentException if the subscription is invalid.
*/
- public static ImsMmTelManager createForSubscriptionId(int subId) {
+ public static @NonNull ImsMmTelManager createForSubscriptionId(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid subscription ID");
}
@@ -357,7 +358,7 @@
* reason.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void registerImsRegistrationCallback(@CallbackExecutor Executor executor,
+ public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull RegistrationCallback c) throws ImsException {
if (c == null) {
throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 6e98a0a..9104d9f 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.WorkerThread;
@@ -177,7 +178,7 @@
* @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
* @throws IllegalArgumentException if the subscription is invalid.
*/
- public static ProvisioningManager createForSubscriptionId(int subId) {
+ public static @NonNull ProvisioningManager createForSubscriptionId(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid subscription ID");
}
@@ -206,7 +207,7 @@
* reason.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void registerProvisioningChangedCallback(@CallbackExecutor Executor executor,
+ public void registerProvisioningChangedCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull Callback callback) throws ImsException {
callback.setExecutor(executor);
try {
@@ -271,7 +272,7 @@
*/
@WorkerThread
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public String getProvisioningStringValue(int key) {
+ public @Nullable String getProvisioningStringValue(int key) {
try {
return getITelephony().getImsProvisioningString(mSubId, key);
} catch (RemoteException e) {
@@ -313,7 +314,7 @@
@WorkerThread
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public @ImsConfigImplBase.SetConfigResult int setProvisioningStringValue(int key,
- String value) {
+ @NonNull String value) {
try {
return getITelephony().setImsProvisioningString(mSubId, key, value);
} catch (RemoteException e) {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 8aef7a2..1a5cd5a 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -824,7 +824,7 @@
* {@link NetworkSpecifierBuilder#setPeerHandle(PeerHandle)} to specify the peer to which the
* connection is created.
*/
- public static class NetworkSpecifierBuilder {
+ public static final class NetworkSpecifierBuilder {
private DiscoverySession mDiscoverySession;
private PeerHandle mPeerHandle;
private String mPskPassphrase;