Merge "Oh Minute instead of O'Minute for 1-9 minutes after the hour."
diff --git a/Android.bp b/Android.bp
index 56547b2..4c07fcf 100644
--- a/Android.bp
+++ b/Android.bp
@@ -248,7 +248,6 @@
"core/java/android/os/ICancellationSignal.aidl",
"core/java/android/os/IDeviceIdentifiersPolicyService.aidl",
"core/java/android/os/IDeviceIdleController.aidl",
- "core/java/android/os/IDynamicAndroidService.aidl",
"core/java/android/os/IHardwarePropertiesManager.aidl",
":libincident_aidl",
"core/java/android/os/IMaintenanceActivityListener.aidl",
@@ -272,6 +271,7 @@
"core/java/android/os/IUserManager.aidl",
":libvibrator_aidl",
"core/java/android/os/IVibratorService.aidl",
+ "core/java/android/os/image/IDynamicSystemService.aidl",
"core/java/android/os/storage/IStorageManager.aidl",
"core/java/android/os/storage/IStorageEventListener.aidl",
"core/java/android/os/storage/IStorageShutdownObserver.aidl",
diff --git a/api/current.txt b/api/current.txt
index eea59ba..636339a 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5481,10 +5481,10 @@
method public boolean getAutoExpandBubble();
method @Nullable public android.app.PendingIntent getDeleteIntent();
method public int getDesiredHeight();
+ method @DimenRes public int getDesiredHeightResId();
method @NonNull public android.graphics.drawable.Icon getIcon();
method @NonNull public android.app.PendingIntent getIntent();
method public boolean getSuppressInitialNotification();
- method @Deprecated public CharSequence getTitle();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.Notification.BubbleMetadata> CREATOR;
}
@@ -5495,10 +5495,10 @@
method @NonNull public android.app.Notification.BubbleMetadata.Builder setAutoExpandBubble(boolean);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setDeleteIntent(@Nullable android.app.PendingIntent);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeight(int);
+ method @NonNull public android.app.Notification.BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setIcon(@NonNull android.graphics.drawable.Icon);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setIntent(@NonNull android.app.PendingIntent);
method @NonNull public android.app.Notification.BubbleMetadata.Builder setSuppressInitialNotification(boolean);
- method @Deprecated public android.app.Notification.BubbleMetadata.Builder setTitle(CharSequence);
}
public static class Notification.Builder {
@@ -5848,8 +5848,8 @@
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
- field public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType";
- field public static final String META_DATA_RULE_INSTANCE_LIMIT = "android.app.zen.automatic.ruleInstanceLimit";
+ field public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.service.zen.automatic.ruleType";
+ field public static final String META_DATA_RULE_INSTANCE_LIMIT = "android.service.zen.automatic.ruleInstanceLimit";
}
public static class NotificationManager.Policy implements android.os.Parcelable {
@@ -9794,6 +9794,7 @@
field public static final int BIND_DEBUG_UNBIND = 2; // 0x2
field public static final int BIND_EXTERNAL_SERVICE = -2147483648; // 0x80000000
field public static final int BIND_IMPORTANT = 64; // 0x40
+ field public static final int BIND_INCLUDE_CAPABILITIES = 4096; // 0x1000
field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
field public static final String BIOMETRIC_SERVICE = "biometric";
@@ -22664,18 +22665,22 @@
public final class GnssClock implements android.os.Parcelable {
method public int describeContents();
method public double getBiasNanos();
- method public double getBiasUncertaintyNanos();
+ method @FloatRange(from=0.0f) public double getBiasUncertaintyNanos();
method public double getDriftNanosPerSecond();
- method public double getDriftUncertaintyNanosPerSecond();
+ method @FloatRange(from=0.0f) public double getDriftUncertaintyNanosPerSecond();
+ method public long getElapsedRealtimeNanos();
+ method @IntRange(from=0) public long getElapsedRealtimeUncertaintyNanos();
method public long getFullBiasNanos();
method public int getHardwareClockDiscontinuityCount();
method public int getLeapSecond();
method public long getTimeNanos();
- method public double getTimeUncertaintyNanos();
+ method @FloatRange(from=0.0f) public double getTimeUncertaintyNanos();
method public boolean hasBiasNanos();
method public boolean hasBiasUncertaintyNanos();
method public boolean hasDriftNanosPerSecond();
method public boolean hasDriftUncertaintyNanosPerSecond();
+ method public boolean hasElapsedRealtimeNanos();
+ method public boolean hasElapsedRealtimeUncertaintyNanos();
method public boolean hasFullBiasNanos();
method public boolean hasLeapSecond();
method public boolean hasTimeUncertaintyNanos();
@@ -23484,11 +23489,11 @@
method public void release();
method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
method @Deprecated public void removeOnRoutingChangedListener(android.media.AudioRecord.OnRoutingChangedListener);
- method public boolean setMicrophoneDirection(int);
- method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
method public int setNotificationMarkerPosition(int);
method public int setPositionNotificationPeriod(int);
method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
+ method public boolean setPreferredMicrophoneDirection(int);
+ method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener);
method public void setRecordPositionUpdateListener(android.media.AudioRecord.OnRecordPositionUpdateListener, android.os.Handler);
method public void startRecording() throws java.lang.IllegalStateException;
@@ -24846,6 +24851,7 @@
field public static final int STATUS_OUTPUT_NOT_ALLOWED = 2; // 0x2
field public static final int STATUS_PENDING = 3; // 0x3
field public static final int STATUS_USABLE = 0; // 0x0
+ field public static final int STATUS_USABLE_IN_FUTURE = 5; // 0x5
}
public static final class MediaDrm.MediaDrmStateException extends java.lang.IllegalStateException {
@@ -25787,8 +25793,6 @@
method public void setLocation(float, float);
method public void setMaxDuration(int) throws java.lang.IllegalArgumentException;
method public void setMaxFileSize(long) throws java.lang.IllegalArgumentException;
- method public boolean setMicrophoneDirection(int);
- method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
method public void setNextOutputFile(java.io.FileDescriptor) throws java.io.IOException;
method public void setNextOutputFile(java.io.File) throws java.io.IOException;
method public void setOnErrorListener(android.media.MediaRecorder.OnErrorListener);
@@ -25799,6 +25803,8 @@
method public void setOutputFile(String) throws java.lang.IllegalStateException;
method public void setOutputFormat(int) throws java.lang.IllegalStateException;
method public boolean setPreferredDevice(android.media.AudioDeviceInfo);
+ method public boolean setPreferredMicrophoneDirection(int);
+ method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
method public void setPreviewDisplay(android.view.Surface);
method public void setProfile(android.media.CamcorderProfile);
method public void setVideoEncoder(int) throws java.lang.IllegalStateException;
@@ -26142,11 +26148,11 @@
}
public interface MicrophoneDirection {
- method public boolean setMicrophoneDirection(int);
- method public boolean setMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
- field public static final int MIC_DIRECTION_BACK = 2; // 0x2
+ method public boolean setPreferredMicrophoneDirection(int);
+ method public boolean setPreferredMicrophoneFieldDimension(@FloatRange(from=-1.0, to=1.0) float);
+ field public static final int MIC_DIRECTION_AWAY_FROM_USER = 2; // 0x2
field public static final int MIC_DIRECTION_EXTERNAL = 3; // 0x3
- field public static final int MIC_DIRECTION_FRONT = 1; // 0x1
+ field public static final int MIC_DIRECTION_TOWARDS_USER = 1; // 0x1
field public static final int MIC_DIRECTION_UNSPECIFIED = 0; // 0x0
}
@@ -30752,7 +30758,6 @@
method public double getAltitudeUncertainty();
method public java.util.List<android.net.MacAddress> getColocatedBssids();
method public int getDatum();
- method public boolean getDependentStationIndication();
method public int getExpectedToMove();
method public double getFloorNumber();
method public double getHeightAboveFloorMeters();
@@ -30765,7 +30770,6 @@
method @Nullable public String getMapImageMimeType();
method @Nullable public android.net.Uri getMapImageUri();
method public boolean getRegisteredLocationAgreementIndication();
- method public boolean getRegisteredLocationDseIndication();
method public boolean isLciSubelementValid();
method public boolean isZaxisSubelementValid();
method @Nullable public android.location.Address toCivicLocationAddress();
diff --git a/api/system-current.txt b/api/system-current.txt
index a9085bc..1fad776 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1076,8 +1076,6 @@
}
public final class AppTarget implements android.os.Parcelable {
- ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle);
- ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull android.content.pm.ShortcutInfo, @Nullable String);
method public int describeContents();
method @Nullable public String getClassName();
method @NonNull public android.app.prediction.AppTargetId getId();
@@ -1089,6 +1087,15 @@
field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTarget> CREATOR;
}
+ public static final class AppTarget.Builder {
+ ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId);
+ method @NonNull public android.app.prediction.AppTarget build();
+ method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String);
+ method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int);
+ method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
+ method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
+ }
+
public final class AppTargetEvent implements android.os.Parcelable {
method public int describeContents();
method public int getAction();
@@ -1354,7 +1361,6 @@
field public static final String BACKUP_SERVICE = "backup";
field public static final String CONTENT_SUGGESTIONS_SERVICE = "content_suggestions";
field public static final String CONTEXTHUB_SERVICE = "contexthub";
- field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android";
field public static final String EUICC_CARD_SERVICE = "euicc_card";
field public static final String HDMI_CONTROL_SERVICE = "hdmi_control";
field public static final String NETD_SERVICE = "netd";
@@ -1381,32 +1387,6 @@
method public void sendOrderedBroadcast(android.content.Intent, String, android.os.Bundle, android.content.BroadcastReceiver, android.os.Handler, int, String, android.os.Bundle);
}
- public class DynamicAndroidClient {
- ctor public DynamicAndroidClient(@NonNull android.content.Context);
- method public void bind();
- method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener, @NonNull java.util.concurrent.Executor);
- method public void setOnStatusChangedListener(@NonNull android.content.DynamicAndroidClient.OnStatusChangedListener);
- method public void start(String, long);
- method public void start(String, long, long);
- method public void unbind();
- field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
- field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
- field public static final int CAUSE_ERROR_IO = 3; // 0x3
- field public static final int CAUSE_ERROR_IPC = 5; // 0x5
- field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
- field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
- field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
- field public static final int STATUS_IN_PROGRESS = 2; // 0x2
- field public static final int STATUS_IN_USE = 4; // 0x4
- field public static final int STATUS_NOT_STARTED = 1; // 0x1
- field public static final int STATUS_READY = 3; // 0x3
- field public static final int STATUS_UNKNOWN = 0; // 0x0
- }
-
- public static interface DynamicAndroidClient.OnStatusChangedListener {
- method public void onStatusChanged(int, int, long);
- }
-
public class Intent implements java.lang.Cloneable android.os.Parcelable {
field public static final String ACTION_BATTERY_LEVEL_CHANGED = "android.intent.action.BATTERY_LEVEL_CHANGED";
field public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
@@ -1481,6 +1461,7 @@
field @NonNull public static final android.os.Parcelable.Creator<android.content.om.OverlayInfo> CREATOR;
field public final String category;
field public final String packageName;
+ field public final String targetOverlayableName;
field public final String targetPackageName;
field public final int userId;
}
@@ -4931,7 +4912,6 @@
method public int getCellularDataNetworkType();
method public int getCellularSignalStrengthDb();
method public int getCellularSignalStrengthDbm();
- method public boolean getIsSameRegisteredCell();
method public int getLinkSpeedMbps();
method public int getProbeElapsedTimeSinceLastUpdateMillis();
method public int getProbeMcsRateSinceLastUpdate();
@@ -4955,6 +4935,7 @@
method public long getTotalTxBad();
method public long getTotalTxRetries();
method public long getTotalTxSuccess();
+ method public boolean isSameRegisteredCell();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.WifiUsabilityStatsEntry> CREATOR;
field public static final int PROBE_STATUS_FAILURE = 3; // 0x3
@@ -5444,14 +5425,14 @@
public final class PowerManager {
method @RequiresPermission(allOf={android.Manifest.permission.READ_DREAM_STATE, android.Manifest.permission.WRITE_DREAM_STATE}) public void dream(long);
method @RequiresPermission(android.Manifest.permission.DEVICE_POWER) public boolean forceSuspend();
- method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveMode();
+ method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public int getPowerSaveModeTrigger();
method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSaveEnabled(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setAdaptivePowerSavePolicy(@NonNull android.os.BatterySaverPolicyConfig);
- method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSavings(boolean, int);
+ method @RequiresPermission(android.Manifest.permission.POWER_SAVER) public boolean setDynamicPowerSaveHint(boolean, int);
method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.POWER_SAVER}) public boolean setPowerSaveModeEnabled(boolean);
method @RequiresPermission(anyOf={android.Manifest.permission.DEVICE_POWER, android.Manifest.permission.USER_ACTIVITY}) public void userActivity(long, int, int);
- field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1
- field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0
+ field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
+ field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
field public static final int USER_ACTIVITY_EVENT_ACCESSIBILITY = 3; // 0x3
field public static final int USER_ACTIVITY_EVENT_BUTTON = 1; // 0x1
field public static final int USER_ACTIVITY_EVENT_OTHER = 0; // 0x0
@@ -5658,6 +5639,36 @@
}
+package android.os.image {
+
+ public class DynamicSystemClient {
+ ctor public DynamicSystemClient(@NonNull android.content.Context);
+ method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void bind();
+ method public void setOnStatusChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+ method public void setOnStatusChangedListener(@NonNull android.os.image.DynamicSystemClient.OnStatusChangedListener);
+ method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long);
+ method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void start(@NonNull String, long, long);
+ method @RequiresPermission("android.permission.MANAGE_DYNAMIC_SYSTEM") public void unbind();
+ field public static final int CAUSE_ERROR_EXCEPTION = 6; // 0x6
+ field public static final int CAUSE_ERROR_INVALID_URL = 4; // 0x4
+ field public static final int CAUSE_ERROR_IO = 3; // 0x3
+ field public static final int CAUSE_ERROR_IPC = 5; // 0x5
+ field public static final int CAUSE_INSTALL_CANCELLED = 2; // 0x2
+ field public static final int CAUSE_INSTALL_COMPLETED = 1; // 0x1
+ field public static final int CAUSE_NOT_SPECIFIED = 0; // 0x0
+ field public static final int STATUS_IN_PROGRESS = 2; // 0x2
+ field public static final int STATUS_IN_USE = 4; // 0x4
+ field public static final int STATUS_NOT_STARTED = 1; // 0x1
+ field public static final int STATUS_READY = 3; // 0x3
+ field public static final int STATUS_UNKNOWN = 0; // 0x0
+ }
+
+ public static interface DynamicSystemClient.OnStatusChangedListener {
+ method public void onStatusChanged(int, int, long);
+ }
+
+}
+
package android.os.storage {
public class StorageManager {
@@ -6424,7 +6435,7 @@
public abstract class ContentCaptureService extends android.app.Service {
ctor public ContentCaptureService();
- method public final void disableContentCaptureServices();
+ method public final void disableSelf();
method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
method public void onConnected();
@@ -7564,11 +7575,11 @@
field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc
}
- public final class DataSpecificRegistrationStates implements android.os.Parcelable {
+ public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
method public void writeToParcel(android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationStates> CREATOR;
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
}
public final class DisconnectCause {
@@ -7677,7 +7688,7 @@
method public int getAccessNetworkTechnology();
method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
method @Nullable public android.telephony.CellIdentity getCellIdentity();
- method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates();
+ method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
method public int getDomain();
method public int getRegistrationState();
method public int getRejectCause();
diff --git a/api/test-current.txt b/api/test-current.txt
index 04409ed..01b56c4 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -352,6 +352,10 @@
method public boolean isUiModeLocked();
}
+ public class WallpaperManager {
+ method @RequiresPermission("android.permission.SET_WALLPAPER_COMPONENT") public boolean setWallpaperComponent(android.content.ComponentName);
+ }
+
public class WindowConfiguration implements java.lang.Comparable<android.app.WindowConfiguration> android.os.Parcelable {
ctor public WindowConfiguration();
method public int compareTo(android.app.WindowConfiguration);
@@ -473,7 +477,6 @@
}
public final class AppTarget implements android.os.Parcelable {
- ctor public AppTarget(@NonNull android.app.prediction.AppTargetId, @NonNull String, @Nullable String, @NonNull android.os.UserHandle);
method public int describeContents();
method @Nullable public String getClassName();
method @NonNull public android.app.prediction.AppTargetId getId();
@@ -485,6 +488,15 @@
field @NonNull public static final android.os.Parcelable.Creator<android.app.prediction.AppTarget> CREATOR;
}
+ public static final class AppTarget.Builder {
+ ctor public AppTarget.Builder(@NonNull android.app.prediction.AppTargetId);
+ method @NonNull public android.app.prediction.AppTarget build();
+ method @NonNull public android.app.prediction.AppTarget.Builder setClassName(@NonNull String);
+ method @NonNull public android.app.prediction.AppTarget.Builder setRank(@IntRange(from=0) int);
+ method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull String, @NonNull android.os.UserHandle);
+ method @NonNull public android.app.prediction.AppTarget.Builder setTarget(@NonNull android.content.pm.ShortcutInfo);
+ }
+
public final class AppTargetEvent implements android.os.Parcelable {
method public int describeContents();
method public int getAction();
@@ -600,6 +612,7 @@
public abstract class Context {
method public android.content.Context createPackageContextAsUser(String, int, android.os.UserHandle) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.view.Display getDisplay();
+ method public abstract int getDisplayId();
method public android.os.UserHandle getUser();
method public int getUserId();
method public void setAutofillOptions(@Nullable android.content.AutofillOptions);
@@ -610,6 +623,7 @@
public class ContextWrapper extends android.content.Context {
method public android.view.Display getDisplay();
+ method public int getDisplayId();
}
public class Intent implements java.lang.Cloneable android.os.Parcelable {
@@ -919,19 +933,23 @@
method public void resetBiasUncertaintyNanos();
method public void resetDriftNanosPerSecond();
method public void resetDriftUncertaintyNanosPerSecond();
+ method public void resetElapsedRealtimeNanos();
+ method public void resetElapsedRealtimeUncertaintyNanos();
method public void resetFullBiasNanos();
method public void resetLeapSecond();
method public void resetTimeUncertaintyNanos();
method public void set(android.location.GnssClock);
method public void setBiasNanos(double);
- method public void setBiasUncertaintyNanos(double);
+ method public void setBiasUncertaintyNanos(@FloatRange(from=0.0f) double);
method public void setDriftNanosPerSecond(double);
- method public void setDriftUncertaintyNanosPerSecond(double);
+ method public void setDriftUncertaintyNanosPerSecond(@FloatRange(from=0.0f) double);
+ method public void setElapsedRealtimeNanos(long);
+ method public void setElapsedRealtimeUncertaintyNanos(@IntRange(from=0) long);
method public void setFullBiasNanos(long);
method public void setHardwareClockDiscontinuityCount(int);
method public void setLeapSecond(int);
method public void setTimeNanos(long);
- method public void setTimeUncertaintyNanos(double);
+ method public void setTimeUncertaintyNanos(@FloatRange(from=0.0f) double);
}
public final class GnssMeasurement implements android.os.Parcelable {
@@ -1791,11 +1809,11 @@
}
public final class PowerManager {
- method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveMode();
- method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSavings(boolean, int);
+ method @RequiresPermission("android.permission.POWER_SAVER") public int getPowerSaveModeTrigger();
+ method @RequiresPermission("android.permission.POWER_SAVER") public boolean setDynamicPowerSaveHint(boolean, int);
method @RequiresPermission(anyOf={"android.permission.DEVICE_POWER", "android.permission.POWER_SAVER"}) public boolean setPowerSaveModeEnabled(boolean);
- field public static final int POWER_SAVER_MODE_DYNAMIC = 1; // 0x1
- field public static final int POWER_SAVER_MODE_PERCENTAGE = 0; // 0x0
+ field public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1; // 0x1
+ field public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0; // 0x0
}
public class Process {
@@ -2143,7 +2161,7 @@
public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final String AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES = "autofill_compat_mode_allowed_packages";
- field public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
+ field public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
field public static final String BATTERY_SAVER_CONSTANTS = "battery_saver_constants";
field public static final String CAPTIVE_PORTAL_FALLBACK_PROBE_SPECS = "captive_portal_fallback_probe_specs";
field public static final String CAPTIVE_PORTAL_FALLBACK_URL = "captive_portal_fallback_url";
@@ -2428,7 +2446,7 @@
public abstract class ContentCaptureService extends android.app.Service {
ctor public ContentCaptureService();
- method public final void disableContentCaptureServices();
+ method public final void disableSelf();
method public void onActivityEvent(@NonNull android.service.contentcapture.ActivityEvent);
method public void onActivitySnapshot(@NonNull android.view.contentcapture.ContentCaptureSessionId, @NonNull android.service.contentcapture.SnapshotData);
method public void onConnected();
@@ -2547,10 +2565,34 @@
package android.telephony {
+ public final class AccessNetworkConstants {
+ field public static final int TRANSPORT_TYPE_WLAN = 2; // 0x2
+ field public static final int TRANSPORT_TYPE_WWAN = 1; // 0x1
+ }
+
public class CarrierConfigManager {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void overrideConfig(int, @Nullable android.os.PersistableBundle);
}
+ public final class DataSpecificRegistrationInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method @NonNull public android.telephony.LteVopsSupportInfo getLteVopsSupportInfo();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.DataSpecificRegistrationInfo> CREATOR;
+ }
+
+ public final class LteVopsSupportInfo implements android.os.Parcelable {
+ ctor public LteVopsSupportInfo(int, int);
+ method public int describeContents();
+ method public int getEmcBearerSupport();
+ method public int getVopsSupport();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.LteVopsSupportInfo> CREATOR;
+ field public static final int LTE_STATUS_NOT_AVAILABLE = 1; // 0x1
+ field public static final int LTE_STATUS_NOT_SUPPORTED = 3; // 0x3
+ field public static final int LTE_STATUS_SUPPORTED = 2; // 0x2
+ }
+
public class MbmsDownloadSession implements java.lang.AutoCloseable {
field public static final String MBMS_DOWNLOAD_SERVICE_OVERRIDE_METADATA = "mbms-download-service-override";
}
@@ -2563,7 +2605,52 @@
field public static final String MBMS_STREAMING_SERVICE_OVERRIDE_METADATA = "mbms-streaming-service-override";
}
+ public final class NetworkRegistrationInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getAccessNetworkTechnology();
+ method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
+ method @Nullable public android.telephony.CellIdentity getCellIdentity();
+ method @Nullable public android.telephony.DataSpecificRegistrationInfo getDataSpecificInfo();
+ method public int getDomain();
+ method public int getRegistrationState();
+ method public int getRejectCause();
+ method public int getRoamingType();
+ method public int getTransportType();
+ method public boolean isEmergencyEnabled();
+ method public boolean isRoaming();
+ method public void writeToParcel(android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.telephony.NetworkRegistrationInfo> CREATOR;
+ field public static final int DOMAIN_CS = 1; // 0x1
+ field public static final int DOMAIN_PS = 2; // 0x2
+ field public static final int REGISTRATION_STATE_DENIED = 3; // 0x3
+ field public static final int REGISTRATION_STATE_HOME = 1; // 0x1
+ field public static final int REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING = 0; // 0x0
+ field public static final int REGISTRATION_STATE_NOT_REGISTERED_SEARCHING = 2; // 0x2
+ field public static final int REGISTRATION_STATE_ROAMING = 5; // 0x5
+ field public static final int REGISTRATION_STATE_UNKNOWN = 4; // 0x4
+ field public static final int SERVICE_TYPE_DATA = 2; // 0x2
+ field public static final int SERVICE_TYPE_EMERGENCY = 5; // 0x5
+ field public static final int SERVICE_TYPE_SMS = 3; // 0x3
+ field public static final int SERVICE_TYPE_UNKNOWN = 0; // 0x0
+ field public static final int SERVICE_TYPE_VIDEO = 4; // 0x4
+ field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
+ }
+
+ public static final class NetworkRegistrationInfo.Builder {
+ ctor public NetworkRegistrationInfo.Builder();
+ method @NonNull public android.telephony.NetworkRegistrationInfo build();
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAccessNetworkTechnology(int);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setAvailableServices(@NonNull java.util.List<java.lang.Integer>);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setDomain(int);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setEmergencyOnly(boolean);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRegistrationState(int);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setRejectCause(int);
+ method @NonNull public android.telephony.NetworkRegistrationInfo.Builder setTransportType(int);
+ }
+
public class ServiceState implements android.os.Parcelable {
+ method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo);
method public void setCdmaSystemAndNetworkId(int, int);
method public void setCellBandwidths(int[]);
method public void setChannelNumber(int);
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index 24331af..55b1003 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -196,13 +196,7 @@
std::stringstream stream;
for (const auto& overlay : interesting_apks) {
- std::vector<std::string> verify_args = {"--idmap-path", overlay.idmap_path};
- for (const std::string& policy : overlay.policies) {
- verify_args.emplace_back("--policy");
- verify_args.emplace_back(policy);
- }
-
- if (!Verify(std::vector<std::string>(verify_args))) {
+ if (!Verify(std::vector<std::string>({"--idmap-path", overlay.idmap_path}))) {
std::vector<std::string> create_args = {"--target-apk-path", target_apk_path,
"--overlay-apk-path", overlay.apk_path,
"--idmap-path", overlay.idmap_path};
diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt
index d740961..a3776c4 100644
--- a/config/boot-image-profile.txt
+++ b/config/boot-image-profile.txt
@@ -4759,7 +4759,6 @@
HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppForSms(Ljava/lang/String;ILjava/lang/String;)J
HPLandroid/os/IDeviceIdleController$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
HPLandroid/os/IDeviceIdleController$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
-HPLandroid/os/IDynamicAndroidService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HPLandroid/os/IHardwarePropertiesManager$Stub;->getDefaultTransactionName(I)Ljava/lang/String;
HPLandroid/os/IHardwarePropertiesManager$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HPLandroid/os/IInstalld$Stub$Proxy;->clearAppData(Ljava/lang/String;Ljava/lang/String;IIJ)V
@@ -5081,6 +5080,7 @@
HPLandroid/os/health/HealthStatsWriter;->writeParcelableMap(Landroid/os/Parcel;Landroid/util/ArrayMap;)V
HPLandroid/os/health/TimerStat;-><init>(IJ)V
HPLandroid/os/health/TimerStat;->writeToParcel(Landroid/os/Parcel;I)V
+HPLandroid/os/image/IDynamicSystemService$Stub;->onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z
HPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->onStorageStateChanged(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
HPLandroid/os/storage/IStorageManager$Stub$Proxy;->allocateBytes(Ljava/lang/String;JILjava/lang/String;)V
HPLandroid/os/storage/IStorageManager$Stub$Proxy;->changeEncryptionPassword(ILjava/lang/String;)I
@@ -24027,7 +24027,6 @@
HSPLandroid/os/IDeviceIdleController$Stub;-><init>()V
HSPLandroid/os/IDeviceIdleController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IDeviceIdleController;
HSPLandroid/os/IDumpstate$Stub;-><init>()V
-HSPLandroid/os/IDynamicAndroidService$Stub;-><init>()V
HSPLandroid/os/IExternalVibratorService$Stub;-><init>()V
HSPLandroid/os/IHardwarePropertiesManager$Stub;-><init>()V
HSPLandroid/os/IIncidentCompanion$Stub;-><init>()V
@@ -24837,6 +24836,7 @@
HSPLandroid/os/ZygoteProcess;->zygoteSendArgsAndGetResult(Landroid/os/ZygoteProcess$ZygoteState;ZLjava/util/ArrayList;)Landroid/os/Process$ProcessStartResult;
HSPLandroid/os/health/HealthStatsParceler$1;-><init>()V
HSPLandroid/os/health/TimerStat$1;-><init>()V
+HSPLandroid/os/image/IDynamicSystemService$Stub;-><init>()V
HSPLandroid/os/storage/IStorageEventListener$Stub$Proxy;->asBinder()Landroid/os/IBinder;
HSPLandroid/os/storage/IStorageEventListener$Stub;->asBinder()Landroid/os/IBinder;
HSPLandroid/os/storage/IStorageManager$Stub$Proxy;->getVolumeList(ILjava/lang/String;I)[Landroid/os/storage/StorageVolume;
@@ -47386,7 +47386,6 @@
Landroid/os/DropBoxManager$Entry$1;
Landroid/os/DropBoxManager$Entry;
Landroid/os/DropBoxManager;
-Landroid/os/DynamicAndroidManager;
Landroid/os/Environment$UserEnvironment;
Landroid/os/Environment;
Landroid/os/EventLogTags;
@@ -47428,8 +47427,6 @@
Landroid/os/IDeviceIdleController;
Landroid/os/IDumpstate$Stub;
Landroid/os/IDumpstate;
-Landroid/os/IDynamicAndroidService$Stub;
-Landroid/os/IDynamicAndroidService;
Landroid/os/IExternalVibratorService$Stub;
Landroid/os/IExternalVibratorService;
Landroid/os/IHardwarePropertiesManager$Stub;
@@ -47689,6 +47686,10 @@
Landroid/os/health/SystemHealthManager;
Landroid/os/health/TimerStat$1;
Landroid/os/health/TimerStat;
+Landroid/os/image/DynamicSystemClient;
+Landroid/os/image/DynamicSystemManager;
+Landroid/os/image/IDynamicSystemService$Stub;
+Landroid/os/image/IDynamicSystemService;
Landroid/os/storage/DiskInfo;
Landroid/os/storage/IObbActionListener$Stub;
Landroid/os/storage/IObbActionListener;
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 76d69cd..79cdb77 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -1680,7 +1680,6 @@
Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String;
Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V
Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V
-Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V
Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J
Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V
Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V
diff --git a/config/preloaded-classes b/config/preloaded-classes
index fda028d..abdbab2 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -2724,7 +2724,6 @@
android.os.DropBoxManager$Entry$1
android.os.DropBoxManager$Entry
android.os.DropBoxManager
-android.os.DynamicAndroidManager
android.os.Environment$UserEnvironment
android.os.Environment
android.os.EventLogTags
@@ -2909,6 +2908,8 @@
android.os.health.SystemHealthManager
android.os.health.TimerStat$1
android.os.health.TimerStat
+android.os.image.DynamicSystemClient
+android.os.image.DynamicSystemManager
android.os.storage.IObbActionListener$Stub
android.os.storage.IObbActionListener
android.os.storage.IStorageManager$Stub$Proxy
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index ec2825e..7180c01 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -231,7 +231,7 @@
* Sets the zen policy.
*/
public void setZenPolicy(ZenPolicy zenPolicy) {
- this.mZenPolicy = zenPolicy;
+ this.mZenPolicy = (zenPolicy == null ? null : zenPolicy.copy());
}
/**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 7ba6146..d634aa5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -21,6 +21,7 @@
import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;
import android.annotation.ColorInt;
+import android.annotation.DimenRes;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
import android.annotation.IntDef;
@@ -8521,6 +8522,7 @@
private PendingIntent mDeleteIntent;
private Icon mIcon;
private int mDesiredHeight;
+ @DimenRes private int mDesiredHeightResId;
private int mFlags;
/**
@@ -8547,10 +8549,11 @@
private static final int FLAG_SUPPRESS_INITIAL_NOTIFICATION = 0x00000002;
private BubbleMetadata(PendingIntent expandIntent, PendingIntent deleteIntent,
- Icon icon, int height) {
+ Icon icon, int height, @DimenRes int heightResId) {
mPendingIntent = expandIntent;
mIcon = icon;
mDesiredHeight = height;
+ mDesiredHeightResId = heightResId;
mDeleteIntent = deleteIntent;
}
@@ -8562,6 +8565,7 @@
if (in.readInt() != 0) {
mDeleteIntent = PendingIntent.CREATOR.createFromParcel(in);
}
+ mDesiredHeightResId = in.readInt();
}
/**
@@ -8581,17 +8585,6 @@
}
/**
- * @return the title that will appear along with the app content defined by
- * {@link #getIntent()} for this bubble.
- *
- * @deprecated titles are no longer required or shown.
- */
- @Deprecated
- public CharSequence getTitle() {
- return "";
- }
-
- /**
* @return the icon that will be displayed for this bubble when it is collapsed.
*/
@NonNull
@@ -8600,7 +8593,7 @@
}
/**
- * @return the ideal height for the floating window that app content defined by
+ * @return the ideal height, in DPs, for the floating window that app content defined by
* {@link #getIntent()} for this bubble.
*/
public int getDesiredHeight() {
@@ -8608,6 +8601,15 @@
}
/**
+ * @return the resId of ideal height for the floating window that app content defined by
+ * {@link #getIntent()} for this bubble.
+ */
+ @DimenRes
+ public int getDesiredHeightResId() {
+ return mDesiredHeightResId;
+ }
+
+ /**
* @return whether this bubble should auto expand when it is posted.
*
* @see BubbleMetadata.Builder#setAutoExpandBubble(boolean)
@@ -8654,6 +8656,7 @@
if (mDeleteIntent != null) {
mDeleteIntent.writeToParcel(out, 0);
}
+ out.writeInt(mDesiredHeightResId);
}
private void setFlags(int flags) {
@@ -8668,6 +8671,7 @@
private PendingIntent mPendingIntent;
private Icon mIcon;
private int mDesiredHeight;
+ @DimenRes private int mDesiredHeightResId;
private int mFlags;
private PendingIntent mDeleteIntent;
@@ -8691,19 +8695,6 @@
}
/**
- * Sets the title that will appear along with the app content for this bubble.
- *
- * <p>A title is required and should expect to fit on a single line and make sense when
- * shown with the content defined by {@link #setIntent(PendingIntent)}.</p>
- *
- * @deprecated titles are no longer required or shown.
- */
- @Deprecated
- public BubbleMetadata.Builder setTitle(CharSequence title) {
- return this;
- }
-
- /**
* Sets the icon that will represent the bubble when it is collapsed.
*
* <p>An icon is required and should be representative of the content within the bubble.
@@ -8733,13 +8724,35 @@
}
/**
- * Sets the desired height for the app content defined by
+ * Sets the desired height in DPs for the app content defined by
* {@link #setIntent(PendingIntent)}, this height may not be respected if there is not
* enough space on the screen or if the provided height is too small to be useful.
+ * <p>
+ * If {@link #setDesiredHeightResId(int)} was previously called on this builder, the
+ * previous value set will be cleared after calling this method, and this value will
+ * be used instead.
*/
@NonNull
public BubbleMetadata.Builder setDesiredHeight(int height) {
mDesiredHeight = Math.max(height, 0);
+ mDesiredHeightResId = 0;
+ return this;
+ }
+
+
+ /**
+ * Sets the desired height via resId for the app content defined by
+ * {@link #setIntent(PendingIntent)}, this height may not be respected if there is not
+ * enough space on the screen or if the provided height is too small to be useful.
+ * <p>
+ * If {@link #setDesiredHeight(int)} was previously called on this builder, the
+ * previous value set will be cleared after calling this method, and this value will
+ * be used instead.
+ */
+ @NonNull
+ public BubbleMetadata.Builder setDesiredHeightResId(@DimenRes int heightResId) {
+ mDesiredHeightResId = heightResId;
+ mDesiredHeight = 0;
return this;
}
@@ -8801,7 +8814,7 @@
throw new IllegalStateException("Must supply an icon for the bubble");
}
BubbleMetadata data = new BubbleMetadata(mPendingIntent, mDeleteIntent,
- mIcon, mDesiredHeight);
+ mIcon, mDesiredHeight, mDesiredHeightResId);
data.setFlags(mFlags);
return data;
}
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 1aacf96..0bec21f 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -315,7 +315,8 @@
* This tag should contain a localized name of the type of the zen rule provided by the
* activity.
*/
- public static final String META_DATA_AUTOMATIC_RULE_TYPE = "android.app.automatic.ruleType";
+ public static final String META_DATA_AUTOMATIC_RULE_TYPE =
+ "android.service.zen.automatic.ruleType";
/**
* An optional {@code meta-data} tag for activities that handle
@@ -325,7 +326,7 @@
* can be created for this rule type. Omit or enter a value <= 0 to allow unlimited instances.
*/
public static final String META_DATA_RULE_INSTANCE_LIMIT =
- "android.app.zen.automatic.ruleInstanceLimit";
+ "android.service.zen.automatic.ruleInstanceLimit";
/** Value signifying that the user has not expressed a per-app visibility override value.
* @hide */
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4d280b7..d67bfb6 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -131,13 +131,11 @@
import android.os.Build;
import android.os.DeviceIdleManager;
import android.os.DropBoxManager;
-import android.os.DynamicAndroidManager;
import android.os.HardwarePropertiesManager;
import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
import android.os.IDeviceIdleController;
import android.os.IDumpstate;
-import android.os.IDynamicAndroidService;
import android.os.IHardwarePropertiesManager;
import android.os.IPowerManager;
import android.os.IRecoverySystem;
@@ -155,6 +153,8 @@
import android.os.UserManager;
import android.os.Vibrator;
import android.os.health.SystemHealthManager;
+import android.os.image.DynamicSystemManager;
+import android.os.image.IDynamicSystemService;
import android.os.storage.StorageManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
@@ -1275,15 +1275,15 @@
IRollbackManager.Stub.asInterface(b));
}});
- registerService(Context.DYNAMIC_ANDROID_SERVICE, DynamicAndroidManager.class,
- new CachedServiceFetcher<DynamicAndroidManager>() {
+ registerService(Context.DYNAMIC_SYSTEM_SERVICE, DynamicSystemManager.class,
+ new CachedServiceFetcher<DynamicSystemManager>() {
@Override
- public DynamicAndroidManager createService(ContextImpl ctx)
+ public DynamicSystemManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(
- Context.DYNAMIC_ANDROID_SERVICE);
- return new DynamicAndroidManager(
- IDynamicAndroidService.Stub.asInterface(b));
+ Context.DYNAMIC_SYSTEM_SERVICE);
+ return new DynamicSystemManager(
+ IDynamicSystemService.Stub.asInterface(b));
}});
//CHECKSTYLE:ON IndentationCheck
}
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index a929fe0..325a54b 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -25,6 +25,7 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -1666,6 +1667,7 @@
*
* @hide
*/
+ @TestApi
@SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT)
public boolean setWallpaperComponent(ComponentName name) {
diff --git a/core/java/android/app/prediction/AppTarget.java b/core/java/android/app/prediction/AppTarget.java
index bb1b96c..826c149 100644
--- a/core/java/android/app/prediction/AppTarget.java
+++ b/core/java/android/app/prediction/AppTarget.java
@@ -43,20 +43,13 @@
private final ShortcutInfo mShortcutInfo;
- private int mRank;
+ private final int mRank;
/**
- * Creates an instance of AppTarget that represent a launchable component.
- *
- * @param id A unique id for this launchable target.
- * @param packageName Package name of the target.
- * @param className Class name of the target.
- * @param user The UserHandle of the user which this target belongs to.
- *
+ * @deprecated use the Builder class
* @hide
*/
- @SystemApi
- @TestApi
+ @Deprecated
public AppTarget(@NonNull AppTargetId id, @NonNull String packageName,
@Nullable String className, @NonNull UserHandle user) {
mId = id;
@@ -65,18 +58,14 @@
mPackageName = Preconditions.checkNotNull(packageName);
mClassName = className;
mUser = Preconditions.checkNotNull(user);
+ mRank = 0;
}
/**
- * Creates an instance of AppTarget that represent a launchable shortcut.
- *
- * @param id A unique id for this launchable target.
- * @param shortcutInfo The {@link ShortcutInfo} that is represented with this target.
- * @param className Class name fo the target.
- *
+ * @deprecated use the Builder class
* @hide
*/
- @SystemApi
+ @Deprecated
public AppTarget(@NonNull AppTargetId id, @NonNull ShortcutInfo shortcutInfo,
@Nullable String className) {
mId = id;
@@ -85,6 +74,17 @@
mPackageName = mShortcutInfo.getPackage();
mUser = mShortcutInfo.getUserHandle();
mClassName = className;
+ mRank = 0;
+ }
+
+ private AppTarget(AppTargetId id, String packageName, UserHandle user,
+ ShortcutInfo shortcutInfo, String className, int rank) {
+ mId = id;
+ mShortcutInfo = shortcutInfo;
+ mPackageName = packageName;
+ mClassName = className;
+ mUser = user;
+ mRank = rank;
}
private AppTarget(Parcel parcel) {
@@ -142,17 +142,6 @@
}
/**
- * Sets the rank of the for the target.
- * @hide
- */
- public void setRank(@IntRange(from = 0) int rank) {
- if (rank < 0) {
- throw new IllegalArgumentException("rank cannot be a negative value");
- }
- mRank = rank;
- }
-
- /**
* Returns the rank for the target. Rank of an AppTarget is a non-negative integer that
* represents the importance of this target compared to other candidate targets. A smaller value
* means higher importance in the list.
@@ -196,6 +185,101 @@
dest.writeInt(mRank);
}
+ /**
+ * A builder for app targets.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static final class Builder {
+
+ @NonNull
+ private final AppTargetId mId;
+
+ private String mPackageName;
+ private UserHandle mUser;
+ private ShortcutInfo mShortcutInfo;
+
+ private String mClassName;
+ private int mRank;
+
+ /**
+ * @param id A unique id for this launchable target.
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public Builder(@NonNull AppTargetId id) {
+ mId = id;
+ }
+
+ /**
+ * Sets the target to be an app.
+ *
+ * @param packageName PackageName of the app
+ * @param user The UserHandle of the user which this target belongs to.
+ *
+ * @throws IllegalArgumentException is the target is already set
+ */
+ @NonNull
+ public Builder setTarget(@NonNull String packageName, @NonNull UserHandle user) {
+ if (mPackageName == null) {
+ throw new IllegalArgumentException("Target is already set");
+ }
+ mPackageName = Preconditions.checkNotNull(packageName);
+ mUser = Preconditions.checkNotNull(user);
+ return this;
+ }
+
+ /**
+ * Sets the target to be a ShortcutInfo.
+ *
+ * @throws IllegalArgumentException is the target is already set
+ */
+ @NonNull
+ public Builder setTarget(@NonNull ShortcutInfo info) {
+ setTarget(info.getPackage(), info.getUserHandle());
+ mShortcutInfo = Preconditions.checkNotNull(info);
+ return this;
+ }
+
+ /**
+ * Sets the className for the target
+ */
+ @NonNull
+ public Builder setClassName(@NonNull String className) {
+ mClassName = Preconditions.checkNotNull(className);
+ return this;
+ }
+
+ /**
+ * Sets the rank of the for the target.
+ */
+ @NonNull
+ public Builder setRank(@IntRange(from = 0) int rank) {
+ if (rank < 0) {
+ throw new IllegalArgumentException("rank cannot be a negative value");
+ }
+ mRank = rank;
+ return this;
+ }
+
+ /**
+ * Builds a new AppTarget instance.
+ *
+ * @throws IllegalStateException if no target is set
+ * @see #setTarget(ShortcutInfo)
+ * @see #setTarget(String, UserHandle)
+ */
+ @NonNull
+ public AppTarget build() {
+ if (mPackageName == null) {
+ throw new IllegalStateException("No target set");
+ }
+ return new AppTarget(mId, mPackageName, mUser, mShortcutInfo, mClassName, mRank);
+ }
+ }
+
public static final @android.annotation.NonNull Parcelable.Creator<AppTarget> CREATOR =
new Parcelable.Creator<AppTarget>() {
public AppTarget createFromParcel(Parcel parcel) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fb933b1..d7a2e1b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -338,6 +338,14 @@
public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100;
/**
+ * Flag for {@link #bindService}: If binding from an app that has specific capabilities
+ * due to its foreground state such as an activity or foreground service, then this flag will
+ * allow the bound app to get the same capabilities, as long as it has the required permissions
+ * as well.
+ */
+ public static final int BIND_INCLUDE_CAPABILITIES = 0x00001000;
+
+ /**
* Flag for {@link #bindService}: This flag is intended to be used only by the system to adjust
* the scheduling policy for IMEs (and any other out-of-process user-visible components that
* work closely with the top app) so that UI hosted in such services can have the same
@@ -4644,11 +4652,10 @@
/**
* Use with {@link #getSystemService(String)} to retrieve an
- * {@link android.os.DynamicAndroidManager}.
+ * {@link android.os.image.DynamicSystemManager}.
* @hide
*/
- @SystemApi
- public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android";
+ public static final String DYNAMIC_SYSTEM_SERVICE = "dynamic_system";
/**
* Determine whether the given permission is allowed for a particular
@@ -5322,6 +5329,7 @@
* @return display ID associated with this {@link Context}.
* @hide
*/
+ @TestApi
public abstract int getDisplayId();
/**
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index 999d986..aabe59d 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -18,12 +18,14 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
/**
* Immutable overlay information about a package. All PackageInfos that
@@ -138,6 +140,14 @@
public final String targetPackageName;
/**
+ * Name of the target overlayable declaration.
+ *
+ * @hide
+ */
+ @SystemApi
+ public final String targetOverlayableName;
+
+ /**
* Category of the overlay package
*
* @hide
@@ -190,16 +200,19 @@
* @hide
*/
public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
- this(source.packageName, source.targetPackageName, source.category, source.baseCodePath,
- state, source.userId, source.priority, source.isStatic);
+ this(source.packageName, source.targetPackageName, source.targetOverlayableName,
+ source.category, source.baseCodePath, state, source.userId, source.priority,
+ source.isStatic);
}
/** @hide */
public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
- @NonNull String category, @NonNull String baseCodePath, int state, int userId,
+ @Nullable String targetOverlayableName, @Nullable String category,
+ @NonNull String baseCodePath, int state, int userId,
int priority, boolean isStatic) {
this.packageName = packageName;
this.targetPackageName = targetPackageName;
+ this.targetOverlayableName = targetOverlayableName;
this.category = category;
this.baseCodePath = baseCodePath;
this.state = state;
@@ -213,6 +226,7 @@
public OverlayInfo(Parcel source) {
packageName = source.readString();
targetPackageName = source.readString();
+ targetOverlayableName = source.readString();
category = source.readString();
baseCodePath = source.readString();
state = source.readInt();
@@ -256,6 +270,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(packageName);
dest.writeString(targetPackageName);
+ dest.writeString(targetOverlayableName);
dest.writeString(category);
dest.writeString(baseCodePath);
dest.writeInt(state);
@@ -335,6 +350,8 @@
result = prime * result + state;
result = prime * result + ((packageName == null) ? 0 : packageName.hashCode());
result = prime * result + ((targetPackageName == null) ? 0 : targetPackageName.hashCode());
+ result = prime * result + ((targetOverlayableName == null) ? 0
+ : targetOverlayableName.hashCode());
result = prime * result + ((category == null) ? 0 : category.hashCode());
result = prime * result + ((baseCodePath == null) ? 0 : baseCodePath.hashCode());
return result;
@@ -364,7 +381,10 @@
if (!targetPackageName.equals(other.targetPackageName)) {
return false;
}
- if (!category.equals(other.category)) {
+ if (!Objects.equals(targetOverlayableName, other.targetOverlayableName)) {
+ return false;
+ }
+ if (!Objects.equals(category, other.category)) {
return false;
}
if (!baseCodePath.equals(other.baseCodePath)) {
@@ -375,7 +395,9 @@
@Override
public String toString() {
- return "OverlayInfo { overlay=" + packageName + ", target=" + targetPackageName + ", state="
- + state + " (" + stateToString(state) + "), userId=" + userId + " }";
+ return "OverlayInfo { overlay=" + packageName + ", targetPackage=" + targetPackageName
+ + ((targetOverlayableName == null) ? ""
+ : ", targetOverlyabale=" + targetOverlayableName)
+ + ", state=" + state + " (" + stateToString(state) + "), userId=" + userId + " }";
}
}
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index 725d601..d6fb28f 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -354,12 +354,12 @@
public String overlayTarget;
/**
- * What overlayable set of elements package, if any, this package will overlay.
+ * The name of the overlayable set of elements package, if any, this package will overlay.
*
* Overlayable name defined within the target package, or null.
* @hide
*/
- public String overlayTargetName;
+ public String targetOverlayableName;
/**
* The overlay category, if any, of this package
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 743a302..b480939 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -689,7 +689,7 @@
pi.restrictedAccountType = p.mRestrictedAccountType;
pi.requiredAccountType = p.mRequiredAccountType;
pi.overlayTarget = p.mOverlayTarget;
- pi.overlayTargetName = p.mOverlayTargetName;
+ pi.targetOverlayableName = p.mOverlayTargetName;
pi.overlayCategory = p.mOverlayCategory;
pi.overlayPriority = p.mOverlayPriority;
pi.mOverlayIsStatic = p.mOverlayIsStatic;
diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl
index b5c6604..e1d605e 100644
--- a/core/java/android/os/IPowerManager.aidl
+++ b/core/java/android/os/IPowerManager.aidl
@@ -53,10 +53,10 @@
boolean isPowerSaveMode();
PowerSaveState getPowerSaveState(int serviceType);
boolean setPowerSaveModeEnabled(boolean mode);
- boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled, int disableThreshold);
+ boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold);
boolean setAdaptivePowerSavePolicy(in BatterySaverPolicyConfig config);
boolean setAdaptivePowerSaveEnabled(boolean enabled);
- int getPowerSaveMode();
+ int getPowerSaveModeTrigger();
boolean isDeviceIdleMode();
boolean isLightDeviceIdleMode();
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 36bae2d..64e2f89 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -1460,7 +1460,7 @@
* an on/off switch for a subset of features.
* @hide
*
- * @param dynamicPowerSavingsEnabled A signal indicating to the system if it believes the
+ * @param powerSaveHint A signal indicating to the system if it believes the
* dynamic power savings behaviors should be activated.
* @param disableThreshold When the suggesting app believes it would be safe to disable dynamic
* power savings behaviors.
@@ -1471,10 +1471,9 @@
@SystemApi
@TestApi
@RequiresPermission(permission.POWER_SAVER)
- public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled,
- int disableThreshold) {
+ public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) {
try {
- return mService.setDynamicPowerSavings(dynamicPowerSavingsEnabled, disableThreshold);
+ return mService.setDynamicPowerSaveHint(powerSaveHint, disableThreshold);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1525,54 +1524,54 @@
/**
* Indicates automatic battery saver toggling by the system will be based on percentage.
*
- * @see PowerManager#getPowerSaveMode()
+ * @see PowerManager#getPowerSaveModeTrigger()
*
* @hide
*/
@SystemApi
@TestApi
- public static final int POWER_SAVER_MODE_PERCENTAGE = 0;
+ public static final int POWER_SAVE_MODE_TRIGGER_PERCENTAGE = 0;
/**
* Indicates automatic battery saver toggling by the system will be based on the state
* of the dynamic power savings signal.
*
- * @see PowerManager#setDynamicPowerSavings(boolean, int)
- * @see PowerManager#getPowerSaveMode()
+ * @see PowerManager#setDynamicPowerSaveHint(boolean, int)
+ * @see PowerManager#getPowerSaveModeTrigger()
*
* @hide
*/
@SystemApi
@TestApi
- public static final int POWER_SAVER_MODE_DYNAMIC = 1;
+ public static final int POWER_SAVE_MODE_TRIGGER_DYNAMIC = 1;
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
- POWER_SAVER_MODE_PERCENTAGE,
- POWER_SAVER_MODE_DYNAMIC
+ POWER_SAVE_MODE_TRIGGER_PERCENTAGE,
+ POWER_SAVE_MODE_TRIGGER_DYNAMIC
})
- public @interface AutoPowerSaverMode{}
+ public @interface AutoPowerSaveModeTriggers {}
/**
* Returns the current battery saver control mode. Values it may return are defined in
- * AutoPowerSaverMode. Note that this is a global device state, not a per user setting.
+ * AutoPowerSaveModeTriggers. Note that this is a global device state, not a per user setting.
*
* @return The current value power saver mode for the system.
*
- * @see AutoPowerSaverMode
- * @see PowerManager#getPowerSaveMode()
+ * @see AutoPowerSaveModeTriggers
+ * @see PowerManager#getPowerSaveModeTrigger()
* @hide
*/
- @AutoPowerSaverMode
+ @AutoPowerSaveModeTriggers
@SystemApi
@TestApi
@RequiresPermission(android.Manifest.permission.POWER_SAVER)
- public int getPowerSaveMode() {
+ public int getPowerSaveModeTrigger() {
try {
- return mService.getPowerSaveMode();
+ return mService.getPowerSaveModeTrigger();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index c74cbff..7958ddd 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -23,7 +23,7 @@
import android.content.ContentResolver;
import android.content.Context;
import android.hardware.vibrator.V1_0.EffectStrength;
-import android.hardware.vibrator.V1_2.Effect;
+import android.hardware.vibrator.V1_3.Effect;
import android.net.Uri;
import android.util.MathUtils;
@@ -94,6 +94,18 @@
*/
public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK;
+ /**
+ * A texture effect meant to replicate soft ticks.
+ *
+ * Unlike normal effects, texture effects are meant to be called repeatedly, generally in
+ * response to some motion, in order to replicate the feeling of some texture underneath the
+ * user's fingers.
+ *
+ * @see #get(int)
+ * @hide
+ */
+ public static final int EFFECT_TEXTURE_TICK = Effect.TEXTURE_TICK;
+
/** {@hide} */
@TestApi
public static final int EFFECT_STRENGTH_LIGHT = EffectStrength.LIGHT;
@@ -746,6 +758,7 @@
case EFFECT_CLICK:
case EFFECT_DOUBLE_CLICK:
case EFFECT_TICK:
+ case EFFECT_TEXTURE_TICK:
case EFFECT_THUD:
case EFFECT_POP:
case EFFECT_HEAVY_CLICK:
@@ -798,7 +811,7 @@
out.writeInt(mEffectStrength);
}
- public static final @android.annotation.NonNull Parcelable.Creator<Prebaked> CREATOR =
+ public static final @NonNull Parcelable.Creator<Prebaked> CREATOR =
new Parcelable.Creator<Prebaked>() {
@Override
public Prebaked createFromParcel(Parcel in) {
@@ -813,7 +826,7 @@
};
}
- public static final @android.annotation.NonNull Parcelable.Creator<VibrationEffect> CREATOR =
+ public static final @NonNull Parcelable.Creator<VibrationEffect> CREATOR =
new Parcelable.Creator<VibrationEffect>() {
@Override
public VibrationEffect createFromParcel(Parcel in) {
diff --git a/core/java/android/content/DynamicAndroidClient.java b/core/java/android/os/image/DynamicSystemClient.java
similarity index 64%
rename from core/java/android/content/DynamicAndroidClient.java
rename to core/java/android/os/image/DynamicSystemClient.java
index 571cba4..33a6ee8 100644
--- a/core/java/android/content/DynamicAndroidClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -13,12 +13,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content;
+package android.os.image;
+import android.annotation.BytesLong;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
@@ -34,12 +40,28 @@
import java.util.concurrent.Executor;
/**
- * This class contains methods and constants used to start DynamicAndroid
- * installation, and a listener for progress update.
+ * <p>This class contains methods and constants used to start a {@code DynamicSystem} installation,
+ * and a listener for status updates.</p>
+ *
+ * <p>{@code DynamicSystem} allows user to run certified system images in a non destructive manner
+ * without needing to prior OEM unlock. While running in {@code DynamicSystem}, persitent storage
+ * for factory reset protection (FRP) remains unchanged. The new system is installed in a
+ * temporarily allocated partition. After the installation is completed, the device will be running
+ * in the new system on next reboot. Then, when the user reboots the device again, it will leave
+ * {@code DynamicSystem} and go back into the original system. Since the userdata for
+ * {@code DynamicSystem} is also newly created during the installation, running in
+ * {@code DynamicSystem} doesn't change user's app data.</p>
+ *
+ * <p>With {@link #setOnStatusChangedListener}, API users can register an
+ * {@link #OnStatusChangedListener} and get status updates and cause when the installation is
+ * started, stopped, or cancelled. It also sends progress updates during the installation. With
+ * {@link #start}, API users can start an installation with the {@link Uri} to a gzipped system
+ * image. The {@link Uri} can be a web URL or a content Uri to a local path.</p>
+ *
* @hide
*/
@SystemApi
-public class DynamicAndroidClient {
+public class DynamicSystemClient {
/** @hide */
@IntDef(prefix = { "STATUS_" }, value = {
STATUS_UNKNOWN,
@@ -64,23 +86,23 @@
@Retention(RetentionPolicy.SOURCE)
public @interface StatusChangedCause {}
- private static final String TAG = "DynAndroidClient";
+ private static final String TAG = "DynSystemClient";
private static final long DEFAULT_USERDATA_SIZE = (10L << 30);
- /** Listener for installation status update. */
+ /** Listener for installation status updates. */
public interface OnStatusChangedListener {
/**
* This callback is called when installation status is changed, and when the
- * client is {@link #bind} to DynamicAndroid installation service.
+ * client is {@link #bind} to {@code DynamicSystem} installation service.
*
- * @param status status code, also defined in {@code DynamicAndroidClient}.
- * @param cause cause code, also defined in {@code DynamicAndroidClient}.
+ * @param status status code, also defined in {@code DynamicSystemClient}.
+ * @param cause cause code, also defined in {@code DynamicSystemClient}.
* @param progress number of bytes installed.
*/
void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause,
- long progress);
+ @BytesLong long progress);
}
/*
@@ -98,7 +120,7 @@
/** Installation is finished but the user has not launched it. */
public static final int STATUS_READY = 3;
- /** Device is running in Dynamic Android. */
+ /** Device is running in {@code DynamicSystem}. */
public static final int STATUS_IN_USE = 4;
/*
@@ -113,7 +135,7 @@
/** Status changed because installation is cancelled. */
public static final int CAUSE_INSTALL_CANCELLED = 2;
- /** Installation failed due to IOException. */
+ /** Installation failed due to {@code IOException}. */
public static final int CAUSE_ERROR_IO = 3;
/** Installation failed because the image URL source is not supported. */
@@ -141,7 +163,7 @@
public static final int MSG_UNREGISTER_LISTENER = 2;
/**
- * Message for status update.
+ * Message for status updates.
* @hide
*/
public static final int MSG_POST_STATUS = 3;
@@ -150,7 +172,7 @@
* Messages keys
*/
/**
- * Message key, for progress update.
+ * Message key, for progress updates.
* @hide
*/
public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE";
@@ -163,14 +185,14 @@
* @hide
*/
public static final String ACTION_START_INSTALL =
- "android.content.action.START_INSTALL";
+ "android.os.image.action.START_INSTALL";
/**
- * Intent action: notify user if we are currently running in Dynamic Android.
+ * Intent action: notify user if we are currently running in {@code DynamicSystem}.
* @hide
*/
public static final String ACTION_NOTIFY_IF_IN_USE =
- "android.content.action.NOTIFY_IF_IN_USE";
+ "android.os.image.action.NOTIFY_IF_IN_USE";
/*
* Intent Keys
@@ -195,16 +217,16 @@
private static class IncomingHandler extends Handler {
- private final WeakReference<DynamicAndroidClient> mWeakClient;
+ private final WeakReference<DynamicSystemClient> mWeakClient;
- IncomingHandler(DynamicAndroidClient service) {
+ IncomingHandler(DynamicSystemClient service) {
super(Looper.getMainLooper());
mWeakClient = new WeakReference<>(service);
}
@Override
public void handleMessage(Message msg) {
- DynamicAndroidClient service = mWeakClient.get();
+ DynamicSystemClient service = mWeakClient.get();
if (service != null) {
service.handleMessage(msg);
@@ -212,9 +234,9 @@
}
}
- private class DynAndroidServiceConnection implements ServiceConnection {
+ private class DynSystemServiceConnection implements ServiceConnection {
public void onServiceConnected(ComponentName className, IBinder service) {
- Slog.v(TAG, "DynAndroidService connected");
+ Slog.v(TAG, "DynSystemService connected");
mService = new Messenger(service);
@@ -232,13 +254,13 @@
}
public void onServiceDisconnected(ComponentName className) {
- Slog.v(TAG, "DynAndroidService disconnected");
+ Slog.v(TAG, "DynSystemService disconnected");
mService = null;
}
}
private final Context mContext;
- private final DynAndroidServiceConnection mConnection;
+ private final DynSystemServiceConnection mConnection;
private final Messenger mMessenger;
private boolean mBound;
@@ -247,12 +269,16 @@
private Messenger mService;
/**
+ * Create a new {@code DynamicSystem} client.
+ *
+ * @param context a {@link Context} will be used to bind the installation service.
+ *
* @hide
*/
@SystemApi
- public DynamicAndroidClient(@NonNull Context context) {
+ public DynamicSystemClient(@NonNull Context context) {
mContext = context;
- mConnection = new DynAndroidServiceConnection();
+ mConnection = new DynSystemServiceConnection();
mMessenger = new Messenger(new IncomingHandler(this));
}
@@ -261,8 +287,8 @@
* the executor.
*/
public void setOnStatusChangedListener(
- @NonNull OnStatusChangedListener listener,
- @NonNull @CallbackExecutor Executor executor) {
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnStatusChangedListener listener) {
mListener = listener;
mExecutor = executor;
}
@@ -278,12 +304,15 @@
}
/**
- * Bind to DynamicAndroidInstallationService.
+ * Bind to {@code DynamicSystem} installation service. Binding to the installation service
+ * allows it to send status updates to {@link #OnStatusChangedListener}. It is recommanded
+ * to bind before calling {@link #start} and get status updates.
*/
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public void bind() {
Intent intent = new Intent();
- intent.setClassName("com.android.dynandroid",
- "com.android.dynandroid.DynamicAndroidInstallationService");
+ intent.setClassName("com.android.dynsystem",
+ "com.android.dynsystem.DynamicSystemInstallationService");
mContext.bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
@@ -291,8 +320,10 @@
}
/**
- * Unbind from DynamicAndroidInstallationService.
+ * Unbind from {@code DynamicSystem} installation service. Unbinding from the installation
+ * service stops it from sending following status updates.
*/
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public void unbind() {
if (!mBound) {
return;
@@ -315,27 +346,40 @@
}
/**
- * Start installing DynamicAndroid from URL with default userdata size.
+ * Start installing {@code DynamicSystem} from URL with default userdata size.
+ *
+ * Calling this function will first start an Activity to confirm device credential, using
+ * {@link KeyguardManager}. If it's confirmed, the installation service will be started.
+ *
+ * This function doesn't require prior calling {@link #bind}.
*
* @param systemUrl A network URL or a file URL to system image.
* @param systemSize size of system image.
*/
- public void start(String systemUrl, long systemSize) {
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+ public void start(@NonNull String systemUrl, @BytesLong long systemSize) {
start(systemUrl, systemSize, DEFAULT_USERDATA_SIZE);
}
/**
- * Start installing DynamicAndroid from URL.
+ * Start installing {@code DynamicSystem} from URL.
+ *
+ * Calling this function will first start an Activity to confirm device credential, using
+ * {@link KeyguardManager}. If it's confirmed, the installation service will be started.
+ *
+ * This function doesn't require prior calling {@link #bind}.
*
* @param systemUrl A network URL or a file URL to system image.
* @param systemSize size of system image.
* @param userdataSize bytes reserved for userdata.
*/
- public void start(String systemUrl, long systemSize, long userdataSize) {
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
+ public void start(@NonNull String systemUrl, @BytesLong long systemSize,
+ @BytesLong long userdataSize) {
Intent intent = new Intent();
- intent.setClassName("com.android.dynandroid",
- "com.android.dynandroid.VerificationActivity");
+ intent.setClassName("com.android.dynsystem",
+ "com.android.dynsystem.VerificationActivity");
intent.setAction(ACTION_START_INSTALL);
diff --git a/core/java/android/os/DynamicAndroidManager.java b/core/java/android/os/image/DynamicSystemManager.java
similarity index 81%
rename from core/java/android/os/DynamicAndroidManager.java
rename to core/java/android/os/image/DynamicSystemManager.java
index 5238896..0458c2a 100644
--- a/core/java/android/os/DynamicAndroidManager.java
+++ b/core/java/android/os/image/DynamicSystemManager.java
@@ -14,50 +14,51 @@
* limitations under the License.
*/
-package android.os;
+package android.os.image;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.gsi.GsiProgress;
+import android.os.RemoteException;
/**
- * The DynamicAndroidManager offers a mechanism to use a new Android image temporarily. After the
+ * The DynamicSystemManager offers a mechanism to use a new system image temporarily. After the
* installation, the device can reboot into this image with a new created /data. This image will
* last until the next reboot and then the device will go back to the original image. However the
* installed image and the new created /data are not deleted but disabled. Thus the application can
* either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to
* delete it completely. In other words, there are three device states: no installation, installed
- * and running. The procedure to install a DynamicAndroid starts with a {@link #startInstallation},
+ * and running. The procedure to install a DynamicSystem starts with a {@link #startInstallation},
* followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is
* complete, the device state changes from no installation to the installed state and a followed
- * reboot will change its state to running. Note one instance of dynamic android can exist on a
- * given device thus the {@link #startInstallation} will fail if the device is currently running a
- * DynamicAndroid.
+ * reboot will change its state to running. Note one instance of DynamicSystem can exist on a given
+ * device thus the {@link #startInstallation} will fail if the device is currently running a
+ * DynamicSystem.
*
* @hide
*/
-@SystemService(Context.DYNAMIC_ANDROID_SERVICE)
-public class DynamicAndroidManager {
- private static final String TAG = "DynamicAndroidManager";
+@SystemService(Context.DYNAMIC_SYSTEM_SERVICE)
+public class DynamicSystemManager {
+ private static final String TAG = "DynamicSystemManager";
- private final IDynamicAndroidService mService;
+ private final IDynamicSystemService mService;
/** {@hide} */
- public DynamicAndroidManager(IDynamicAndroidService service) {
+ public DynamicSystemManager(IDynamicSystemService service) {
mService = service;
}
- /** The DynamicAndroidManager.Session represents a started session for the installation. */
+ /** The DynamicSystemManager.Session represents a started session for the installation. */
public class Session {
private Session() {}
/**
- * Write a chunk of the DynamicAndroid system image
+ * Write a chunk of the DynamicSystem system image
*
* @return {@code true} if the call succeeds. {@code false} if there is any native runtime
* error.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean write(byte[] buf) {
try {
return mService.write(buf);
@@ -72,7 +73,7 @@
* @return {@code true} if the call succeeds. {@code false} if there is any native runtime
* error.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean commit() {
try {
return mService.commit();
@@ -82,16 +83,16 @@
}
}
/**
- * Start DynamicAndroid installation. This call may take an unbounded amount of time. The caller
+ * Start DynamicSystem installation. This call may take an unbounded amount of time. The caller
* may use another thread to call the getStartProgress() to get the progress.
*
* @param systemSize system size in bytes
* @param userdataSize userdata size in bytes
* @return {@code true} if the call succeeds. {@code false} either the device does not contain
- * enough space or a DynamicAndroid is currently in use where the {@link #isInUse} would be
+ * enough space or a DynamicSystem is currently in use where the {@link #isInUse} would be
* true.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public Session startInstallation(long systemSize, long userdataSize) {
try {
if (mService.startInstallation(systemSize, userdataSize)) {
@@ -112,7 +113,7 @@
* status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or
* IGsiService.STATUS_COMPLETE.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public GsiProgress getInstallationProgress() {
try {
return mService.getInstallationProgress();
@@ -129,7 +130,7 @@
* @return {@code true} if the call succeeds. {@code false} if there is no installation
* currently.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean abort() {
try {
return mService.abort();
@@ -138,8 +139,8 @@
}
}
- /** @return {@code true} if the device is running a dynamic android */
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ /** @return {@code true} if the device is running a dynamic system */
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean isInUse() {
try {
return mService.isInUse();
@@ -148,8 +149,8 @@
}
}
- /** @return {@code true} if the device has a dynamic android installed */
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ /** @return {@code true} if the device has a dynamic system installed */
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean isInstalled() {
try {
return mService.isInstalled();
@@ -159,11 +160,11 @@
}
/**
- * Remove DynamicAndroid installation if present
+ * Remove DynamicSystem installation if present
*
* @return {@code true} if the call succeeds. {@code false} if there is no installed image.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean remove() {
try {
return mService.remove();
@@ -173,11 +174,11 @@
}
/**
- * Enable DynamicAndroid when it's not enabled, otherwise, disable it.
+ * Enable DynamicSystem when it's not enabled, otherwise, disable it.
*
* @return {@code true} if the call succeeds. {@code false} if there is no installed image.
*/
- @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean toggle() {
try {
return mService.toggle();
diff --git a/core/java/android/os/IDynamicAndroidService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl
similarity index 83%
rename from core/java/android/os/IDynamicAndroidService.aidl
rename to core/java/android/os/image/IDynamicSystemService.aidl
index 0b28799..15f5b68 100644
--- a/core/java/android/os/IDynamicAndroidService.aidl
+++ b/core/java/android/os/image/IDynamicSystemService.aidl
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.os;
+package android.os.image;
import android.gsi.GsiProgress;
/** {@hide} */
-interface IDynamicAndroidService
+interface IDynamicSystemService
{
/**
- * Start DynamicAndroid installation. This call may take 60~90 seconds. The caller
+ * Start DynamicSystem installation. This call may take 60~90 seconds. The caller
* may use another thread to call the getStartProgress() to get the progress.
*
* @param systemSize system size in bytes
@@ -53,26 +53,26 @@
boolean isInUse();
/**
- * @return true if the device has an DynamicAndroid image installed
+ * @return true if the device has an DynamicSystem image installed
*/
boolean isInstalled();
/**
- * Remove DynamicAndroid installation if present
+ * Remove DynamicSystem installation if present
*
* @return true if the call succeeds
*/
boolean remove();
/**
- * Enable DynamicAndroid when it's not enabled, otherwise, disable it.
+ * Enable DynamicSystem when it's not enabled, otherwise, disable it.
*
* @return true if the call succeeds
*/
boolean toggle();
/**
- * Write a chunk of the DynamicAndroid system image
+ * Write a chunk of the DynamicSystem system image
*
* @return true if the call succeeds
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d4908ca..6dd7ecc 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -73,6 +73,7 @@
import android.os.DropBoxManager;
import android.os.IBinder;
import android.os.LocaleList;
+import android.os.PowerManager.AutoPowerSaveModeTriggers;
import android.os.Process;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -12599,12 +12600,11 @@
/**
* Battery level [1-100] at which low power mode automatically turns on.
* If 0, it will not automatically turn on. For Q and newer, it will only automatically
- * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVER_MODE}
+ * turn on if the value is greater than 0 and the {@link #AUTOMATIC_POWER_SAVE_MODE}
* setting is also set to
- * {@link android.os.PowerManager.AutoPowerSaverMode#POWER_SAVER_MODE_PERCENTAGE}.
- *
- * @see #AUTOMATIC_POWER_SAVER_MODE
- * @see android.os.PowerManager#getPowerSaveMode()
+ * {@link android.os.PowerManager.AutoPowerSaveMode#POWER_SAVE_MODE_TRIGGER_PERCENTAGE}.
+ * @see #AUTOMATIC_POWER_SAVE_MODE
+ * @see android.os.PowerManager#getPowerSaveModeTrigger()
* @hide
*/
public static final String LOW_POWER_MODE_TRIGGER_LEVEL = "low_power_trigger_level";
@@ -12614,22 +12614,22 @@
/**
* Whether battery saver is currently set to trigger based on percentage, dynamic power
- * savings trigger, or none. See {@link android.os.PowerManager.AutoPowerSaverMode} for
+ * savings trigger, or none. See {@link AutoPowerSaveModeTriggers} for
* accepted values.
*
* @hide
*/
@TestApi
- public static final String AUTOMATIC_POWER_SAVER_MODE = "automatic_power_saver_mode";
+ public static final String AUTOMATIC_POWER_SAVE_MODE = "automatic_power_save_mode";
- private static final Validator AUTOMATIC_POWER_SAVER_MODE_VALIDATOR =
+ private static final Validator AUTOMATIC_POWER_SAVE_MODE_VALIDATOR =
new SettingsValidators.DiscreteValueValidator(new String[] {"0", "1"});
/**
* The setting that backs the disable threshold for the setPowerSavingsWarning api in
* PowerManager
*
- * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int)
+ * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int)
* @hide
*/
@TestApi
@@ -12639,9 +12639,9 @@
new SettingsValidators.InclusiveIntegerRangeValidator(0, 100);
/**
- * The setting which backs the setDynamicPowerSavings api in PowerManager.
+ * The setting which backs the setDynamicPowerSaveHint api in PowerManager.
*
- * @see android.os.PowerManager#setDynamicPowerSavings(boolean, int)
+ * @see android.os.PowerManager#setDynamicPowerSaveHint(boolean, int)
* @hide
*/
@TestApi
@@ -13630,7 +13630,7 @@
VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL, LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
VALIDATORS.put(LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
LOW_POWER_MODE_TRIGGER_LEVEL_VALIDATOR);
- VALIDATORS.put(AUTOMATIC_POWER_SAVER_MODE, AUTOMATIC_POWER_SAVER_MODE_VALIDATOR);
+ VALIDATORS.put(AUTOMATIC_POWER_SAVE_MODE, AUTOMATIC_POWER_SAVE_MODE_VALIDATOR);
VALIDATORS.put(DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
DYNAMIC_POWER_SAVINGS_VALIDATOR);
VALIDATORS.put(BLUETOOTH_ON, BLUETOOTH_ON_VALIDATOR);
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index df11397..fb07aba 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -298,12 +298,12 @@
/**
* Disables the Content Capture service for the given user.
*/
- public final void disableContentCaptureServices() {
- if (sDebug) Log.d(TAG, "disableContentCaptureServices()");
+ public final void disableSelf() {
+ if (sDebug) Log.d(TAG, "disableSelf()");
final IContentCaptureServiceCallback callback = mCallback;
if (callback == null) {
- Log.w(TAG, "disableContentCaptureServices(): no server callback");
+ Log.w(TAG, "disableSelf(): no server callback");
return;
}
try {
@@ -367,7 +367,6 @@
stateFlags = initialState;
} else {
stateFlags |= ContentCaptureSession.STATE_DISABLED;
-
}
setClientState(clientReceiver, stateFlags, mClientInterface.asBinder());
}
diff --git a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
index 6ecd82f..fb60619 100644
--- a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
+++ b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java
@@ -139,6 +139,7 @@
mSettingsActivity = settingsActivity;
}
+ @NonNull
public ServiceInfo getServiceInfo() {
return mServiceInfo;
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index de10ffb..da6ef4c 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -52,14 +52,14 @@
DEFAULT_FLAGS.put("settings_slice_injection", "true");
DEFAULT_FLAGS.put("settings_systemui_theme", "true");
DEFAULT_FLAGS.put("settings_mainline_module", "true");
- DEFAULT_FLAGS.put("settings_dynamic_android", "false");
+ DEFAULT_FLAGS.put("settings_dynamic_system", "false");
DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false");
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, "true");
DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
- DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "false");
+ DEFAULT_FLAGS.put("settings_wifi_details_saved_screen", "true");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index cd075bf..0043d32 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -88,10 +88,10 @@
private static native void nativeDestroy(long nativeObject);
private static native void nativeDisconnect(long nativeObject);
- private static native GraphicBuffer nativeScreenshot(IBinder displayToken,
+ private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
boolean captureSecureLayers);
- private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
+ private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
Rect sourceCrop, float frameScale);
private static native long nativeCreateTransaction();
@@ -431,7 +431,52 @@
public static final int METADATA_TASK_ID = 3;
/**
+ * A wrapper around GraphicBuffer that contains extra information about how to
+ * interpret the screenshot GraphicBuffer.
+ * @hide
+ */
+ public static class ScreenshotGraphicBuffer {
+ private final GraphicBuffer mGraphicBuffer;
+ private final ColorSpace mColorSpace;
+
+ public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
+ mGraphicBuffer = graphicBuffer;
+ mColorSpace = colorSpace;
+ }
+
+ /**
+ * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object.
+ * @param width The width in pixels of the buffer
+ * @param height The height in pixels of the buffer
+ * @param format The format of each pixel as specified in {@link PixelFormat}
+ * @param usage Hint indicating how the buffer will be used
+ * @param unwrappedNativeObject The native object of GraphicBuffer
+ * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
+ */
+ private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
+ int usage, long unwrappedNativeObject, int namedColorSpace) {
+ GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
+ usage, unwrappedNativeObject);
+ ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
+ return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
+ }
+
+ public ColorSpace getColorSpace() {
+ return mColorSpace;
+ }
+
+ public GraphicBuffer getGraphicBuffer() {
+ return mGraphicBuffer;
+ }
+ }
+
+ /**
* Builder class for {@link SurfaceControl} objects.
+ *
+ * By default the surface will be hidden, and have "unset" bounds, meaning it can
+ * be as large as the bounds of its parent if a buffer or child so requires.
+ *
+ * It is necessary to set at least a name via {@link Builder#setName}
*/
public static class Builder {
private SurfaceSession mSession;
@@ -466,11 +511,11 @@
@NonNull
public SurfaceControl build() {
if (mWidth < 0 || mHeight < 0) {
- throw new IllegalArgumentException(
+ throw new IllegalStateException(
"width and height must be positive or unset");
}
if ((mWidth > 0 || mHeight > 0) && (isColorLayerSet() || isContainerLayerSet())) {
- throw new IllegalArgumentException(
+ throw new IllegalStateException(
"Only buffer layers can set a valid buffer size.");
}
return new SurfaceControl(
@@ -860,7 +905,9 @@
* Release the local reference to the server-side surface. The surface
* may continue to exist on-screen as long as its parent continues
* to exist. To explicitly remove a surface from the screen use
- * {@link Transaction#reparent} with a null-parent.
+ * {@link Transaction#reparent} with a null-parent. After release,
+ * {@link #isValid} will return false and other methods will throw
+ * an exception.
*
* Always call release() when you're done with a SurfaceControl.
*/
@@ -902,7 +949,8 @@
/**
* Check whether this instance points to a valid layer with the system-compositor. For
- * example this may be false if construction failed, or the layer was released.
+ * example this may be false if construction failed, or the layer was released
+ * ({@link #release}).
*
* @return Whether this SurfaceControl is valid.
*/
@@ -1815,10 +1863,10 @@
throw new IllegalArgumentException("consumer must not be null");
}
- final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height,
- useIdentityTransform, rotation);
+ final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
+ height, useIdentityTransform, rotation);
try {
- consumer.attachAndQueueBuffer(buffer);
+ consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
} catch (RuntimeException e) {
Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
@@ -1861,17 +1909,16 @@
}
SurfaceControl.rotateCropForSF(sourceCrop, rotation);
- final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height,
- useIdentityTransform, rotation);
+ final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width,
+ height, useIdentityTransform, rotation);
if (buffer == null) {
Log.w(TAG, "Failed to take screenshot");
return null;
}
- // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
- // should continue to fix screenshot.
- return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer),
- ColorSpace.get(ColorSpace.Named.SRGB));
+ return Bitmap.wrapHardwareBuffer(
+ HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()),
+ buffer.getColorSpace());
}
/**
@@ -1897,8 +1944,8 @@
* @return Returns a GraphicBuffer that contains the captured content.
* @hide
*/
- public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width,
- int height, boolean useIdentityTransform, int rotation) {
+ public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop,
+ int width, int height, boolean useIdentityTransform, int rotation) {
if (display == null) {
throw new IllegalArgumentException("displayToken must not be null");
}
@@ -1917,7 +1964,7 @@
*
* @hide
*/
- public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
+ public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
Rect sourceCrop, int width, int height, boolean useIdentityTransform,
int rotation) {
if (display == null) {
@@ -1951,7 +1998,7 @@
* @return Returns a GraphicBuffer that contains the layer capture.
* @hide
*/
- public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
+ public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
float frameScale) {
return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
}
@@ -2042,8 +2089,7 @@
}
/**
- * Close the transaction, if the transaction was not already applied this will cancel the
- * transaction.
+ * Release the native transaction object, without applying it.
*/
@Override
public void close() {
@@ -2128,8 +2174,8 @@
}
/**
- * Set the default buffer size for the SurfaceControl, if there is an
- * {@link Surface} assosciated with the control, then
+ * Set the default buffer size for the SurfaceControl, if there is a
+ * {@link Surface} associated with the control, then
* this will be the default size for buffers dequeued from it.
* @param sc The surface to set the buffer size for.
* @param w The default width
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index ee8d663..e931448 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -491,7 +491,7 @@
if (mBackgroundControl == null) {
return;
}
- if ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0) {
+ if ((mSubLayer > 0) && ((mSurfaceFlags & SurfaceControl.OPAQUE) != 0)) {
mBackgroundControl.show();
mBackgroundControl.setLayer(Integer.MIN_VALUE);
} else {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index a4d80dc..9101c36 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -142,7 +142,7 @@
* This field should be made private, so it is hidden from the SDK.
* {@hide}
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768704)
protected OnHierarchyChangeListener mOnHierarchyChangeListener;
// The view contained within this ViewGroup that has or contains focus.
@@ -239,7 +239,7 @@
@ViewDebug.FlagToString(mask = FLAG_PADDING_NOT_NULL, equals = FLAG_PADDING_NOT_NULL,
name = "PADDING_NOT_NULL")
}, formatToHexString = true)
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769411)
protected int mGroupFlags;
/**
@@ -314,7 +314,7 @@
*
* {@hide}
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769647)
protected static final int FLAG_SUPPORT_STATIC_TRANSFORMATIONS = 0x800;
// UNUSED FLAG VALUE: 0x1000;
@@ -368,7 +368,7 @@
* When set, this ViewGroup should not intercept touch events.
* {@hide}
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123983692)
protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
/**
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 35ed7bf..46a59f0 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -54,6 +54,16 @@
int NAV_BAR_RIGHT = 1 << 1;
int NAV_BAR_BOTTOM = 1 << 2;
+ // Navigation bar interaction modes
+ int NAV_BAR_MODE_3BUTTON = 0;
+ int NAV_BAR_MODE_2BUTTON = 1;
+ int NAV_BAR_MODE_GESTURAL = 2;
+
+ // Associated overlays for each nav bar mode
+ String NAV_BAR_MODE_3BUTTON_OVERLAY = "com.android.internal.systemui.navbar.threebutton";
+ String NAV_BAR_MODE_2BUTTON_OVERLAY = "com.android.internal.systemui.navbar.twobutton";
+ String NAV_BAR_MODE_GESTURAL_OVERLAY = "com.android.internal.systemui.navbar.gestural";
+
/**
* Broadcast sent when a user activity is detected.
*/
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index a3e6549..afddc38 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -32,6 +32,7 @@
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.util.Log;
import android.view.contentcapture.ContentCaptureSession.FlushReason;
@@ -52,11 +53,13 @@
private static final String TAG = ContentCaptureManager.class.getSimpleName();
/** @hide */
+ public static final int RESULT_CODE_OK = 0;
+ /** @hide */
public static final int RESULT_CODE_TRUE = 1;
/** @hide */
public static final int RESULT_CODE_FALSE = 2;
/** @hide */
- public static final int RESULT_CODE_NOT_SERVICE = -1;
+ public static final int RESULT_CODE_SECURITY_EXCEPTION = -1;
/**
* Timeout for calls to system_server.
@@ -297,6 +300,34 @@
}
/**
+ * Gets the (optional) intent used to launch the service-specific settings.
+ *
+ * <p>This method is static because it's called by Settings, which might not be whitelisted
+ * for content capture (in which case the ContentCaptureManager on its context would be null).
+ *
+ * @hide
+ */
+ @Nullable
+ public static ComponentName getServiceSettingsComponentName() {
+ final IBinder binder = ServiceManager
+ .checkService(Context.CONTENT_CAPTURE_MANAGER_SERVICE);
+ if (binder == null) return null;
+
+ final IContentCaptureManager service = IContentCaptureManager.Stub.asInterface(binder);
+ final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS);
+ try {
+ service.getServiceSettingsActivity(resultReceiver);
+ final int resultCode = resultReceiver.getIntResult();
+ if (resultCode == RESULT_CODE_SECURITY_EXCEPTION) {
+ throw new SecurityException(resultReceiver.getStringResult());
+ }
+ return resultReceiver.getParcelableResult();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Checks whether content capture is enabled for this activity.
*
* <p>There are many reasons it could be disabled, such as:
@@ -365,7 +396,7 @@
return true;
case RESULT_CODE_FALSE:
return false;
- case RESULT_CODE_NOT_SERVICE:
+ case RESULT_CODE_SECURITY_EXCEPTION:
throw new SecurityException("caller is not user's ContentCapture service");
default:
Log.wtf(TAG, "received invalid result: " + resultCode);
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 6d41b28..ed1ca2a 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -135,11 +135,18 @@
public static final int STATE_SERVICE_DIED = 0x400;
/**
+ * Session is disabled because the service package is being udpated.
+ *
+ * @hide
+ */
+ public static final int STATE_SERVICE_UPDATING = 0x800;
+
+ /**
* Session is enabled, after the service died and came back to live.
*
* @hide
*/
- public static final int STATE_SERVICE_RESURRECTED = 0x800;
+ public static final int STATE_SERVICE_RESURRECTED = 0x1000;
private static final int INITIAL_CHILDREN_CAPACITY = 5;
diff --git a/core/java/android/view/contentcapture/IContentCaptureManager.aidl b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
index e3b0372..15fbaa2 100644
--- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl
+++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl
@@ -67,4 +67,9 @@
* Returns whether the content capture feature is enabled for the calling user.
*/
void isContentCaptureFeatureEnabled(in IResultReceiver result);
+
+ /**
+ * Returns a ComponentName with the name of custom service activity, if defined.
+ */
+ void getServiceSettingsActivity(in IResultReceiver result);
}
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index 666af59..790b8f9 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -230,7 +230,8 @@
/**
* Callback from {@code system_server} after call to
- * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int, IBinder)}
+ * {@link IContentCaptureManager#startSession(IBinder, ComponentName, String, int,
+ * IResultReceiver)}.
*
* @param resultCode session state
* @param binder handle to {@code IContentCaptureDirectManager}
diff --git a/core/java/android/view/textclassifier/TextClassifierImpl.java b/core/java/android/view/textclassifier/TextClassifierImpl.java
index cb44f79..0f2e702e 100644
--- a/core/java/android/view/textclassifier/TextClassifierImpl.java
+++ b/core/java/android/view/textclassifier/TextClassifierImpl.java
@@ -86,7 +86,8 @@
new File("/data/misc/textclassifier/lang_id.model");
// Actions
- private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX = "actions_suggestions.model";
+ private static final String ACTIONS_FACTORY_MODEL_FILENAME_REGEX =
+ "actions_suggestions\\.(.*)\\.model";
private static final File UPDATED_ACTIONS_MODEL =
new File("/data/misc/textclassifier/actions_suggestions.model");
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index a93a011..54fff9b 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -237,7 +237,7 @@
if (DEBUG) {
Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services");
}
- if (isDestroyed()) {
+ if (mChooserListAdapter == null || isDestroyed()) {
break;
}
unbindRemainingServices();
@@ -822,6 +822,7 @@
mRefinementResultReceiver = null;
}
unbindRemainingServices();
+ mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT);
mChooserHandler.removeMessages(CHOOSER_TARGET_SERVICE_RESULT);
if (USE_PREDICTION_MANAGER_FOR_DIRECT_TARGETS) {
mAppPredictor.unregisterPredictionUpdates(mAppPredictorCallback);
@@ -1277,11 +1278,10 @@
}
mAppPredictor.notifyAppTargetEvent(
new AppTargetEvent.Builder(
- new AppTarget(
- new AppTargetId(shortcutId),
- componentName.getPackageName(),
- componentName.getClassName(),
- getUser()),
+ new AppTarget.Builder(new AppTargetId(shortcutId))
+ .setTarget(componentName.getPackageName(), getUser())
+ .setClassName(componentName.getClassName())
+ .build(),
AppTargetEvent.ACTION_LAUNCH
).setLaunchLocation(LAUNCH_LOCATON_DIRECT_SHARE)
.build());
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 5c144d3..0a83fcc 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -481,7 +481,11 @@
@Override
public String toString() {
- return getClass().getSimpleName() + "[" + mComponentName + "]";
+ return getClass().getSimpleName() + "[" + mComponentName
+ + " " + System.identityHashCode(this)
+ + (mService != null ? " (bound)" : " (unbound)")
+ + (mDestroyed ? " (destroyed)" : "")
+ + "]";
}
/**
diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl
index 41e2fc8..b36c3fa 100644
--- a/core/java/com/android/internal/widget/ILockSettings.aidl
+++ b/core/java/com/android/internal/widget/ILockSettings.aidl
@@ -42,7 +42,7 @@
long getLong(in String key, in long defaultValue, in int userId);
@UnsupportedAppUsage
String getString(in String key, in String defaultValue, in int userId);
- void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId);
+ void setLockCredential(in byte[] credential, int type, in byte[] savedCredential, int requestedQuality, int userId, boolean allowUntrustedChange);
void resetKeyStore(int userId);
VerifyCredentialResponse checkCredential(in byte[] credential, int type, int userId,
in ICheckCredentialProgressCallback progressCallback);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 30f4d6f..dd48c15 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -669,17 +669,25 @@
/**
* Clear any lock pattern or password.
*/
- public void clearLock(byte[] savedCredential, int userHandle) {
+ public boolean clearLock(byte[] savedCredential, int userHandle) {
+ return clearLock(savedCredential, userHandle, false);
+ }
+
+ /**
+ * Clear any lock pattern or password, with the option to ignore incorrect existing credential.
+ */
+ public boolean clearLock(byte[] savedCredential, int userHandle, boolean allowUntrustedChange) {
final int currentQuality = getKeyguardStoredPasswordQuality(userHandle);
setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_UNSPECIFIED, userHandle);
try{
getLockSettings().setLockCredential(null, CREDENTIAL_TYPE_NONE,
- savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle);
+ savedCredential, PASSWORD_QUALITY_UNSPECIFIED, userHandle,
+ allowUntrustedChange);
} catch (Exception e) {
Log.e(TAG, "Failed to clear lock", e);
setKeyguardStoredPasswordQuality(currentQuality, userHandle);
- return;
+ return false;
}
if (userHandle == UserHandle.USER_SYSTEM) {
@@ -689,6 +697,7 @@
}
onAfterChangingPassword(userHandle);
+ return true;
}
/**
@@ -726,19 +735,28 @@
/**
* Save a lock pattern.
* @param pattern The new pattern to save.
+ * @param savedPattern The previously saved pattern, converted to byte[] format
* @param userId the user whose pattern is to be saved.
+ *
+ * @return whether this was successful or not.
*/
- public void saveLockPattern(List<LockPatternView.Cell> pattern, int userId) {
- this.saveLockPattern(pattern, null, userId);
+ public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
+ int userId) {
+ return saveLockPattern(pattern, savedPattern, userId, false);
}
+
/**
* Save a lock pattern.
* @param pattern The new pattern to save.
* @param savedPattern The previously saved pattern, converted to byte[] format
* @param userId the user whose pattern is to be saved.
+ * @param allowUntrustedChange whether we want to allow saving a new password if the existing
+ * password being provided is incorrect.
+ *
+ * @return whether this was successful or not.
*/
- public void saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
- int userId) {
+ public boolean saveLockPattern(List<LockPatternView.Cell> pattern, byte[] savedPattern,
+ int userId, boolean allowUntrustedChange) {
if (!hasSecureLockScreen()) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
@@ -753,11 +771,11 @@
setKeyguardStoredPasswordQuality(PASSWORD_QUALITY_SOMETHING, userId);
try {
getLockSettings().setLockCredential(bytePattern, CREDENTIAL_TYPE_PATTERN, savedPattern,
- PASSWORD_QUALITY_SOMETHING, userId);
+ PASSWORD_QUALITY_SOMETHING, userId, allowUntrustedChange);
} catch (Exception e) {
Log.e(TAG, "Couldn't save lock pattern", e);
setKeyguardStoredPasswordQuality(currentQuality, userId);
- return;
+ return false;
}
// Update the device encryption password.
if (userId == UserHandle.USER_SYSTEM
@@ -771,6 +789,7 @@
reportPatternWasChosen(userId);
onAfterChangingPassword(userId);
+ return true;
}
private void updateCryptoUserInfo(int userId) {
@@ -873,17 +892,20 @@
* password.
* @param password The password to save
* @param savedPassword The previously saved lock password, or null if none
- * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(android.content.ComponentName)}
+ * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
+ * android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
*
+ * @return whether this was successful or not.
+ *
* @deprecated Pass password as a byte array
*/
@Deprecated
- public void saveLockPassword(String password, String savedPassword, int requestedQuality,
+ public boolean saveLockPassword(String password, String savedPassword, int requestedQuality,
int userHandle) {
byte[] passwordBytes = password != null ? password.getBytes() : null;
byte[] savedPasswordBytes = savedPassword != null ? savedPassword.getBytes() : null;
- saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle);
+ return saveLockPassword(passwordBytes, savedPasswordBytes, requestedQuality, userHandle);
}
/**
@@ -893,11 +915,34 @@
* @param password The password to save
* @param savedPassword The previously saved lock password, or null if none
* @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
- * android.content.ComponentName)}
+ * android.content.ComponentName)}
* @param userHandle The userId of the user to change the password for
+ *
+ * @return whether this was successful or not.
*/
- public void saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
+ public boolean saveLockPassword(byte[] password, byte[] savedPassword, int requestedQuality,
int userHandle) {
+ return saveLockPassword(password, savedPassword, requestedQuality,
+ userHandle, false);
+ }
+
+ /**
+ * Save a lock password. Does not ensure that the password is as good
+ * as the requested mode, but will adjust the mode to be as good as the
+ * password.
+ * @param password The password to save
+ * @param savedPassword The previously saved lock password, or null if none
+ * @param requestedQuality {@see DevicePolicyManager#getPasswordQuality(
+ * android.content.ComponentName)}
+ * @param userHandle The userId of the user to change the password for
+ * @param allowUntrustedChange whether we want to allow saving a new password if the existing
+ * password being provided is incorrect.
+ *
+ * @return whether this method saved the new password successfully or not. This flow will fail
+ * and return false if the given credential is wrong and allowUntrustedChange is false.
+ */
+ public boolean saveLockPassword(byte[] password, byte[] savedPassword,
+ int requestedQuality, int userHandle, boolean allowUntrustedChange) {
if (!hasSecureLockScreen()) {
throw new UnsupportedOperationException(
"This operation requires the lock screen feature.");
@@ -919,16 +964,17 @@
setKeyguardStoredPasswordQuality(newKeyguardQuality, userHandle);
try {
getLockSettings().setLockCredential(password, CREDENTIAL_TYPE_PASSWORD, savedPassword,
- requestedQuality, userHandle);
+ requestedQuality, userHandle, allowUntrustedChange);
} catch (Exception e) {
Log.e(TAG, "Unable to save lock password", e);
setKeyguardStoredPasswordQuality(currentQuality, userHandle);
- return;
+ return false;
}
updateEncryptionPasswordIfNeeded(password, passwordQuality, userHandle);
updatePasswordHistory(password, userHandle);
onAfterChangingPassword(userHandle);
+ return true;
}
/**
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index 02dffdc2..342aba0 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -821,18 +821,18 @@
return jStatus;
}
-static int android_media_AudioRecord_set_microphone_direction(JNIEnv *env, jobject thiz,
- jint direction) {
+static int android_media_AudioRecord_set_preferred_microphone_direction(
+ JNIEnv *env, jobject thiz, jint direction) {
sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
- "Unable to retrieve AudioRecord pointer for setMicrophoneDirection()");
+ "Unable to retrieve AudioRecord pointer for setPreferredMicrophoneDirection()");
return (jint)AUDIO_JAVA_ERROR;
}
jint jStatus = AUDIO_JAVA_SUCCESS;
- status_t status =
- lpRecorder->setMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction));
+ status_t status = lpRecorder->setPreferredMicrophoneDirection(
+ static_cast<audio_microphone_direction_t>(direction));
if (status != NO_ERROR) {
jStatus = nativeToJavaStatus(status);
}
@@ -840,17 +840,17 @@
return jStatus;
}
-static int android_media_AudioRecord_set_microphone_field_dimension(JNIEnv *env, jobject thiz,
- jfloat zoom) {
+static int android_media_AudioRecord_set_preferred_microphone_field_dimension(
+ JNIEnv *env, jobject thiz, jfloat zoom) {
sp<AudioRecord> lpRecorder = getAudioRecord(env, thiz);
if (lpRecorder == NULL) {
jniThrowException(env, "java/lang/IllegalStateException",
- "Unable to retrieve AudioRecord pointer for setMicrophoneFieldDimension()");
+ "Unable to retrieve AudioRecord pointer for setPreferredMicrophoneFieldDimension()");
return (jint)AUDIO_JAVA_ERROR;
}
jint jStatus = AUDIO_JAVA_SUCCESS;
- status_t status = lpRecorder->setMicrophoneFieldDimension(zoom);
+ status_t status = lpRecorder->setPreferredMicrophoneFieldDimension(zoom);
if (status != NO_ERROR) {
jStatus = nativeToJavaStatus(status);
}
@@ -913,10 +913,10 @@
{"native_get_active_microphones", "(Ljava/util/ArrayList;)I",
(void *)android_media_AudioRecord_get_active_microphones},
{"native_getPortId", "()I", (void *)android_media_AudioRecord_get_port_id},
- {"native_set_microphone_direction", "(I)I",
- (void *)android_media_AudioRecord_set_microphone_direction},
- {"native_set_microphone_field_dimension", "(F)I",
- (void *)android_media_AudioRecord_set_microphone_field_dimension},
+ {"native_set_preferred_microphone_direction", "(I)I",
+ (void *)android_media_AudioRecord_set_preferred_microphone_direction},
+ {"native_set_preferred_microphone_field_dimension", "(F)I",
+ (void *)android_media_AudioRecord_set_preferred_microphone_field_dimension},
};
// field names found in android/media/AudioRecord.java
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 4a6c72b..94f96ba 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -126,6 +126,41 @@
jfieldID white;
} gDisplayPrimariesClassInfo;
+static struct {
+ jclass clazz;
+ jmethodID builder;
+} gScreenshotGraphicBufferClassInfo;
+
+class JNamedColorSpace {
+public:
+ // ColorSpace.Named.SRGB.ordinal() = 0;
+ static constexpr jint SRGB = 0;
+
+ // ColorSpace.Named.DISPLAY_P3.ordinal() = 6;
+ static constexpr jint DISPLAY_P3 = 6;
+};
+
+constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
+ switch (dataspace) {
+ case ui::Dataspace::DISPLAY_P3:
+ return JNamedColorSpace::DISPLAY_P3;
+ default:
+ return JNamedColorSpace::SRGB;
+ }
+}
+
+constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
+ switch (colorMode) {
+ case ui::ColorMode::DISPLAY_P3:
+ case ui::ColorMode::BT2100_PQ:
+ case ui::ColorMode::BT2100_HLG:
+ case ui::ColorMode::DISPLAY_BT2020:
+ return ui::Dataspace::DISPLAY_P3;
+ default:
+ return ui::Dataspace::V0_SRGB;
+ }
+}
+
// ----------------------------------------------------------------------------
static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -210,9 +245,12 @@
if (displayToken == NULL) {
return NULL;
}
+ const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
+ const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
+
Rect sourceCrop = rectFromObj(env, sourceCropObj);
sp<GraphicBuffer> buffer;
- status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB,
+ status_t res = ScreenshotClient::capture(displayToken, dataspace,
ui::PixelFormat::RGBA_8888,
sourceCrop, width, height,
useIdentityTransform, rotation, captureSecureLayers, &buffer);
@@ -220,13 +258,15 @@
return NULL;
}
- return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
- gGraphicBufferClassInfo.builder,
+ const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+ return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
+ gScreenshotGraphicBufferClassInfo.builder,
buffer->getWidth(),
buffer->getHeight(),
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
- (jlong)buffer.get());
+ (jlong)buffer.get(),
+ namedColorSpace);
}
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
@@ -243,20 +283,23 @@
}
sp<GraphicBuffer> buffer;
- status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB,
+ const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
+ status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
ui::PixelFormat::RGBA_8888, sourceCrop,
frameScale, &buffer);
if (res != NO_ERROR) {
return NULL;
}
- return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
- gGraphicBufferClassInfo.builder,
+ const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+ return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
+ gScreenshotGraphicBufferClassInfo.builder,
buffer->getWidth(),
buffer->getHeight(),
buffer->getPixelFormat(),
(jint)buffer->getUsage(),
- (jlong)buffer.get());
+ (jlong)buffer.get(),
+ namedColorSpace);
}
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1306,9 +1349,13 @@
(void*)nativeSetOverrideScalingMode },
{"nativeGetHandle", "(J)Landroid/os/IBinder;",
(void*)nativeGetHandle },
- {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;",
+ {"nativeScreenshot",
+ "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
+ "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
(void*)nativeScreenshot },
- {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
+ {"nativeCaptureLayers",
+ "(Landroid/os/IBinder;Landroid/graphics/Rect;F)"
+ "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
(void*)nativeCaptureLayers },
{"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
(void*)nativeSetInputWindowInfo },
@@ -1386,6 +1433,14 @@
gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
"createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");
+ jclass screenshotGraphicsBufferClazz = FindClassOrDie(env,
+ "android/view/SurfaceControl$ScreenshotGraphicBuffer");
+ gScreenshotGraphicBufferClassInfo.clazz =
+ MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
+ gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
+ screenshotGraphicsBufferClazz,
+ "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
+
jclass displayedContentSampleClazz = FindClassOrDie(env,
"android/hardware/display/DisplayedContentSample");
gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 25caafb..b4be3f5 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2316,4 +2316,7 @@
// OPEN: Settings > Face > Remove face
// OS: Q
DIALOG_FACE_REMOVE = 1693;
+
+ // Settings > Display > Theme
+ DARK_UI_SETTINGS = 1698;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 305fc97..cb8ece7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1849,8 +1849,8 @@
<permission android:name="android.permission.HARDWARE_TEST"
android:protectionLevel="signature" />
- <!-- @hide Allows an application to manage DynamicAndroid image -->
- <permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID"
+ <!-- @hide Allows an application to manage DynamicSystem image -->
+ <permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM"
android:protectionLevel="signature" />
<!-- @SystemApi Allows access to Broadcast Radio
diff --git a/core/res/res/drawable-car/car_dialog_button_background.xml b/core/res/res/drawable-car/car_dialog_button_background.xml
index dc742d5..67506cb 100644
--- a/core/res/res/drawable-car/car_dialog_button_background.xml
+++ b/core/res/res/drawable-car/car_dialog_button_background.xml
@@ -15,7 +15,7 @@
~ limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@*android:color/car_card_ripple_background">
+ android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">
<color android:color="@*android:color/car_white_1000" />
</item>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 14edf6f..14202f2 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3222,6 +3222,12 @@
-->
<integer name="config_navBarOpacityMode">0</integer>
+ <!-- Controls the navigation bar interaction mode:
+ 0: 3 button mode (back, home, overview buttons)
+ 1: 2 button mode (back, home buttons + swipe up for overview)
+ 2: gestures only for back, home and overview -->
+ <integer name="config_navBarInteractionMode">0</integer>
+
<!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
These values are in DPs and will be converted to pixel sizes internally. -->
<string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">16x16</string>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 24fd3a8..7186d8e 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -802,7 +802,7 @@
<string name="permgrouprequest_visual">Allow
<b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g></b> to access your photos and videos?</string>
<!-- Subtitle of the message shown to the user when the apps requests permission to access photos and videos [CHAR LIMIT=150]-->
- <string name="permgrouprequestdetail_visual">Locations and other people in your photos and videos can be identified by the app</string>
+ <string name="permgrouprequestdetail_visual">This includes any locations tagged in your photos and videos</string>
<!-- Title for the capability of an accessibility service to retrieve window content. -->
<string name="capability_title_canRetrieveWindowContent">Retrieve window content</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 93c8458..8797b0e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2832,6 +2832,7 @@
<java-symbol type="string" name="config_packagedKeyboardName" />
<java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" />
<java-symbol type="integer" name="config_navBarOpacityMode" />
+ <java-symbol type="integer" name="config_navBarInteractionMode" />
<java-symbol type="color" name="system_bar_background_semi_transparent" />
<!-- EditText suggestion popup. -->
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 85947bd..8fc6a96 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -129,7 +129,7 @@
Settings.Global.AUTOFILL_LOGGING_LEVEL,
Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
- Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
+ Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST,
Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
index 72d1ab1..e1ccd75 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/LegacyIntentClassificationFactoryTest.java
@@ -64,7 +64,9 @@
null,
null,
null,
- null);
+ null,
+ 0,
+ 0);
List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create(
InstrumentationRegistry.getContext(),
@@ -98,7 +100,9 @@
null,
null,
null,
- null);
+ null,
+ 0,
+ 0);
List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create(
InstrumentationRegistry.getContext(),
diff --git a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
index ccf8607..2e97e63 100644
--- a/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
+++ b/core/tests/coretests/src/android/view/textclassifier/intent/TemplateClassificationIntentFactoryTest.java
@@ -82,7 +82,9 @@
null,
null,
null,
- createRemoteActionTemplates());
+ createRemoteActionTemplates(),
+ 0,
+ 0);
List<LabeledIntent> intents =
mTemplateClassificationIntentFactory.create(
@@ -121,7 +123,9 @@
null,
null,
null,
- createRemoteActionTemplates());
+ createRemoteActionTemplates(),
+ 0,
+ 0);
List<LabeledIntent> intents =
mTemplateClassificationIntentFactory.create(
@@ -156,7 +160,9 @@
null,
null,
null,
- null);
+ null,
+ 0,
+ 0);
mTemplateClassificationIntentFactory.create(
InstrumentationRegistry.getContext(),
@@ -189,7 +195,9 @@
null,
null,
null,
- new RemoteActionTemplate[0]);
+ new RemoteActionTemplate[0],
+ 0,
+ 0);
mTemplateClassificationIntentFactory.create(
InstrumentationRegistry.getContext(),
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 185fa07..8c2375e 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -599,7 +599,7 @@
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+ verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
// First invocation is from onCreate
assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
@@ -629,7 +629,7 @@
ArgumentCaptor<LogMaker> logMakerCaptor = ArgumentCaptor.forClass(LogMaker.class);
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
- verify(mockLogger, Mockito.times(2)).write(logMakerCaptor.capture());
+ verify(mockLogger, Mockito.times(3)).write(logMakerCaptor.capture());
// First invocation is from onCreate
assertThat(logMakerCaptor.getAllValues().get(1).getCategory(),
is(MetricsEvent.ACTION_SHARE_WITH_PREVIEW));
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index a0d14f9..afb5071 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -308,6 +308,8 @@
<permission name="android.permission.STATUS_BAR_SERVICE"/>
<permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
<permission name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS"/>
+ <permission name="android.permission.SET_WALLPAPER" />
+ <permission name="android.permission.SET_WALLPAPER_COMPONENT" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
@@ -330,9 +332,9 @@
<permission name="android.permission.CONTROL_VPN"/>
</privapp-permissions>
- <privapp-permissions package="com.android.dynandroid">
+ <privapp-permissions package="com.android.dynsystem">
<permission name="android.permission.REBOOT"/>
- <permission name="android.permission.MANAGE_DYNAMIC_ANDROID"/>
+ <permission name="android.permission.MANAGE_DYNAMIC_SYSTEM"/>
</privapp-permissions>
</permissions>
diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java
index 8507c83..5384061 100644
--- a/location/java/android/location/GnssClock.java
+++ b/location/java/android/location/GnssClock.java
@@ -16,6 +16,8 @@
package android.location;
+import android.annotation.FloatRange;
+import android.annotation.IntRange;
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -36,6 +38,8 @@
private static final int HAS_BIAS_UNCERTAINTY = (1<<4);
private static final int HAS_DRIFT = (1<<5);
private static final int HAS_DRIFT_UNCERTAINTY = (1<<6);
+ private static final int HAS_ELAPSED_REALTIME_NANOS = (1 << 7);
+ private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS = (1 << 8);
// End enumerations in sync with gps.h
@@ -49,6 +53,8 @@
private double mDriftNanosPerSecond;
private double mDriftUncertaintyNanosPerSecond;
private int mHardwareClockDiscontinuityCount;
+ private long mElapsedRealtimeNanos;
+ private long mElapsedRealtimeUncertaintyNanos;
/**
* @hide
@@ -74,6 +80,8 @@
mDriftNanosPerSecond = clock.mDriftNanosPerSecond;
mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond;
mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount;
+ mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos;
+ mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos;
}
/**
@@ -167,6 +175,7 @@
* <p>This value is often effectively zero (it is the reference clock by which all other times
* and time uncertainties are measured), and thus this field may often be 0, or not provided.
*/
+ @FloatRange(from = 0.0f)
public double getTimeUncertaintyNanos() {
return mTimeUncertaintyNanos;
}
@@ -176,7 +185,7 @@
* @hide
*/
@TestApi
- public void setTimeUncertaintyNanos(double timeUncertaintyNanos) {
+ public void setTimeUncertaintyNanos(@FloatRange(from = 0.0f) double timeUncertaintyNanos) {
setFlag(HAS_TIME_UNCERTAINTY);
mTimeUncertaintyNanos = timeUncertaintyNanos;
}
@@ -297,6 +306,7 @@
*
* <p>The value is only available if {@link #hasBiasUncertaintyNanos()} is {@code true}.
*/
+ @FloatRange(from = 0.0f)
public double getBiasUncertaintyNanos() {
return mBiasUncertaintyNanos;
}
@@ -306,7 +316,7 @@
* @hide
*/
@TestApi
- public void setBiasUncertaintyNanos(double biasUncertaintyNanos) {
+ public void setBiasUncertaintyNanos(@FloatRange(from = 0.0f) double biasUncertaintyNanos) {
setFlag(HAS_BIAS_UNCERTAINTY);
mBiasUncertaintyNanos = biasUncertaintyNanos;
}
@@ -379,6 +389,7 @@
* <p>The value is only available if {@link #hasDriftUncertaintyNanosPerSecond()} is
* {@code true}.
*/
+ @FloatRange(from = 0.0f)
public double getDriftUncertaintyNanosPerSecond() {
return mDriftUncertaintyNanosPerSecond;
}
@@ -388,7 +399,8 @@
* @hide
*/
@TestApi
- public void setDriftUncertaintyNanosPerSecond(double driftUncertaintyNanosPerSecond) {
+ public void setDriftUncertaintyNanosPerSecond(
+ @FloatRange(from = 0.0f) double driftUncertaintyNanosPerSecond) {
setFlag(HAS_DRIFT_UNCERTAINTY);
mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond;
}
@@ -404,6 +416,90 @@
}
/**
+ * Returns {@code true} if {@link #getElapsedRealtimeNanos()} is available, {@code false}
+ * otherwise.
+ */
+ public boolean hasElapsedRealtimeNanos() {
+ return isFlagSet(HAS_ELAPSED_REALTIME_NANOS);
+ }
+
+ /**
+ * Returns the elapsed real-time of this clock since system boot, in nanoseconds.
+ *
+ * <p>The value is only available if {@link #hasElapsedRealtimeNanos()} is
+ * {@code true}.
+ */
+ public long getElapsedRealtimeNanos() {
+ return mElapsedRealtimeNanos;
+ }
+
+ /**
+ * Sets the elapsed real-time of this clock since system boot, in nanoseconds.
+ * @hide
+ */
+ @TestApi
+ public void setElapsedRealtimeNanos(long elapsedRealtimeNanos) {
+ setFlag(HAS_ELAPSED_REALTIME_NANOS);
+ mElapsedRealtimeNanos = elapsedRealtimeNanos;
+ }
+
+ /**
+ * Resets the elapsed real-time of this clock since system boot, in nanoseconds.
+ * @hide
+ */
+ @TestApi
+ public void resetElapsedRealtimeNanos() {
+ resetFlag(HAS_ELAPSED_REALTIME_NANOS);
+ mElapsedRealtimeNanos = 0;
+ }
+
+ /**
+ * Returns {@code true} if {@link #getElapsedRealtimeUncertaintyNanos()} is available, {@code
+ * false} otherwise.
+ */
+ public boolean hasElapsedRealtimeUncertaintyNanos() {
+ return isFlagSet(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+ }
+
+ /**
+ * Gets the estimate of the relative precision of the alignment of the
+ * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ *
+ * <p>The value is only available if {@link #hasElapsedRealtimeUncertaintyNanos()} is
+ * {@code true}.
+ */
+ @IntRange(from = 0)
+ public long getElapsedRealtimeUncertaintyNanos() {
+ return mElapsedRealtimeUncertaintyNanos;
+ }
+
+ /**
+ * Sets the estimate of the relative precision of the alignment of the
+ * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ * @hide
+ */
+ @TestApi
+ public void setElapsedRealtimeUncertaintyNanos(
+ @IntRange(from = 0) long elapsedRealtimeUncertaintyNanos) {
+ setFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+ mElapsedRealtimeUncertaintyNanos = elapsedRealtimeUncertaintyNanos;
+ }
+
+ /**
+ * Resets the estimate of the relative precision of the alignment of the
+ * {@link #getElapsedRealtimeNanos()} timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ * @hide
+ */
+ @TestApi
+ public void resetElapsedRealtimeUncertaintyNanos() {
+ resetFlag(HAS_ELAPSED_REALTIME_UNCERTAINTY_NANOS);
+ mElapsedRealtimeUncertaintyNanos = Long.MAX_VALUE;
+ }
+
+ /**
* Gets count of hardware clock discontinuities.
*
* <p>When this value stays the same, vs. a value in a previously reported {@link GnssClock}, it
@@ -446,6 +542,8 @@
gpsClock.mDriftNanosPerSecond = parcel.readDouble();
gpsClock.mDriftUncertaintyNanosPerSecond = parcel.readDouble();
gpsClock.mHardwareClockDiscontinuityCount = parcel.readInt();
+ gpsClock.mElapsedRealtimeNanos = parcel.readLong();
+ gpsClock.mElapsedRealtimeUncertaintyNanos = parcel.readLong();
return gpsClock;
}
@@ -468,6 +566,8 @@
parcel.writeDouble(mDriftNanosPerSecond);
parcel.writeDouble(mDriftUncertaintyNanosPerSecond);
parcel.writeInt(mHardwareClockDiscontinuityCount);
+ parcel.writeLong(mElapsedRealtimeNanos);
+ parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
}
@Override
@@ -514,6 +614,16 @@
"HardwareClockDiscontinuityCount",
mHardwareClockDiscontinuityCount));
+ builder.append(String.format(
+ format,
+ "ElapsedRealtimeNanos",
+ hasElapsedRealtimeNanos() ? mElapsedRealtimeNanos : null));
+
+ builder.append(String.format(
+ format,
+ "ElapsedRealtimeUncertaintyNanos",
+ hasElapsedRealtimeUncertaintyNanos() ? mElapsedRealtimeUncertaintyNanos : null));
+
return builder.toString();
}
@@ -528,6 +638,8 @@
resetDriftNanosPerSecond();
resetDriftUncertaintyNanosPerSecond();
setHardwareClockDiscontinuityCount(Integer.MIN_VALUE);
+ resetElapsedRealtimeNanos();
+ resetElapsedRealtimeUncertaintyNanos();
}
private void setFlag(int flag) {
diff --git a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
index e5fd0d3..b4be219 100644
--- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
+++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java
@@ -238,6 +238,8 @@
* window after the end of that call.
* 3. If the device is in a emergency callback state, this is provided by querying
* TelephonyManager.
+ * 4. If the user has recently sent an Emergency SMS and telephony reports that it is in
+ * emergency SMS mode, this is provided by querying TelephonyManager.
* @return true if is considered in user initiated emergency mode for NI purposes
*/
public boolean getInEmergency() {
@@ -246,7 +248,9 @@
&& ((SystemClock.elapsedRealtime() - mCallEndElapsedRealtimeMillis)
< mEmergencyExtensionMillis);
boolean isInEmergencyCallback = mTelephonyManager.getEmergencyCallbackMode();
- return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension;
+ boolean isInEmergencySmsMode = mTelephonyManager.isInEmergencySmsMode();
+ return mIsInEmergencyCall || isInEmergencyCallback || isInEmergencyExtension
+ || isInEmergencySmsMode;
}
public void setEmergencyExtensionSeconds(int emergencyExtensionSeconds) {
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 8051236..a7760a80 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -1798,8 +1798,8 @@
*
* @return true if sucessful.
*/
- public boolean setMicrophoneDirection(@DirectionMode int direction) {
- return native_set_microphone_direction(direction) == AudioSystem.SUCCESS;
+ public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) {
+ return native_set_preferred_microphone_direction(direction) == AudioSystem.SUCCESS;
}
/**
@@ -1810,10 +1810,11 @@
* though 0 (no zoom) to 1 (maximum zoom).
* @return true if sucessful.
*/
- public boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom) {
+ public boolean setPreferredMicrophoneFieldDimension(
+ @FloatRange(from = -1.0, to = 1.0) float zoom) {
Preconditions.checkArgument(
zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)");
- return native_set_microphone_field_dimension(zoom) == AudioSystem.SUCCESS;
+ return native_set_preferred_microphone_field_dimension(zoom) == AudioSystem.SUCCESS;
}
//---------------------------------------------------------
@@ -1969,8 +1970,8 @@
private native int native_getPortId();
- private native int native_set_microphone_direction(int direction);
- private native int native_set_microphone_field_dimension(float zoom);
+ private native int native_set_preferred_microphone_direction(int direction);
+ private native int native_set_preferred_microphone_field_dimension(float zoom);
//---------------------------------------------------------
// Utility methods
diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java
index 005f2d4..a08aec3 100644
--- a/media/java/android/media/MediaDrm.java
+++ b/media/java/android/media/MediaDrm.java
@@ -552,6 +552,13 @@
*/
public static final int STATUS_INTERNAL_ERROR = 4;
+ /**
+ * The key is not yet usable to decrypt media because the start
+ * time is in the future. The key will become usable when
+ * its start time is reached.
+ */
+ public static final int STATUS_USABLE_IN_FUTURE = 5;
+
/** @hide */
@IntDef({
STATUS_USABLE,
@@ -559,6 +566,7 @@
STATUS_OUTPUT_NOT_ALLOWED,
STATUS_PENDING,
STATUS_INTERNAL_ERROR,
+ STATUS_USABLE_IN_FUTURE,
})
@Retention(RetentionPolicy.SOURCE)
public @interface KeyStatusCode {}
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index e7b4752..575a0bb 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -1537,8 +1537,8 @@
* @param direction Direction constant.
* @return true if sucessful.
*/
- public boolean setMicrophoneDirection(@DirectionMode int direction) {
- return native_setMicrophoneDirection(direction) == 0;
+ public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) {
+ return native_setPreferredMicrophoneDirection(direction) == 0;
}
/**
@@ -1549,14 +1549,15 @@
* though 0 (no zoom) to 1 (maximum zoom).
* @return true if sucessful.
*/
- public boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom) {
+ public boolean setPreferredMicrophoneFieldDimension(
+ @FloatRange(from = -1.0, to = 1.0) float zoom) {
Preconditions.checkArgument(
zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)");
- return native_setMicrophoneFieldDimension(zoom) == 0;
+ return native_setPreferredMicrophoneFieldDimension(zoom) == 0;
}
- private native int native_setMicrophoneDirection(int direction);
- private native int native_setMicrophoneFieldDimension(float zoom);
+ private native int native_setPreferredMicrophoneDirection(int direction);
+ private native int native_setPreferredMicrophoneFieldDimension(float zoom);
//--------------------------------------------------------------------------
// Implementation of AudioRecordingMonitor interface
diff --git a/media/java/android/media/MicrophoneDirection.java b/media/java/android/media/MicrophoneDirection.java
index 2382da5..e4eec44 100644
--- a/media/java/android/media/MicrophoneDirection.java
+++ b/media/java/android/media/MicrophoneDirection.java
@@ -32,13 +32,21 @@
*/
int MIC_DIRECTION_UNSPECIFIED = 0;
/**
- * Optimize capture for audio coming from the screen-side of the device.
+ * Optimize capture for audio coming from the side of the device facing the user.
+ * In the typical case, a device with a single screen, screen-side camera/microphone and
+ * non-screen-side camera/microphone, this will be the screen side (as in a "selfie").
+ * For a different device geometry, it is the side for which the expectation is to be
+ * facing the user.
*/
- int MIC_DIRECTION_FRONT = 1;
+ int MIC_DIRECTION_TOWARDS_USER = 1;
/**
- * Optimize capture for audio coming from the side of the device opposite the screen.
+ * Optimize capture for audio coming from the side of the device pointing away from the user.
+ * In the typical case, a device with a single screen, screen-side camera/microphone and
+ * non-screen-side camera/microphone, this will be the non-screen side.
+ * For a different device geometry, it is the side for which the expectation is to be
+ * facing away from the user. This is the "taking a video of something else" case.
*/
- int MIC_DIRECTION_BACK = 2;
+ int MIC_DIRECTION_AWAY_FROM_USER = 2;
/**
* Optimize capture for audio coming from an off-device microphone.
*/
@@ -47,8 +55,8 @@
/** @hide */
/*public*/ @IntDef({
MIC_DIRECTION_UNSPECIFIED,
- MIC_DIRECTION_FRONT,
- MIC_DIRECTION_BACK,
+ MIC_DIRECTION_TOWARDS_USER,
+ MIC_DIRECTION_AWAY_FROM_USER,
MIC_DIRECTION_EXTERNAL
})
@Retention(RetentionPolicy.SOURCE)
@@ -58,18 +66,23 @@
* which side of the device to optimize capture from. Typically used in conjunction with
* the camera capturing video.
*
+ * Usage would include specifying the audio capture to follow camera being used to capture
+ * video.
* @param direction Direction constant.
* @return true if sucessful.
*/
- boolean setMicrophoneDirection(@DirectionMode int direction);
+ boolean setPreferredMicrophoneDirection(@DirectionMode int direction);
/**
* Specifies the zoom factor (i.e. the field dimension) for the selected microphone
* (for processing). The selected microphone is determined by the use-case for the stream.
*
+ * Usage would include specifying the audio focus to follow the zoom specified for the camera
+ * being used to capture video.
+ *
* @param zoom the desired field dimension of microphone capture. Range is from -1 (wide angle),
* though 0 (no zoom) to 1 (maximum zoom).
* @return true if sucessful.
*/
- boolean setMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom);
+ boolean setPreferredMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom);
}
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 3ec0903..24fff06 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -760,9 +760,9 @@
return jStatus;
}
-static jint android_media_MediaRecord_setMicrophoneDirection(
+static jint android_media_MediaRecord_setPreferredMicrophoneDirection(
JNIEnv *env, jobject thiz, jint direction) {
- ALOGV("setMicrophoneDirection(%d)", direction);
+ ALOGV("setPreferredMicrophoneDirection(%d)", direction);
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
if (mr == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
@@ -771,7 +771,7 @@
jint jStatus = AUDIO_JAVA_SUCCESS;
status_t status =
- mr->setMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction));
+ mr->setPreferredMicrophoneDirection(static_cast<audio_microphone_direction_t>(direction));
if (status != NO_ERROR) {
jStatus = nativeToJavaStatus(status);
}
@@ -779,9 +779,9 @@
return jStatus;
}
-static jint android_media_MediaRecord_setMicrophoneFieldDimension(
+static jint android_media_MediaRecord_setPreferredMicrophoneFieldDimension(
JNIEnv *env, jobject thiz, jfloat zoom) {
- ALOGV("setMicrophoneFieldDimension(%f)", zoom);
+ ALOGV("setPreferredMicrophoneFieldDimension(%f)", zoom);
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
if (mr == NULL) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
@@ -789,7 +789,7 @@
}
jint jStatus = AUDIO_JAVA_SUCCESS;
- status_t status = mr->setMicrophoneFieldDimension(zoom);
+ status_t status = mr->setPreferredMicrophoneFieldDimension(zoom);
if (status != NO_ERROR) {
jStatus = nativeToJavaStatus(status);
}
@@ -850,8 +850,10 @@
{"native_getActiveMicrophones", "(Ljava/util/ArrayList;)I", (void *)android_media_MediaRecord_getActiveMicrophones},
{"native_getPortId", "()I", (void *)android_media_MediaRecord_getPortId},
- {"native_setMicrophoneDirection", "(I)I", (void *)android_media_MediaRecord_setMicrophoneDirection},
- {"native_setMicrophoneFieldDimension", "(F)I", (void *)android_media_MediaRecord_setMicrophoneFieldDimension},
+ {"native_setPreferredMicrophoneDirection", "(I)I",
+ (void *)android_media_MediaRecord_setPreferredMicrophoneDirection},
+ {"native_setPreferredMicrophoneFieldDimension", "(F)I",
+ (void *)android_media_MediaRecord_setPreferredMicrophoneFieldDimension},
};
// This function only registers the native methods, and is called from
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index e1dc406..1f2480b 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -148,6 +148,7 @@
AHardwareBuffer_getNativeHandle; # introduced=26
AHardwareBuffer_isSupported; # introduced=29
AHardwareBuffer_lock; # introduced=26
+ AHardwareBuffer_lockAndGetInfo; # introduced=29
AHardwareBuffer_lockPlanes; # introduced=29
AHardwareBuffer_recvHandleFromUnixSocket; # introduced=26
AHardwareBuffer_release; # introduced=26
diff --git a/packages/DynamicAndroidInstallationService/Android.mk b/packages/DynamicSystemInstallationService/Android.mk
similarity index 86%
rename from packages/DynamicAndroidInstallationService/Android.mk
rename to packages/DynamicSystemInstallationService/Android.mk
index 13d96ac..16aca1b 100644
--- a/packages/DynamicAndroidInstallationService/Android.mk
+++ b/packages/DynamicSystemInstallationService/Android.mk
@@ -8,7 +8,7 @@
LOCAL_USE_AAPT2 := true
-LOCAL_PACKAGE_NAME := DynamicAndroidInstallationService
+LOCAL_PACKAGE_NAME := DynamicSystemInstallationService
LOCAL_CERTIFICATE := platform
LOCAL_PRIVILEGED_MODULE := true
LOCAL_PRIVATE_PLATFORM_APIS := true
diff --git a/packages/DynamicAndroidInstallationService/AndroidManifest.xml b/packages/DynamicSystemInstallationService/AndroidManifest.xml
similarity index 80%
rename from packages/DynamicAndroidInstallationService/AndroidManifest.xml
rename to packages/DynamicSystemInstallationService/AndroidManifest.xml
index 32acad4..2911117 100644
--- a/packages/DynamicAndroidInstallationService/AndroidManifest.xml
+++ b/packages/DynamicSystemInstallationService/AndroidManifest.xml
@@ -1,10 +1,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.dynandroid"
+ package="com.android.dynsystem"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.MANAGE_DYNAMIC_ANDROID" />
+ <uses-permission android:name="android.permission.MANAGE_DYNAMIC_SYSTEM" />
<uses-permission android:name="android.permission.REBOOT" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
@@ -13,24 +13,24 @@
android:label="@string/app_name">
<service
- android:name=".DynamicAndroidInstallationService"
+ android:name=".DynamicSystemInstallationService"
android:enabled="true"
android:exported="true"
- android:permission="android.permission.MANAGE_DYNAMIC_ANDROID"
- android:process=":dynandroid">
+ android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM"
+ android:process=":dynsystem">
<intent-filter>
- <action android:name="android.content.action.NOTIFY_IF_IN_USE" />
+ <action android:name="android.os.image.action.NOTIFY_IF_IN_USE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</service>
<activity android:name=".VerificationActivity"
android:exported="true"
- android:permission="android.permission.MANAGE_DYNAMIC_ANDROID"
+ android:permission="android.permission.MANAGE_DYNAMIC_SYSTEM"
android:theme="@android:style/Theme.Material.Light.Dialog.NoActionBar"
- android:process=":dynandroid">
+ android:process=":dynsystem">
<intent-filter>
- <action android:name="android.content.action.START_INSTALL" />
+ <action android:name="android.os.image.action.START_INSTALL" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
diff --git a/packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2 b/packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2
similarity index 100%
rename from packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2
rename to packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2
diff --git a/packages/DynamicAndroidInstallationService/NOTICE b/packages/DynamicSystemInstallationService/NOTICE
similarity index 100%
rename from packages/DynamicAndroidInstallationService/NOTICE
rename to packages/DynamicSystemInstallationService/NOTICE
diff --git a/packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml b/packages/DynamicSystemInstallationService/res/drawable/ic_system_update_googblue_24dp.xml
similarity index 100%
rename from packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml
rename to packages/DynamicSystemInstallationService/res/drawable/ic_system_update_googblue_24dp.xml
diff --git a/packages/DynamicAndroidInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml
similarity index 64%
rename from packages/DynamicAndroidInstallationService/res/values/strings.xml
rename to packages/DynamicSystemInstallationService/res/values/strings.xml
index 03c7c28..a72e4e2 100644
--- a/packages/DynamicAndroidInstallationService/res/values/strings.xml
+++ b/packages/DynamicSystemInstallationService/res/values/strings.xml
@@ -12,14 +12,14 @@
<!-- password page description [CHAR LIMIT=128] -->
<string name="keyguard_description">Please enter your password and continue to AndroidOnTap installation</string>
- <!-- Displayed on notification: DynAndroid installation is completed [CHAR LIMIT=128] -->
+ <!-- Displayed on notification: AndroidOnTap installation is completed [CHAR LIMIT=128] -->
<string name="notification_install_completed">New system is ready, you can reboot into it or discard it.</string>
- <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] -->
+ <!-- Displayed on notification: AndroidOnTap installation is in progress [CHAR LIMIT=128] -->
<string name="notification_install_inprogress">Installation is in progress.</string>
- <!-- Displayed on notification: DynAndroid installation is in progress [CHAR LIMIT=128] -->
+ <!-- Displayed on notification: AndroidOnTap installation is in progress [CHAR LIMIT=128] -->
<string name="notification_install_failed">Installation Failed.</string>
<!-- Displayed on notification: We are running in AndroidOnTap [CHAR LIMIT=128] -->
- <string name="notification_dynandroid_in_use">We are running in AndroidOnTap.</string>
+ <string name="notification_dynsystem_in_use">We are running in AndroidOnTap.</string>
<!-- Action on notification: Cancel installation [CHAR LIMIT=16] -->
<string name="notification_action_cancel">Cancel</string>
@@ -28,11 +28,11 @@
<!-- Action on notification: Uninstall AndroidOnTap [CHAR LIMIT=16] -->
<string name="notification_action_uninstall">Uninstall</string>
<!-- Action on notification: Reboot to AndroidOnTap [CHAR LIMIT=16] -->
- <string name="notification_action_reboot_to_dynandroid">Reboot</string>
+ <string name="notification_action_reboot_to_dynsystem">Reboot</string>
- <!-- Toast when installed DynamicAndroid is discarded [CHAR LIMIT=64] -->
- <string name="toast_dynandroid_discarded">Installed AndroidOnTap is discarded.</string>
- <!-- Toast when we fail to launch into DynamicAndroid [CHAR LIMIT=64] -->
- <string name="toast_failed_to_reboot_to_dynandroid">Failed to reboot into AndroidOnTap.</string>
+ <!-- Toast when installed AndroidOnTap is discarded [CHAR LIMIT=64] -->
+ <string name="toast_dynsystem_discarded">Installed AndroidOnTap is discarded.</string>
+ <!-- Toast when we fail to launch into AndroidOnTap [CHAR LIMIT=64] -->
+ <string name="toast_failed_to_reboot_to_dynsystem">Failed to reboot into AndroidOnTap.</string>
</resources>
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
similarity index 84%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
index dd1be89..38576ee 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java
@@ -14,20 +14,20 @@
* limitations under the License.
*/
-package com.android.dynandroid;
+package com.android.dynsystem;
import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.DynamicAndroidClient;
import android.content.Intent;
import android.os.UserHandle;
+import android.os.image.DynamicSystemClient;
import android.util.Log;
/**
* A BoardcastReceiver waiting for ACTION_BOOT_COMPLETED and ask
* the service to display a notification if we are currently running
- * in DynamicAndroid.
+ * in DynamicSystem.
*/
public class BootCompletedReceiver extends BroadcastReceiver {
@@ -41,9 +41,9 @@
if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Intent startServiceIntent = new Intent(
- context, DynamicAndroidInstallationService.class);
+ context, DynamicSystemInstallationService.class);
- startServiceIntent.setAction(DynamicAndroidClient.ACTION_NOTIFY_IF_IN_USE);
+ startServiceIntent.setAction(DynamicSystemClient.ACTION_NOTIFY_IF_IN_USE);
context.startServiceAsUser(startServiceIntent, UserHandle.SYSTEM);
}
}
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
similarity index 78%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
index d942bab..df2c571 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
@@ -14,28 +14,28 @@
* limitations under the License.
*/
-package com.android.dynandroid;
+package com.android.dynsystem;
-import static android.content.DynamicAndroidClient.ACTION_NOTIFY_IF_IN_USE;
-import static android.content.DynamicAndroidClient.ACTION_START_INSTALL;
-import static android.content.DynamicAndroidClient.CAUSE_ERROR_EXCEPTION;
-import static android.content.DynamicAndroidClient.CAUSE_ERROR_INVALID_URL;
-import static android.content.DynamicAndroidClient.CAUSE_ERROR_IO;
-import static android.content.DynamicAndroidClient.CAUSE_INSTALL_CANCELLED;
-import static android.content.DynamicAndroidClient.CAUSE_INSTALL_COMPLETED;
-import static android.content.DynamicAndroidClient.CAUSE_NOT_SPECIFIED;
-import static android.content.DynamicAndroidClient.STATUS_IN_PROGRESS;
-import static android.content.DynamicAndroidClient.STATUS_IN_USE;
-import static android.content.DynamicAndroidClient.STATUS_NOT_STARTED;
-import static android.content.DynamicAndroidClient.STATUS_READY;
import static android.os.AsyncTask.Status.FINISHED;
import static android.os.AsyncTask.Status.PENDING;
import static android.os.AsyncTask.Status.RUNNING;
+import static android.os.image.DynamicSystemClient.ACTION_NOTIFY_IF_IN_USE;
+import static android.os.image.DynamicSystemClient.ACTION_START_INSTALL;
+import static android.os.image.DynamicSystemClient.CAUSE_ERROR_EXCEPTION;
+import static android.os.image.DynamicSystemClient.CAUSE_ERROR_INVALID_URL;
+import static android.os.image.DynamicSystemClient.CAUSE_ERROR_IO;
+import static android.os.image.DynamicSystemClient.CAUSE_INSTALL_CANCELLED;
+import static android.os.image.DynamicSystemClient.CAUSE_INSTALL_COMPLETED;
+import static android.os.image.DynamicSystemClient.CAUSE_NOT_SPECIFIED;
+import static android.os.image.DynamicSystemClient.STATUS_IN_PROGRESS;
+import static android.os.image.DynamicSystemClient.STATUS_IN_USE;
+import static android.os.image.DynamicSystemClient.STATUS_NOT_STARTED;
+import static android.os.image.DynamicSystemClient.STATUS_READY;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_EXCEPTION;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_INVALID_URL;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_ERROR_IO;
-import static com.android.dynandroid.InstallationAsyncTask.RESULT_OK;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_EXCEPTION;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_INVALID_URL;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_ERROR_IO;
+import static com.android.dynsystem.InstallationAsyncTask.RESULT_OK;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -43,16 +43,16 @@
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
-import android.content.DynamicAndroidClient;
import android.content.Intent;
import android.os.Bundle;
-import android.os.DynamicAndroidManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.image.DynamicSystemClient;
+import android.os.image.DynamicSystemManager;
import android.util.Log;
import android.widget.Toast;
@@ -60,31 +60,31 @@
import java.util.ArrayList;
/**
- * This class is the service in charge of DynamicAndroid installation.
+ * This class is the service in charge of DynamicSystem installation.
* It also posts status to notification bar and wait for user's
* cancel and confirm commnands.
*/
-public class DynamicAndroidInstallationService extends Service
+public class DynamicSystemInstallationService extends Service
implements InstallationAsyncTask.InstallStatusListener {
- private static final String TAG = "DynAndroidInstallationService";
+ private static final String TAG = "DynSystemInstallationService";
/*
* Intent actions
*/
private static final String ACTION_CANCEL_INSTALL =
- "com.android.dynandroid.ACTION_CANCEL_INSTALL";
+ "com.android.dynsystem.ACTION_CANCEL_INSTALL";
private static final String ACTION_DISCARD_INSTALL =
- "com.android.dynandroid.ACTION_DISCARD_INSTALL";
- private static final String ACTION_REBOOT_TO_DYN_ANDROID =
- "com.android.dynandroid.ACTION_REBOOT_TO_DYN_ANDROID";
+ "com.android.dynsystem.ACTION_DISCARD_INSTALL";
+ private static final String ACTION_REBOOT_TO_DYN_SYSTEM =
+ "com.android.dynsystem.ACTION_REBOOT_TO_DYN_SYSTEM";
private static final String ACTION_REBOOT_TO_NORMAL =
- "com.android.dynandroid.ACTION_REBOOT_TO_NORMAL";
+ "com.android.dynsystem.ACTION_REBOOT_TO_NORMAL";
/*
* For notification
*/
- private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynandroid";
+ private static final String NOTIFICATION_CHANNEL_ID = "com.android.dynsystem";
private static final int NOTIFICATION_ID = 1;
/*
@@ -97,15 +97,15 @@
final Messenger mMessenger = new Messenger(new IncomingHandler(this));
static class IncomingHandler extends Handler {
- private final WeakReference<DynamicAndroidInstallationService> mWeakService;
+ private final WeakReference<DynamicSystemInstallationService> mWeakService;
- IncomingHandler(DynamicAndroidInstallationService service) {
+ IncomingHandler(DynamicSystemInstallationService service) {
mWeakService = new WeakReference<>(service);
}
@Override
public void handleMessage(Message msg) {
- DynamicAndroidInstallationService service = mWeakService.get();
+ DynamicSystemInstallationService service = mWeakService.get();
if (service != null) {
service.handleMessage(msg);
@@ -113,7 +113,7 @@
}
}
- private DynamicAndroidManager mDynAndroid;
+ private DynamicSystemManager mDynSystem;
private NotificationManager mNM;
private long mSystemSize;
@@ -130,7 +130,7 @@
prepareNotification();
- mDynAndroid = (DynamicAndroidManager) getSystemService(Context.DYNAMIC_ANDROID_SERVICE);
+ mDynSystem = (DynamicSystemManager) getSystemService(Context.DYNAMIC_SYSTEM_SERVICE);
}
@Override
@@ -156,8 +156,8 @@
executeCancelCommand();
} else if (ACTION_DISCARD_INSTALL.equals(action)) {
executeDiscardCommand();
- } else if (ACTION_REBOOT_TO_DYN_ANDROID.equals(action)) {
- executeRebootToDynAndroidCommand();
+ } else if (ACTION_REBOOT_TO_DYN_SYSTEM.equals(action)) {
+ executeRebootToDynSystemCommand();
} else if (ACTION_REBOOT_TO_NORMAL.equals(action)) {
executeRebootToNormalCommand();
} else if (ACTION_NOTIFY_IF_IN_USE.equals(action)) {
@@ -215,17 +215,17 @@
return;
}
- if (isInDynamicAndroid()) {
- Log.e(TAG, "We are already running in DynamicAndroid");
+ if (isInDynamicSystem()) {
+ Log.e(TAG, "We are already running in DynamicSystem");
return;
}
- String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL);
- mSystemSize = intent.getLongExtra(DynamicAndroidClient.KEY_SYSTEM_SIZE, 0);
- mUserdataSize = intent.getLongExtra(DynamicAndroidClient.KEY_USERDATA_SIZE, 0);
+ String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL);
+ mSystemSize = intent.getLongExtra(DynamicSystemClient.KEY_SYSTEM_SIZE, 0);
+ mUserdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0);
mInstallTask = new InstallationAsyncTask(
- url, mSystemSize, mUserdataSize, mDynAndroid, this);
+ url, mSystemSize, mUserdataSize, mDynSystem, this);
mInstallTask.execute();
@@ -251,7 +251,7 @@
}
private void executeDiscardCommand() {
- if (isInDynamicAndroid()) {
+ if (isInDynamicSystem()) {
Log.e(TAG, "We are now running in AOT, please reboot to normal system first");
return;
}
@@ -262,16 +262,16 @@
}
Toast.makeText(this,
- getString(R.string.toast_dynandroid_discarded),
+ getString(R.string.toast_dynsystem_discarded),
Toast.LENGTH_LONG).show();
resetTaskAndStop();
postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
- mDynAndroid.remove();
+ mDynSystem.remove();
}
- private void executeRebootToDynAndroidCommand() {
+ private void executeRebootToDynSystemCommand() {
if (mInstallTask == null || mInstallTask.getStatus() != FINISHED) {
Log.e(TAG, "Trying to reboot to AOT while there is no complete installation");
return;
@@ -282,10 +282,10 @@
mNM.cancel(NOTIFICATION_ID);
Toast.makeText(this,
- getString(R.string.toast_failed_to_reboot_to_dynandroid),
+ getString(R.string.toast_failed_to_reboot_to_dynsystem),
Toast.LENGTH_LONG).show();
- mDynAndroid.remove();
+ mDynSystem.remove();
return;
}
@@ -293,12 +293,12 @@
PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (powerManager != null) {
- powerManager.reboot("dynandroid");
+ powerManager.reboot("dynsystem");
}
}
private void executeRebootToNormalCommand() {
- if (!isInDynamicAndroid()) {
+ if (!isInDynamicSystem()) {
Log.e(TAG, "It's already running in normal system.");
return;
}
@@ -346,7 +346,7 @@
}
private PendingIntent createPendingIntent(String action) {
- Intent intent = new Intent(this, DynamicAndroidInstallationService.class);
+ Intent intent = new Intent(this, DynamicSystemInstallationService.class);
intent.setAction(action);
return PendingIntent.getService(this, 0, intent, 0);
}
@@ -375,8 +375,8 @@
builder.setContentText(getString(R.string.notification_install_completed));
builder.addAction(new Notification.Action.Builder(
- null, getString(R.string.notification_action_reboot_to_dynandroid),
- createPendingIntent(ACTION_REBOOT_TO_DYN_ANDROID)).build());
+ null, getString(R.string.notification_action_reboot_to_dynsystem),
+ createPendingIntent(ACTION_REBOOT_TO_DYN_SYSTEM)).build());
builder.addAction(new Notification.Action.Builder(
null, getString(R.string.notification_action_discard),
@@ -385,7 +385,7 @@
break;
case STATUS_IN_USE:
- builder.setContentText(getString(R.string.notification_dynandroid_in_use));
+ builder.setContentText(getString(R.string.notification_dynsystem_in_use));
builder.addAction(new Notification.Action.Builder(
null, getString(R.string.notification_action_uninstall),
@@ -409,7 +409,7 @@
}
private boolean verifyRequest(Intent intent) {
- String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL);
+ String url = intent.getStringExtra(DynamicSystemClient.KEY_SYSTEM_URL);
return VerificationActivity.isVerified(url);
}
@@ -443,16 +443,16 @@
private void notifyOneClient(Messenger client, int status, int cause) throws RemoteException {
Bundle bundle = new Bundle();
- bundle.putLong(DynamicAndroidClient.KEY_INSTALLED_SIZE, mInstalledSize);
+ bundle.putLong(DynamicSystemClient.KEY_INSTALLED_SIZE, mInstalledSize);
client.send(Message.obtain(null,
- DynamicAndroidClient.MSG_POST_STATUS, status, cause, bundle));
+ DynamicSystemClient.MSG_POST_STATUS, status, cause, bundle));
}
private int getStatus() {
- if (isInDynamicAndroid()) {
+ if (isInDynamicSystem()) {
return STATUS_IN_USE;
- } else if (isDynamicAndroidInstalled()) {
+ } else if (isDynamicSystemInstalled()) {
return STATUS_READY;
} else if (mInstallTask == null) {
return STATUS_NOT_STARTED;
@@ -479,17 +479,17 @@
}
}
- private boolean isInDynamicAndroid() {
- return mDynAndroid.isInUse();
+ private boolean isInDynamicSystem() {
+ return mDynSystem.isInUse();
}
- private boolean isDynamicAndroidInstalled() {
- return mDynAndroid.isInstalled();
+ private boolean isDynamicSystemInstalled() {
+ return mDynSystem.isInstalled();
}
void handleMessage(Message msg) {
switch (msg.what) {
- case DynamicAndroidClient.MSG_REGISTER_LISTENER:
+ case DynamicSystemClient.MSG_REGISTER_LISTENER:
try {
Messenger client = msg.replyTo;
@@ -505,7 +505,7 @@
}
break;
- case DynamicAndroidClient.MSG_UNREGISTER_LISTENER:
+ case DynamicSystemClient.MSG_UNREGISTER_LISTENER:
mClients.remove(msg.replyTo);
break;
default:
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
similarity index 90%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
index 03fc773..052fc0a 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-package com.android.dynandroid;
+package com.android.dynsystem;
import android.gsi.GsiProgress;
import android.os.AsyncTask;
-import android.os.DynamicAndroidManager;
+import android.os.image.DynamicSystemManager;
import android.util.Log;
import android.webkit.URLUtil;
@@ -60,9 +60,9 @@
private final String mUrl;
private final long mSystemSize;
private final long mUserdataSize;
- private final DynamicAndroidManager mDynamicAndroid;
+ private final DynamicSystemManager mDynSystem;
private final InstallStatusListener mListener;
- private DynamicAndroidManager.Session mInstallationSession;
+ private DynamicSystemManager.Session mInstallationSession;
private int mResult = NO_RESULT;
@@ -70,11 +70,11 @@
InstallationAsyncTask(String url, long systemSize, long userdataSize,
- DynamicAndroidManager dynAndroid, InstallStatusListener listener) {
+ DynamicSystemManager dynSystem, InstallStatusListener listener) {
mUrl = url;
mSystemSize = systemSize;
mUserdataSize = userdataSize;
- mDynamicAndroid = dynAndroid;
+ mDynSystem = dynSystem;
mListener = listener;
}
@@ -98,7 +98,7 @@
Thread thread = new Thread(() -> {
mInstallationSession =
- mDynamicAndroid.startInstallation(mSystemSize, mUserdataSize);
+ mDynSystem.startInstallation(mSystemSize, mUserdataSize);
});
@@ -106,12 +106,12 @@
while (thread.isAlive()) {
if (isCancelled()) {
- boolean aborted = mDynamicAndroid.abort();
- Log.d(TAG, "Called DynamicAndroidManager.abort(), result = " + aborted);
+ boolean aborted = mDynSystem.abort();
+ Log.d(TAG, "Called DynamicSystemManager.abort(), result = " + aborted);
return RESULT_OK;
}
- GsiProgress progress = mDynamicAndroid.getInstallationProgress();
+ GsiProgress progress = mDynSystem.getInstallationProgress();
installedSize = progress.bytes_processed;
if (installedSize > reportedInstalledSize + minStepToReport) {
@@ -146,7 +146,7 @@
? bytes : Arrays.copyOf(bytes, numBytesRead);
if (!mInstallationSession.write(writeBuffer)) {
- throw new IOException("Failed write() to DynamicAndroid");
+ throw new IOException("Failed write() to DynamicSystem");
}
installedSize += numBytesRead;
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
similarity index 87%
rename from packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java
rename to packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
index c18c4fe..f05930f 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/VerificationActivity.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java
@@ -14,19 +14,19 @@
* limitations under the License.
*/
-package com.android.dynandroid;
+package com.android.dynsystem;
-import static android.content.DynamicAndroidClient.KEY_SYSTEM_SIZE;
-import static android.content.DynamicAndroidClient.KEY_SYSTEM_URL;
-import static android.content.DynamicAndroidClient.KEY_USERDATA_SIZE;
+import static android.os.image.DynamicSystemClient.KEY_SYSTEM_SIZE;
+import static android.os.image.DynamicSystemClient.KEY_SYSTEM_URL;
+import static android.os.image.DynamicSystemClient.KEY_USERDATA_SIZE;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
-import android.content.DynamicAndroidClient;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserHandle;
+import android.os.image.DynamicSystemClient;
import android.util.Log;
@@ -88,8 +88,8 @@
sVerifiedUrl = url;
// start service
- Intent intent = new Intent(this, DynamicAndroidInstallationService.class);
- intent.setAction(DynamicAndroidClient.ACTION_START_INSTALL);
+ Intent intent = new Intent(this, DynamicSystemInstallationService.class);
+ intent.setAction(DynamicSystemClient.ACTION_START_INSTALL);
intent.putExtra(KEY_SYSTEM_URL, url);
intent.putExtra(KEY_SYSTEM_SIZE, systemSize);
intent.putExtra(KEY_USERDATA_SIZE, userdataSize);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index b34f445..b025df4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -185,14 +185,14 @@
*/
public static void revertScheduleToNoneIfNeeded(Context context) {
ContentResolver resolver = context.getContentResolver();
- final int currentMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ final int currentMode = Global.getInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
boolean providerConfigured = !TextUtils.isEmpty(context.getString(
com.android.internal.R.string.config_batterySaverScheduleProvider));
- if (currentMode == PowerManager.POWER_SAVER_MODE_DYNAMIC && !providerConfigured) {
+ if (currentMode == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC && !providerConfigured) {
Global.putInt(resolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
- Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Global.putInt(resolver, Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
}
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index a33f9a8..de7202c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -844,7 +844,7 @@
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL_MAX,
GlobalSettingsProto.LowPowerMode.TRIGGER_LEVEL_MAX);
dumpSetting(s, p,
- Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
+ Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
GlobalSettingsProto.LowPowerMode.AUTOMATIC_POWER_SAVER_MODE);
dumpSetting(s, p,
Settings.Global.LOW_POWER_MODE_STICKY,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 9e46ad6..7337cdb 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -19,6 +19,12 @@
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
import android.Manifest;
import android.annotation.NonNull;
@@ -33,6 +39,8 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.om.IOverlayManager;
+import android.content.om.OverlayInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
@@ -3235,7 +3243,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 176;
+ private static final int SETTINGS_VERSION = 177;
private final int mUserId;
@@ -4311,6 +4319,57 @@
currentVersion = 176;
}
+ if (currentVersion == 176) {
+ // Version 176: Migrate the existing swipe up setting into the resource overlay
+ // for the navigation bar interaction mode.
+
+ final IOverlayManager overlayManager = IOverlayManager.Stub.asInterface(
+ ServiceManager.getService(Context.OVERLAY_SERVICE));
+ int navBarMode = -1;
+
+ // Migrate the swipe up setting only if it is set
+ final SettingsState secureSettings = getSecureSettingsLocked(userId);
+ final Setting swipeUpSetting = secureSettings.getSettingLocked(
+ Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
+ if (swipeUpSetting != null && !swipeUpSetting.isNull()) {
+ navBarMode = swipeUpSetting.getValue().equals("1")
+ ? NAV_BAR_MODE_2BUTTON
+ : NAV_BAR_MODE_3BUTTON;
+ }
+
+ // Temporary: Only for migration for dogfooders, to be removed
+ try {
+ final OverlayInfo info = overlayManager.getOverlayInfo(
+ "com.android.internal.experiment.navbar.type.inset",
+ UserHandle.USER_CURRENT);
+ if (info != null && info.isEnabled()) {
+ navBarMode = NAV_BAR_MODE_GESTURAL;
+ }
+ } catch (RemoteException e) {
+ // Ingore, fall through
+ }
+
+ if (navBarMode != -1) {
+ try {
+ overlayManager.setEnabled(NAV_BAR_MODE_3BUTTON_OVERLAY,
+ navBarMode == NAV_BAR_MODE_3BUTTON,
+ UserHandle.USER_CURRENT);
+ overlayManager.setEnabled(NAV_BAR_MODE_2BUTTON_OVERLAY,
+ navBarMode == NAV_BAR_MODE_2BUTTON,
+ UserHandle.USER_CURRENT);
+ overlayManager.setEnabled(NAV_BAR_MODE_GESTURAL_OVERLAY,
+ navBarMode == NAV_BAR_MODE_GESTURAL,
+ UserHandle.USER_CURRENT);
+ } catch (RemoteException e) {
+ throw new IllegalStateException(
+ "Failed to set nav bar interaction mode overlay");
+ }
+ }
+
+ currentVersion = 177;
+ }
+
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 441f88c..d6e61eb 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -182,6 +182,10 @@
<!-- Permission needed to run keyguard manager tests in CTS -->
<uses-permission android:name="android.permission.CONTROL_KEYGUARD_SECURE_NOTIFICATIONS" />
+ <!-- Permission needed to test wallpaper component -->
+ <uses-permission android:name="android.permission.SET_WALLPAPER" />
+ <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" />
+
<application android:label="@string/app_label"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true">
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
index 3d2f570..0a0530c0 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/VolumeDialogController.java
@@ -60,6 +60,7 @@
boolean areCaptionsEnabled();
void setCaptionsEnabled(boolean isEnabled);
+ boolean isCaptionStreamOptedOut();
void getCaptionsComponentState(boolean fromTooltip);
diff --git a/packages/SystemUI/res/color/caption_tint_color_selector.xml b/packages/SystemUI/res/color/caption_tint_color_selector.xml
new file mode 100644
index 0000000..30843ec
--- /dev/null
+++ b/packages/SystemUI/res/color/caption_tint_color_selector.xml
@@ -0,0 +1,23 @@
+<?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
+ -->
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto">
+ <item sysui:optedOut="true"
+ android:color="?android:attr/colorButtonNormal"/>
+
+ <item android:color="?android:attr/colorAccent"/>
+</selector>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 6c8110b..a02962e 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -92,7 +92,6 @@
android:layout_width="@dimen/multi_user_avatar_expanded_size"
android:layout_height="@dimen/multi_user_avatar_expanded_size"
android:layout_gravity="center"
- android:tint="?android:attr/colorAccent"
android:scaleType="centerInside"/>
</com.android.systemui.statusbar.phone.MultiUserSwitch>
diff --git a/packages/SystemUI/res/layout/volume_dialog.xml b/packages/SystemUI/res/layout/volume_dialog.xml
index 1d0a242..d1c80c4 100644
--- a/packages/SystemUI/res/layout/volume_dialog.xml
+++ b/packages/SystemUI/res/layout/volume_dialog.xml
@@ -15,6 +15,7 @@
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:sysui="http://schemas.android.com/apk/res-auto"
android:id="@+id/volume_dialog_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -117,16 +118,17 @@
android:clipToPadding="false"
android:translationZ="@dimen/volume_dialog_elevation"
android:background="@drawable/rounded_bg_full">
- <com.android.keyguard.AlphaOptimizedImageButton
+ <com.android.systemui.volume.CaptionsToggleImageButton
android:id="@+id/odi_captions_icon"
android:src="@drawable/ic_volume_odi_captions_disabled"
style="@style/VolumeButtons"
android:background="@drawable/rounded_ripple"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:tint="@color/accent_tint_color_selector"
+ android:tint="@color/caption_tint_color_selector"
android:layout_gravity="center"
- android:soundEffectsEnabled="false" />
+ android:soundEffectsEnabled="false"
+ sysui:optedOut="false"/>
</FrameLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 27d2bcd..e0bcf24 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -146,5 +146,9 @@
<attr name="showAirplaneMode" format="boolean" />
</declare-styleable>
+ <declare-styleable name="CaptionsToggleImageButton">
+ <attr name="optedOut" format="boolean" />
+ </declare-styleable>
+
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 265c620..62309fd 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -549,11 +549,11 @@
<!-- Content description of the do not disturb tile in quick settings when on in alarms only (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_dnd_alarms_on">alarms only</string>
<!-- Content description of the do not disturb tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_dnd">Do not disturb.</string>
+ <string name="accessibility_quick_settings_dnd">Do Not Disturb.</string>
<!-- Announcement made when do not disturb changes to off (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_dnd_changed_off">Do not disturb turned off.</string>
+ <string name="accessibility_quick_settings_dnd_changed_off">Do Not Disturb turned off.</string>
<!-- Announcement made when do not disturb changes to on (not shown on the screen). [CHAR LIMIT=NONE] -->
- <string name="accessibility_quick_settings_dnd_changed_on">Do not disturb turned on.</string>
+ <string name="accessibility_quick_settings_dnd_changed_on">Do Not Disturb turned on.</string>
<!-- Content description of the bluetooth tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_bluetooth">Bluetooth.</string>
<!-- Content description of the bluetooth tile in quick settings when off (not shown on the screen). [CHAR LIMIT=NONE] -->
@@ -699,7 +699,7 @@
<!-- QuickSettings: Onboarding text that introduces users to long press on an option in order to view the option's menu in Settings [CHAR LIMIT=NONE] -->
<string name="quick_settings_header_onboarding_text">Touch & hold icons for more options</string>
<!-- QuickSettings: Do not disturb [CHAR LIMIT=NONE] -->
- <string name="quick_settings_dnd_label">Do not disturb</string>
+ <string name="quick_settings_dnd_label">Do Not Disturb</string>
<!-- QuickSettings: Do not disturb - Priority only [CHAR LIMIT=NONE] -->
<string name="quick_settings_dnd_priority_label">Priority only</string>
<!-- QuickSettings: Do not disturb - Alarms only [CHAR LIMIT=NONE] -->
@@ -1814,14 +1814,14 @@
<string name="tuner_full_zen_title">Show with volume controls</string>
<!-- SysUI Tuner: Label for screen about do not disturb settings [CHAR LIMIT=60] -->
- <string name="volume_and_do_not_disturb">Do not disturb</string>
+ <string name="volume_and_do_not_disturb">Do Not Disturb</string>
<!-- SysUI Tuner: Switch to control whether volume buttons enter/exit do
not disturb [CHAR LIMIT=60] -->
<string name="volume_dnd_silent">Volume buttons shortcut</string>
<!-- SysUI Tuner: Switch to control volume up behavior [CHAR LIMIT=60] -->
- <string name="volume_up_silent">Exit do not disturb on volume up</string>
+ <string name="volume_up_silent">Exit Do Not Disturb on volume up</string>
<!-- Name of the battery icon in status bar [CHAR LIMIT=30] -->
<string name="battery">Battery</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index ce65b5a..fd92e9e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -1,5 +1,7 @@
package com.android.keyguard;
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
@@ -24,8 +26,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.colorextraction.ColorExtractor;
+import com.android.internal.colorextraction.ColorExtractor.OnColorsChangedListener;
import com.android.keyguard.clock.ClockManager;
-import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.ClockPlugin;
@@ -37,37 +39,65 @@
import java.util.Arrays;
import java.util.TimeZone;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* Switch to show plugin clock when plugin is connected, otherwise it will show default clock.
*/
public class KeyguardClockSwitch extends RelativeLayout {
+ /**
+ * Controller used to track StatusBar state to know when to show the big_clock_container.
+ */
+ private final StatusBarStateController mStatusBarStateController;
+
+ /**
+ * Color extractor used to apply colors from wallpaper to custom clock faces.
+ */
+ private final SysuiColorExtractor mSysuiColorExtractor;
+
+ /**
+ * Manager used to know when to show a custom clock face.
+ */
+ private final ClockManager mClockManager;
+
+ /**
+ * Layout transition that scales the default clock face.
+ */
private final Transition mTransition;
+
/**
* Optional/alternative clock injected via plugin.
*/
private ClockPlugin mClockPlugin;
+
/**
* Default clock.
*/
private TextClock mClockView;
+
/**
* Frame for default and custom clock.
*/
private FrameLayout mSmallClockFrame;
+
/**
* Container for big custom clock.
*/
private ViewGroup mBigClockContainer;
+
/**
* Status area (date and other stuff) shown below the clock. Plugin can decide whether or not to
* show it below the alternate clock.
*/
private View mKeyguardStatusArea;
+
/**
* Maintain state so that a newly connected plugin can be initialized.
*/
private float mDarkAmount;
+
/**
* If the Keyguard Slice has a header (big center-aligned text.)
*/
@@ -96,22 +126,20 @@
*
* The color palette changes when the wallpaper is changed.
*/
- private SysuiColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> {
+ private final OnColorsChangedListener mColorsListener = (extractor, which) -> {
if ((which & WallpaperManager.FLAG_LOCK) != 0) {
- if (extractor instanceof SysuiColorExtractor) {
- updateColors((SysuiColorExtractor) extractor);
- } else {
- updateColors(Dependency.get(SysuiColorExtractor.class));
- }
+ updateColors();
}
};
- public KeyguardClockSwitch(Context context) {
- this(context, null);
- }
-
- public KeyguardClockSwitch(Context context, AttributeSet attrs) {
+ @Inject
+ public KeyguardClockSwitch(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+ StatusBarStateController statusBarStateController, SysuiColorExtractor colorExtractor,
+ ClockManager clockManager) {
super(context, attrs);
+ mStatusBarStateController = statusBarStateController;
+ mSysuiColorExtractor = colorExtractor;
+ mClockManager = clockManager;
mTransition = new ClockBoundsTransition();
}
@@ -133,22 +161,18 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener);
- StatusBarStateController stateController = Dependency.get(StatusBarStateController.class);
- stateController.addCallback(mStateListener);
- mStateListener.onStateChanged(stateController.getState());
- SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class);
- colorExtractor.addOnColorsChangedListener(mColorsListener);
- updateColors(colorExtractor);
+ mClockManager.addOnClockChangedListener(mClockChangedListener);
+ mStatusBarStateController.addCallback(mStateListener);
+ mSysuiColorExtractor.addOnColorsChangedListener(mColorsListener);
+ updateColors();
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener);
- Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
- Dependency.get(SysuiColorExtractor.class)
- .removeOnColorsChangedListener(mColorsListener);
+ mClockManager.removeOnClockChangedListener(mClockChangedListener);
+ mStatusBarStateController.removeCallback(mStateListener);
+ mSysuiColorExtractor.removeOnColorsChangedListener(mColorsListener);
setClockPlugin(null);
}
@@ -271,14 +295,11 @@
return mClockView.getTextSize();
}
+ /**
+ * Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
+ */
public void refresh() {
mClockView.refresh();
- }
-
- /**
- * Notifies that time tick alarm from doze service fired.
- */
- public void dozeTimeTick() {
if (mClockPlugin != null) {
mClockPlugin.onTimeTick();
}
@@ -293,9 +314,9 @@
}
}
- private void updateColors(SysuiColorExtractor colorExtractor) {
- ColorExtractor.GradientColors colors = colorExtractor.getColors(WallpaperManager.FLAG_LOCK,
- true);
+ private void updateColors() {
+ ColorExtractor.GradientColors colors = mSysuiColorExtractor.getColors(
+ WallpaperManager.FLAG_LOCK, true);
mSupportsDarkText = colors.supportsDarkText();
mColorPalette = colors.getColorPalette();
if (mClockPlugin != null) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 9dd9717..ae8bc52 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -28,9 +28,12 @@
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
+import com.android.systemui.util.InjectionInflationController;
+
// TODO(multi-display): Support multiple external displays
public class KeyguardDisplayManager {
protected static final String TAG = "KeyguardDisplayManager";
@@ -38,6 +41,7 @@
private final MediaRouter mMediaRouter;
private final DisplayManager mDisplayService;
+ private final InjectionInflationController mInjectableInflater;
private final Context mContext;
private boolean mShowing;
@@ -75,8 +79,10 @@
}
};
- public KeyguardDisplayManager(Context context) {
+ public KeyguardDisplayManager(Context context,
+ InjectionInflationController injectableInflater) {
mContext = context;
+ mInjectableInflater = injectableInflater;
mMediaRouter = mContext.getSystemService(MediaRouter.class);
mDisplayService = mContext.getSystemService(DisplayManager.class);
mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */);
@@ -110,7 +116,7 @@
final int displayId = display.getDisplayId();
Presentation presentation = mPresentations.get(displayId);
if (presentation == null) {
- presentation = new KeyguardPresentation(mContext, display);
+ presentation = new KeyguardPresentation(mContext, display, mInjectableInflater);
presentation.setOnDismissListener(dialog -> {
if (null != mPresentations.get(displayId)) {
mPresentations.remove(displayId);
@@ -201,6 +207,7 @@
private final static class KeyguardPresentation extends Presentation {
private static final int VIDEO_SAFE_REGION = 80; // Percentage of display width & height
private static final int MOVE_CLOCK_TIMEOUT = 10000; // 10s
+ private final InjectionInflationController mInjectableInflater;
private View mClock;
private int mUsableWidth;
private int mUsableHeight;
@@ -217,8 +224,10 @@
}
};
- KeyguardPresentation(Context context, Display display) {
+ KeyguardPresentation(Context context, Display display,
+ InjectionInflationController injectionInflater) {
super(context, display, R.style.keyguard_presentation_theme);
+ mInjectableInflater = injectionInflater;
getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
setCancelable(false);
}
@@ -239,7 +248,9 @@
mMarginLeft = (100 - VIDEO_SAFE_REGION) * p.x / 200;
mMarginTop = (100 - VIDEO_SAFE_REGION) * p.y / 200;
- setContentView(R.layout.keyguard_presentation);
+ LayoutInflater inflater = mInjectableInflater.injectable(
+ LayoutInflater.from(getContext()));
+ setContentView(inflater.inflate(R.layout.keyguard_presentation, null));
mClock = findViewById(R.id.clock);
// Avoid screen burn in
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index 808e264..0369e4c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -214,7 +214,6 @@
public void dozeTimeTick() {
refreshTime();
mKeyguardSlice.refresh();
- mClockView.dozeTimeTick();
}
private void refreshTime() {
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index 870ac87..32c1242 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -141,6 +141,8 @@
@Override
public void onTimeTick() {
mAnalogClock.onTimeChanged();
+ mDigitalClock.refresh();
+ mLockClock.refresh();
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
index 7401819..34b2fd8 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/StretchAnalogClockController.java
@@ -136,6 +136,8 @@
@Override
public void onTimeTick() {
mAnalogClock.onTimeChanged();
+ mDigitalClock.refresh();
+ mLockClock.refresh();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 14e910f..8e3afd8 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -43,6 +43,7 @@
import android.graphics.drawable.ShapeDrawable;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.util.AttributeSet;
@@ -457,30 +458,38 @@
void updateHeight() {
if (usingActivityView()) {
Notification.BubbleMetadata data = mEntry.getBubbleMetadata();
- int desiredHeight;
+ float desiredHeight;
if (data == null) {
// This is a contentIntent based bubble, lets allow it to be the max height
// as it was forced into this mode and not prepared to be small
desiredHeight = mStackView.getMaxExpandedHeight();
} else {
- desiredHeight = data.getDesiredHeight() > 0
- ? data.getDesiredHeight()
- : mMinHeight;
+ boolean useRes = data.getDesiredHeightResId() != 0;
+ float desiredPx;
+ if (useRes) {
+ desiredPx = getDimenForPackageUser(data.getDesiredHeightResId(),
+ mEntry.notification.getPackageName(),
+ mEntry.notification.getUser().getIdentifier());
+ } else {
+ desiredPx = data.getDesiredHeight()
+ * getContext().getResources().getDisplayMetrics().density;
+ }
+ desiredHeight = desiredPx > 0 ? desiredPx : mMinHeight;
}
int chromeHeight = mPermissionView.getVisibility() != View.VISIBLE
? mHeaderHeight
: mPermissionHeight;
int max = mStackView.getMaxExpandedHeight() - chromeHeight - mPointerView.getHeight()
- mPointerMargin;
- int height = Math.min(desiredHeight, max);
+ float height = Math.min(desiredHeight, max);
height = Math.max(height, mMinHeight);
LayoutParams lp = (LayoutParams) mActivityView.getLayoutParams();
mNeedsNewHeight = lp.height != height;
if (!mKeyboardVisible) {
// If the keyboard is visible... don't adjust the height because that will cause
// a configuration change and the keyboard will be lost.
- lp.height = height;
- mBubbleHeight = height;
+ lp.height = (int) height;
+ mBubbleHeight = (int) height;
mActivityView.setLayoutParams(lp);
mNeedsNewHeight = false;
}
@@ -712,4 +721,23 @@
mStackView.getNormalizedXPosition(),
mStackView.getNormalizedYPosition());
}
+
+ private int getDimenForPackageUser(int resId, String pkg, int userId) {
+ Resources r;
+ if (pkg != null) {
+ try {
+ if (userId == UserHandle.USER_ALL) {
+ userId = UserHandle.USER_SYSTEM;
+ }
+ r = mPm.getResourcesForApplicationAsUser(pkg, userId);
+ return r.getDimensionPixelSize(resId);
+ } catch (PackageManager.NameNotFoundException ex) {
+ // Uninstalled, don't care
+ } catch (Resources.NotFoundException e) {
+ // Invalid res id, return 0 and user our default
+ Log.e(TAG, "Couldn't find desired height res id", e);
+ }
+ }
+ return 0;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
index 6c4be06..c243899 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java
@@ -211,7 +211,7 @@
mDozeService.requestWakeUp();
}
- private boolean isExecutingTransition() {
+ public boolean isExecutingTransition() {
return !mQueuedRequests.isEmpty();
}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index 031f562..7189a48 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -198,6 +198,14 @@
}
private void onProximityFar(boolean far) {
+ // Proximity checks are asynchronous and the user might have interacted with the phone
+ // when a new event is arriving. This means that a state transition might have happened
+ // and the proximity check is now obsolete.
+ if (mMachine.isExecutingTransition()) {
+ Log.w(TAG, "onProximityFar called during transition. Ignoring sensor response.");
+ return;
+ }
+
final boolean near = !far;
final DozeMachine.State state = mMachine.getState();
final boolean paused = (state == DozeMachine.State.DOZE_AOD_PAUSED);
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
index 477e7d7e..d1939d0 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageProcessHelper.java
@@ -85,7 +85,9 @@
Bitmap bitmap = bitmaps[0];
if (bitmap != null) {
int[] histogram = processHistogram(bitmap);
- return computePercentile85(bitmap, histogram);
+ Float val = computePercentile85(bitmap, histogram);
+ bitmaps[0] = null;
+ return val;
}
Log.e(TAG, "Per85ComputeTask: Can't get bitmap");
return DEFAULT_PER85;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 676e594..d70d0d8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -90,6 +90,7 @@
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -710,7 +711,10 @@
mContext.registerReceiver(mDelayedLockBroadcastReceiver, delayedActionFilter,
SYSTEMUI_PERMISSION, null /* scheduler */);
- mKeyguardDisplayManager = new KeyguardDisplayManager(mContext);
+ InjectionInflationController injectionInflationController =
+ new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent());
+ mKeyguardDisplayManager = new KeyguardDisplayManager(mContext,
+ injectionInflationController);
mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 813faa9..520df97 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -36,6 +36,7 @@
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
@@ -58,6 +59,7 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
@@ -394,6 +396,16 @@
}
}
};
+ private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ if (mAmbientState.isDarkAtAll() && !mAmbientState.isFullyDark()) {
+ outline.setRoundRect(mBackgroundAnimationRect, mCornerRadius);
+ } else {
+ ViewOutlineProvider.BACKGROUND.getOutline(view, outline);
+ }
+ }
+ };
private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC);
private boolean mPulsing;
private boolean mGroupExpandedForMeasure;
@@ -520,6 +532,7 @@
mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
addOnExpandedHeightListener(mRoundnessManager::setExpanded);
+ setOutlineProvider(mOutlineProvider);
// Blocking helper manager wants to know the expanded state, update as well.
NotificationBlockingHelperManager blockingHelperManager =
@@ -1298,6 +1311,7 @@
public void updateClipping() {
boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode
&& !mHeadsUpAnimatingAway;
+ boolean clipToOutline = false;
if (mIsClipped != clipped) {
mIsClipped = clipped;
}
@@ -1306,12 +1320,15 @@
&& mAmbientState.isFullyDark() && mShowDarkShelf) {
setClipBounds(null);
} else if (mAmbientState.isDarkAtAll()) {
- setClipBounds(mBackgroundAnimationRect);
+ clipToOutline = true;
+ invalidateOutline();
} else if (clipped) {
setClipBounds(mRequestedClipBounds);
} else {
setClipBounds(null);
}
+
+ setClipToOutline(clipToOutline);
}
/**
@@ -4805,6 +4822,9 @@
if (!wasDarkAtAll && nowDarkAtAll) {
resetExposedMenuView(true /* animate */, true /* animate */);
}
+ if (nowFullyDark != wasFullyDark || wasDarkAtAll != nowDarkAtAll) {
+ invalidateOutline();
+ }
updateAlgorithmHeightAndPadding();
updateBackgroundDimming();
updatePanelTranslation();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 5a7df1f..ca45209 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.hardware.biometrics.BiometricSourceType;
+import android.metrics.LogMaker;
import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -26,6 +27,8 @@
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardUpdateMonitor;
@@ -140,6 +143,8 @@
}
};
+ private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
+
public BiometricUnlockController(Context context,
DozeScrimController dozeScrimController,
KeyguardViewMediator keyguardViewMediator,
@@ -253,6 +258,8 @@
Trace.endSection();
return;
}
+ mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
+ .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
startWakeAndUnlock(calculateMode(biometricSourceType));
}
@@ -420,12 +427,16 @@
@Override
public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
+ mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
+ .setType(MetricsEvent.TYPE_FAILURE).setSubtype(toSubtype(biometricSourceType)));
cleanup();
}
@Override
public void onBiometricError(int msgId, String errString,
BiometricSourceType biometricSourceType) {
+ mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
+ .setType(MetricsEvent.TYPE_ERROR).setSubtype(toSubtype(biometricSourceType)));
cleanup();
}
@@ -501,4 +512,20 @@
public boolean isBiometricUnlock() {
return isWakeAndUnlock() || mMode == MODE_UNLOCK;
}
+
+ /**
+ * Translates biometric source type for logging purpose.
+ */
+ private int toSubtype(BiometricSourceType biometricSourceType) {
+ switch (biometricSourceType) {
+ case FINGERPRINT:
+ return 0;
+ case FACE:
+ return 1;
+ case IRIS:
+ return 2;
+ default:
+ return 3;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index ef82b34..e9a9606 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -50,8 +50,6 @@
import android.graphics.Region;
import android.graphics.Region.Op;
import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.AttributeSet;
@@ -150,10 +148,6 @@
private final NavigationBarTransitions mBarTransitions;
private final OverviewProxyService mOverviewProxyService;
- // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
- final static boolean WORKAROUND_INVALID_LAYOUT = true;
- final static int MSG_CHECK_INVALID_LAYOUT = 8686;
-
// performs manual animation in sync with layout transitions
private final NavTransitionListener mTransitionListener = new NavTransitionListener();
@@ -260,29 +254,6 @@
}
};
- private class H extends Handler {
- public void handleMessage(Message m) {
- switch (m.what) {
- case MSG_CHECK_INVALID_LAYOUT:
- final String how = "" + m.obj;
- final int w = getWidth();
- final int h = getHeight();
- final int vw = getCurrentView().getWidth();
- final int vh = getCurrentView().getHeight();
-
- if (h != vh || w != vw) {
- Log.w(TAG, String.format(
- "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
- how, w, h, vw, vh));
- if (WORKAROUND_INVALID_LAYOUT) {
- requestLayout();
- }
- }
- break;
- }
- }
- }
-
private final AccessibilityDelegate mQuickStepAccessibilityDelegate
= new AccessibilityDelegate() {
private AccessibilityAction mToggleOverviewAction;
@@ -450,7 +421,7 @@
mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */
};
- mPrototypeController = new NavigationPrototypeController(mHandler, mContext);
+ mPrototypeController = new NavigationPrototypeController(mContext);
mPrototypeController.register();
mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController());
@@ -591,8 +562,6 @@
getHomeButton().abortCurrentGesture();
}
- private H mHandler = new H();
-
public View getCurrentView() {
return mCurrentView;
}
@@ -1193,23 +1162,23 @@
}
@Override
- protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int w = MeasureSpec.getSize(widthMeasureSpec);
+ int h = MeasureSpec.getSize(heightMeasureSpec);
if (DEBUG) Log.d(TAG, String.format(
- "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
+ "onMeasure: (%dx%d) old: (%dx%d)", w, h, getMeasuredWidth(), getMeasuredHeight()));
final boolean newVertical = w > 0 && h > w;
if (newVertical != mIsVertical) {
mIsVertical = newVertical;
if (DEBUG) {
- Log.d(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w,
+ Log.d(TAG, String.format("onMeasure: h=%d, w=%d, vert=%s", h, w,
mIsVertical ? "y" : "n"));
}
reorient();
notifyVerticalChangedListener(newVertical);
}
-
- postCheckForInvalidLayout("sizeChanged");
- super.onSizeChanged(w, h, oldw, oldh);
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void notifyVerticalChangedListener(boolean newVertical) {
@@ -1264,28 +1233,6 @@
return uiCarModeChanged;
}
- /*
- @Override
- protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
- if (DEBUG) Log.d(TAG, String.format(
- "onLayout: %s (%d,%d,%d,%d)",
- changed?"changed":"notchanged", left, top, right, bottom));
- super.onLayout(changed, left, top, right, bottom);
- }
-
- // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
- // fails, any touch on the display will fix the layout.
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
- if (ev.getAction() == MotionEvent.ACTION_DOWN) {
- postCheckForInvalidLayout("touch");
- }
- return super.onInterceptTouchEvent(ev);
- }
- */
-
-
private String getResourceName(int resId) {
if (resId != 0) {
final android.content.res.Resources res = getContext().getResources();
@@ -1299,10 +1246,6 @@
}
}
- private void postCheckForInvalidLayout(final String how) {
- mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
- }
-
private static String visibilityToString(int vis) {
switch (vis) {
case View.INVISIBLE:
@@ -1471,7 +1414,7 @@
void onVerticalChanged(boolean isVertical);
}
- private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
+ private final Consumer<Boolean> mDockedListener = exists -> post(() -> {
mDockedStackExists = exists;
updateRecentsIcon();
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index 979de07..9ea8b64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -67,8 +67,8 @@
private final Context mContext;
- public NavigationPrototypeController(Handler handler, Context context) {
- super(handler);
+ public NavigationPrototypeController(Context context) {
+ super(new Handler());
mContext = context;
updateSwipeLTRBackSetting();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 253bdfb..b902e43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -92,6 +92,7 @@
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -141,6 +142,7 @@
private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties()
.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ private final InjectionInflationController mInjectionInflationController;
private final PowerManager mPowerManager;
private final AccessibilityManager mAccessibilityManager;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
@@ -336,10 +338,12 @@
@Inject
public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
+ InjectionInflationController injectionInflationController,
NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler pulseExpansionHandler) {
super(context, attrs);
setWillNotDraw(!DEBUG);
+ mInjectionInflationController = injectionInflationController;
mFalsingManager = FalsingManager.getInstance(context);
mPowerManager = context.getSystemService(PowerManager.class);
mWakeUpCoordinator = coordinator;
@@ -475,10 +479,11 @@
// Re-inflate the status view group.
int index = indexOfChild(mKeyguardStatusView);
removeView(mKeyguardStatusView);
- mKeyguardStatusView = (KeyguardStatusView) LayoutInflater.from(mContext).inflate(
- R.layout.keyguard_status_view,
- this,
- false);
+ mKeyguardStatusView = (KeyguardStatusView) mInjectionInflationController
+ .injectable(LayoutInflater.from(mContext)).inflate(
+ R.layout.keyguard_status_view,
+ this,
+ false);
addView(mKeyguardStatusView, index);
// Re-associate the clock container with the keyguard clock switch.
@@ -490,10 +495,11 @@
index = indexOfChild(mKeyguardBottomArea);
removeView(mKeyguardBottomArea);
KeyguardBottomAreaView oldBottomArea = mKeyguardBottomArea;
- mKeyguardBottomArea = (KeyguardBottomAreaView) LayoutInflater.from(mContext).inflate(
- R.layout.keyguard_bottom_area,
- this,
- false);
+ mKeyguardBottomArea = (KeyguardBottomAreaView) mInjectionInflationController
+ .injectable(LayoutInflater.from(mContext)).inflate(
+ R.layout.keyguard_bottom_area,
+ this,
+ false);
mKeyguardBottomArea.initFrom(oldBottomArea);
addView(mKeyguardBottomArea, index);
initBottomArea();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index a8ae5f6..9609057 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -114,17 +114,19 @@
if (mSingleTapEnabled) {
mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
"SINGLE_TAP");
+ return true;
}
- return mSingleTapEnabled;
+ return false;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
- if (mDoubleTapEnabled) {
+ if (mDoubleTapEnabled || mSingleTapEnabled) {
mService.wakeUpIfDozing(SystemClock.uptimeMillis(), StatusBarWindowView.this,
"DOUBLE_TAP");
+ return true;
}
- return mDoubleTapEnabled;
+ return false;
}
};
private final TunerService.Tunable mTunable = (key, newValue) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index e6b6672..7705e4e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -23,6 +23,7 @@
import android.view.LayoutInflater;
import android.view.View;
+import com.android.keyguard.KeyguardClockSwitch;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.qs.QSCarrierGroup;
import com.android.systemui.qs.QSFooterImpl;
@@ -130,6 +131,11 @@
* Creates the QSCarrierGroup
*/
QSCarrierGroup createQSCarrierGroup();
+
+ /**
+ * Creates the KeyguardClockSwitch.
+ */
+ KeyguardClockSwitch createKeyguardClockSwitch();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
new file mode 100644
index 0000000..8ec66e4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/CaptionsToggleImageButton.java
@@ -0,0 +1,67 @@
+/*
+ * 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.volume;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.android.keyguard.AlphaOptimizedImageButton;
+import com.android.systemui.R;
+
+/** Toggle button in Volume Dialog that allows extra state for when streams are opted-out */
+public class CaptionsToggleImageButton extends AlphaOptimizedImageButton {
+
+ private static final int[] OPTED_OUT_STATE = new int[] { R.attr.optedOut };
+
+ private boolean mComponentEnabled = false;
+ private boolean mOptedOut = false;
+
+ public CaptionsToggleImageButton(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ public int[] onCreateDrawableState(int extraSpace) {
+ int[] state = super.onCreateDrawableState(extraSpace + 1);
+ if (mOptedOut) {
+ mergeDrawableStates(state, OPTED_OUT_STATE);
+ }
+ return state;
+ }
+
+ Runnable setComponentEnabled(boolean isComponentEnabled) {
+ this.mComponentEnabled = isComponentEnabled;
+
+ return this.setImageResourceAsync(this.mComponentEnabled
+ ? R.drawable.ic_volume_odi_captions
+ : R.drawable.ic_volume_odi_captions_disabled);
+ }
+
+ boolean getComponentEnabled() {
+ return this.mComponentEnabled;
+ }
+
+ /** Sets whether or not the current stream has opted out of captions */
+ void setOptedOut(boolean isOptedOut) {
+ this.mOptedOut = isOptedOut;
+ refreshDrawableState();
+ }
+
+ boolean getOptedOut() {
+ return this.mOptedOut;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
index 2fa8889..a3db533 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java
@@ -282,6 +282,13 @@
Settings.Secure.ODI_CAPTIONS_ENABLED, isEnabled ? 1 : 0);
}
+ @Override
+ public boolean isCaptionStreamOptedOut() {
+ int currentValue = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.ODI_CAPTIONS_OPTED_OUT, 0);
+ return currentValue == 1;
+ }
+
public void getCaptionsComponentState(boolean fromTooltip) {
if (mDestroyed) return;
mWorker.obtainMessage(W.GET_CAPTIONS_COMPONENT_STATE, fromTooltip).sendToTarget();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index cdda216..bd7824d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -133,7 +133,7 @@
private ViewGroup mRinger;
private ImageButton mRingerIcon;
private ViewGroup mODICaptionsView;
- private ImageButton mODICaptionsIcon;
+ private CaptionsToggleImageButton mODICaptionsIcon;
private View mSettingsView;
private ImageButton mSettingsIcon;
private FrameLayout mZenIcon;
@@ -587,11 +587,15 @@
}
private void updateCaptionsIcon() {
- mHandler.post(
- mODICaptionsIcon.setImageResourceAsync(
- mController.areCaptionsEnabled()
- ? R.drawable.ic_volume_odi_captions
- : R.drawable.ic_volume_odi_captions_disabled));
+ boolean componentEnabled = mController.areCaptionsEnabled();
+ if (mODICaptionsIcon.getComponentEnabled() != componentEnabled) {
+ mHandler.post(mODICaptionsIcon.setComponentEnabled(componentEnabled));
+ }
+
+ boolean isOptedOut = mController.isCaptionStreamOptedOut();
+ if (mODICaptionsIcon.getOptedOut() != isOptedOut) {
+ mHandler.post(() -> mODICaptionsIcon.setOptedOut(isOptedOut));
+ }
}
private void onCaptionIconClicked() {
@@ -952,7 +956,7 @@
}
private void updateVolumeRowH(VolumeRow row) {
- if (D.BUG) Log.d(TAG, "updateVolumeRowH s=" + row.stream);
+ if (D.BUG) Log.i(TAG, "updateVolumeRowH s=" + row.stream);
if (mState == null) return;
final StreamState ss = mState.states.get(row.stream);
if (ss == null) return;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
index 29505a2..632b0c0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchTest.java
@@ -39,10 +39,12 @@
import android.widget.TextClock;
import com.android.keyguard.clock.ClockManager;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ClockPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +72,10 @@
@Before
public void setUp() {
- LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater layoutInflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
mKeyguardClockSwitch =
(KeyguardClockSwitch) layoutInflater.inflate(R.layout.keyguard_clock_switch, null);
mClockContainer = mKeyguardClockSwitch.findViewById(R.id.clock_view);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
index 3582ab01..31ea39c 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.java
@@ -24,8 +24,10 @@
import android.testing.TestableLooper.RunWithLooper;
import android.view.LayoutInflater;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.util.Assert;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +50,10 @@
@Before
public void setUp() {
Assert.sMainLooper = TestableLooper.get(this).getLooper();
- LayoutInflater layoutInflater = LayoutInflater.from(getContext());
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater layoutInflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
mKeyguardStatusView =
(KeyguardStatusView) layoutInflater.inflate(R.layout.keyguard_status_view, null);
org.mockito.MockitoAnnotations.initMocks(this);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 5a1f24a..1bcf880 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -312,7 +312,6 @@
return new BubbleMetadata.Builder()
.setIntent(bubbleIntent)
.setDeleteIntent(deleteIntent)
- .setTitle("bubble title")
.setIcon(Icon.createWithResource(mContext, R.drawable.android))
.setDesiredHeight(314)
.build();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
index eec836f..dfe2913 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardPresentationTest.java
@@ -23,7 +23,9 @@
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,7 +37,10 @@
@Test
public void testInflation_doesntCrash() {
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
- LayoutInflater inflater = LayoutInflater.from(getContext());
+ InjectionInflationController inflationController = new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent());
+ LayoutInflater inflater = inflationController
+ .injectable(LayoutInflater.from(getContext()));
inflater.inflate(R.layout.keyguard_presentation, null);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index 6889c57..232c6a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -27,6 +27,7 @@
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardStatusView;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.AmbientPulseManager;
@@ -38,6 +39,7 @@
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -104,7 +106,10 @@
private class TestableNotificationPanelView extends NotificationPanelView {
TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler expansionHandler) {
- super(NotificationPanelViewTest.this.mContext, null, coordinator, expansionHandler);
+ super(NotificationPanelViewTest.this.mContext, null,
+ new InjectionInflationController(
+ SystemUIFactory.getInstance().getRootComponent()),
+ coordinator, expansionHandler);
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index a15e89c..b522344 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -39,7 +39,10 @@
IconShapeRoundedRectOverlay \
IconShapeSquareOverlay \
IconShapeSquircleOverlay \
- IconShapeTeardropOverlay
+ IconShapeTeardropOverlay \
+ NavigationBarMode3ButtonOverlay \
+ NavigationBarMode2ButtonOverlay \
+ NavigationBarModeGesturalOverlay
include $(BUILD_PHONY_PACKAGE)
include $(CLEAR_VARS)
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk
new file mode 100644
index 0000000..410d6d8
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2018, 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 := NavigationBarMode2Button
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := NavigationBarMode2ButtonOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..970380f
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.internal.systemui.navbar.twobutton"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="com.android.internal.navigation_bar_mode"
+ android:priority="1"/>
+
+ <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml
new file mode 100644
index 0000000..b353322
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/config.xml
@@ -0,0 +1,25 @@
+<?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.
+ */
+-->
+<resources>
+ <!-- Controls the navigation bar interaction mode:
+ 0: 3 button mode (back, home, overview buttons)
+ 1: 2 button mode (back, home buttons + swipe up for overview)
+ 2: gestures only for back, home and overview -->
+ <integer name="config_navBarInteractionMode">1</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml
new file mode 100644
index 0000000..1696ecf
--- /dev/null
+++ b/packages/overlays/NavigationBarMode2ButtonOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of overlay [CHAR LIMIT=64] -->
+ <string name="navigation_bar_mode_title" translatable="false">2 Button Navigation Bar</string>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk
new file mode 100644
index 0000000..2bc9a6a
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2018, 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 := NavigationBarMode3Button
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := NavigationBarMode3ButtonOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..628fc1d
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.internal.systemui.navbar.threebutton"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="com.android.internal.navigation_bar_mode"
+ android:priority="1"/>
+
+ <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml
new file mode 100644
index 0000000..7bd0a14
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/config.xml
@@ -0,0 +1,25 @@
+<?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.
+ */
+-->
+<resources>
+ <!-- Controls the navigation bar interaction mode:
+ 0: 3 button mode (back, home, overview buttons)
+ 1: 2 button mode (back, home buttons + swipe up for overview)
+ 2: gestures only for back, home and overview -->
+ <integer name="config_navBarInteractionMode">0</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml
new file mode 100644
index 0000000..201b9e9
--- /dev/null
+++ b/packages/overlays/NavigationBarMode3ButtonOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of overlay [CHAR LIMIT=64] -->
+ <string name="navigation_bar_mode_title" translatable="false">3 Button Navigation Bar</string>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk
new file mode 100644
index 0000000..5f7e0eb
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/Android.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2018, 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 := NavigationBarModeGestural
+LOCAL_CERTIFICATE := platform
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := NavigationBarModeGesturalOverlay
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_RRO_PACKAGE)
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml b/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml
new file mode 100644
index 0000000..aff82d8
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<!--
+/**
+ * Copyright (c) 2018, 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.internal.systemui.navbar.gestural"
+ android:versionCode="1"
+ android:versionName="1.0">
+ <overlay android:targetPackage="android"
+ android:category="com.android.internal.navigation_bar_mode"
+ android:priority="1"/>
+
+ <application android:label="@string/navigation_bar_mode_title" android:hasCode="false"/>
+</manifest>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
new file mode 100644
index 0000000..48c3769
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -0,0 +1,25 @@
+<?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.
+ */
+-->
+<resources>
+ <!-- Controls the navigation bar interaction mode:
+ 0: 3 button mode (back, home, overview buttons)
+ 1: 2 button mode (back, home buttons + swipe up for overview)
+ 2: gestures only for back, home and overview -->
+ <integer name="config_navBarInteractionMode">2</integer>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml
new file mode 100644
index 0000000..8d38916
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2018, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Name of overlay [CHAR LIMIT=64] -->
+ <string name="navigation_bar_mode_title" translatable="false">Gestural Navigation Bar</string>
+</resources>
\ No newline at end of file
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 7447331..95abd05 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -74,6 +74,9 @@
// The view switched to summary mode (most relevant for notifications)
TYPE_COLLAPSE = 14;
+ // The action results an error.
+ TYPE_ERROR = 15;
+
// The notification was adjusted by the assistant. Enum value is
// out of sequence due to b/122737498.
TYPE_NOTIFICATION_ASSISTANT_ADJUSTMENT = 1573;
@@ -7138,6 +7141,14 @@
// OS: Q
DISPLAY_POLICY = 1696;
+ // Biometric authentication.
+ // TYPE: SUCCESS, FAILURE or ERROR
+ // SUBTYPE: 0 is fingerprint, 1 is face, 2 is iris and 3 is unknown.
+ // OS: Q
+ BIOMETRIC_AUTH = 1697;
+
+ // Settings > Display > Theme
+ DARK_UI_SETTINGS = 1698;
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/art-profile b/services/art-profile
index 6368c63..f0b9234 100644
--- a/services/art-profile
+++ b/services/art-profile
@@ -1136,7 +1136,7 @@
Lcom/android/server/DropBoxManagerService$EntryFile;
Lcom/android/server/DropBoxManagerService$FileList;
Lcom/android/server/DropBoxManagerService;
-Lcom/android/server/DynamicAndroidService;
+Lcom/android/server/DynamicSystemService;
Lcom/android/server/EntropyMixer$1;
Lcom/android/server/EntropyMixer$2;
Lcom/android/server/EntropyMixer;
@@ -4769,9 +4769,9 @@
PLcom/android/server/DropBoxManagerService$EntryFile;->getFile(Ljava/io/File;)Ljava/io/File;
PLcom/android/server/DropBoxManagerService;->checkPermission(ILjava/lang/String;)Z
PLcom/android/server/DropBoxManagerService;->getNextEntry(Ljava/lang/String;JLjava/lang/String;)Landroid/os/DropBoxManager$Entry;
-PLcom/android/server/DynamicAndroidService;->connect(Landroid/os/IBinder$DeathRecipient;)Landroid/gsi/IGsiService;
-PLcom/android/server/DynamicAndroidService;->getGsiService()Landroid/gsi/IGsiService;
-PLcom/android/server/DynamicAndroidService;->isInUse()Z
+PLcom/android/server/DynamicSystemService;->connect(Landroid/os/IBinder$DeathRecipient;)Landroid/gsi/IGsiService;
+PLcom/android/server/DynamicSystemService;->getGsiService()Landroid/gsi/IGsiService;
+PLcom/android/server/DynamicSystemService;->isInUse()Z
PLcom/android/server/EntropyMixer$1;->handleMessage(Landroid/os/Message;)V
PLcom/android/server/EntropyMixer$2;->onReceive(Landroid/content/Context;Landroid/content/Intent;)V
PLcom/android/server/EventLogTags;->writeBatterySaverMode(IIIIILjava/lang/String;I)V
@@ -15043,7 +15043,7 @@
SPLcom/android/server/DropBoxManagerService;->onBootPhase(I)V
SPLcom/android/server/DropBoxManagerService;->onStart()V
SPLcom/android/server/DropBoxManagerService;->trimToFit()J
-SPLcom/android/server/DynamicAndroidService;-><init>(Landroid/content/Context;)V
+SPLcom/android/server/DynamicSystemService;-><init>(Landroid/content/Context;)V
SPLcom/android/server/EntropyMixer;-><init>(Landroid/content/Context;)V
SPLcom/android/server/EntropyMixer;-><init>(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
SPLcom/android/server/EntropyMixer;->addDeviceSpecificEntropy()V
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 76d464d..87a265c 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -80,6 +80,7 @@
import com.android.server.LocalServices;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.infra.AbstractMasterSystemService;
+import com.android.server.infra.FrameworkResourcesServiceNameResolver;
import com.android.server.infra.SecureSettingsServiceNameResolver;
import java.io.FileDescriptor;
@@ -132,6 +133,12 @@
@GuardedBy("sLock")
private static int sVisibleDatasetsMaxCount = 0;
+ /**
+ * Object used to set the name of the augmented autofill service.
+ */
+ @NonNull
+ final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver;
+
private final AutoFillUI mUi;
private final LocalLog mRequestsHistory = new LocalLog(20);
@@ -200,6 +207,11 @@
getServiceForUserLocked(userId);
}
}
+
+ mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
+ com.android.internal.R.string.config_defaultAugmentedAutofillService);
+ mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
+ (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService());
}
@Override // from AbstractMasterSystemService
@@ -521,7 +533,7 @@
new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
strategy.calculateScores(callback, Arrays.asList(AutofillValue.forText(value1)),
- new String[] { value2 }, null, algorithmName, null, null, null);
+ new String[] { value2 }, new String[] { null }, algorithmName, null, null, null);
}
// Called by Shell command.
@@ -549,37 +561,19 @@
+ MAX_TEMP_AUGMENTED_SERVICE_DURATION_MS + " (called with " + durationMs + ")");
}
- synchronized (mLock) {
- final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
- service.mAugmentedAutofillResolver.setTemporaryService(userId, serviceName,
- durationMs);
- }
- }
+ mAugmentedAutofillResolver.setTemporaryService(userId, serviceName, durationMs);
}
// Called by Shell command
void resetTemporaryAugmentedAutofillService(@UserIdInt int userId) {
enforceCallingPermissionForManagement();
- synchronized (mLock) {
- final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
- service.mAugmentedAutofillResolver.resetTemporaryService(userId);
- }
- }
+ mAugmentedAutofillResolver.resetTemporaryService(userId);
}
// Called by Shell command
boolean isDefaultAugmentedServiceEnabled(@UserIdInt int userId) {
enforceCallingPermissionForManagement();
-
- synchronized (mLock) {
- final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
- return service.mAugmentedAutofillResolver.isDefaultServiceEnabled(userId);
- }
- }
- return false;
+ return mAugmentedAutofillResolver.isDefaultServiceEnabled(userId);
}
// Called by Shell command
@@ -590,7 +584,7 @@
synchronized (mLock) {
final AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
if (service != null) {
- final boolean changed = service.mAugmentedAutofillResolver
+ final boolean changed = mAugmentedAutofillResolver
.setDefaultServiceEnabled(userId, enabled);
if (changed) {
service.updateRemoteAugmentedAutofillService();
@@ -1348,6 +1342,7 @@
pw.print(" sVerbose: "); pw.println(realVerbose);
// Dump per-user services
dumpLocked("", pw);
+ mAugmentedAutofillResolver.dumpShort(pw); pw.println();
pw.print("Max partitions per session: "); pw.println(sPartitionMaxCount);
pw.print("Max visible datasets: "); pw.println(sVisibleDatasetsMaxCount);
if (sFullScreenMode != null) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index ad5e689..89c4043 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -83,7 +83,6 @@
import com.android.server.autofill.RemoteAugmentedAutofillService.RemoteAugmentedAutofillServiceCallbacks;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.infra.AbstractPerUserSystemService;
-import com.android.server.infra.FrameworkResourcesServiceNameResolver;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -159,13 +158,6 @@
/** When was {@link PruneTask} last executed? */
private long mLastPrune = 0;
- // TODO(b/128911469): move to AutofillManagerService
- /**
- * Object used to set the name of the augmented autofill service.
- */
- @NonNull
- final FrameworkResourcesServiceNameResolver mAugmentedAutofillResolver;
-
/**
* Reference to the {@link RemoteAugmentedAutofillService}, is set on demand.
*/
@@ -195,11 +187,6 @@
mFieldClassificationStrategy = new FieldClassificationStrategy(getContext(), userId);
mAutofillCompatState = autofillCompatState;
- mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(master.getContext(),
- com.android.internal.R.string.config_defaultAugmentedAutofillService);
- mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
- (u, s) -> updateRemoteAugmentedAutofillService());
-
updateLocked(disabled);
}
@@ -951,8 +938,7 @@
.getString(R.string.config_defaultAutofillService));
pw.print(prefix); pw.println("mAugmentedAutofillNamer: ");
- pw.print(prefix2); mAugmentedAutofillResolver.dumpShort(pw); pw.println();
- pw.print(prefix2); mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println();
+ pw.print(prefix2); mMaster.mAugmentedAutofillResolver.dumpShort(pw, mUserId); pw.println();
if (mRemoteAugmentedAutofillService != null) {
pw.print(prefix); pw.println("RemoteAugmentedAutofillService: ");
@@ -1109,7 +1095,7 @@
@GuardedBy("mLock")
@Nullable RemoteAugmentedAutofillService getRemoteAugmentedAutofillServiceLocked() {
if (mRemoteAugmentedAutofillService == null) {
- final String serviceName = mAugmentedAutofillResolver.getServiceName(mUserId);
+ final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId);
if (serviceName == null) {
if (mMaster.verbose) {
Slog.v(TAG, "getRemoteAugmentedAutofillServiceLocked(): not set");
@@ -1117,8 +1103,8 @@
return null;
}
final Pair<ServiceInfo, ComponentName> pair = RemoteAugmentedAutofillService
- .getComponentName(
- serviceName, mUserId, mAugmentedAutofillResolver.isTemporary(mUserId));
+ .getComponentName(serviceName, mUserId,
+ mMaster.mAugmentedAutofillResolver.isTemporary(mUserId));
if (pair == null) return null;
mRemoteAugmentedAutofillServiceInfo = pair.first;
@@ -1148,7 +1134,8 @@
}
/**
- * Called when the {@link #mAugmentedAutofillResolver} changed (among other places).
+ * Called when the {@link AutofillManagerService#mAugmentedAutofillResolver}
+ * changed (among other places).
*/
void updateRemoteAugmentedAutofillService() {
synchronized (mLock) {
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
index 9995d8e..b2760e0 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java
@@ -18,6 +18,12 @@
import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE;
import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION;
+import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_TRUE;
+
+import static com.android.internal.util.SyncResultReceiver.bundleFor;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -57,7 +63,6 @@
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
-import com.android.internal.util.SyncResultReceiver;
import com.android.server.LocalServices;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
@@ -167,6 +172,22 @@
}
@Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatingLocked(int userId) {
+ final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatingLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatedLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
protected void enforceCallingPermissionForManagement() {
getContext().enforceCallingPermission(MANAGE_CONTENT_CAPTURE, mTag);
}
@@ -414,8 +435,7 @@
if (isService) return true;
try {
- result.send(ContentCaptureManager.RESULT_CODE_NOT_SERVICE,
- /* resultData= */ null);
+ result.send(RESULT_CODE_SECURITY_EXCEPTION, /* resultData= */ null);
} catch (RemoteException e) {
Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e);
}
@@ -518,8 +538,7 @@
connectedServiceComponentName = service.getServiceComponentName();
}
try {
- result.send(/* resultCode= */ 0,
- SyncResultReceiver.bundleFor(connectedServiceComponentName));
+ result.send(RESULT_CODE_OK, bundleFor(connectedServiceComponentName));
} catch (RemoteException e) {
Slog.w(mTag, "Unable to send service component name: " + e);
}
@@ -547,14 +566,40 @@
enabled = !mDisabledByDeviceConfig && !isDisabledBySettingsLocked(userId);
}
try {
- result.send(enabled ? ContentCaptureManager.RESULT_CODE_TRUE
- : ContentCaptureManager.RESULT_CODE_FALSE, /* resultData= */null);
+ result.send(enabled ? RESULT_CODE_TRUE : RESULT_CODE_FALSE, /* resultData= */null);
} catch (RemoteException e) {
Slog.w(mTag, "Unable to send isContentCaptureFeatureEnabled(): " + e);
}
}
@Override
+ public void getServiceSettingsActivity(@NonNull IResultReceiver result) {
+ try {
+ enforceCallingPermissionForManagement();
+ } catch (SecurityException e) {
+ try {
+ result.send(RESULT_CODE_SECURITY_EXCEPTION, bundleFor(e.getMessage()));
+ } catch (RemoteException e2) {
+ Slog.w(mTag, "Unable to send getServiceSettingsIntent() exception: " + e2);
+ return;
+ }
+ }
+
+ final int userId = UserHandle.getCallingUserId();
+ final ComponentName componentName;
+ synchronized (mLock) {
+ final ContentCapturePerUserService service = getServiceForUserLocked(userId);
+ if (service == null) return;
+ componentName = service.getServiceSettingsActivityLocked();
+ }
+ try {
+ result.send(RESULT_CODE_OK, bundleFor(componentName));
+ } catch (RemoteException e) {
+ Slog.w(mTag, "Unable to send getServiceSettingsIntent(): " + e);
+ }
+ }
+
+ @Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), mTag, pw)) return;
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index d7d97b3..b27554a 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -74,7 +74,7 @@
AbstractPerUserSystemService<ContentCapturePerUserService, ContentCaptureManagerService>
implements ContentCaptureServiceCallbacks {
- private static final String TAG = ContentCaptureManagerService.class.getSimpleName();
+ private static final String TAG = ContentCapturePerUserService.class.getSimpleName();
@GuardedBy("mLock")
private final ArrayMap<String, ContentCaptureServerSession> mSessions =
@@ -87,7 +87,8 @@
* master's cache (for example, because a temporary service was set).
*/
@GuardedBy("mLock")
- private RemoteContentCaptureService mRemoteService;
+ @Nullable
+ RemoteContentCaptureService mRemoteService;
private final ContentCaptureServiceRemoteCallback mRemoteServiceCallback =
new ContentCaptureServiceRemoteCallback();
@@ -135,6 +136,10 @@
}
if (!disabled) {
+ if (mMaster.debug) {
+ Slog.d(TAG, "updateRemoteService(): creating new remote service for "
+ + serviceComponentName);
+ }
mRemoteService = new RemoteContentCaptureService(mMaster.getContext(),
ContentCaptureService.SERVICE_INTERFACE, serviceComponentName,
mRemoteServiceCallback, mUserId, this, mMaster.isBindInstantServiceAllowed(),
@@ -182,20 +187,40 @@
}
mZombie = false;
- final int numSessions = mSessions.size();
- if (mMaster.debug) {
- Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
- + numSessions + " sessions");
- }
-
- for (int i = 0; i < numSessions; i++) {
- final ContentCaptureServerSession session = mSessions.valueAt(i);
- session.resurrectLocked();
- }
+ resurrectSessionsLocked();
}
}
}
+ private void resurrectSessionsLocked() {
+ final int numSessions = mSessions.size();
+ if (mMaster.debug) {
+ Slog.d(TAG, "Ressurrecting remote service (" + mRemoteService + ") on "
+ + numSessions + " sessions");
+ }
+
+ for (int i = 0; i < numSessions; i++) {
+ final ContentCaptureServerSession session = mSessions.valueAt(i);
+ session.resurrectLocked();
+ }
+ }
+
+ void onPackageUpdatingLocked() {
+ final int numSessions = mSessions.size();
+ if (mMaster.debug) {
+ Slog.d(TAG, "Pausing " + numSessions + " sessions while package is updating");
+ }
+ for (int i = 0; i < numSessions; i++) {
+ final ContentCaptureServerSession session = mSessions.valueAt(i);
+ session.pauseLocked();
+ }
+ }
+
+ void onPackageUpdatedLocked() {
+ updateRemoteServiceLocked(!isEnabledLocked());
+ resurrectSessionsLocked();
+ }
+
// TODO(b/119613670): log metrics
@GuardedBy("mLock")
public void startSessionLocked(@NonNull IBinder activityToken,
@@ -274,9 +299,12 @@
return;
}
+ // Make sure service is bound, just in case the initial connection failed somehow
+ mRemoteService.ensureBoundLocked();
+
final ContentCaptureServerSession newSession = new ContentCaptureServerSession(
- activityToken, this, mRemoteService, componentName, clientReceiver, taskId,
- displayId, sessionId, uid, flags);
+ activityToken, this, componentName, clientReceiver, taskId, displayId, sessionId,
+ uid, flags);
if (mMaster.verbose) {
Slog.v(TAG, "startSession(): new session for "
+ ComponentName.flattenToShortString(componentName) + " and id " + sessionId);
@@ -290,21 +318,6 @@
return mWhitelistHelper.isWhitelisted(componentName);
}
- /**
- * @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 (mMaster.verbose) {
- Slog.v(TAG, "whitelisting packages: " + packages + " and activities: "
- + components);
- }
- mWhitelistHelper.setWhitelist(packages, components);
- }
- }
-
// TODO(b/119613670): log metrics
@GuardedBy("mLock")
public void finishSessionLocked(@NonNull String sessionId) {
@@ -332,6 +345,18 @@
mRemoteService.onUserDataRemovalRequest(request);
}
+ @GuardedBy("mLock")
+ @Nullable
+ public ComponentName getServiceSettingsActivityLocked() {
+ if (mInfo == null) return null;
+
+ final String activityName = mInfo.getSettingsActivity();
+ if (activityName == null) return null;
+
+ final String packageName = mInfo.getServiceInfo().packageName;
+ return new ComponentName(packageName, activityName);
+ }
+
/**
* Asserts the component is owned by the caller.
*/
@@ -518,12 +543,16 @@
@Override
public void setContentCaptureWhitelist(List<String> packages,
List<ComponentName> activities) {
+ // TODO(b/122595322): add CTS test for when it's null
if (mMaster.verbose) {
- Slog.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities="
- + activities + ")");
+ Slog.v(TAG, "setContentCaptureWhitelist(" + (packages == null
+ ? "null_packages" : packages.size() + " packages")
+ + ", " + (activities == null
+ ? "null_activities" : activities.size() + " activities") + ")");
}
- setWhitelist(packages, activities);
-
+ synchronized (mLock) {
+ mWhitelistHelper.setWhitelist(packages, activities);
+ }
// TODO(b/119613670): log metrics
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
index da19836..9b2c05f 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureServerSession.java
@@ -15,6 +15,12 @@
*/
package com.android.server.contentcapture;
+import static android.service.contentcapture.ContentCaptureService.setClientState;
+import static android.view.contentcapture.ContentCaptureSession.STATE_ACTIVE;
+import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
+import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_RESURRECTED;
+import static android.view.contentcapture.ContentCaptureSession.STATE_SERVICE_UPDATING;
+
import android.annotation.NonNull;
import android.content.ComponentName;
import android.os.IBinder;
@@ -23,7 +29,6 @@
import android.util.LocalLog;
import android.util.Slog;
import android.view.contentcapture.ContentCaptureContext;
-import android.view.contentcapture.ContentCaptureSession;
import android.view.contentcapture.ContentCaptureSessionId;
import com.android.internal.annotations.GuardedBy;
@@ -38,7 +43,6 @@
final IBinder mActivityToken;
private final ContentCapturePerUserService mService;
- private final RemoteContentCaptureService mRemoteService;
// NOTE: this is the "internal" context (like package and taskId), not the explicit content
// set by apps - those are only send to the ContentCaptureService.
@@ -61,15 +65,13 @@
private final int mUid;
ContentCaptureServerSession(@NonNull IBinder activityToken,
- @NonNull ContentCapturePerUserService service,
- @NonNull RemoteContentCaptureService remoteService,
- @NonNull ComponentName appComponentName, @NonNull IResultReceiver sessionStateReceiver,
+ @NonNull ContentCapturePerUserService service, @NonNull ComponentName appComponentName,
+ @NonNull IResultReceiver sessionStateReceiver,
int taskId, int displayId, @NonNull String sessionId, int uid, int flags) {
mActivityToken = activityToken;
mService = service;
mId = Preconditions.checkNotNull(sessionId);
mUid = uid;
- mRemoteService = remoteService;
mContentCaptureContext = new ContentCaptureContext(/* clientContext= */ null,
appComponentName, taskId, displayId, flags);
mSessionStateReceiver = sessionStateReceiver;
@@ -87,8 +89,12 @@
*/
@GuardedBy("mLock")
public void notifySessionStartedLocked(@NonNull IResultReceiver clientReceiver) {
- mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
- ContentCaptureSession.STATE_ACTIVE);
+ if (mService.mRemoteService == null) {
+ Slog.w(TAG, "notifySessionStartedLocked(): no remote service");
+ return;
+ }
+ mService.mRemoteService.onSessionStarted(mContentCaptureContext, mId, mUid, clientReceiver,
+ STATE_ACTIVE);
}
/**
@@ -101,7 +107,11 @@
logHistory.log("snapshot: id=" + mId);
}
- mRemoteService.onActivitySnapshotRequest(mId, snapshotData);
+ if (mService.mRemoteService == null) {
+ Slog.w(TAG, "sendActivitySnapshotLocked(): no remote service");
+ return;
+ }
+ mService.mRemoteService.onActivitySnapshotRequest(mId, snapshotData);
}
/**
@@ -134,7 +144,11 @@
}
// TODO(b/111276913): must call client to set session as FINISHED_BY_SERVER
if (notifyRemoteService) {
- mRemoteService.onSessionFinished(mId);
+ if (mService.mRemoteService == null) {
+ Slog.w(TAG, "destroyLocked(): no remote service");
+ return;
+ }
+ mService.mRemoteService.onSessionFinished(mId);
}
}
@@ -143,10 +157,27 @@
*/
@GuardedBy("mLock")
public void resurrectLocked() {
- mRemoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
+ final RemoteContentCaptureService remoteService = mService.mRemoteService;
+ if (remoteService == null) {
+ Slog.w(TAG, "destroyLocked(: no remote service");
+ return;
+ }
+ if (mService.isVerbose()) {
+ Slog.v(TAG, "resurrecting " + mActivityToken + " on " + remoteService);
+ }
+ remoteService.onSessionStarted(new ContentCaptureContext(mContentCaptureContext,
ContentCaptureContext.FLAG_RECONNECTED), mId, mUid, mSessionStateReceiver,
- ContentCaptureSession.STATE_ACTIVE
- | ContentCaptureSession.STATE_SERVICE_RESURRECTED);
+ STATE_ACTIVE | STATE_SERVICE_RESURRECTED);
+ }
+
+ /**
+ * Called to pause the session while the service is being updated.
+ */
+ @GuardedBy("mLock")
+ public void pauseLocked() {
+ if (mService.isVerbose()) Slog.v(TAG, "pausing " + mActivityToken);
+ setClientState(mSessionStateReceiver, STATE_DISABLED | STATE_SERVICE_UPDATING,
+ /* binder= */ null);
}
@GuardedBy("mLock")
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index 2ce5059..df9ccbc 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -54,7 +54,7 @@
mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
// Bind right away, which will trigger a onConnected() on service's
- scheduleBind();
+ ensureBoundLocked();
}
@Override // from AbstractRemoteService
@@ -89,6 +89,10 @@
}
}
+ public void ensureBoundLocked() {
+ scheduleBind();
+ }
+
/**
* Called by {@link ContentCaptureServerSession} to generate a call to the
* {@link RemoteContentCaptureService} to indicate the session was created.
diff --git a/services/core/java/com/android/server/DynamicAndroidService.java b/services/core/java/com/android/server/DynamicSystemService.java
similarity index 92%
rename from services/core/java/com/android/server/DynamicAndroidService.java
rename to services/core/java/com/android/server/DynamicSystemService.java
index b02bfb1..f5bd11c 100644
--- a/services/core/java/com/android/server/DynamicAndroidService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -22,25 +22,25 @@
import android.gsi.IGsiService;
import android.os.IBinder;
import android.os.IBinder.DeathRecipient;
-import android.os.IDynamicAndroidService;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
+import android.os.image.IDynamicSystemService;
import android.util.Slog;
/**
- * DynamicAndroidService implements IDynamicAndroidService. It provides permission check before
+ * DynamicSystemService implements IDynamicSystemService. It provides permission check before
* passing requests to gsid
*/
-public class DynamicAndroidService extends IDynamicAndroidService.Stub implements DeathRecipient {
- private static final String TAG = "DynamicAndroidService";
+public class DynamicSystemService extends IDynamicSystemService.Stub implements DeathRecipient {
+ private static final String TAG = "DynamicSystemService";
private static final String NO_SERVICE_ERROR = "no gsiservice";
private static final int GSID_ROUGH_TIMEOUT_MS = 8192;
private Context mContext;
private volatile IGsiService mGsiService;
- DynamicAndroidService(Context context) {
+ DynamicSystemService(Context context) {
mContext = context;
}
@@ -93,9 +93,9 @@
private void checkPermission() {
if (mContext.checkCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_DYNAMIC_ANDROID)
+ android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
!= PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires MANAGE_DYNAMIC_ANDROID permission");
+ throw new SecurityException("Requires MANAGE_DYNAMIC_SYSTEM permission");
}
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index b89223b..f0244c3 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -3597,10 +3597,18 @@
pw.println(" " + provider + ": " + location);
}
- mGeofenceManager.dump(pw);
-
- pw.append(" ");
- mBlacklist.dump(pw);
+ if (mGeofenceManager != null) {
+ mGeofenceManager.dump(pw);
+ } else {
+ pw.println(" Geofences: null");
+ }
+
+ if (mBlacklist != null) {
+ pw.append(" ");
+ mBlacklist.dump(pw);
+ } else {
+ pw.println(" mBlacklist=null");
+ }
if (mLocationControllerExtraPackage != null) {
pw.println(" Location controller extra package: " + mLocationControllerExtraPackage
@@ -3614,8 +3622,12 @@
}
}
- pw.append(" fudger: ");
- mLocationFudger.dump(fd, pw, args);
+ if (mLocationFudger != null) {
+ pw.append(" fudger: ");
+ mLocationFudger.dump(fd, pw, args);
+ } else {
+ pw.println(" fudger: null");
+ }
if (args.length > 0 && "short".equals(args[0])) {
return;
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 10b67c1..2e5dd3b 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1257,6 +1257,7 @@
}
scheduleWriteLocked();
}
+ uidState.evalForegroundOps(mOpModeWatchers);
}
String[] uidPackageNames = getPackagesForUid(uid);
@@ -2414,8 +2415,6 @@
private void commitUidPendingStateLocked(UidState uidState) {
final boolean lastForeground = uidState.state <= UID_STATE_MAX_LAST_NON_RESTRICTED;
final boolean nowForeground = uidState.pendingState <= UID_STATE_MAX_LAST_NON_RESTRICTED;
- uidState.state = uidState.pendingState;
- uidState.pendingStateCommitTime = 0;
if (uidState.hasForegroundWatchers && lastForeground != nowForeground) {
for (int fgi = uidState.foregroundOps.size() - 1; fgi >= 0; fgi--) {
if (!uidState.foregroundOps.valueAt(fgi)) {
@@ -2424,11 +2423,10 @@
final int code = uidState.foregroundOps.keyAt(fgi);
// For location ops we consider fg state only if the fg service
// is of location type, for all other ops any fg service will do.
- final long resolvedLastRestrictedUidState = resolveFirstUnrestrictedUidState(code);
- final boolean resolvedLastFg = uidState.state <= resolvedLastRestrictedUidState;
- final boolean resolvedNowBg = uidState.pendingState
- <= resolvedLastRestrictedUidState;
- if (resolvedLastFg == resolvedNowBg) {
+ final long firstUnrestrictedUidState = resolveFirstUnrestrictedUidState(code);
+ final boolean resolvedLastFg = uidState.state <= firstUnrestrictedUidState;
+ final boolean resolvedNowFg = uidState.pendingState <= firstUnrestrictedUidState;
+ if (resolvedLastFg == resolvedNowFg) {
continue;
}
final ArraySet<ModeCallback> callbacks = mOpModeWatchers.get(code);
@@ -2460,6 +2458,8 @@
}
}
}
+ uidState.state = uidState.pendingState;
+ uidState.pendingStateCommitTime = 0;
}
private Ops getOpsRawLocked(int uid, String packageName, boolean edit,
diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
index 4289a25..54a4ad4 100644
--- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java
@@ -16,7 +16,6 @@
package com.android.server.broadcastradio;
-import android.annotation.NonNull;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -26,14 +25,13 @@
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
-import android.os.ParcelableException;
import android.os.RemoteException;
import android.util.Slog;
-import com.android.internal.util.Preconditions;
import com.android.server.SystemService;
import com.android.server.broadcastradio.hal2.AnnouncementAggregator;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
@@ -45,16 +43,20 @@
private final ServiceImpl mServiceImpl = new ServiceImpl();
- private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1 =
- new com.android.server.broadcastradio.hal1.BroadcastRadioService();
- private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2 =
- new com.android.server.broadcastradio.hal2.BroadcastRadioService();
+ private final com.android.server.broadcastradio.hal1.BroadcastRadioService mHal1;
+ private final com.android.server.broadcastradio.hal2.BroadcastRadioService mHal2;
private final Object mLock = new Object();
- private List<RadioManager.ModuleProperties> mModules = null;
+ private List<RadioManager.ModuleProperties> mV1Modules = null;
public BroadcastRadioService(Context context) {
super(context);
+
+ mHal1 = new com.android.server.broadcastradio.hal1.BroadcastRadioService();
+ mV1Modules = mHal1.loadModules();
+ OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
+ mHal2 = new com.android.server.broadcastradio.hal2.BroadcastRadioService(
+ max.isPresent() ? max.getAsInt() + 1 : 0);
}
@Override
@@ -62,14 +64,6 @@
publishBinderService(Context.RADIO_SERVICE, mServiceImpl);
}
- /**
- * Finds next available index for newly loaded modules.
- */
- private static int getNextId(@NonNull List<RadioManager.ModuleProperties> modules) {
- OptionalInt max = modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max();
- return max.isPresent() ? max.getAsInt() + 1 : 0;
- }
-
private class ServiceImpl extends IRadioService.Stub {
private void enforcePolicyAccess() {
if (PackageManager.PERMISSION_GRANTED != getContext().checkCallingPermission(
@@ -81,14 +75,10 @@
@Override
public List<RadioManager.ModuleProperties> listModules() {
enforcePolicyAccess();
- synchronized (mLock) {
- if (mModules != null) return mModules;
-
- mModules = mHal1.loadModules();
- mModules.addAll(mHal2.loadModules(getNextId(mModules)));
-
- return mModules;
- }
+ List<RadioManager.ModuleProperties> modules = new ArrayList<>();
+ modules.addAll(mV1Modules);
+ modules.addAll(mHal2.listModules());
+ return modules;
}
@Override
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
index 954c001..b8810c8f 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java
@@ -18,20 +18,22 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.hardware.broadcastradio.V2_0.IBroadcastRadio;
import android.hardware.radio.IAnnouncementListener;
import android.hardware.radio.ICloseHandle;
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
-import android.hardware.broadcastradio.V2_0.IBroadcastRadio;
import android.hidl.manager.V1_0.IServiceManager;
+import android.hidl.manager.V1_0.IServiceNotification;
+import android.os.IHwBinder.DeathRecipient;
import android.os.RemoteException;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
+
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -39,52 +41,104 @@
public class BroadcastRadioService {
private static final String TAG = "BcRadio2Srv";
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private int mNextModuleId = 0;
+
+ @GuardedBy("mLock")
+ private final Map<String, Integer> mServiceNameToModuleIdMap = new HashMap<>();
+
+ @GuardedBy("mLock")
private final Map<Integer, RadioModule> mModules = new HashMap<>();
- private static @NonNull List<String> listByInterface(@NonNull String fqName) {
+ private IServiceNotification.Stub mServiceListener = new IServiceNotification.Stub() {
+ @Override
+ public void onRegistration(String fqName, String serviceName, boolean preexisting) {
+ Slog.v(TAG, "onRegistration(" + fqName + ", " + serviceName + ", " + preexisting + ")");
+ Integer moduleId;
+ synchronized (mLock) {
+ // If the service has been registered before, reuse its previous module ID.
+ moduleId = mServiceNameToModuleIdMap.get(serviceName);
+ boolean newService = false;
+ if (moduleId == null) {
+ newService = true;
+ moduleId = mNextModuleId;
+ }
+
+ RadioModule module = RadioModule.tryLoadingModule(moduleId, serviceName);
+ if (module == null) {
+ return;
+ }
+ Slog.v(TAG, "loaded broadcast radio module " + moduleId + ": " + serviceName
+ + " (HAL 2.0)");
+ mModules.put(moduleId, module);
+
+ if (newService) {
+ mServiceNameToModuleIdMap.put(serviceName, moduleId);
+ mNextModuleId++;
+ }
+
+ try {
+ module.getService().linkToDeath(mDeathRecipient, moduleId);
+ } catch (RemoteException ex) {
+ // Service has already died, so remove its entry from mModules.
+ mModules.remove(moduleId);
+ }
+ }
+ }
+ };
+
+ private DeathRecipient mDeathRecipient = new DeathRecipient() {
+ @Override
+ public void serviceDied(long cookie) {
+ Slog.v(TAG, "serviceDied(" + cookie + ")");
+ synchronized (mLock) {
+ int moduleId = (int) cookie;
+ mModules.remove(moduleId);
+
+ for (Map.Entry<String, Integer> entry : mServiceNameToModuleIdMap.entrySet()) {
+ if (entry.getValue() == moduleId) {
+ Slog.i(TAG, "service " + entry.getKey()
+ + " died; removed RadioModule with ID " + moduleId);
+ return;
+ }
+ }
+ }
+ }
+ };
+
+ public BroadcastRadioService(int nextModuleId) {
+ mNextModuleId = nextModuleId;
try {
IServiceManager manager = IServiceManager.getService();
if (manager == null) {
- Slog.e(TAG, "Failed to get HIDL Service Manager");
- return Collections.emptyList();
+ Slog.e(TAG, "failed to get HIDL Service Manager");
+ return;
}
-
- List<String> list = manager.listByInterface(fqName);
- if (list == null) {
- Slog.e(TAG, "Didn't get interface list from HIDL Service Manager");
- return Collections.emptyList();
- }
- return list;
+ manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener);
} catch (RemoteException ex) {
- Slog.e(TAG, "Failed fetching interface list", ex);
- return Collections.emptyList();
+ Slog.e(TAG, "failed to register for service notifications: ", ex);
}
}
- public @NonNull Collection<RadioManager.ModuleProperties> loadModules(int idx) {
- Slog.v(TAG, "loadModules(" + idx + ")");
-
- for (String serviceName : listByInterface(IBroadcastRadio.kInterfaceName)) {
- Slog.v(TAG, "checking service: " + serviceName);
-
- RadioModule module = RadioModule.tryLoadingModule(idx, serviceName);
- if (module != null) {
- Slog.i(TAG, "loaded broadcast radio module " + idx + ": " +
- serviceName + " (HAL 2.0)");
- mModules.put(idx++, module);
- }
+ public @NonNull Collection<RadioManager.ModuleProperties> listModules() {
+ synchronized (mLock) {
+ return mModules.values().stream().map(module -> module.mProperties)
+ .collect(Collectors.toList());
}
-
- return mModules.values().stream().map(module -> module.mProperties).
- collect(Collectors.toList());
}
public boolean hasModule(int id) {
- return mModules.containsKey(id);
+ synchronized (mLock) {
+ return mModules.containsKey(id);
+ }
}
public boolean hasAnyModules() {
- return !mModules.isEmpty();
+ synchronized (mLock) {
+ return !mModules.isEmpty();
+ }
}
public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
@@ -95,7 +149,10 @@
throw new IllegalArgumentException("Non-audio sessions not supported with HAL 2.x");
}
- RadioModule module = mModules.get(moduleId);
+ RadioModule module = null;
+ synchronized (mLock) {
+ module = mModules.get(moduleId);
+ }
if (module == null) {
throw new IllegalArgumentException("Invalid module ID");
}
@@ -111,12 +168,14 @@
@NonNull IAnnouncementListener listener) {
AnnouncementAggregator aggregator = new AnnouncementAggregator(listener);
boolean anySupported = false;
- for (RadioModule module : mModules.values()) {
- try {
- aggregator.watchModule(module, enabledTypes);
- anySupported = true;
- } catch (UnsupportedOperationException ex) {
- Slog.v(TAG, "Announcements not supported for this module", ex);
+ synchronized (mLock) {
+ for (RadioModule module : mModules.values()) {
+ try {
+ aggregator.watchModule(module, enabledTypes);
+ anySupported = true;
+ } catch (UnsupportedOperationException ex) {
+ Slog.v(TAG, "Announcements not supported for this module", ex);
+ }
}
}
if (!anySupported) {
diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
index 816ba0b..832f8e1 100644
--- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java
@@ -20,8 +20,6 @@
import android.annotation.Nullable;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.hardware.radio.ITuner;
-import android.hardware.radio.RadioManager;
import android.hardware.broadcastradio.V2_0.AmFmRegionConfig;
import android.hardware.broadcastradio.V2_0.Announcement;
import android.hardware.broadcastradio.V2_0.DabTableEntry;
@@ -30,13 +28,12 @@
import android.hardware.broadcastradio.V2_0.ICloseHandle;
import android.hardware.broadcastradio.V2_0.ITunerSession;
import android.hardware.broadcastradio.V2_0.Result;
-import android.os.ParcelableException;
+import android.hardware.radio.RadioManager;
import android.os.RemoteException;
import android.util.MutableInt;
import android.util.Slog;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@@ -78,6 +75,10 @@
}
}
+ public @NonNull IBroadcastRadio getService() {
+ return mService;
+ }
+
public @NonNull TunerSession openSession(@NonNull android.hardware.radio.ITunerCallback userCb)
throws RemoteException {
TunerCallback cb = new TunerCallback(Objects.requireNonNull(userCb));
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 32f34b8..3010324 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -37,7 +37,6 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.ColorSpace;
-import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.SensorManager;
@@ -1275,11 +1274,12 @@
if (token == null) {
return false;
}
- final GraphicBuffer gb = SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
- token, new Rect(), 0 /* width */, 0 /* height */, false /* useIdentityTransform */,
- 0 /* rotation */);
+ final SurfaceControl.ScreenshotGraphicBuffer gb =
+ SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
+ token, new Rect(), 0 /* width */, 0 /* height */,
+ false /* useIdentityTransform */, 0 /* rotation */);
try {
- outSurface.attachAndQueueBuffer(gb);
+ outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
} catch (RuntimeException e) {
Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 430203d..ed894ee 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -131,14 +131,10 @@
private final boolean mRefreshServiceOnPackageUpdate;
/**
- * Name of the service's package that was active but then was removed because its package
- * update.
- *
- * <p>It's a temporary state set / used by the {@link PackageMonitor} implementation, but
- * defined here so it can be dumped.
+ * Name of the service packages whose APK are being updated, keyed by user id.
*/
@GuardedBy("mLock")
- private String mLastActivePackageName;
+ private SparseArray<String> mUpdatingPackageNames;
/**
* Default constructor.
@@ -565,6 +561,20 @@
}
/**
+ * Called before the package that provides the service for the given user is being updated.
+ */
+ protected void onServicePackageUpdatingLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageUpdatingLocked(" + userId + ")");
+ }
+
+ /**
+ * Called after the package that provides the service for the given user is being updated.
+ */
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageUpdated(" + userId + ")");
+ }
+
+ /**
* Called after the service is removed from the cache.
*/
@SuppressWarnings("unused")
@@ -602,8 +612,10 @@
final int size = mServicesCache.size();
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
pw.print(" Verbose: "); pw.println(realVerbose);
- pw.print(" Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
- pw.print(" Last active service on update: "); pw.println(mLastActivePackageName);
+ pw.print("Refresh on package update: "); pw.println(mRefreshServiceOnPackageUpdate);
+ if (mUpdatingPackageNames != null) {
+ pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
+ }
if (mServiceNameResolver != null) {
pw.print(prefix); pw.print("Name resolver: ");
mServiceNameResolver.dumpShort(pw); pw.println();
@@ -644,39 +656,49 @@
final PackageMonitor monitor = new PackageMonitor() {
@Override
- public void onPackageUpdateStarted(String packageName, int uid) {
+ public void onPackageUpdateStarted(@NonNull String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageUpdateStarted(): " + packageName);
+ final String activePackageName = getActiveServicePackageNameLocked();
+ if (!packageName.equals(activePackageName)) return;
+
+ final int userId = getChangingUserId();
synchronized (mLock) {
- final String activePackageName = getActiveServicePackageNameLocked();
- if (packageName.equals(activePackageName)) {
- final int userId = getChangingUserId();
- if (mRefreshServiceOnPackageUpdate) {
- if (debug) {
- Slog.d(mTag, "Removing service for user " + userId
- + " because package " + activePackageName
- + " is being updated");
- }
- mLastActivePackageName = activePackageName;
- removeCachedServiceLocked(userId);
- } else {
- if (debug) {
- Slog.d(mTag, "Holding service for user " + userId
- + " while package " + activePackageName
- + " is being updated");
- }
+ if (mUpdatingPackageNames == null) {
+ mUpdatingPackageNames = new SparseArray<String>(mServicesCache.size());
+ }
+ mUpdatingPackageNames.put(userId, packageName);
+ onServicePackageUpdatingLocked(userId);
+ if (mRefreshServiceOnPackageUpdate) {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId + " because package "
+ + activePackageName + " is being updated");
+ }
+ removeCachedServiceLocked(userId);
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being updated");
}
}
}
}
@Override
- public void onPackageUpdateFinished(String packageName, int uid) {
+ public void onPackageUpdateFinished(@NonNull String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageUpdateFinished(): " + packageName);
+ final int userId = getChangingUserId();
synchronized (mLock) {
- String activePackageName = getActiveServicePackageNameLocked();
- if (activePackageName == null) {
- activePackageName = mLastActivePackageName;
- mLastActivePackageName = null;
- }
- if (!packageName.equals(activePackageName)) {
+ final String activePackageName = mUpdatingPackageNames == null ? null
+ : mUpdatingPackageNames.get(userId);
+ if (packageName.equals(activePackageName)) {
+ if (mUpdatingPackageNames != null) {
+ mUpdatingPackageNames.remove(userId);
+ if (mUpdatingPackageNames.size() == 0) {
+ mUpdatingPackageNames = null;
+ }
+ }
+ onServicePackageUpdatedLocked(userId);
+ } else {
handlePackageUpdateLocked(packageName);
}
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 0c5fb79..3e134b2 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -323,8 +323,8 @@
}
Arrays.fill(newPasswordChars, '\u0000');
final int quality = DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC;
- setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD,
- managedUserPassword, quality, managedUserId);
+ setLockCredentialInternal(newPassword, CREDENTIAL_TYPE_PASSWORD, managedUserPassword,
+ quality, managedUserId, false);
// We store a private credential for the managed user that's unlocked by the primary
// account holder's credential. As such, the user will never be prompted to enter this
// password directly, so we always store a password.
@@ -1302,12 +1302,14 @@
if (profilePasswordMap != null && profilePasswordMap.containsKey(managedUserId)) {
setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE,
profilePasswordMap.get(managedUserId),
- DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+ DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
+ false);
} else {
Slog.wtf(TAG, "clear tied profile challenges, but no password supplied.");
// Supplying null here would lead to untrusted credential change
setLockCredentialInternal(null, CREDENTIAL_TYPE_NONE, null,
- DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId);
+ DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, managedUserId,
+ true);
}
mStorage.removeChildProfileLock(managedUserId);
removeKeystoreProfileKey(managedUserId);
@@ -1330,8 +1332,8 @@
// should call setLockCredentialInternal.
@Override
public void setLockCredential(byte[] credential, int type,
- byte[] savedCredential, int requestedQuality, int userId)
- throws RemoteException {
+ byte[] savedCredential, int requestedQuality, int userId,
+ boolean allowUntrustedChange) throws RemoteException {
if (!mLockPatternUtils.hasSecureLockScreen()) {
throw new UnsupportedOperationException(
@@ -1339,7 +1341,8 @@
}
checkWritePermission(userId);
synchronized (mSeparateChallengeLock) {
- setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId);
+ setLockCredentialInternal(credential, type, savedCredential, requestedQuality, userId,
+ allowUntrustedChange);
setSeparateProfileChallengeEnabledLocked(userId, true, null);
notifyPasswordChanged(userId);
}
@@ -1347,7 +1350,8 @@
}
private void setLockCredentialInternal(byte[] credential, @CredentialType int credentialType,
- byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
+ byte[] savedCredential, int requestedQuality, int userId,
+ boolean allowUntrustedChange) throws RemoteException {
// Normalize savedCredential and credential such that empty string is always represented
// as null.
if (savedCredential == null || savedCredential.length == 0) {
@@ -1359,7 +1363,7 @@
synchronized (mSpManager) {
if (isSyntheticPasswordBasedCredentialLocked(userId)) {
spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
- requestedQuality, userId);
+ requestedQuality, userId, allowUntrustedChange);
return;
}
}
@@ -1410,7 +1414,7 @@
initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential,
currentHandle.type, requestedQuality, userId);
spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential,
- requestedQuality, userId);
+ requestedQuality, userId, allowUntrustedChange);
return;
}
}
@@ -1705,7 +1709,7 @@
mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
if (shouldReEnrollBaseZero) {
setLockCredentialInternal(credential, storedHash.type, credentialToVerify,
- DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId);
+ DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, userId, false);
}
}
@@ -1796,7 +1800,7 @@
storedHash.type == CREDENTIAL_TYPE_PATTERN
? DevicePolicyManager.PASSWORD_QUALITY_SOMETHING
: DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
- /* TODO(roosa): keep the same password quality */, userId);
+ /* TODO(roosa): keep the same password quality */, userId, false);
if (!hasChallenge) {
notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
// Use credentials to create recoverable keystore snapshot.
@@ -1841,7 +1845,7 @@
/* TODO(roosa): keep the same password quality */;
if (shouldReEnroll) {
setLockCredentialInternal(credential, storedHash.type, credential,
- reEnrollQuality, userId);
+ reEnrollQuality, userId, false);
} else {
// Now that we've cleared of all required GK migration, let's do the final
// migration to synthetic password.
@@ -2544,7 +2548,8 @@
@GuardedBy("mSpManager")
private void spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
- byte[] savedCredential, int requestedQuality, int userId) throws RemoteException {
+ byte[] savedCredential, int requestedQuality, int userId,
+ boolean allowUntrustedChange) throws RemoteException {
if (DEBUG) Slog.d(TAG, "spBasedSetLockCredentialInternalLocked: user=" + userId);
if (isManagedProfileWithUnifiedLock(userId)) {
// get credential from keystore when managed profile has unified lock
@@ -2565,27 +2570,31 @@
VerifyCredentialResponse response = authResult.gkResponse;
AuthenticationToken auth = authResult.authToken;
- // If existing credential is provided, then it must match.
+ // If existing credential is provided, the existing credential must match.
if (savedCredential != null && auth == null) {
- throw new RemoteException("Failed to enroll " +
- (credentialType == CREDENTIAL_TYPE_PASSWORD ? "password" : "pattern"));
+ throw new IllegalStateException("Failed to enroll "
+ + (credentialType == CREDENTIAL_TYPE_PASSWORD
+ ? "password" : "pattern"));
}
-
boolean untrustedReset = false;
if (auth != null) {
onAuthTokenKnownForUser(userId, auth);
- } else if (response != null
- && response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
+ } else if (response == null) {
+ throw new IllegalStateException("Password change failed.");
+ } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_ERROR) {
// We are performing an untrusted credential change, by DevicePolicyManager or other
// internal callers that don't provide the existing credential
Slog.w(TAG, "Untrusted credential change invoked");
// Try to get a cached auth token, so we can keep SP unchanged.
auth = mSpCache.get(userId);
+ if (!allowUntrustedChange) {
+ throw new IllegalStateException("Untrusted credential change was invoked but it was"
+ + " not allowed. This is likely a bug. Auth token is null: "
+ + Boolean.toString(auth == null));
+ }
untrustedReset = true;
- } else /* response == null || responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
- Slog.w(TAG, "spBasedSetLockCredentialInternalLocked: " +
- (response != null ? "rate limit exceeded" : "failed"));
- return;
+ } else /* responseCode == VerifyCredentialResponse.RESPONSE_RETRY */ {
+ throw new IllegalStateException("Rate limit exceeded, so password was not changed.");
}
if (auth != null) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index ca3c826..e43fc1f 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4106,9 +4106,11 @@
if (r == null) {
return;
}
- if (adjustment.getSignals() != null) {
- Bundle.setDefusable(adjustment.getSignals(), true);
- r.addAdjustment(adjustment);
+ if (mAssistants.isAdjustmentAllowed(adjustment.getKey())) {
+ if (adjustment.getSignals() != null) {
+ Bundle.setDefusable(adjustment.getSignals(), true);
+ r.addAdjustment(adjustment);
+ }
}
}
@@ -7313,6 +7315,12 @@
}
}
+ protected boolean isAdjustmentAllowed(String type) {
+ synchronized (mLock) {
+ return mAllowedAdjustments.contains(type);
+ }
+ }
+
protected void onNotificationsSeenLocked(ArrayList<NotificationRecord> records) {
// There should be only one, but it's a list, so while we enforce
// singularity elsewhere, we keep it general here, to avoid surprises.
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index b0d2704..15ed063 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -83,6 +83,9 @@
if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) {
return true;
}
+ if (!Objects.equals(theTruth.targetOverlayableName, oldSettings.targetOverlayableName)) {
+ return true;
+ }
if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) {
return true;
}
@@ -149,6 +152,7 @@
mSettings.init(overlayPackage.packageName, newUserId,
overlayPackage.overlayTarget,
+ overlayPackage.targetOverlayableName,
overlayPackage.applicationInfo.getBaseCodePath(),
overlayPackage.isStaticOverlayPackage(),
overlayPackage.overlayPriority,
@@ -331,6 +335,7 @@
}
mSettings.init(packageName, userId, overlayPackage.overlayTarget,
+ overlayPackage.targetOverlayableName,
overlayPackage.applicationInfo.getBaseCodePath(),
overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
overlayPackage.overlayCategory);
@@ -395,7 +400,7 @@
if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) {
mListener.onOverlaysChanged(pkg.overlayTarget, userId);
}
- mSettings.init(packageName, userId, pkg.overlayTarget,
+ mSettings.init(packageName, userId, pkg.overlayTarget, pkg.targetOverlayableName,
pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
pkg.overlayPriority, pkg.overlayCategory);
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index 2b4ec03..667dfa1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -65,12 +65,13 @@
private final ArrayList<SettingsItem> mItems = new ArrayList<>();
void init(@NonNull final String packageName, final int userId,
- @NonNull final String targetPackageName, @NonNull final String baseCodePath,
- boolean isStatic, int priority, String overlayCategory) {
+ @NonNull final String targetPackageName, @Nullable final String targetOverlayableName,
+ @NonNull final String baseCodePath, boolean isStatic, int priority,
+ @Nullable String overlayCategory) {
remove(packageName, userId);
final SettingsItem item =
- new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
- isStatic, priority, overlayCategory);
+ new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
+ baseCodePath, isStatic, priority, overlayCategory);
if (isStatic) {
// All static overlays are always enabled.
item.setEnabled(true);
@@ -302,16 +303,17 @@
pw.println(item.mPackageName + ":" + item.getUserId() + " {");
pw.increaseIndent();
- pw.println("mPackageName.......: " + item.mPackageName);
- pw.println("mUserId............: " + item.getUserId());
- pw.println("mTargetPackageName.: " + item.getTargetPackageName());
- pw.println("mBaseCodePath......: " + item.getBaseCodePath());
- pw.println("mState.............: " + OverlayInfo.stateToString(item.getState()));
- pw.println("mState.............: " + OverlayInfo.stateToString(item.getState()));
- pw.println("mIsEnabled.........: " + item.isEnabled());
- pw.println("mIsStatic..........: " + item.isStatic());
- pw.println("mPriority..........: " + item.mPriority);
- pw.println("mCategory..........: " + item.mCategory);
+ pw.println("mPackageName...........: " + item.mPackageName);
+ pw.println("mUserId................: " + item.getUserId());
+ pw.println("mTargetPackageName.....: " + item.getTargetPackageName());
+ pw.println("mTargetOverlayableName.: " + item.getTargetOverlayableName());
+ pw.println("mBaseCodePath..........: " + item.getBaseCodePath());
+ pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
+ pw.println("mState.................: " + OverlayInfo.stateToString(item.getState()));
+ pw.println("mIsEnabled.............: " + item.isEnabled());
+ pw.println("mIsStatic..............: " + item.isStatic());
+ pw.println("mPriority..............: " + item.mPriority);
+ pw.println("mCategory..............: " + item.mCategory);
pw.decreaseIndent();
pw.println("}");
@@ -335,6 +337,7 @@
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_STATE = "state";
private static final String ATTR_TARGET_PACKAGE_NAME = "targetPackageName";
+ private static final String ATTR_TARGET_OVERLAYABLE_NAME = "targetOverlayableName";
private static final String ATTR_IS_STATIC = "isStatic";
private static final String ATTR_PRIORITY = "priority";
private static final String ATTR_CATEGORY = "category";
@@ -387,6 +390,8 @@
final int userId = XmlUtils.readIntAttribute(parser, ATTR_USER_ID);
final String targetPackageName = XmlUtils.readStringAttribute(parser,
ATTR_TARGET_PACKAGE_NAME);
+ final String targetOverlayableName = XmlUtils.readStringAttribute(parser,
+ ATTR_TARGET_OVERLAYABLE_NAME);
final String baseCodePath = XmlUtils.readStringAttribute(parser, ATTR_BASE_CODE_PATH);
final int state = XmlUtils.readIntAttribute(parser, ATTR_STATE);
final boolean isEnabled = XmlUtils.readBooleanAttribute(parser, ATTR_IS_ENABLED);
@@ -394,8 +399,8 @@
final int priority = XmlUtils.readIntAttribute(parser, ATTR_PRIORITY);
final String category = XmlUtils.readStringAttribute(parser, ATTR_CATEGORY);
- return new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
- state, isEnabled, isStatic, priority, category);
+ return new SettingsItem(packageName, userId, targetPackageName, targetOverlayableName,
+ baseCodePath, state, isEnabled, isStatic, priority, category);
}
public static void persist(@NonNull final ArrayList<SettingsItem> table,
@@ -422,6 +427,8 @@
XmlUtils.writeStringAttribute(xml, ATTR_PACKAGE_NAME, item.mPackageName);
XmlUtils.writeIntAttribute(xml, ATTR_USER_ID, item.mUserId);
XmlUtils.writeStringAttribute(xml, ATTR_TARGET_PACKAGE_NAME, item.mTargetPackageName);
+ XmlUtils.writeStringAttribute(xml, ATTR_TARGET_OVERLAYABLE_NAME,
+ item.mTargetOverlayableName);
XmlUtils.writeStringAttribute(xml, ATTR_BASE_CODE_PATH, item.mBaseCodePath);
XmlUtils.writeIntAttribute(xml, ATTR_STATE, item.mState);
XmlUtils.writeBooleanAttribute(xml, ATTR_IS_ENABLED, item.mIsEnabled);
@@ -436,6 +443,7 @@
private final int mUserId;
private final String mPackageName;
private final String mTargetPackageName;
+ private final String mTargetOverlayableName;
private String mBaseCodePath;
private @OverlayInfo.State int mState;
private boolean mIsEnabled;
@@ -445,12 +453,14 @@
private String mCategory;
SettingsItem(@NonNull final String packageName, final int userId,
- @NonNull final String targetPackageName, @NonNull final String baseCodePath,
+ @NonNull final String targetPackageName,
+ @Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
final @OverlayInfo.State int state, final boolean isEnabled, final boolean isStatic,
- final int priority, String category) {
+ final int priority, @Nullable String category) {
mPackageName = packageName;
mUserId = userId;
mTargetPackageName = targetPackageName;
+ mTargetOverlayableName = targetOverlayableName;
mBaseCodePath = baseCodePath;
mState = state;
mIsEnabled = isEnabled || isStatic;
@@ -461,16 +471,21 @@
}
SettingsItem(@NonNull final String packageName, final int userId,
- @NonNull final String targetPackageName, @NonNull final String baseCodePath,
- final boolean isStatic, final int priority, String category) {
- this(packageName, userId, targetPackageName, baseCodePath, OverlayInfo.STATE_UNKNOWN,
- false, isStatic, priority, category);
+ @NonNull final String targetPackageName,
+ @Nullable final String targetOverlayableName, @NonNull final String baseCodePath,
+ final boolean isStatic, final int priority, @Nullable String category) {
+ this(packageName, userId, targetPackageName, targetOverlayableName, baseCodePath,
+ OverlayInfo.STATE_UNKNOWN, false, isStatic, priority, category);
}
private String getTargetPackageName() {
return mTargetPackageName;
}
+ private String getTargetOverlayableName() {
+ return mTargetOverlayableName;
+ }
+
private int getUserId() {
return mUserId;
}
@@ -520,7 +535,7 @@
private boolean setCategory(String category) {
if (!Objects.equals(mCategory, category)) {
- mCategory = category.intern();
+ mCategory = (category == null) ? null : category.intern();
invalidateCache();
return true;
}
@@ -529,8 +544,8 @@
private OverlayInfo getOverlayInfo() {
if (mCache == null) {
- mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
- mState, mUserId, mPriority, mIsStatic);
+ mCache = new OverlayInfo(mPackageName, mTargetPackageName, mTargetOverlayableName,
+ mCategory, mBaseCodePath, mState, mUserId, mPriority, mIsStatic);
}
return mCache;
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index e36ac23..40f2a2b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1552,13 +1552,13 @@
oldPermAreModernStorageModel = false;
}
- boolean shouldBeRestricted;
+ boolean shouldBeHidden;
boolean shouldBeFixed;
boolean shouldBeGranted = false;
boolean shouldBeRevoked = false;
int userFlags = -1;
if (useLegacyStoragePermissionModel) {
- shouldBeRestricted = isModernStoragePermission;
+ shouldBeHidden = isModernStoragePermission;
shouldBeFixed = isQApp || isModernStoragePermission;
if (shouldBeFixed) {
@@ -1576,7 +1576,7 @@
shouldBeRevoked = !shouldBeGranted;
}
} else {
- shouldBeRestricted = isLegacyStoragePermission;
+ shouldBeHidden = isLegacyStoragePermission;
shouldBeFixed = isLegacyStoragePermission;
if (shouldBeFixed) {
@@ -1636,7 +1636,12 @@
changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm), userId,
FLAG_PERMISSION_HIDDEN,
- shouldBeRestricted ? FLAG_PERMISSION_HIDDEN : 0);
+ shouldBeHidden ? FLAG_PERMISSION_HIDDEN : 0);
+
+ if (shouldBeHidden) {
+ changed |= ps.updatePermissionFlags(mSettings.getPermissionLocked(perm),
+ userId, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
+ }
}
if (changed) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5a32aa0..55af357 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5126,7 +5126,7 @@
// Start home.
mActivityTaskManagerInternal.startHomeOnDisplay(mCurrentUserId, "startDockOrHome",
- displayId, fromHomeKey);
+ displayId, true /* allowInstrumenting */, fromHomeKey);
}
/**
@@ -5214,13 +5214,15 @@
private VibrationEffect getVibrationEffect(int effectId) {
long[] pattern;
switch (effectId) {
- case HapticFeedbackConstants.CLOCK_TICK:
case HapticFeedbackConstants.CONTEXT_CLICK:
return VibrationEffect.get(VibrationEffect.EFFECT_TICK);
case HapticFeedbackConstants.TEXT_HANDLE_MOVE:
if (!mHapticTextHandleEnabled) {
return null;
}
+ // fallthrough
+ case HapticFeedbackConstants.CLOCK_TICK:
+ return VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK);
case HapticFeedbackConstants.KEYBOARD_RELEASE:
case HapticFeedbackConstants.VIRTUAL_KEY_RELEASE:
case HapticFeedbackConstants.ENTRY_BUMP:
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 9b427f5..cfe11bf 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -4489,8 +4489,7 @@
}
@Override // Binder call
- public boolean setDynamicPowerSavings(boolean dynamicPowerSavingsEnabled,
- int disableThreshold) {
+ public boolean setDynamicPowerSaveHint(boolean powerSaveHint, int disableThreshold) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER,
"updateDynamicPowerSavings");
final long ident = Binder.clearCallingIdentity();
@@ -4503,7 +4502,7 @@
// abort updating if we weren't able to succeed on the threshold
success &= Settings.Global.putInt(resolver,
Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
- dynamicPowerSavingsEnabled ? 1 : 0);
+ powerSaveHint ? 1 : 0);
}
return success;
} finally {
@@ -4542,13 +4541,13 @@
}
@Override // Binder call
- public int getPowerSaveMode() {
+ public int getPowerSaveModeTrigger() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null);
final long ident = Binder.clearCallingIdentity();
try {
return Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
index 61daca7..b7be768 100644
--- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
+++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java
@@ -188,7 +188,7 @@
@GuardedBy("mLock")
private int mSettingBatterySaverTriggerThreshold;
- /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVER_MODE. */
+ /** Previously known value of Settings.Global.AUTOMATIC_POWER_SAVE_MODE. */
@GuardedBy("mLock")
private int mSettingAutomaticBatterySaver;
@@ -248,7 +248,7 @@
/** @return true if the automatic percentage based mode should be used */
private boolean isAutomaticModeActiveLocked() {
- return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_PERCENTAGE
+ return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE
&& mSettingBatterySaverTriggerThreshold > 0;
}
@@ -264,7 +264,7 @@
/** @return true if the dynamic mode should be used */
private boolean isDynamicModeActiveLocked() {
- return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVER_MODE_DYNAMIC
+ return mSettingAutomaticBatterySaver == PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC
&& mDynamicPowerSavingsBatterySaver;
}
@@ -304,7 +304,7 @@
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, mSettingsObserver, UserHandle.USER_SYSTEM);
cr.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.AUTOMATIC_POWER_SAVER_MODE),
+ Settings.Global.AUTOMATIC_POWER_SAVE_MODE),
false, mSettingsObserver, UserHandle.USER_SYSTEM);
cr.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED),
@@ -367,8 +367,8 @@
final int lowPowerModeTriggerLevel = getGlobalSetting(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0);
final int automaticBatterySaverMode = getGlobalSetting(
- Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ Settings.Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
final int dynamicPowerSavingsDisableThreshold = getGlobalSetting(
Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
mDynamicPowerSavingsDefaultDisableThreshold);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index b262a00..fc7646f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -364,7 +364,7 @@
* - Use the secondary home defined in the config.
*/
public abstract boolean startHomeOnDisplay(int userId, String reason, int displayId,
- boolean fromHomeKey);
+ boolean allowInstrumenting, boolean fromHomeKey);
/** Start home activities on all displays that support system decorations. */
public abstract boolean startHomeOnAllDisplays(int userId, String reason);
/** @return true if the given process is the factory test process. */
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index c91ee8e..b8e6b0c 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6492,10 +6492,10 @@
@Override
public boolean startHomeOnDisplay(int userId, String reason, int displayId,
- boolean fromHomeKey) {
+ boolean allowInstrumenting, boolean fromHomeKey) {
synchronized (mGlobalLock) {
return mRootActivityContainer.startHomeOnDisplay(userId, reason, displayId,
- fromHomeKey);
+ allowInstrumenting, fromHomeKey);
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 26df832..3813669 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -208,7 +208,10 @@
try {
synchronized (mService.getWindowManagerLock()) {
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
- mPendingAnimations.get(i).mTask.setCanAffectSystemUiFlags(behindSystemBars);
+ final Task task = mPendingAnimations.get(i).mTask;
+ if (task.getActivityType() != mTargetActivityType) {
+ task.setCanAffectSystemUiFlags(behindSystemBars);
+ }
}
mService.mWindowPlacerLocked.requestTraversal();
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 24cf7f1..46b5f3a 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -347,7 +347,8 @@
}
boolean startHomeOnDisplay(int userId, String reason, int displayId) {
- return startHomeOnDisplay(userId, reason, displayId, false /*fromHomeKey*/);
+ return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,
+ false /* fromHomeKey */);
}
/**
@@ -361,7 +362,8 @@
* If there are multiple activities matched, use first one.
* - Use the secondary home defined in the config.
*/
- boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean fromHomeKey) {
+ boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,
+ boolean fromHomeKey) {
// Fallback to top focused display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
displayId = getTopDisplayFocusedStack().mDisplayId;
@@ -383,7 +385,7 @@
return false;
}
- if (!canStartHomeOnDisplay(aInfo, displayId, false /* allowInstrumenting */)) {
+ if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {
return false;
}
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index e0d85e8..4379b7c 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -41,7 +41,7 @@
return new TaskScreenshotAnimatable(task, getBufferFromTask(task));
}
- private static GraphicBuffer getBufferFromTask(Task task) {
+ private static SurfaceControl.ScreenshotGraphicBuffer getBufferFromTask(Task task) {
if (task == null) {
return null;
}
@@ -51,7 +51,10 @@
task.getSurfaceControl().getHandle(), tmpRect, 1f);
}
- private TaskScreenshotAnimatable(Task task, GraphicBuffer buffer) {
+ private TaskScreenshotAnimatable(Task task,
+ SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer) {
+ GraphicBuffer buffer = screenshotBuffer == null
+ ? null : screenshotBuffer.getGraphicBuffer();
mTask = task;
mWidth = (buffer != null) ? buffer.getWidth() : 1;
mHeight = (buffer != null) ? buffer.getHeight() : 1;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index beb3d82..6fe8b43 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -279,8 +279,11 @@
Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task);
return null;
}
- final GraphicBuffer buffer = SurfaceControl.captureLayers(
- task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+ final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
+ SurfaceControl.captureLayers(
+ task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
+ final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
+ : null;
if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
if (DEBUG_SCREENSHOT) {
Slog.w(TAG_WM, "Failed to take screenshot for " + task);
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index dddc6b7..166a33d 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -34,8 +34,6 @@
import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
import android.graphics.Bitmap;
-import android.graphics.ColorSpace;
-import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Bundle;
@@ -738,17 +736,16 @@
final Rect bounds = wallpaperWindowState.getBounds();
bounds.offsetTo(0, 0);
- GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
+ SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);
if (wallpaperBuffer == null) {
Slog.w(TAG_WM, "Failed to screenshot wallpaper");
return null;
}
- // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
- // should continue to fix screenshot.
- return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer),
- ColorSpace.get(ColorSpace.Named.SRGB));
+ return Bitmap.wrapHardwareBuffer(
+ HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()),
+ wallpaperBuffer.getColorSpace());
}
private WindowState getTopVisibleWallpaper() {
diff --git a/services/core/jni/com_android_server_VibratorService.cpp b/services/core/jni/com_android_server_VibratorService.cpp
index 63dca62..d5fbd2b 100644
--- a/services/core/jni/com_android_server_VibratorService.cpp
+++ b/services/core/jni/com_android_server_VibratorService.cpp
@@ -96,7 +96,7 @@
}
R val = static_cast<R>(effect);
auto iter = hardware::hidl_enum_range<R>();
- return val >= *iter.begin() && val < *std::prev(iter.end());
+ return val >= *iter.begin() && val <= *std::prev(iter.end());
}
static void vibratorInit(JNIEnv /* env */, jobject /* clazz */)
@@ -170,6 +170,9 @@
} else if (isValidEffect<V1_2::Effect>(effect)) {
ret = halCall(&V1_2::IVibrator::perform_1_2, static_cast<V1_2::Effect>(effect),
effectStrength, callback);
+ } else if (isValidEffect<V1_3::Effect>(effect)) {
+ ret = halCall(&V1_3::IVibrator::perform_1_3, static_cast<V1_3::Effect>(effect),
+ effectStrength, callback);
} else {
ALOGW("Unable to perform haptic effect, invalid effect ID (%" PRId32 ")",
static_cast<int32_t>(effect));
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 2d01471..633367a 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -5133,11 +5133,14 @@
final boolean result;
try {
if (token == null) {
+ // This is the legacy reset password for DPM. Here we want to be able to override
+ // the old device password without necessarily knowing it.
if (!TextUtils.isEmpty(password)) {
mLockPatternUtils.saveLockPassword(password.getBytes(), null, quality,
- userHandle);
+ userHandle, /*allowUntrustedChange */true);
} else {
- mLockPatternUtils.clearLock(null, userHandle);
+ mLockPatternUtils.clearLock(null, userHandle,
+ /*allowUntrustedChange */ true);
}
result = true;
} else {
@@ -5246,12 +5249,11 @@
// would allow bypassing of the maximum time to lock.
mInjector.settingsGlobalPutInt(Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
}
+ getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+ UserHandle.USER_SYSTEM, timeMs);
} finally {
mInjector.binderRestoreCallingIdentity(ident);
}
-
- getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
- UserHandle.USER_SYSTEM, timeMs);
}
private void updateProfileLockTimeoutLocked(@UserIdInt int userId) {
@@ -5269,8 +5271,13 @@
}
policy.mLastMaximumTimeToLock = timeMs;
- getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
- userId, policy.mLastMaximumTimeToLock);
+ final long ident = mInjector.binderClearCallingIdentity();
+ try {
+ getPowerManagerInternal().setMaximumScreenOffTimeoutFromDeviceAdmin(
+ userId, policy.mLastMaximumTimeToLock);
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
}
@Override
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 419f52c..d4ccb0b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -849,7 +849,7 @@
private void startOtherServices() {
final Context context = mSystemContext;
VibratorService vibrator = null;
- DynamicAndroidService dynamicAndroid = null;
+ DynamicSystemService dynamicSystem = null;
IStorageManager storageManager = null;
NetworkManagementService networkManagement = null;
IpSecService ipSecService = null;
@@ -968,9 +968,9 @@
ServiceManager.addService("vibrator", vibrator);
traceEnd();
- traceBeginAndSlog("StartDynamicAndroidService");
- dynamicAndroid = new DynamicAndroidService(context);
- ServiceManager.addService("dynamic_android", dynamicAndroid);
+ traceBeginAndSlog("StartDynamicSystemService");
+ dynamicSystem = new DynamicSystemService(context);
+ ServiceManager.addService("dynamic_system", dynamicSystem);
traceEnd();
if (!isWatch) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
index 2e5efbd..212d2a8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/power/batterysaver/BatterySaverStateMachineTest.java
@@ -112,7 +112,7 @@
Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_ENABLED, 0) != 0,
mPersistedState.global.getOrDefault(
Global.LOW_POWER_MODE_STICKY_AUTO_DISABLE_LEVEL, 90),
- mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVER_MODE, 0),
+ mPersistedState.global.getOrDefault(Global.AUTOMATIC_POWER_SAVE_MODE, 0),
mPersistedState.global.getOrDefault(
Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0) != 0,
mPersistedState.global.getOrDefault(
@@ -321,7 +321,7 @@
@Test
public void testAutoBatterySaver() {
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
- mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0);
+ mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0);
assertEquals(false, mDevice.batterySaverEnabled);
assertEquals(100, mPersistedState.batteryLevel);
@@ -789,7 +789,7 @@
.thenReturn(true);
initDevice();
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
- mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE, 0);
+ mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE, 0);
mTarget.setBatterySaverEnabledManually(true);
@@ -906,8 +906,8 @@
@Test
public void testAutoBatterySaver_smartBatterySaverEnabled() {
mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
- mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_DYNAMIC);
+ mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
assertEquals(false, mDevice.batterySaverEnabled);
@@ -1029,8 +1029,8 @@
// Test dynamic threshold higher than automatic to make sure it doesn't interfere when it's
// not enabled.
mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 50);
- mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_PERCENTAGE);
+ mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_PERCENTAGE);
mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 0);
assertEquals(false, mDevice.batterySaverEnabled);
@@ -1138,8 +1138,8 @@
// not enabled.
mDevice.putGlobalSetting(Global.LOW_POWER_MODE_TRIGGER_LEVEL, 50);
mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD, 30);
- mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVER_MODE,
- PowerManager.POWER_SAVER_MODE_DYNAMIC);
+ mDevice.putGlobalSetting(Global.AUTOMATIC_POWER_SAVE_MODE,
+ PowerManager.POWER_SAVE_MODE_TRIGGER_DYNAMIC);
mDevice.putGlobalSetting(Global.DYNAMIC_POWER_SAVINGS_ENABLED, 1);
assertEquals(false, mDevice.batterySaverEnabled);
diff --git a/services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
similarity index 68%
rename from services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java
rename to services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
index 1494284..4a9dd97 100644
--- a/services/tests/servicestests/src/com/android/server/DynamicAndroidServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/DynamicSystemServiceTest.java
@@ -16,28 +16,28 @@
package com.android.server;
-import android.os.IDynamicAndroidService;
import android.os.ServiceManager;
+import android.os.image.IDynamicSystemService;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
-public class DynamicAndroidServiceTest extends AndroidTestCase {
- private static final String TAG = "DynamicAndroidServiceTests";
- private IDynamicAndroidService mService;
+public class DynamicSystemServiceTest extends AndroidTestCase {
+ private static final String TAG = "DynamicSystemServiceTests";
+ private IDynamicSystemService mService;
@Override
protected void setUp() throws Exception {
mService =
- IDynamicAndroidService.Stub.asInterface(
- ServiceManager.getService("dynamic_android"));
+ IDynamicSystemService.Stub.asInterface(
+ ServiceManager.getService("dynamic_system"));
}
@LargeTest
public void test1() {
- assertTrue("dynamic_android service available", mService != null);
+ assertTrue("dynamic_system service available", mService != null);
try {
mService.startInstallation(1 << 20, 8 << 30);
- fail("DynamicAndroidService did not throw SecurityException as expected");
+ fail("DynamicSystemService did not throw SecurityException as expected");
} catch (SecurityException e) {
// expected
} catch (Exception e) {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
index 94d21dd..ca4330f 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/CachedSyntheticPasswordTests.java
@@ -61,12 +61,12 @@
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// clear password
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, null,
- PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, true);
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
// set a new password
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword,
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -81,7 +81,7 @@
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// Untrusted change password
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true);
assertNotEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
assertNotEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
@@ -99,7 +99,7 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
// Untrusted change password
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true);
// Verify the password
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(newPassword,
@@ -124,10 +124,12 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// Untrusted change password
- assertExpectException(IllegalStateException.class, /* messageRegex= */ null,
+ assertExpectException(
+ IllegalStateException.class,
+ /* messageRegex= */ "Untrusted credential reset not possible without cached SP",
() -> mService.setLockCredential(newPassword,
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID));
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, true));
assertEquals(sid, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
// Verify the new password doesn't work but the old one still does
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 6e0ba3c..255e694b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -85,9 +85,9 @@
try {
mService.setLockCredential("newpwd".getBytes(), CREDENTIAL_TYPE_PASSWORD,
- "badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ "badpwd".getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
fail("Did not fail when enrolling using incorrect credential");
- } catch (RemoteException expected) {
+ } catch (IllegalStateException expected) {
assertTrue(expected.getMessage().equals(FAILED_MESSAGE));
}
assertVerifyCredentials(PRIMARY_USER_ID, "password", CREDENTIAL_TYPE_PASSWORD, sid);
@@ -97,7 +97,7 @@
final String PASSWORD = "password";
initializeStorageWithCredential(PRIMARY_USER_ID, PASSWORD, CREDENTIAL_TYPE_PASSWORD, 1234);
mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, PASSWORD.getBytes(),
- PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
assertFalse(mService.havePassword(PRIMARY_USER_ID));
assertFalse(mService.havePattern(PRIMARY_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
@@ -108,7 +108,7 @@
final String secondUnifiedPassword = "testManagedProfileUnifiedChallenge-pwd-2";
mService.setLockCredential(firstUnifiedPassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
- null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+ null, PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false);
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -143,15 +143,16 @@
mStorageManager.setIgnoreBadUnlock(true);
// Change primary password and verify that profile SID remains
mService.setLockCredential(secondUnifiedPassword.getBytes(),
- LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
- firstUnifiedPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, firstUnifiedPassword.getBytes(),
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mStorageManager.setIgnoreBadUnlock(false);
assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
// Clear unified challenge
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
- secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ secondUnifiedPassword.getBytes(), PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID,
+ false);
assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
@@ -162,7 +163,7 @@
final String profilePassword = "testManagedProfileSeparateChallenge-profile";
mService.setLockCredential(primaryPassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_COMPLEX, PRIMARY_USER_ID, false);
/* Currently in LockSettingsService.setLockCredential, unlockUser() is called with the new
* credential as part of verifyCredential() before the new credential is committed in
* StorageManager. So we relax the check in our mock StorageManager to allow that.
@@ -170,7 +171,7 @@
mStorageManager.setIgnoreBadUnlock(true);
mService.setLockCredential(profilePassword.getBytes(),
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID);
+ PASSWORD_QUALITY_COMPLEX, MANAGED_PROFILE_USER_ID, false);
mStorageManager.setIgnoreBadUnlock(false);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
@@ -197,7 +198,7 @@
// Change primary credential and make sure we don't affect profile
mStorageManager.setIgnoreBadUnlock(true);
mService.setLockCredential("pwd".getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
- primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ primaryPassword.getBytes(), PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mStorageManager.setIgnoreBadUnlock(false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
profilePassword.getBytes(), LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0,
@@ -208,7 +209,7 @@
private void testCreateCredential(int userId, String credential, int type, int quality)
throws RemoteException {
mService.setLockCredential(credential.getBytes(), type, null, quality,
- userId);
+ userId, false);
assertVerifyCredentials(userId, credential, type, -1);
}
@@ -218,7 +219,7 @@
try {
mService.setLockCredential(credential.getBytes(), type, null, quality,
- userId);
+ userId, false);
fail("An exception should have been thrown.");
} catch (UnsupportedOperationException e) {
// Success - the exception was expected.
@@ -233,7 +234,7 @@
final long sid = 1234;
initializeStorageWithCredential(userId, oldCredential, oldType, sid);
mService.setLockCredential(newCredential.getBytes(), newType, oldCredential.getBytes(),
- quality, userId);
+ quality, userId, false);
assertVerifyCredentials(userId, newCredential, newType, sid);
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 6a07a45..58055e5 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -102,7 +102,7 @@
disableSyntheticPassword();
mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
enableSyntheticPassword();
@@ -127,7 +127,7 @@
: PASSWORD_QUALITY_UNSPECIFIED;
int type = password != null ? LockPatternUtils.CREDENTIAL_TYPE_PASSWORD
: LockPatternUtils.CREDENTIAL_TYPE_NONE;
- mService.setLockCredential(password, type, null, quality, userId);
+ mService.setLockCredential(password, type, null, quality, userId, false);
}
public void testSyntheticPasswordChangeCredential() throws RemoteException {
@@ -137,7 +137,7 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
mService.setLockCredential(newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
newPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -166,12 +166,12 @@
long sid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
// clear password
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
- PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
assertEquals(0 ,mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
// set a new password
mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -186,7 +186,7 @@
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
mService.setLockCredential(badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, password,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
badPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, 0, PRIMARY_USER_ID)
.getResponseCode());
@@ -245,7 +245,7 @@
final byte[] password = "getASyntheticPassword".getBytes();
initializeCredentialUnderSP(password, PRIMARY_USER_ID);
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE, password,
- PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
reset(mAuthSecretService);
mService.onUnlockUser(PRIMARY_USER_ID);
@@ -257,7 +257,7 @@
final byte[] UnifiedPassword = "testManagedProfileUnifiedChallengeMigration-pwd".getBytes();
disableSyntheticPassword();
mService.setLockCredential(UnifiedPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
@@ -294,9 +294,9 @@
"testManagedProfileSeparateChallengeMigration-profile".getBytes();
disableSyntheticPassword();
mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false);
final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
final byte[] primaryStorageKey = mStorageManager.getUserUnlockToken(PRIMARY_USER_ID);
@@ -404,7 +404,7 @@
assertTrue(mLocalService.isEscrowTokenActive(handle, PRIMARY_USER_ID));
mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN, password,
- PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false);
mLocalService.setLockCredentialWithToken(newPassword,
LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, handle, token,
@@ -443,7 +443,7 @@
// Set up pre-SP user password
disableSyntheticPassword();
mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
enableSyntheticPassword();
long handle = mLocalService.addEscrowToken(token, PRIMARY_USER_ID, null);
@@ -491,12 +491,12 @@
public void testgetHashFactorPrimaryUser() throws RemoteException {
final byte[] password = "password".getBytes();
mService.setLockCredential(password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
final byte[] hashFactor = mService.getHashFactor(password, PRIMARY_USER_ID);
assertNotNull(hashFactor);
mService.setLockCredential(null, LockPatternUtils.CREDENTIAL_TYPE_NONE,
- password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID);
+ password, PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
final byte[] newHashFactor = mService.getHashFactor(null, PRIMARY_USER_ID);
assertNotNull(newHashFactor);
// Hash factor should never change after password change/removal
@@ -506,7 +506,7 @@
public void testgetHashFactorManagedProfileUnifiedChallenge() throws RemoteException {
final byte[] pattern = "1236".getBytes();
mService.setLockCredential(pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
- null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID);
+ null, PASSWORD_QUALITY_SOMETHING, PRIMARY_USER_ID, false);
mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
assertNotNull(mService.getHashFactor(null, MANAGED_PROFILE_USER_ID));
}
@@ -515,9 +515,9 @@
final byte[] primaryPassword = "primary".getBytes();
final byte[] profilePassword = "profile".getBytes();
mService.setLockCredential(primaryPassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, PRIMARY_USER_ID, false);
mService.setLockCredential(profilePassword, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, null,
- PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID);
+ PASSWORD_QUALITY_ALPHABETIC, MANAGED_PROFILE_USER_ID, false);
assertNotNull(mService.getHashFactor(profilePassword, MANAGED_PROFILE_USER_ID));
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index a8da80e..426122a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -353,7 +353,6 @@
FileOutputStream fos = mPolicyFile.startWrite();
fos.write(preupgradeXml.getBytes());
mPolicyFile.finishWrite(fos);
- FileInputStream fStream = new FileInputStream(mFile);
// Setup managed services
mListener = mListeners.new ManagedServiceInfo(
@@ -369,6 +368,8 @@
dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
when(mConditionProviders.getConfig()).thenReturn(dndConfig);
+ when(mAssistants.isAdjustmentAllowed(anyString())).thenReturn(true);
+
try {
mService.init(mTestableLooper.getLooper(),
mPackageManager, mPackageManagerClient, mockLightsManager,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
index 23bae88..de4fb98 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -37,6 +37,7 @@
import android.platform.test.annotations.Presubmit;
import android.util.SparseIntArray;
+import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
@@ -118,6 +119,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnIntentStarted() throws Exception {
Intent intent = new Intent("action 1");
@@ -128,6 +130,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnIntentFailed() throws Exception {
testOnIntentStarted();
@@ -143,6 +146,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunched() throws Exception {
testOnIntentStarted();
@@ -154,6 +158,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchFinished() throws Exception {
testOnActivityLaunched();
@@ -168,6 +173,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchCancelled() throws Exception {
testOnActivityLaunched();
@@ -181,6 +187,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchedTrampoline() throws Exception {
testOnIntentStarted();
@@ -197,6 +204,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchFinishedTrampoline() throws Exception {
testOnActivityLaunchedTrampoline();
@@ -211,6 +219,7 @@
}
@Test
+ @FlakyTest(bugId = 129138370)
public void testOnActivityLaunchCancelledTrampoline() throws Exception {
testOnActivityLaunchedTrampoline();
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index 81553a3..afa35b4 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -51,6 +52,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static final int TRANSPORT_TYPE_WWAN = 1;
/**
@@ -58,6 +60,7 @@
* @hide
*/
@SystemApi
+ @TestApi
public static final int TRANSPORT_TYPE_WLAN = 2;
/** @hide */
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5f9ef3c..805a840 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1543,6 +1543,21 @@
"allow_non_emergency_calls_in_ecm_bool";
/**
+ * Time that the telephony framework stays in "emergency SMS mode" after an emergency SMS is
+ * sent to the network. This is used by carriers to configure the time
+ * {@link TelephonyManager#isInEmergencySmsMode()} will be true after an emergency SMS is sent.
+ * This is used by GNSS to override user location permissions so that the carrier network can
+ * get the user's location for emergency services.
+ *
+ * The default is 0, which means that this feature is disabled. The maximum value for this timer
+ * is 300000 mS (5 minutes).
+ *
+ * @hide
+ */
+ public static final String KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT =
+ "emergency_sms_mode_timer_ms_int";
+
+ /**
* Flag indicating whether to allow carrier video calls to emergency numbers.
* When {@code true}, video calls to emergency numbers will be allowed. When {@code false},
* video calls to emergency numbers will be initiated as audio-only calls instead.
@@ -1847,12 +1862,32 @@
"use_wfc_home_network_mode_in_roaming_network_bool";
/**
+ * Flag specifying whether the carrier is allowed to use metered network to download a
+ * certificate of Carrier-WiFi.
+ * {@code false} - default value.
+ *
+ * @hide
+ */
+ public static final String KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL =
+ "allow_metered_network_for_cert_download_bool";
+
+ /**
* Carrier specified WiFi networks.
* @hide
*/
public static final String KEY_CARRIER_WIFI_STRING_ARRAY = "carrier_wifi_string_array";
/**
+ * Base64 Encoding method the carrier will use for encoding encrypted IMSI and SSID.
+ * The value set as below:
+ * 2045 - RFC2045 (default value)
+ * 4648 - RFC4648
+ *
+ * @hide
+ */
+ public static final String KEY_IMSI_ENCODING_METHOD_INT = "imsi_encoding_method_int";
+
+ /**
* Time delay (in ms) after which we show the notification to switch the preferred
* network.
* @hide
@@ -2917,6 +2952,7 @@
sDefaults.putString(KEY_MMS_UA_PROF_URL_STRING, "");
sDefaults.putString(KEY_MMS_USER_AGENT_STRING, "");
sDefaults.putBoolean(KEY_ALLOW_NON_EMERGENCY_CALLS_IN_ECM_BOOL, true);
+ sDefaults.putInt(KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT, 0);
sDefaults.putBoolean(KEY_USE_RCS_PRESENCE_BOOL, false);
sDefaults.putBoolean(KEY_FORCE_IMEI_BOOL, false);
sDefaults.putInt(
@@ -2982,7 +3018,9 @@
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.putBoolean(KEY_ALLOW_METERED_NETWORK_FOR_CERT_DOWNLOAD_BOOL, false);
sDefaults.putStringArray(KEY_CARRIER_WIFI_STRING_ARRAY, null);
+ sDefaults.putInt(KEY_IMSI_ENCODING_METHOD_INT, 2045);
sDefaults.putInt(KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT, -1);
sDefaults.putInt(KEY_EMERGENCY_NOTIFICATION_DELAY_INT, -1);
sDefaults.putBoolean(KEY_ALLOW_USSD_REQUESTS_VIA_TELEPHONY_MANAGER_BOOL, true);
diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
similarity index 65%
rename from telephony/java/android/telephony/DataSpecificRegistrationStates.java
rename to telephony/java/android/telephony/DataSpecificRegistrationInfo.java
index 8eb345a..fbf488e 100644
--- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java
@@ -1,7 +1,24 @@
+/*
+ * Copyright 2018 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.telephony;
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -13,7 +30,8 @@
* @hide
*/
@SystemApi
-public final class DataSpecificRegistrationStates implements Parcelable{
+@TestApi
+public final class DataSpecificRegistrationInfo implements Parcelable {
/**
* @hide
* The maximum number of simultaneous Data Calls that
@@ -53,27 +71,27 @@
/**
* Provides network support info for LTE VoPS and LTE Emergency bearer support
*/
- private final LteVopsSupportInfo lteVopsSupportInfo;
+ private final LteVopsSupportInfo mLteVopsSupportInfo;
/**
* @hide
*/
- DataSpecificRegistrationStates(
+ DataSpecificRegistrationInfo(
int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable,
boolean isEnDcAvailable, LteVopsSupportInfo lteVops) {
this.maxDataCalls = maxDataCalls;
this.isDcNrRestricted = isDcNrRestricted;
this.isNrAvailable = isNrAvailable;
this.isEnDcAvailable = isEnDcAvailable;
- this.lteVopsSupportInfo = lteVops;
+ this.mLteVopsSupportInfo = lteVops;
}
- private DataSpecificRegistrationStates(Parcel source) {
+ private DataSpecificRegistrationInfo(Parcel source) {
maxDataCalls = source.readInt();
isDcNrRestricted = source.readBoolean();
isNrAvailable = source.readBoolean();
isEnDcAvailable = source.readBoolean();
- lteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
+ mLteVopsSupportInfo = LteVopsSupportInfo.CREATOR.createFromParcel(source);
}
@Override
@@ -82,7 +100,7 @@
dest.writeBoolean(isDcNrRestricted);
dest.writeBoolean(isNrAvailable);
dest.writeBoolean(isEnDcAvailable);
- lteVopsSupportInfo.writeToParcel(dest, flags);
+ mLteVopsSupportInfo.writeToParcel(dest, flags);
}
@Override
@@ -98,7 +116,7 @@
.append(" isDcNrRestricted = " + isDcNrRestricted)
.append(" isNrAvailable = " + isNrAvailable)
.append(" isEnDcAvailable = " + isEnDcAvailable)
- .append(lteVopsSupportInfo.toString())
+ .append(mLteVopsSupportInfo.toString())
.append(" }")
.toString();
}
@@ -106,41 +124,41 @@
@Override
public int hashCode() {
return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable,
- lteVopsSupportInfo);
+ mLteVopsSupportInfo);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
- if (!(o instanceof DataSpecificRegistrationStates)) return false;
+ if (!(o instanceof DataSpecificRegistrationInfo)) return false;
- DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o;
+ DataSpecificRegistrationInfo other = (DataSpecificRegistrationInfo) o;
return this.maxDataCalls == other.maxDataCalls
&& this.isDcNrRestricted == other.isDcNrRestricted
&& this.isNrAvailable == other.isNrAvailable
&& this.isEnDcAvailable == other.isEnDcAvailable
- && this.lteVopsSupportInfo.equals(other.lteVopsSupportInfo);
+ && this.mLteVopsSupportInfo.equals(other.mLteVopsSupportInfo);
}
- public static final @android.annotation.NonNull Parcelable.Creator<DataSpecificRegistrationStates> CREATOR =
- new Parcelable.Creator<DataSpecificRegistrationStates>() {
+ public static final @NonNull Parcelable.Creator<DataSpecificRegistrationInfo> CREATOR =
+ new Parcelable.Creator<DataSpecificRegistrationInfo>() {
@Override
- public DataSpecificRegistrationStates createFromParcel(Parcel source) {
- return new DataSpecificRegistrationStates(source);
+ public DataSpecificRegistrationInfo createFromParcel(Parcel source) {
+ return new DataSpecificRegistrationInfo(source);
}
@Override
- public DataSpecificRegistrationStates[] newArray(int size) {
- return new DataSpecificRegistrationStates[size];
+ public DataSpecificRegistrationInfo[] newArray(int size) {
+ return new DataSpecificRegistrationInfo[size];
}
};
/**
- * @return LteVopsSupportInfo
+ * @return The LTE VOPS (Voice over Packet Switched) support information
*/
@NonNull
public LteVopsSupportInfo getLteVopsSupportInfo() {
- return lteVopsSupportInfo;
+ return mLteVopsSupportInfo;
}
}
diff --git a/telephony/java/android/telephony/LteVopsSupportInfo.java b/telephony/java/android/telephony/LteVopsSupportInfo.java
index ee45f07..ec9f078 100644
--- a/telephony/java/android/telephony/LteVopsSupportInfo.java
+++ b/telephony/java/android/telephony/LteVopsSupportInfo.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -30,6 +31,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class LteVopsSupportInfo implements Parcelable {
/**@hide*/
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 9145b25..1dc2997 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
@@ -38,6 +39,7 @@
* @hide
*/
@SystemApi
+@TestApi
public final class NetworkRegistrationInfo implements Parcelable {
/**
* Network domain
@@ -174,10 +176,10 @@
private CellIdentity mCellIdentity;
@Nullable
- private VoiceSpecificRegistrationStates mVoiceSpecificStates;
+ private VoiceSpecificRegistrationInfo mVoiceSpecificInfo;
@Nullable
- private DataSpecificRegistrationStates mDataSpecificStates;
+ private DataSpecificRegistrationInfo mDataSpecificInfo;
/**
* @param domain Network domain. Must be a {@link Domain}. For transport type
@@ -234,7 +236,7 @@
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
emergencyOnly, availableServices, cellIdentity);
- mVoiceSpecificStates = new VoiceSpecificRegistrationStates(cssSupported, roamingIndicator,
+ mVoiceSpecificInfo = new VoiceSpecificRegistrationInfo(cssSupported, roamingIndicator,
systemIsInPrl, defaultRoamingIndicator);
}
@@ -253,9 +255,9 @@
this(domain, transportType, registrationState, accessNetworkTechnology, rejectCause,
emergencyOnly, availableServices, cellIdentity);
- mDataSpecificStates = new DataSpecificRegistrationStates(
+ mDataSpecificInfo = new DataSpecificRegistrationInfo(
maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, lteVopsSupportInfo);
- updateNrState(mDataSpecificStates);
+ updateNrState(mDataSpecificInfo);
}
private NetworkRegistrationInfo(Parcel source) {
@@ -269,10 +271,10 @@
mAvailableServices = new ArrayList<>();
source.readList(mAvailableServices, Integer.class.getClassLoader());
mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader());
- mVoiceSpecificStates = source.readParcelable(
- VoiceSpecificRegistrationStates.class.getClassLoader());
- mDataSpecificStates = source.readParcelable(
- DataSpecificRegistrationStates.class.getClassLoader());
+ mVoiceSpecificInfo = source.readParcelable(
+ VoiceSpecificRegistrationInfo.class.getClassLoader());
+ mDataSpecificInfo = source.readParcelable(
+ DataSpecificRegistrationInfo.class.getClassLoader());
mNrState = source.readInt();
}
@@ -389,16 +391,16 @@
* @hide
*/
@Nullable
- public VoiceSpecificRegistrationStates getVoiceSpecificStates() {
- return mVoiceSpecificStates;
+ public VoiceSpecificRegistrationInfo getVoiceSpecificInfo() {
+ return mVoiceSpecificInfo;
}
/**
* @return Data registration related info
*/
@Nullable
- public DataSpecificRegistrationStates getDataSpecificStates() {
- return mDataSpecificStates;
+ public DataSpecificRegistrationInfo getDataSpecificInfo() {
+ return mDataSpecificInfo;
}
@Override
@@ -474,8 +476,8 @@
? mAvailableServices.stream().map(type -> serviceTypeToString(type))
.collect(Collectors.joining(",")) : null) + "]")
.append(" cellIdentity=").append(mCellIdentity)
- .append(" voiceSpecificStates=").append(mVoiceSpecificStates)
- .append(" dataSpecificStates=").append(mDataSpecificStates)
+ .append(" voiceSpecificInfo=").append(mVoiceSpecificInfo)
+ .append(" dataSpecificInfo=").append(mDataSpecificInfo)
.append(" nrState=").append(nrStateToString(mNrState))
.append("}").toString();
}
@@ -484,7 +486,7 @@
public int hashCode() {
return Objects.hash(mDomain, mTransportType, mRegistrationState, mRoamingType,
mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
- mCellIdentity, mVoiceSpecificStates, mDataSpecificStates, mNrState);
+ mCellIdentity, mVoiceSpecificInfo, mDataSpecificInfo, mNrState);
}
@Override
@@ -505,8 +507,8 @@
&& mEmergencyOnly == other.mEmergencyOnly
&& mAvailableServices.equals(other.mAvailableServices)
&& Objects.equals(mCellIdentity, other.mCellIdentity)
- && Objects.equals(mVoiceSpecificStates, other.mVoiceSpecificStates)
- && Objects.equals(mDataSpecificStates, other.mDataSpecificStates)
+ && Objects.equals(mVoiceSpecificInfo, other.mVoiceSpecificInfo)
+ && Objects.equals(mDataSpecificInfo, other.mDataSpecificInfo)
&& mNrState == other.mNrState;
}
@@ -521,8 +523,8 @@
dest.writeBoolean(mEmergencyOnly);
dest.writeList(mAvailableServices);
dest.writeParcelable(mCellIdentity, 0);
- dest.writeParcelable(mVoiceSpecificStates, 0);
- dest.writeParcelable(mDataSpecificStates, 0);
+ dest.writeParcelable(mVoiceSpecificInfo, 0);
+ dest.writeParcelable(mDataSpecificInfo, 0);
dest.writeInt(mNrState);
}
@@ -543,7 +545,7 @@
*
* @param state data specific registration state contains the 5G NR indicators.
*/
- private void updateNrState(DataSpecificRegistrationStates state) {
+ private void updateNrState(DataSpecificRegistrationInfo state) {
mNrState = NR_STATE_NONE;
if (state.isEnDcAvailable) {
if (!state.isDcNrRestricted && state.isNrAvailable) {
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index df31f50..49398ed 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -1855,6 +1855,7 @@
/**
* @hide
*/
+ @TestApi
public void addNetworkRegistrationInfo(NetworkRegistrationInfo regState) {
if (regState == null) return;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 0d4d654..5df7bf7 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7082,6 +7082,35 @@
}
/**
+ * Query Telephony to see if there has recently been an emergency SMS sent to the network by the
+ * user and we are still within the time interval after the emergency SMS was sent that we are
+ * considered in Emergency SMS mode.
+ *
+ * <p>This mode is used by other applications to allow them to perform special functionality,
+ * such as allow the GNSS service to provide user location to the carrier network for emergency
+ * when an emergency SMS is sent. This interval is set by
+ * {@link CarrierConfigManager#KEY_EMERGENCY_SMS_MODE_TIMER_MS_INT}. If
+ * the carrier does not support this mode, this function will always return false.
+ *
+ * @return true if this device is in emergency SMS mode, false otherwise.
+ *
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public boolean isInEmergencySmsMode() {
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony.isInEmergencySmsMode();
+ }
+ } catch (RemoteException ex) {
+ Rlog.e(TAG, "getNetworkSelectionMode RemoteException", ex);
+ }
+ return false;
+ }
+
+ /**
* Set the preferred network type.
*
* <p>Requires Permission:
diff --git a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
similarity index 63%
rename from telephony/java/android/telephony/VoiceSpecificRegistrationStates.java
rename to telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
index d8ce5b4..18a533a 100644
--- a/telephony/java/android/telephony/VoiceSpecificRegistrationStates.java
+++ b/telephony/java/android/telephony/VoiceSpecificRegistrationInfo.java
@@ -1,5 +1,22 @@
+/*
+ * Copyright 2018 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.telephony;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.os.Parcelable;
@@ -10,14 +27,14 @@
* Class that stores information specific to voice network registration.
* @hide
*/
-public class VoiceSpecificRegistrationStates implements Parcelable{
+public class VoiceSpecificRegistrationInfo implements Parcelable{
/**
* oncurrent services support indicator. if
* registered on a CDMA system.
* false - Concurrent services not supported,
* true - Concurrent services supported
*/
- public final boolean cssSupported;
+ public final boolean cssSupported;
/**
* TSB-58 Roaming Indicator if registered
@@ -40,15 +57,15 @@
*/
public final int defaultRoamingIndicator;
- VoiceSpecificRegistrationStates(boolean cssSupported, int roamingIndicator, int systemIsInPrl,
- int defaultRoamingIndicator) {
+ VoiceSpecificRegistrationInfo(boolean cssSupported, int roamingIndicator, int systemIsInPrl,
+ int defaultRoamingIndicator) {
this.cssSupported = cssSupported;
this.roamingIndicator = roamingIndicator;
this.systemIsInPrl = systemIsInPrl;
this.defaultRoamingIndicator = defaultRoamingIndicator;
}
- private VoiceSpecificRegistrationStates(Parcel source) {
+ private VoiceSpecificRegistrationInfo(Parcel source) {
this.cssSupported = source.readBoolean();
this.roamingIndicator = source.readInt();
this.systemIsInPrl = source.readInt();
@@ -70,7 +87,7 @@
@Override
public String toString() {
- return "VoiceSpecificRegistrationStates {"
+ return "VoiceSpecificRegistrationInfo {"
+ " mCssSupported=" + cssSupported
+ " mRoamingIndicator=" + roamingIndicator
+ " mSystemIsInPrl=" + systemIsInPrl
@@ -87,11 +104,11 @@
public boolean equals(Object o) {
if (this == o) return true;
- if (o == null || !(o instanceof VoiceSpecificRegistrationStates)) {
+ if (o == null || !(o instanceof VoiceSpecificRegistrationInfo)) {
return false;
}
- VoiceSpecificRegistrationStates other = (VoiceSpecificRegistrationStates) o;
+ VoiceSpecificRegistrationInfo other = (VoiceSpecificRegistrationInfo) o;
return this.cssSupported == other.cssSupported
&& this.roamingIndicator == other.roamingIndicator
&& this.systemIsInPrl == other.systemIsInPrl
@@ -99,16 +116,16 @@
}
- public static final @android.annotation.NonNull Parcelable.Creator<VoiceSpecificRegistrationStates> CREATOR =
- new Parcelable.Creator<VoiceSpecificRegistrationStates>() {
+ public static final @NonNull Parcelable.Creator<VoiceSpecificRegistrationInfo> CREATOR =
+ new Parcelable.Creator<VoiceSpecificRegistrationInfo>() {
@Override
- public VoiceSpecificRegistrationStates createFromParcel(Parcel source) {
- return new VoiceSpecificRegistrationStates(source);
+ public VoiceSpecificRegistrationInfo createFromParcel(Parcel source) {
+ return new VoiceSpecificRegistrationInfo(source);
}
@Override
- public VoiceSpecificRegistrationStates[] newArray(int size) {
- return new VoiceSpecificRegistrationStates[size];
+ public VoiceSpecificRegistrationInfo[] newArray(int size) {
+ return new VoiceSpecificRegistrationInfo[size];
}
};
-}
\ No newline at end of file
+}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 10cc99e..d98f8d8 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -1707,6 +1707,11 @@
*/
int getNetworkSelectionMode(int subId);
+ /**
+ * Return true if the device is in emergency sms mode, false otherwise.
+ */
+ boolean isInEmergencySmsMode();
+
/**
* Get a list of SMS apps on a user.
*/
diff --git a/test-mock/api/test-current.txt b/test-mock/api/test-current.txt
index 6765316..a87e2f5 100644
--- a/test-mock/api/test-current.txt
+++ b/test-mock/api/test-current.txt
@@ -3,6 +3,7 @@
public class MockContext extends android.content.Context {
method public android.view.Display getDisplay();
+ method public int getDisplayId();
}
@Deprecated public class MockPackageManager extends android.content.pm.PackageManager {
diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
index 01176f2..e595164 100644
--- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
+++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java
@@ -345,7 +345,7 @@
}
/** Whether the primary registered cell of current entry is same as that of previous entry */
- public boolean getIsSameRegisteredCell() {
+ public boolean isSameRegisteredCell() {
return mIsSameRegisteredCell;
}
}
diff --git a/wifi/java/android/net/wifi/rtt/ResponderLocation.java b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
index 37d5f0a..e1d82f8 100644
--- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java
+++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java
@@ -1169,6 +1169,8 @@
* (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
* <p>
* Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
+ *
+ * @hide
*/
public boolean getRegisteredLocationDseIndication() {
if (!mIsLciValid) {
@@ -1185,6 +1187,8 @@
* (see 802.11REVmc Section 11.12.3 - Registered STA Operation).
* <p>
* Only valid if {@link #isLciSubelementValid()} returns true, or will throw an exception.
+ *
+ * @hide
*/
public boolean getDependentStationIndication() {
if (!mIsLciValid) {
diff --git a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
index cd60f02..5184152 100644
--- a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java
@@ -116,6 +116,6 @@
assertEquals(expected.getCellularSignalStrengthDbm(),
actual.getCellularSignalStrengthDbm());
assertEquals(expected.getCellularSignalStrengthDb(), actual.getCellularSignalStrengthDb());
- assertEquals(expected.getIsSameRegisteredCell(), actual.getIsSameRegisteredCell());
+ assertEquals(expected.isSameRegisteredCell(), actual.isSameRegisteredCell());
}
}