diff options
157 files changed, 4470 insertions, 1396 deletions
diff --git a/Android.bp b/Android.bp index 9077344adf21..fb6ff0fb6dbc 100644 --- a/Android.bp +++ b/Android.bp @@ -1121,6 +1121,7 @@ java_library { "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 e37d4f82ad9b..92f51290f919 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5266,6 +5266,7 @@ package android.app { 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 @@ package android.app { 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 @@ package android.content.pm { 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 @@ package android.content.pm { 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 @@ package android.location { 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 @@ package android.location { } 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 @@ package android.media { } 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 @@ package android.media { 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 @@ package android.net.wifi.aware { 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 @@ package android.service.notification { 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(); @@ -44435,10 +44418,10 @@ package android.telephony { } public final class CellIdentityNr extends android.telephony.CellIdentity { - method public int getChannelNumber(); method public String getMccString(); method public String getMncString(); method public long getNci(); + method public int getNrarfcn(); method public int getPci(); method public int getTac(); method public void writeToParcel(android.os.Parcel, int); @@ -44786,6 +44769,7 @@ package android.telephony { 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 @@ package android.telephony { 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 @@ package android.telephony { 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 fdfaf91096a0..7a06803053e8 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -282,12 +282,38 @@ package android.hardware { 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 c9dca26021c4..951926d2437d 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -474,7 +474,7 @@ package android.app { 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 @@ package android.location { 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 @@ 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 @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 @@ package android.net.wifi.aware { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.provider { 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 @@ package android.provider { } 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 @@ package android.provider { 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 @@ package android.security.keystore.recovery { 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 @@ package android.security.keystore.recovery { 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 @@ package android.telephony.ims { 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 @@ package android.telephony.ims { } 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 @@ package android.telephony.ims { } 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 @@ package android.telephony.ims { 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 @@ package android.telephony.ims { 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 @@ package android.telephony.ims { } 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 22a3fb39d2f6..7e044698c72c 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -60,6 +60,17 @@ package android.content { } +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 e270f422b7ee..659696ae0b97 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -563,11 +563,13 @@ package android.content { 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 @@ package android.location { } 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 @@ package android.location { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.os { 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 @@ package android.provider { } 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 @@ package android.provider { 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 831cac261d34..e57327991a82 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -36,6 +36,7 @@ import android.view.ViewDebug; 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 @@ public abstract class ActionBar { @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 d1d4bd56f1c7..56bf8fa8ffce 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -127,6 +127,7 @@ import android.view.autofill.AutofillPopupWindow; 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 @@ public class Activity extends ContextThemeWrapper 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 @@ public class Activity extends ContextThemeWrapper 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 @@ public class Activity extends ContextThemeWrapper 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 08239a1e7ed9..c0a702f28b8d 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3115,10 +3115,6 @@ public final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { if (!r.activity.mFinished && pendingActions != null) { pendingActions.setOldState(r.state); pendingActions.setRestoreInstanceState(true); + } + if (pendingActions != null) { pendingActions.setCallOnPostCreate(true); } } else { @@ -3942,7 +3940,7 @@ public final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { 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 @@ public final class ActivityThread extends ClientTransactionHandler { 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 062a462b71fd..161e2ad06ec0 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -61,7 +61,7 @@ public class BroadcastOptions { "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 @@ public class BroadcastOptions { * 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 f690f5d4a88e..03806faaeaa8 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -31,6 +31,7 @@ import android.annotation.SystemApi; 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.Gravity; 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 @@ public class Notification implements Parcelable private long mTimeout; private String mShortcutId; + private LocusId mLocusId; private CharSequence mSettingsText; private BubbleMetadata mBubbleMetadata; @@ -2274,6 +2277,10 @@ public class Notification implements Parcelable mShortcutId = parcel.readString(); } + if (parcel.readInt() != 0) { + mLocusId = LocusId.CREATOR.createFromParcel(parcel); + } + mBadgeIcon = parcel.readInt(); if (parcel.readInt() != 0) { @@ -2397,6 +2404,7 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable } /** + * 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 0d25f4d5fe24..f59bc9891c86 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 @@ public final class AutofillOptions implements Parcelable { /** * 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 @@ public final class AutofillOptions implements Parcelable { } /** + * 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 @@ public final class AutofillOptions implements Parcelable { 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 @@ public final class AutofillOptions implements Parcelable { @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 final class AutofillOptions implements Parcelable { 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 @@ public final class AutofillOptions implements Parcelable { 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 beb1fb68d218..4199528893e6 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -69,6 +69,7 @@ import android.view.View; 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 @@ public abstract class Context { /** * @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 d5273dba2cc2..7b61807f9684 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -22,11 +22,13 @@ import android.annotation.SystemApi; 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.os.UserHandle; 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 @@ public final class ShortcutInfo implements Parcelable { @Nullable private Person[] mPersons; + @Nullable + private LocusId mLocusId; + private int mRank; /** @@ -415,6 +421,8 @@ public final class ShortcutInfo implements Parcelable { } mRank = b.mRank; mExtras = b.mExtras; + mLocusId = b.mLocusId; + updateTimestamp(); } @@ -521,6 +529,7 @@ public final class ShortcutInfo implements Parcelable { 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 @@ public final class ShortcutInfo implements Parcelable { if (source.mExtras != null) { mExtras = source.mExtras; } + + if (source.mLocusId != null) { + mLocusId = source.mLocusId; + } } /** @@ -941,6 +954,8 @@ public final class ShortcutInfo implements Parcelable { private PersistableBundle mExtras; + private LocusId mLocusId; + /** * Old style constructor. * @hide @@ -973,6 +988,19 @@ public final class ShortcutInfo implements Parcelable { } /** + * 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 @@ public final class ShortcutInfo implements Parcelable { } /** + * 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 @@ public final class ShortcutInfo implements Parcelable { } mPersons = source.readParcelableArray(cl, Person.class); + mLocusId = source.readParcelable(cl); } @Override @@ -2048,6 +2088,7 @@ public final class ShortcutInfo implements Parcelable { } dest.writeParcelableArray(mPersons, flags); + dest.writeParcelable(mLocusId, flags); } public static final @android.annotation.NonNull Creator<ShortcutInfo> CREATOR = @@ -2263,6 +2304,10 @@ public final class ShortcutInfo implements Parcelable { 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 @@ public final class ShortcutInfo implements Parcelable { 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 @@ public final class ShortcutInfo implements Parcelable { 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 55b340f267a6..139a5ee09dd8 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -286,14 +286,15 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan * @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 9609e99275c9..5043d4ce86df 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -98,7 +98,7 @@ interface IFaceService { // 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 0ec63b5815f1..2c453bfc4d42 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 @@ public class HwBlob { * @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 7919a00166bf..dc640c95b515 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 @@ public class HwParcel { * * @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 @@ public class HwParcel { 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 @@ public class HwParcel { * 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 @@ public class HwParcel { * @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 @@ public class HwParcel { * @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 @@ public class HwParcel { * @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 f13bf5fccd38..8d341b603eb4 100644 --- a/core/java/android/os/NativeHandle.java +++ b/core/java/android/os/NativeHandle.java @@ -99,6 +99,8 @@ public final class NativeHandle implements Closeable { * @return a boolean value */ public boolean hasSingleFileDescriptor() { + checkOpen(); + return mFds.length == 1 && mInts.length == 0; } @@ -108,7 +110,7 @@ public final class NativeHandle implements Closeable { * 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 @@ public final class NativeHandle implements Closeable { 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 @@ public final class NativeHandle implements Closeable { */ @Override public void close() throws java.io.IOException { - if (!mOwn) { - return; - } - - try { - for (FileDescriptor fd : mFds) { - Os.close(fd); + checkOpen(); + + 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 @@ public final class NativeHandle implements Closeable { * @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 @@ public final class NativeHandle implements Closeable { * @hide */ private int[] getFdsAsIntArray() { + checkOpen(); + int numFds = mFds.length; int[] fds = new int[numFds]; @@ -182,11 +195,13 @@ public final class NativeHandle implements Closeable { } /** - * Fetch file descriptors. + * Fetch file descriptors * * @return the fds. */ - public FileDescriptor[] getFileDescriptors() { + public @NonNull FileDescriptor[] getFileDescriptors() { + checkOpen(); + return mFds; } @@ -195,7 +210,9 @@ public final class NativeHandle implements Closeable { * * @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 7f73dab82d88..42633778a321 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -2705,7 +2705,7 @@ public class UserManager { */ @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 @@ public class UserManager { */ @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 @@ public class UserManager { */ @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 5d4539cb62af..ba54bd25dbb2 100644 --- a/core/java/android/provider/DeviceConfig.java +++ b/core/java/android/provider/DeviceConfig.java @@ -33,10 +33,12 @@ import android.provider.Settings.ResetMode; 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 final class DeviceConfig { 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 @@ public final class DeviceConfig { 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 @@ public final class DeviceConfig { * @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 f2bb87dc18b6..7a16742c651f 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10684,7 +10684,7 @@ public final class Settings { /** * 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 @@ public final class Settings { * 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 final class Settings { */ 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 8f6b6ec13c50..8801217f9ebe 100644 --- a/core/java/android/security/keystore/recovery/KeyChainProtectionParams.java +++ b/core/java/android/security/keystore/recovery/KeyChainProtectionParams.java @@ -165,7 +165,7 @@ public final class KeyChainProtectionParams implements Parcelable { * @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 @@ public final class KeyChainProtectionParams implements Parcelable { * @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 @@ public final class KeyChainProtectionParams implements Parcelable { * @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 @@ public final class KeyChainProtectionParams implements Parcelable { * @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 @@ public final class KeyChainProtectionParams implements Parcelable { * @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 @@ public final class KeyChainProtectionParams implements Parcelable { 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 18517aaf84bf..2f584717ec6f 100644 --- a/core/java/android/security/keystore/recovery/KeyChainSnapshot.java +++ b/core/java/android/security/keystore/recovery/KeyChainSnapshot.java @@ -147,7 +147,7 @@ public final class KeyChainSnapshot implements Parcelable { 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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 @@ public final class KeyChainSnapshot implements Parcelable { * @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 6d1533ecb6f4..d036d144aaa1 100644 --- a/core/java/android/security/keystore/recovery/KeyDerivationParams.java +++ b/core/java/android/security/keystore/recovery/KeyDerivationParams.java @@ -140,7 +140,7 @@ public final class KeyDerivationParams implements Parcelable { 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 04e965f062de..51bd2ae0d066 100644 --- a/core/java/android/security/keystore/recovery/RecoveryCertPath.java +++ b/core/java/android/security/keystore/recovery/RecoveryCertPath.java @@ -74,7 +74,7 @@ public final class RecoveryCertPath implements Parcelable { 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 a88aa8cb4401..cc3e57859b64 100644 --- a/core/java/android/security/keystore/recovery/RecoveryController.java +++ b/core/java/android/security/keystore/recovery/RecoveryController.java @@ -283,6 +283,7 @@ public class RecoveryController { */ @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 2b2438ad2e11..3e595e0ce859 100644 --- a/core/java/android/security/keystore/recovery/RecoverySession.java +++ b/core/java/android/security/keystore/recovery/RecoverySession.java @@ -193,7 +193,7 @@ public class RecoverySession implements AutoCloseable { * * @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 c6e62726ae60..665c937591a3 100644 --- a/core/java/android/security/keystore/recovery/WrappedApplicationKey.java +++ b/core/java/android/security/keystore/recovery/WrappedApplicationKey.java @@ -72,7 +72,7 @@ public final class WrappedApplicationKey implements Parcelable { * @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 @@ public final class WrappedApplicationKey implements Parcelable { * @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 @@ public final class WrappedApplicationKey implements Parcelable { * @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 @@ public final class WrappedApplicationKey implements Parcelable { * @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 @@ public final class WrappedApplicationKey implements Parcelable { 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 7ef40cd20895..96949985cb84 100644 --- a/core/java/android/service/notification/ZenPolicy.java +++ b/core/java/android/service/notification/ZenPolicy.java @@ -358,7 +358,7 @@ public final class ZenPolicy implements Parcelable { * 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 436cb4ff7072..e2af6f5ed102 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 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @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 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @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 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @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 @@ public final class ArrayMap<K, V> implements Map<K, V> { * @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 43786f7489b5..b99336bb0dbf 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -39,6 +39,8 @@ public class FeatureFlagUtils { 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 @@ public class FeatureFlagUtils { 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 @@ public class FeatureFlagUtils { 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 cf49803a7225..e4de7045721b 100644 --- a/core/java/android/util/LongSparseArray.java +++ b/core/java/android/util/LongSparseArray.java @@ -21,9 +21,6 @@ import com.android.internal.util.GrowingArrayUtils; 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 @@ public class LongSparseArray<E> implements Cloneable { * 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 @@ public class LongSparseArray<E> implements Cloneable { * 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 @@ public class LongSparseArray<E> implements Cloneable { */ @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 @@ public class LongSparseArray<E> implements Cloneable { * 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 8dcdb4026246..f167f009a942 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 @@ public class LongSparseLongArray implements Cloneable { * 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 @@ public class LongSparseLongArray implements Cloneable { * 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 89ea2d35fc2f..67dfb02a0b95 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 @@ public class SparseArray<E> implements Cloneable { * 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 @@ public class SparseArray<E> implements Cloneable { * 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 @@ public class SparseArray<E> implements Cloneable { */ @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 @@ public class SparseArray<E> implements Cloneable { * <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 d4c40954bdd1..03fa1c996027 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 @@ public class SparseBooleanArray implements Cloneable { * 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 @@ public class SparseBooleanArray implements Cloneable { * 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 @@ public class SparseBooleanArray implements Cloneable { * 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 9e6bad1d9ae0..c68dc4edcfb7 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 @@ public class SparseIntArray implements Cloneable { * 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 @@ public class SparseIntArray implements Cloneable { * 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 @@ public class SparseIntArray implements Cloneable { * 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 81db2b7ff715..37a92024f374 100644 --- a/core/java/android/util/SparseLongArray.java +++ b/core/java/android/util/SparseLongArray.java @@ -182,6 +182,10 @@ public class SparseLongArray implements Cloneable { * 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 @@ public class SparseLongArray implements Cloneable { * 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 874be814ed9a..287365f70344 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -9530,8 +9530,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // 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 f2474a58b176..4dc20d4fad6d 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -7845,6 +7845,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * to this field. */ @ViewDebug.ExportedProperty(category = "layout") + @InspectableProperty(name = "layout_marginLeft") public int leftMargin; /** @@ -8036,6 +8045,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * to this field. */ @ViewDebug.ExportedProperty(category = "layout") + @InspectableProperty(name = "layout_marginTop") public int topMargin; /** @@ -8044,6 +8054,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * to this field. */ @ViewDebug.ExportedProperty(category = "layout") + @InspectableProperty(name = "layout_marginRight") public int rightMargin; /** @@ -8052,6 +8063,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * 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 885bd2a39580..a3e65496bcd0 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -193,6 +193,15 @@ public final class ContentCaptureManager { 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 6bf1eba30f55..1f0971e7d6c5 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -121,11 +121,11 @@ public abstract class ContentCaptureSession implements AutoCloseable { 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 000000000000..8e0bdf9eaa85 --- /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 2ef8d04939bd..125b0d311511 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 @@ import java.util.StringJoiner; * 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 @@ import java.util.StringJoiner; * @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 @@ public final class TextClassificationConstants { 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 d047c55a5908..868cbb1ce58e 100644 --- a/core/java/android/view/textclassifier/TextClassificationManager.java +++ b/core/java/android/view/textclassifier/TextClassificationManager.java @@ -20,9 +20,11 @@ import android.annotation.NonNull; 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 @@ public final class TextClassificationManager { if (mSettingsObserver != null) { getApplicationContext().getContentResolver() .unregisterContentObserver(mSettingsObserver); + DeviceConfig.removeOnPropertyChangedListener(mSettingsObserver); } } finally { super.finalize(); @@ -277,7 +280,8 @@ public final class TextClassificationManager { } } - 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 @@ public final class TextClassificationManager { 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 4ce0d5d21fd6..e3499f9f961f 100644 --- a/core/java/android/widget/AbsoluteLayout.java +++ b/core/java/android/widget/AbsoluteLayout.java @@ -21,6 +21,7 @@ import android.content.res.TypedArray; 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 @@ public class AbsoluteLayout extends ViewGroup { /** * 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 3570c79430a4..69da9112ca01 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -443,6 +443,9 @@ public class FrameLayout extends ViewGroup { * @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 e833df9d498a..bdde4352d69d 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -1987,6 +1987,7 @@ public class LinearLayout extends ViewGroup { * 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 @@ public class LinearLayout extends ViewGroup { @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 109c0a432c1b..8ee31e212cbf 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -1286,6 +1286,7 @@ public class RelativeLayout extends ViewGroup { * 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 22931fcb3e97..ac23093a0073 100644 --- a/core/java/android/widget/TableRow.java +++ b/core/java/android/widget/TableRow.java @@ -26,6 +26,7 @@ import android.view.View; 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 @@ public class TableRow extends LinearLayout { * <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 67e0446e19e5..fd978f5329a5 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -18,6 +18,11 @@ package com.android.internal.app; 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.OnClickListener; 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 @@ public class ChooserActivity extends ResolverActivity { * {@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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { .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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { @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 @@ public class ChooserActivity extends ResolverActivity { } } - 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 @@ public class ChooserActivity extends ResolverActivity { conn.destroy(); } mServiceConnections.clear(); - mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT); } public void onSetupVoiceInteraction() { @@ -1420,7 +1451,93 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { @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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { } } + 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 @@ public class ChooserActivity extends ResolverActivity { @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 @@ public class ChooserActivity extends ResolverActivity { } 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 @@ public class ChooserActivity extends ResolverActivity { 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 @@ public class ChooserActivity extends ResolverActivity { // 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 @@ public class ChooserActivity extends ResolverActivity { } } + /** + * 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 @@ public class ChooserActivity extends ResolverActivity { // 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 @@ public class ChooserActivity extends ResolverActivity { 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); + + 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)); - 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(); + 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 @@ public class ChooserActivity extends ResolverActivity { } 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 @@ public class ChooserActivity extends ResolverActivity { 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 091991130391..011cc041f0c1 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.ActivityThread; 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 @@ public class ResolverActivity extends Activity { 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 @@ public class ResolverActivity extends Activity { 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 @@ public class ResolverActivity extends Activity { 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 @@ public class ResolverActivity extends Activity { 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 @@ public class ResolverActivity extends Activity { 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 000000000000..eec82bc2403e --- /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 64bdc6e1eb37..f48b56d7af36 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.AccessibilityEvent; 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 @@ public class ViewPager extends ViewGroup { * 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 c1cbd525b4d1..62df6e73deea 100644 --- a/core/proto/android/providers/settings/global.proto +++ b/core/proto/android/providers/settings/global.proto @@ -1043,7 +1043,9 @@ message GlobalSettingsProto { 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 000000000000..0fb26e13fe57 --- /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 cf812603fb89..d4585eb1e6fc 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 02fae4a2c1b3..e9b1bd3af0dc 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 818caa87d4d5..ccd35cd1b634 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 39cbd269c75a..fafd8fe29f8c 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 4e47b1fb6b2a..5b658b7ea0d9 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 3ea9070d9340..e01f4215b7f4 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 c17aa9254808..109cff9a7d57 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 com.android.internal.util.ContrastColorUtil.satisfiesTextContrast; 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 @@ public class NotificationTest { 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 de1453ab5a99..d100f40aa4f7 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.filters.SmallTest; 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 @@ public class DeviceConfigTest { } @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 @@ public class DeviceConfigTest { 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 ad1403db242c..2beff6675f15 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -468,6 +468,7 @@ public class SettingsBackupTest { 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 000000000000..1b3c72452339 --- /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 9fbc1666aed1..3578bc0c911d 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 @@ public class ChooserActivityTest { 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 000000000000..ab6830b106d0 --- /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 fdbc3ddf8c31..3e32c21da23b 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 @@ import java.util.List; 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 @@ public final class GnssMeasurementCorrections implements Parcelable { 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { 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 @@ public final class GnssMeasurementCorrections implements Parcelable { List<GnssSingleSatCorrection> singleSatCorrectionList = new ArrayList<>(); parcel.readTypedList(singleSatCorrectionList, GnssSingleSatCorrection.CREATOR); gnssMeasurementCorrectons.setSingleSatelliteCorrectionList( - singleSatCorrectionList.isEmpty() ? null : singleSatCorrectionList); + singleSatCorrectionList); return gnssMeasurementCorrectons.build(); } @@ -177,7 +195,7 @@ public final class GnssMeasurementCorrections implements Parcelable { } @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 @@ public final class GnssMeasurementCorrections implements Parcelable { 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 @@ public final class GnssMeasurementCorrections implements Parcelable { * 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 c5095d7747e9..9d05287f6b76 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 @@ import android.os.Parcelable; 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 @@ public final class GnssReflectingPlane implements Parcelable { } /** 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 @@ public final class GnssReflectingPlane implements Parcelable { * 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 @@ public final class GnssReflectingPlane implements Parcelable { 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 @@ public final class GnssReflectingPlane implements Parcelable { } @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 final class GnssReflectingPlane implements Parcelable { 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 @@ public final class GnssReflectingPlane implements Parcelable { * 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 dbf3fd9762ea..e9019097e327 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 @@ public final class GnssSingleSatCorrection implements Parcelable { /** * 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * <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 @@ public final class GnssSingleSatCorrection implements Parcelable { 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * <p>Interpretation depends on {@link #getConstellationType()}. See {@link * GnssStatus#getSvid(int)}. */ + @IntRange(from = 0) public int getSatelliteId() { return mSatId; } @@ -154,6 +174,7 @@ public final class GnssSingleSatCorrection implements Parcelable { * * @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 @@ public final class GnssSingleSatCorrection implements Parcelable { * 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * <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 @@ public final class GnssSingleSatCorrection implements Parcelable { 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 @@ public final class GnssSingleSatCorrection implements Parcelable { 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 @@ public final class GnssSingleSatCorrection implements Parcelable { 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 @@ public final class GnssSingleSatCorrection implements Parcelable { 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * 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 @@ public final class GnssSingleSatCorrection implements Parcelable { * 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 @@ public final class GnssSingleSatCorrection implements Parcelable { } /** 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 @@ public final class GnssSingleSatCorrection implements Parcelable { } /** 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 609a15e1be7e..4e37654e7c65 100644 --- a/location/java/android/location/GpsStatus.java +++ b/location/java/android/location/GpsStatus.java @@ -30,6 +30,7 @@ import java.util.NoSuchElementException; * <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 @@ public final class GpsStatus { /** * Used for receiving notifications when GPS status has changed. * @deprecated use {@link GnssStatus.Callback} instead. + * @removed */ @Deprecated public interface Listener { @@ -142,6 +144,7 @@ public final class GpsStatus { * 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 6828c597fe9a..8af153283d70 100644 --- a/location/java/android/location/LocationManager.java +++ b/location/java/android/location/LocationManager.java @@ -44,12 +44,12 @@ import android.os.Process; 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 @@ public class LocationManager { 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 @@ public class LocationManager { "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 @@ public class LocationManager { * @hide */ @TestApi - public String[] getBackgroundThrottlingWhitelist() { + public @NonNull String[] getBackgroundThrottlingWhitelist() { try { return mService.getBackgroundThrottlingWhitelist(); } catch (RemoteException e) { @@ -417,7 +412,7 @@ public class LocationManager { * @hide */ @TestApi - public String[] getIgnoreSettingsWhitelist() { + public @NonNull String[] getIgnoreSettingsWhitelist() { try { return mService.getIgnoreSettingsWhitelist(); } catch (RemoteException e) { @@ -431,7 +426,7 @@ public class LocationManager { * 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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * 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 @@ public class LocationManager { * @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 @@ public class LocationManager { * 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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { @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 @@ public class LocationManager { @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { */ @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * * @hide */ - public void removeAllGeofences(PendingIntent intent) { + public void removeAllGeofences(@NonNull PendingIntent intent) { checkPendingIntent(intent); String packageName = mContext.getPackageName(); @@ -1290,7 +1295,7 @@ public class LocationManager { * @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 @@ public class LocationManager { @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { @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 @@ public class LocationManager { * * @hide */ + @Nullable public Location getLastLocation() { String packageName = mContext.getPackageName(); @@ -1434,7 +1441,8 @@ public class LocationManager { * @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 @@ public class LocationManager { } } - // --- 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 @@ public class LocationManager { * 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 @@ public class LocationManager { * 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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * 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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { // 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 @@ public class LocationManager { 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 @@ public class LocationManager { 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 @@ public class LocationManager { } 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 class LocationManager { 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 @@ public class LocationManager { 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 @@ public class LocationManager { 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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { * Don't use it. Use {@link #registerGnssMeasurementsCallback} instead. * @hide * @deprecated Not supported anymore. + * @removed */ @Deprecated @SystemApi @@ -2083,7 +1971,8 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { } /** - * 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 @@ public class LocationManager { * @hide * @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)} * instead. + * @removed */ @Deprecated @SystemApi @@ -2155,7 +2042,8 @@ public class LocationManager { * * @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 @@ public class LocationManager { * Don't use it. Use {@link #registerGnssNavigationMessageCallback} instead. * @hide * @deprecated Not supported anymore. + * @removed */ @Deprecated @SystemApi @@ -2179,12 +2068,12 @@ public class LocationManager { * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { */ @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 @@ public class LocationManager { * @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 @@ public class LocationManager { * * @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 @@ public class LocationManager { @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 @@ public class LocationManager { */ @SystemApi @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) - public boolean unregisterGnssBatchedLocationCallback(BatchedLocationCallback callback) { + public boolean unregisterGnssBatchedLocationCallback( + @NonNull BatchedLocationCallback callback) { mBatchedLocationCallbackTransport.remove(callback); @@ -2379,7 +2262,8 @@ public class LocationManager { * * @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 @@ public class LocationManager { * @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 @@ public class LocationManager { */ @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 6fd063eb62f0..a05d8501bc1f 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 @@ public final class LocationRequest implements Parcelable { * * @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 @@ public final class LocationRequest implements Parcelable { /** @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 @@ public final class LocationRequest implements Parcelable { * @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 @@ public final class LocationRequest implements Parcelable { * @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 @@ public final class LocationRequest implements Parcelable { * @hide */ @SystemApi - public LocationRequest setLowPowerMode(boolean enabled) { + public @NonNull LocationRequest setLowPowerMode(boolean enabled) { mLowPowerMode = enabled; return this; } @@ -386,7 +391,7 @@ public final class LocationRequest implements Parcelable { * @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 @@ public final class LocationRequest implements Parcelable { * @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 @@ public final class LocationRequest implements Parcelable { * @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 @@ public final class LocationRequest implements Parcelable { * @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 @@ public final class LocationRequest implements Parcelable { * @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 final class LocationRequest implements Parcelable { } } - 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 @@ public final class LocationRequest implements Parcelable { /** @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 @@ public final class LocationRequest implements Parcelable { * @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 aed8e4ede1c4..c2f29bc6e3bc 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -374,9 +374,15 @@ public final class AudioAttributes implements Parcelable { */ 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 @@ public final class AudioAttributes implements Parcelable { } /** + * 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 @@ public final class AudioAttributes implements Parcelable { 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 @@ public final class AudioAttributes implements Parcelable { 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 @@ public final class AudioAttributes implements Parcelable { } 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 3ef0235940b1..03dfd3ee6080 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 @@ public class BarView extends LinearLayout { // 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 409f9ea05889..1ef36a2a75b7 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 @@ public class BarViewInfo implements Comparable<BarViewInfo> { 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 @@ public class BarViewInfo implements Comparable<BarViewInfo> { * @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 @@ public class BarViewInfo implements Comparable<BarViewInfo> { 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 a6b24104fa90..bee1b3cb7df5 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.os.UserHandle; 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 class Tile implements Parcelable { */ 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 class Tile implements Parcelable { */ 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 @@ public class Tile implements Parcelable { if (mSummaryOverride != null) { return mSummaryOverride; } + ensureMetadataNotStale(context); CharSequence summary = null; final PackageManager packageManager = context.getPackageManager(); if (mMetaData != null) { @@ -248,6 +254,7 @@ public class Tile implements Parcelable { 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 @@ public class Tile implements Parcelable { 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 @@ public class Tile implements Parcelable { && 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 @@ public class Tile implements Parcelable { && !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 @@ public class Tile implements Parcelable { 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 3d38837d8964..4fc62bb3937f 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 android.util.Log; 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 @@ public class AccessPoint implements Comparable<AccessPoint> { 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 @@ public class AccessPoint implements Comparable<AccessPoint> { */ private String mFqdn; private String mProviderFriendlyName; + private boolean mIsRoaming = false; private boolean mIsCarrierAp = false; @@ -289,15 +297,12 @@ public class AccessPoint implements Comparable<AccessPoint> { // 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 @@ public class AccessPoint implements Comparable<AccessPoint> { } /** + * Initialize an AccessPoint object for a Passpoint network. + */ + 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. - * Make sure to call setScanResults after constructing with this. */ - public AccessPoint(Context context, OsuProvider 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 @@ public class AccessPoint implements Comparable<AccessPoint> { 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 @@ public class AccessPoint implements Comparable<AccessPoint> { * * <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 @@ public class AccessPoint implements Comparable<AccessPoint> { * 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 @@ public class AccessPoint implements Comparable<AccessPoint> { 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 @@ public class AccessPoint implements Comparable<AccessPoint> { 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 @@ public class AccessPoint implements Comparable<AccessPoint> { } /** - * 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 @@ public class AccessPoint implements Comparable<AccessPoint> { 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 @@ public class AccessPoint implements Comparable<AccessPoint> { 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 class AccessPoint implements Comparable<AccessPoint> { */ 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 @@ public class AccessPoint implements Comparable<AccessPoint> { * * 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 871e2485a742..3c106887641d 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 @@ public class WifiStatusTracker extends ConnectivityManager.NetworkCallback { 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 9ce6b34ecd46..a31d64ce8881 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.GuardedBy; 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 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro 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 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro 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 @@ public class WifiTracker implements LifecycleObserver, OnStart, OnStop, OnDestro } 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 f5ead0c1c55b..06f5fde9c92b 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.WifiEnterpriseConfig; 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 org.mockito.MockitoAnnotations; 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 @@ import java.util.concurrent.CountDownLatch; 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 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { .setActive(true) .setScoredNetworkCache( new ArrayList(Arrays.asList(recentScore))) - .setScanResults(SCAN_RESULTS) + .setScanResults(mScanResults) .build(); when(mockWifiNetworkScoreCache.getScoredNetwork(any(ScanResult.class))) @@ -1151,7 +1169,7 @@ public class AccessPointTest { .setActive(true) .setScoredNetworkCache( new ArrayList(Arrays.asList(recentScore))) - .setScanResults(SCAN_RESULTS) + .setScanResults(mScanResults) .build(); int newSpeed = Speed.MODERATE; @@ -1196,7 +1214,7 @@ public class AccessPointTest { 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 @@ public class AccessPointTest { 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 7d227883b1fe..edf414ddf323 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 @@ public class WifiTrackerTest { 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 491f32dd1185..bfda888c9617 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.android.settingslib.drawer.TileUtils.PROFILE_PRIMARY; 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.Test; 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 @@ public class TileTest { 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 29d57b7bbeef..2b272485dff3 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 @@ public class BarChartInfoTest { final BarViewInfo barViewInfo = new BarViewInfo( null /* icon */, 50, - mTitle); + mTitle, + null); final BarChartInfo mBarChartInfo = new BarChartInfo.Builder() .setTitle(mTitle) @@ -91,7 +92,8 @@ public class BarChartInfoTest { 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 @@ public class BarChartInfoTest { 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 3acca2a7ef75..266554be57d3 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 @@ public class BarChartPreferenceTest { 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 @@ public class BarChartPreferenceTest { // 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 @@ public class BarChartPreferenceTest { .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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { 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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 @@ public class BarChartPreferenceTest { @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 0f8fd9265eaa..f7f34f676230 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 @@ class SettingsProtoDumpUtil { 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 000000000000..7c7268865235 --- /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 000000000000..177b8d204ac8 --- /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 50cf37beb878..a40a14a47744 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 c16c91bd4625..8a95cc4910ad 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.WindowManagerGlobal; 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.Interpolators; 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final ScreenshotHelper mScreenshotHelper; private final ScreenRecordHelper mScreenRecordHelper; + private final Extension<GlobalActionsPanelPlugin> mPanelExtension; + /** * @param context everything needs a context :( */ @@ -204,6 +209,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, | 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, * @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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, 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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, .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 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, .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/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 7bbd3b526892..8714a51f98d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -114,6 +114,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo private final DozeParameters mDozeParameters; private final AlarmTimeout mTimeTicker; private final KeyguardVisibilityCallback mKeyguardVisibilityCallback; + private final Handler mHandler; private final SysuiColorExtractor mColorExtractor; private GradientColors mLockColors; @@ -174,8 +175,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mKeyguardVisibilityCallback = new KeyguardVisibilityCallback(); mKeyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback); mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha); + mHandler = getHandler(); mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout, - "hide_aod_wallpaper", new Handler()); + "hide_aod_wallpaper", mHandler); mWakeLock = createWakeLock(); // Scrim alpha is initially set to the value on the resource but might be changed // to make sure that text on top of it is legible. @@ -253,8 +255,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo mScrimBehind.removeCallbacks(mPendingFrameCallback); mPendingFrameCallback = null; } - if (getHandler().hasCallbacks(mBlankingTransitionRunnable)) { - getHandler().removeCallbacks(mBlankingTransitionRunnable); + if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) { + mHandler.removeCallbacks(mBlankingTransitionRunnable); mBlankingTransitionRunnable = null; } @@ -768,7 +770,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo if (DEBUG) { Log.d(TAG, "Fading out scrims with delay: " + delay); } - getHandler().postDelayed(mBlankingTransitionRunnable, delay); + mHandler.postDelayed(mBlankingTransitionRunnable, delay); }; doOnTheNextFrame(mPendingFrameCallback); } @@ -786,7 +788,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo @VisibleForTesting protected Handler getHandler() { - return Handler.getMain(); + return new Handler(); } public int getBackgroundColor() { @@ -821,8 +823,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo @VisibleForTesting protected WakeLock createWakeLock() { - return new DelayedWakeLock(getHandler(), - WakeLock.createPartial(mContext, "Scrims")); + return new DelayedWakeLock(mHandler, WakeLock.createPartial(mContext, "Scrims")); } @Override @@ -853,12 +854,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo */ public void onScreenTurnedOn() { mScreenOn = true; - final Handler handler = getHandler(); - if (handler.hasCallbacks(mBlankingTransitionRunnable)) { + if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) { if (DEBUG) { Log.d(TAG, "Shorter blanking because screen turned on. All good."); } - handler.removeCallbacks(mBlankingTransitionRunnable); + mHandler.removeCallbacks(mBlankingTransitionRunnable); mBlankingTransitionRunnable.run(); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index f88b64a65e28..6db36243bb07 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -37,12 +37,10 @@ import android.animation.ValueAnimator; import android.app.AlarmManager; import android.graphics.Color; import android.os.Handler; -import android.os.Looper; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.View; -import androidx.test.filters.FlakyTest; import androidx.test.filters.SmallTest; import com.android.internal.colorextraction.ColorExtractor.GradientColors; @@ -78,6 +76,7 @@ public class ScrimControllerTest extends SysuiTestCase { private WakeLock mWakeLock; private boolean mAlwaysOnEnabled; private AlarmManager mAlarmManager; + private TestableLooper mLooper; @Before @@ -88,6 +87,7 @@ public class ScrimControllerTest extends SysuiTestCase { mAlarmManager = mock(AlarmManager.class); mAlwaysOnEnabled = true; mDozeParamenters = mock(DozeParameters.class); + mLooper = TestableLooper.get(this); when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled); when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true); mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront, @@ -253,7 +253,6 @@ public class ScrimControllerTest extends SysuiTestCase { assertScrimTint(mScrimBehind, false /* tinted */); } - @FlakyTest(bugId = 124858892) @Test public void transitionToUnlocked() { mScrimController.setPanelExpansion(0f); @@ -298,7 +297,6 @@ public class ScrimControllerTest extends SysuiTestCase { Assert.assertEquals(mScrimState, ScrimState.BOUNCER_SCRIMMED); } - @FlakyTest(bugId = 124858892) @Test public void panelExpansion() { mScrimController.setPanelExpansion(0f); @@ -321,7 +319,6 @@ public class ScrimControllerTest extends SysuiTestCase { mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f); } - @FlakyTest(bugId = 124858892) @Test public void panelExpansionAffectsAlpha() { mScrimController.setPanelExpansion(0f); @@ -666,7 +663,6 @@ public class ScrimControllerTest extends SysuiTestCase { */ private class SynchronousScrimController extends ScrimController { - private FakeHandler mHandler; private boolean mAnimationCancelled; boolean mOnPreDrawCalled; @@ -676,7 +672,6 @@ public class ScrimControllerTest extends SysuiTestCase { AlarmManager alarmManager) { super(scrimBehind, scrimInFront, scrimStateListener, scrimVisibleListener, dozeParameters, alarmManager); - mHandler = new FakeHandler(Looper.myLooper()); } @Override @@ -688,13 +683,10 @@ public class ScrimControllerTest extends SysuiTestCase { void finishAnimationsImmediately() { boolean[] animationFinished = {false}; setOnAnimationFinished(()-> animationFinished[0] = true); - // Execute code that will trigger animations. onPreDraw(); - - // Force finish screen blanking. - mHandler.dispatchQueuedMessages(); // Force finish all animations. + mLooper.processAllMessages(); endAnimation(mScrimBehind, TAG_KEY_ANIM); endAnimation(mScrimInFront, TAG_KEY_ANIM); @@ -724,7 +716,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Override protected Handler getHandler() { - return mHandler; + return new FakeHandler(mLooper.getLooper()); } @Override diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk index 7ce13c2f59e9..a15e89c8bcdb 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -25,12 +25,15 @@ LOCAL_REQUIRED_MODULES := \ 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 000000000000..a5277fa17be0 --- /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 000000000000..0b69ecaf96fe --- /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 000000000000..74ed9ed91ba0 --- /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 000000000000..6c4e1de30066 --- /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 000000000000..7e363f6a3d72 --- /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 000000000000..e4bc8e6c1274 --- /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 000000000000..c104e3e9971b --- /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 000000000000..e52632974091 --- /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 000000000000..78de832d7110 --- /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 000000000000..11f0b4b630d6 --- /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 000000000000..3834fb66c7cd --- /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 000000000000..f73a9cc4d07a --- /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 000000000000..1c2470e9a63a --- /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 000000000000..d2e5b605b6b0 --- /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 000000000000..0b9f636931c0 --- /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 000000000000..1a2f77800e1b --- /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 000000000000..8910308717dd --- /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 000000000000..1d4c8d7c6479 --- /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 000000000000..a90141df14b3 --- /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 000000000000..d31b6a1b483a --- /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 000000000000..70dc701bde13 --- /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 000000000000..d754cbe9e7c2 --- /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 000000000000..87a954636475 --- /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 000000000000..3834fb66c7cd --- /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 000000000000..614828c40d07 --- /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 000000000000..a8aeaf2692ee --- /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 000000000000..7adfe3b88eb6 --- /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 000000000000..8406f4279f2b --- /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 000000000000..919e93e85e40 --- /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 000000000000..5a143735c4d1 --- /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 000000000000..76f883115628 --- /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 000000000000..6a4e44837155 --- /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 000000000000..08ae89f8535d --- /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 000000000000..842b687d2835 --- /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 000000000000..8950fbdabc78 --- /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 000000000000..30478b340ed2 --- /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 000000000000..72d1d31ae2d1 --- /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 000000000000..f92842a2c87c --- /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 000000000000..511757fd85a8 --- /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 3f33813ff4e7..62deaffd9ea4 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 android.view.autofill.IAutoFillManagerClient; 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 @@ final class AutofillManagerServiceImpl 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 @@ final class AutofillManagerServiceImpl 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 @@ final class AutofillManagerServiceImpl 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 @@ final class AutofillManagerServiceImpl @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 b33259d369a0..955d764797c8 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.service.contentcapture.ContentCaptureService.setClientStat 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 static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUC 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.util.Slog; 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 @@ final class ContentCapturePerUserService * 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 class ContentCapturePerUserService 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 @@ final class ContentCapturePerUserService + " 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 @@ final class ContentCapturePerUserService 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 @@ final class ContentCapturePerUserService @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 @@ final class ContentCapturePerUserService @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 @@ final class ContentCapturePerUserService 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 @@ final class ContentCapturePerUserService 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 0955cc56fe14..1a705828554d 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -259,7 +259,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 d2d14829d597..feeb16b3ea62 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.IBiometricServiceLockoutResetCallback; 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.SystemServerInitThreadPool; 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 @@ public class FaceService extends BiometricServiceBase { } @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; + } + + // 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 result; + return false; } @Override @@ -431,6 +454,15 @@ public class FaceService extends BiometricServiceBase { } } } + + // 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 ee968c87e753..0bc46f190e0b 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 @@ public class LockSettingsService extends ILockSettings.Stub { } 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 8ce2568ac3e2..3c1ee3ece7ad 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 ApexManager.java = dariofreni@google.com, narayan@google.com, toddke@an 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 d9a5eb901344..eced165bf257 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.app.Person; 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 @@ class ShortcutPackage extends ShortcutPackageItem { 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 668fc88b6b58..f9c0db0e9a1d 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 @@ public class ShortcutParser { 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/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index a8e8c7c5c142..1ae85b823fd0 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -2430,17 +2430,17 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final boolean singleTaskInstance = preferredDisplay != null && preferredDisplay.isSingleTaskInstance(); - if (singleTaskInstance) { + if (preferredDisplayId != actualDisplayId) { // Suppress the warning toast if the preferredDisplay was set to singleTask. // The singleTaskInstance displays will only contain one task and any attempt to // launch new task will re-route to the default display. - mService.getTaskChangeNotificationController() - .notifyActivityLaunchOnSecondaryDisplayRerouted(task.getTaskInfo(), - preferredDisplayId); - return; - } + if (singleTaskInstance) { + mService.getTaskChangeNotificationController() + .notifyActivityLaunchOnSecondaryDisplayRerouted(task.getTaskInfo(), + preferredDisplayId); + return; + } - if (preferredDisplayId != actualDisplayId) { Slog.w(TAG, "Failed to put " + task + " on display " + preferredDisplayId); // Display a warning toast that we failed to put a task on a secondary display. mService.getTaskChangeNotificationController() diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java index 1392762fca66..4fd84896e101 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 @@ class TaskRecord extends ConfigurationContainer { // 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 @@ class TaskRecord extends ConfigurationContainer { * * @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 @@ class TaskRecord extends ConfigurationContainer { 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 d5a6f00ff30d..20cca66d8a52 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 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP // 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 298b664beb95..bce3e98c7baa 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 IAGnssCallback_V2_0 = android::hardware::gnss::V2_0::IAGnssCallback; 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_V1_1> gnssMeasurementIface_V1_1 = nullptr; 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 @@ static void android_location_GnssLocationProvider_init_once(JNIEnv* env, jclass "(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 @@ static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measuremen 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 @@ static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measuremen 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 @@ static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measuremen 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 @@ static jboolean android_location_GnssMeasurementsProvider_inject_gnss_measuremen }; 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 e36586eba26c..2077ecb2799e 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 static org.mockito.Mockito.verify; 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 @@ public class ShortcutManagerTestUtils { 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 5d0788881704..dc307b547a63 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.content.res.Configuration; 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 @@ public class TaskRecordTests extends ActivityTestsBase { 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/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index c0444bb17ac7..d680b89f96b6 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1812,17 +1812,32 @@ public class CarrierConfigManager { /** * Determine whether user can change Wi-Fi Calling preference in roaming. - * {@code false} - roaming preference {@link KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT} is - * the same as home preference {@link KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT} - * and cannot be changed. - * {@code true} - roaming preference can be changed by user independently. - * + * {@code false} - roaming preference cannot be changed by user independently. If + * {@link #KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL} is false, + * {@link #KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT} is used as the default + * value. If {@link #KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL} is + * true, roaming preference is the same as home preference and + * {@link #KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT} is used as the default value. + * {@code true} - roaming preference can be changed by user independently if + * {@link #KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL} is false. If + * {@link #KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL} is true, this + * configuration is ignored and roaming preference cannot be changed. * @hide */ public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL = "editable_wfc_roaming_mode_bool"; /** + * Flag specifying whether the carrier will use the WFC home network mode in roaming network. + * {@code false} - roaming preference can be selected separately from the home preference. + * {@code true} - roaming preference is the same as home preference and + * {@link #KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT} is used as the default value. + * @hide + */ + public static final String KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL = + "use_wfc_home_network_mode_in_roaming_network_bool"; + + /** * Carrier specified WiFi networks. * @hide */ @@ -2911,6 +2926,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_NOTIFY_VT_HANDOVER_TO_WIFI_FAILURE_BOOL, false); sDefaults.putStringArray(KEY_FILTERED_CNAP_NAMES_STRING_ARRAY, null); sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false); + sDefaults.putBoolean(KEY_USE_WFC_HOME_NETWORK_MODE_IN_ROAMING_NETWORK_BOOL, false); sDefaults.putBoolean(KEY_STK_DISABLE_LAUNCH_BROWSER_BOOL, false); sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null); sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1); diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java index b48388ecd168..5a89ae83fbb6 100644 --- a/telephony/java/android/telephony/CellIdentityNr.java +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -89,11 +89,14 @@ public final class CellIdentityNr extends CellIdentity { } /** - * Get the Absolute Radio Frequency Channel Number. + * Get the New Radio Absolute Radio Frequency Channel Number. + * + * Reference: 3GPP TS 38.101-1 section 5.4.2.1 NR-ARFCN and channel raster. + * Reference: 3GPP TS 38.101-2 section 5.4.2.1 NR-ARFCN and channel raster. + * * @return Integer value in range [0, 3279165] or {@link CellInfo#UNAVAILABLE} if unknown. */ - @Override - public int getChannelNumber() { + public int getNrarfcn() { return mNrArfcn; } diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java index d98f37d976df..b9d8eb637c34 100644 --- a/telephony/java/android/telephony/LocationAccessPolicy.java +++ b/telephony/java/android/telephony/LocationAccessPolicy.java @@ -174,22 +174,22 @@ public final class LocationAccessPolicy { 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 5fd36f4fb253..918bf60c9fa7 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -292,17 +292,16 @@ public class PhoneStateListener { 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 @@ public class PhoneStateListener { /** * 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 @@ public class PhoneStateListener { 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 c516d975a113..480c9d9450f4 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -214,7 +214,7 @@ public class SignalStrength implements Parcelable { * @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 @@ public class SignalStrength implements Parcelable { * @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 ac4d17a0ce65..bdaad5bffe5e 100644 --- a/telephony/java/android/telephony/ims/ImsException.java +++ b/telephony/java/android/telephony/ims/ImsException.java @@ -86,7 +86,8 @@ public class ImsException extends Exception { * @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 a58f361e6601..37b11eda6916 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 @@ public final class ImsExternalCallState implements Parcelable { * @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 @@ public final class ImsExternalCallState implements Parcelable { 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 bb85be16eb3a..58ddf21888fc 100644 --- a/telephony/java/android/telephony/ims/ImsMmTelManager.java +++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java @@ -21,6 +21,7 @@ import android.Manifest; 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 @@ public class ImsMmTelManager { * * @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 @@ public class ImsMmTelManager { * 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 @@ public class ImsMmTelManager { * subscription. * @hide */ - public void onSubscriberAssociatedUriChanged(Uri[] uris) { + public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) { } /**@hide*/ @@ -294,7 +295,7 @@ public class ImsMmTelManager { * @param capabilities The new availability of the capabilities. */ public void onCapabilitiesStatusChanged( - MmTelFeature.MmTelCapabilities capabilities) { + @NonNull MmTelFeature.MmTelCapabilities capabilities) { } /**@hide*/ @@ -319,7 +320,7 @@ public class ImsMmTelManager { * @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 @@ public class ImsMmTelManager { * 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 6e98a0af244a..9104d9f4f110 100644 --- a/telephony/java/android/telephony/ims/ProvisioningManager.java +++ b/telephony/java/android/telephony/ims/ProvisioningManager.java @@ -19,6 +19,7 @@ package android.telephony.ims; 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 @@ public class ProvisioningManager { * @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 @@ public class ProvisioningManager { * 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 @@ public class ProvisioningManager { */ @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 @@ public class ProvisioningManager { @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 8aef7a2cc6b6..1a5cd5a9c832 100644 --- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java +++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java @@ -824,7 +824,7 @@ public class WifiAwareManager { * {@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; |