diff options
199 files changed, 3433 insertions, 1420 deletions
diff --git a/Android.bp b/Android.bp index 56547b22506d..4c07fcf2c17f 100644 --- a/Android.bp +++ b/Android.bp @@ -248,7 +248,6 @@ java_defaults { "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 @@ java_defaults { "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/CleanSpec.mk b/CleanSpec.mk index 30c2c69e8572..6160acbcf130 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -253,6 +253,7 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/vendor/overlay/ExperimentNav $(call add-clean-step, rm -rf $(PRODUCT_OUT)/vendor/overlay/ExperimentNavigationBarSlim) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/SystemUI) $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio) +$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/priv-app/DynamicAndroidInstallationService) # ****************************************************************** # NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER # ****************************************************************** diff --git a/api/current.txt b/api/current.txt index a96129505617..a15daa2fa4c7 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5481,10 +5481,10 @@ package android.app { 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 @@ package android.app { 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 { @@ -9794,6 +9794,7 @@ package android.content { 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"; @@ -12356,6 +12357,7 @@ package android.content.res { method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[]); method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@StyleRes int, @NonNull @StyleableRes int[]) throws android.content.res.Resources.NotFoundException; method @NonNull public android.content.res.TypedArray obtainStyledAttributes(@Nullable android.util.AttributeSet, @NonNull @StyleableRes int[], @AttrRes int, @StyleRes int); + method public void rebase(); method public boolean resolveAttribute(int, android.util.TypedValue, boolean); method public void setTo(android.content.res.Resources.Theme); } @@ -22664,18 +22666,22 @@ package android.location { 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(); @@ -24846,6 +24852,7 @@ package android.media { 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 { @@ -26389,15 +26396,15 @@ package android.media { method public void writeToParcel(@NonNull android.os.Parcel, int); field public static final int COMMAND_CODE_CUSTOM = 0; // 0x0 field @NonNull public static final android.os.Parcelable.Creator<android.media.Session2Command> CREATOR; - field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff - field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 - field public static final int RESULT_SUCCESS = 0; // 0x0 } public static final class Session2Command.Result { ctor public Session2Command.Result(int, @Nullable android.os.Bundle); method public int getResultCode(); method @Nullable public android.os.Bundle getResultData(); + field public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; // 0xffffffff + field public static final int RESULT_INFO_SKIPPED = 1; // 0x1 + field public static final int RESULT_SUCCESS = 0; // 0x0 } public final class Session2CommandGroup implements android.os.Parcelable { @@ -30752,7 +30759,6 @@ package android.net.wifi.rtt { 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 +30771,6 @@ package android.net.wifi.rtt { 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(); @@ -41723,7 +41728,7 @@ package android.service.notification { method public void onNotificationRemoved(android.service.notification.StatusBarNotification); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap); method public void onNotificationRemoved(android.service.notification.StatusBarNotification, android.service.notification.NotificationListenerService.RankingMap, int); - method public void onStatusBarIconsBehaviorChanged(boolean); + method public void onSilentStatusBarIconsVisibilityChanged(boolean); method public final void requestInterruptionFilter(int); method public final void requestListenerHints(int); method public static void requestRebind(android.content.ComponentName); diff --git a/api/system-current.txt b/api/system-current.txt index 2ae3a776a50b..876c2b28ad05 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1361,7 +1361,6 @@ package android.content { 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"; @@ -1388,32 +1387,6 @@ package android.content { 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"; @@ -1488,6 +1461,7 @@ package android.content.om { 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; } @@ -4938,7 +4912,6 @@ package android.net.wifi { 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(); @@ -4962,6 +4935,7 @@ package android.net.wifi { 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 @@ -5451,14 +5425,14 @@ package android.os { 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 @@ -5665,6 +5639,36 @@ package android.os { } +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 { @@ -6431,7 +6435,7 @@ package android.service.contentcapture { 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(); @@ -7571,11 +7575,11 @@ package android.telephony { 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 { @@ -7684,7 +7688,7 @@ package android.telephony { 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(); @@ -9491,6 +9495,10 @@ package android.util { method public int getUid(); } + public final class StatsLog { + method public static void writeRaw(@NonNull byte[], int); + } + public class StatsLogAtoms { field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED = 170; // 0xaa field public static final int PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_DENIED = 8; // 0x8 diff --git a/api/test-current.txt b/api/test-current.txt index 07944fad69ea..6532cf80b98c 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -352,6 +352,10 @@ package android.app { 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); @@ -584,12 +588,14 @@ package android.content { } public final class ContentCaptureOptions implements android.os.Parcelable { + ctor public ContentCaptureOptions(int); ctor public ContentCaptureOptions(int, int, int, int, int, @Nullable android.util.ArraySet<android.content.ComponentName>); method public int describeContents(); method public static android.content.ContentCaptureOptions forWhitelistingItself(); method public void writeToParcel(android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.content.ContentCaptureOptions> CREATOR; field public final int idleFlushingFrequencyMs; + field public final boolean lite; field public final int logHistorySize; field public final int loggingLevel; field public final int maxBufferSize; @@ -608,6 +614,7 @@ package android.content { 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); @@ -618,6 +625,7 @@ package android.content { 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 { @@ -927,19 +935,23 @@ package android.location { 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 { @@ -1799,11 +1811,11 @@ package android.os { } 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 { @@ -2151,7 +2163,7 @@ package android.provider { 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"; @@ -2436,7 +2448,7 @@ package android.service.contentcapture { 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(); @@ -2555,10 +2567,34 @@ package android.telecom { 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"; } @@ -2571,12 +2607,59 @@ package android.telephony { 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); + method public void setDataRoamingType(int); method public void setRilDataRadioTechnology(int); method public void setRilVoiceRadioTechnology(int); + method public void setVoiceRoamingType(int); } public class TelephonyManager { diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp index 24331af9fd6d..55b1003c38af 100644 --- a/cmds/idmap2/idmap2/Scan.cpp +++ b/cmds/idmap2/idmap2/Scan.cpp @@ -196,13 +196,7 @@ Result<Unit> Scan(const std::vector<std::string>& args) { 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/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto index 2a3eee2a7e18..16c936c41559 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -84,4 +84,6 @@ extend google.protobuf.FieldOptions { optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC]; optional bool allow_from_any_uid = 50003 [default = false]; + + optional string log_from_module = 50004; }
\ No newline at end of file diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index d740961cac2a..a3776c4b4d32 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -4759,7 +4759,6 @@ HPLandroid/os/IDeviceIdleController$Stub$Proxy;->addPowerSaveTempWhitelistAppFor 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;->writeLongsMap(Landroid/os/Parcel;Landro 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$Proxy;->isPowerSaveWhitelistApp(Ljava/ 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;->waitForConnectionToZygote(Ljava/lang/String;)V 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/DeviceIdleManager; 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$Stub; 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/HealthStatsWriter; 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 76d69cdce5cf..79cdb77bbd11 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -1680,7 +1680,6 @@ Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[ 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 fda028de33f3..abdbab2a29eb 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -2724,7 +2724,6 @@ android.os.DeviceIdleManager 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.HealthStatsParceler 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/Notification.java b/core/java/android/app/Notification.java index 7ba614685ad8..d634aa578429 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -21,6 +21,7 @@ import static android.graphics.drawable.Icon.TYPE_BITMAP; 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 @@ public class Notification implements Parcelable private PendingIntent mDeleteIntent; private Icon mIcon; private int mDesiredHeight; + @DimenRes private int mDesiredHeightResId; private int mFlags; /** @@ -8547,10 +8549,11 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable if (in.readInt() != 0) { mDeleteIntent = PendingIntent.CREATOR.createFromParcel(in); } + mDesiredHeightResId = in.readInt(); } /** @@ -8581,17 +8585,6 @@ public class Notification implements Parcelable } /** - * @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 @@ public class Notification implements Parcelable } /** - * @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 @@ public class Notification implements Parcelable } /** + * @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 @@ public class Notification implements Parcelable if (mDeleteIntent != null) { mDeleteIntent.writeToParcel(out, 0); } + out.writeInt(mDesiredHeightResId); } private void setFlags(int flags) { @@ -8668,6 +8671,7 @@ public class Notification implements Parcelable private PendingIntent mPendingIntent; private Icon mIcon; private int mDesiredHeight; + @DimenRes private int mDesiredHeightResId; private int mFlags; private PendingIntent mDeleteIntent; @@ -8691,19 +8695,6 @@ public class Notification implements Parcelable } /** - * 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 @@ public class Notification implements Parcelable } /** - * 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 @@ public class Notification implements Parcelable 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/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 4d280b76b3fa..d67bfb6c9c84 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -131,13 +131,11 @@ import android.os.BugreportManager; 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.UserHandle; 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 @@ final class SystemServiceRegistry { 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 a929fe0f688e..325a54bffbfb 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -25,6 +25,7 @@ import android.annotation.SdkConstant; 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 @@ public class WallpaperManager { * * @hide */ + @TestApi @SystemApi @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(ComponentName name) { diff --git a/core/java/android/content/ContentCaptureOptions.java b/core/java/android/content/ContentCaptureOptions.java index 6be0bea4c9f2..1727d341bd82 100644 --- a/core/java/android/content/ContentCaptureOptions.java +++ b/core/java/android/content/ContentCaptureOptions.java @@ -72,9 +72,29 @@ public final class ContentCaptureOptions implements Parcelable { @Nullable public final ArraySet<ComponentName> whitelistedComponents; + /** + * Used to enable just a small set of APIs so it can used by activities belonging to the + * content capture service APK. + */ + public final boolean lite; + + public ContentCaptureOptions(int loggingLevel) { + this(/* lite= */ true, loggingLevel, /* maxBufferSize= */ 0, + /* idleFlushingFrequencyMs= */ 0, /* textChangeFlushingFrequencyMs= */ 0, + /* logHistorySize= */ 0, /* whitelistedComponents= */ null); + } + public ContentCaptureOptions(int loggingLevel, int maxBufferSize, int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, @Nullable ArraySet<ComponentName> whitelistedComponents) { + this(/* lite= */ false, loggingLevel, maxBufferSize, idleFlushingFrequencyMs, + textChangeFlushingFrequencyMs, logHistorySize, whitelistedComponents); + } + + private ContentCaptureOptions(boolean lite, int loggingLevel, int maxBufferSize, + int idleFlushingFrequencyMs, int textChangeFlushingFrequencyMs, int logHistorySize, + @Nullable ArraySet<ComponentName> whitelistedComponents) { + this.lite = lite; this.loggingLevel = loggingLevel; this.maxBufferSize = maxBufferSize; this.idleFlushingFrequencyMs = idleFlushingFrequencyMs; @@ -115,6 +135,9 @@ public final class ContentCaptureOptions implements Parcelable { @Override public String toString() { + if (lite) { + return "ContentCaptureOptions [(lite) loggingLevel=" + loggingLevel + "]"; + } return "ContentCaptureOptions [loggingLevel=" + loggingLevel + ", maxBufferSize=" + maxBufferSize + ", idleFlushingFrequencyMs=" + idleFlushingFrequencyMs + ", textChangeFlushingFrequencyMs=" + textChangeFlushingFrequencyMs @@ -125,6 +148,10 @@ public final class ContentCaptureOptions implements Parcelable { /** @hide */ public void dumpShort(@NonNull PrintWriter pw) { pw.print("logLvl="); pw.print(loggingLevel); + if (lite) { + pw.print(", lite"); + return; + } pw.print(", bufferSize="); pw.print(maxBufferSize); pw.print(", idle="); pw.print(idleFlushingFrequencyMs); pw.print(", textIdle="); pw.print(textChangeFlushingFrequencyMs); @@ -141,7 +168,10 @@ public final class ContentCaptureOptions implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { + parcel.writeBoolean(lite); parcel.writeInt(loggingLevel); + if (lite) return; + parcel.writeInt(maxBufferSize); parcel.writeInt(idleFlushingFrequencyMs); parcel.writeInt(textChangeFlushingFrequencyMs); @@ -154,7 +184,11 @@ public final class ContentCaptureOptions implements Parcelable { @Override public ContentCaptureOptions createFromParcel(Parcel parcel) { + final boolean lite = parcel.readBoolean(); final int loggingLevel = parcel.readInt(); + if (lite) { + return new ContentCaptureOptions(loggingLevel); + } final int maxBufferSize = parcel.readInt(); final int idleFlushingFrequencyMs = parcel.readInt(); final int textChangeFlushingFrequencyMs = parcel.readInt(); @@ -171,6 +205,5 @@ public final class ContentCaptureOptions implements Parcelable { public ContentCaptureOptions[] newArray(int size) { return new ContentCaptureOptions[size]; } - }; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index fb933b1a7163..d7a2e1b80f84 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -338,6 +338,14 @@ public abstract class Context { 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 @@ public abstract class Context { /** * 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 @@ public abstract class Context { * @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 999d98662828..aabe59d18383 100644 --- a/core/java/android/content/om/OverlayInfo.java +++ b/core/java/android/content/om/OverlayInfo.java @@ -18,12 +18,14 @@ package android.content.om; 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 class OverlayInfo implements Parcelable { 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 @@ public final class OverlayInfo implements Parcelable { * @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 final class OverlayInfo implements Parcelable { 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 final class OverlayInfo implements Parcelable { 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 @@ public final class OverlayInfo implements Parcelable { 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 @@ public final class OverlayInfo implements Parcelable { 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 @@ public final class OverlayInfo implements Parcelable { @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 725d60117780..d6fb28f694fd 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -354,12 +354,12 @@ public class PackageInfo implements Parcelable { 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 743a302cc543..b480939ae450 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -689,7 +689,7 @@ public class PackageParser { 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/content/res/Resources.java b/core/java/android/content/res/Resources.java index 6b8416d46601..d7e4e1452cfe 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -1721,8 +1721,6 @@ public class Resources { * Rebases the theme against the parent Resource object's current * configuration by re-applying the styles passed to * {@link #applyStyle(int, boolean)}. - * - * @hide */ public void rebase() { mThemeImpl.rebase(); diff --git a/core/java/android/os/IPowerManager.aidl b/core/java/android/os/IPowerManager.aidl index b5c6604c8b99..e1d605e1c99d 100644 --- a/core/java/android/os/IPowerManager.aidl +++ b/core/java/android/os/IPowerManager.aidl @@ -53,10 +53,10 @@ interface IPowerManager 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 36bae2daf9bd..64e2f890ee47 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -1460,7 +1460,7 @@ public final class PowerManager { * 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 @@ public final class PowerManager { @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 @@ public final class PowerManager { /** * 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 c74cbff567c5..7958ddd29c70 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -23,7 +23,7 @@ import android.annotation.TestApi; 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 abstract class VibrationEffect implements Parcelable { */ 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 @@ public abstract class VibrationEffect implements Parcelable { 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 @@ public abstract class VibrationEffect implements Parcelable { 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 abstract class VibrationEffect implements Parcelable { }; } - 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/os/ZygoteProcess.java b/core/java/android/os/ZygoteProcess.java index 40238d2a9f27..34200077044d 100644 --- a/core/java/android/os/ZygoteProcess.java +++ b/core/java/android/os/ZygoteProcess.java @@ -66,22 +66,14 @@ import java.util.UUID; */ public class ZygoteProcess { - /** - * @hide for internal use only. - */ - public static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; + private static final int ZYGOTE_CONNECT_TIMEOUT_MS = 20000; /** - * @hide for internal use only. - * * Use a relatively short delay, because for app zygote, this is in the critical path of * service launch. */ - public static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50; + private static final int ZYGOTE_CONNECT_RETRY_DELAY_MS = 50; - /** - * @hide for internal use only - */ private static final String LOG_TAG = "ZygoteProcess"; /** @@ -141,7 +133,7 @@ public class ZygoteProcess { /** * State for communicating with the zygote process. */ - public static class ZygoteState { + private static class ZygoteState implements AutoCloseable { final LocalSocketAddress mZygoteSocketAddress; final LocalSocketAddress mUsapSocketAddress; @@ -178,12 +170,12 @@ public class ZygoteProcess { * address * @throws IOException */ - public static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress, - @Nullable LocalSocketAddress usapSocketAddress) + static ZygoteState connect(@NonNull LocalSocketAddress zygoteSocketAddress, + @Nullable LocalSocketAddress usapSocketAddress) throws IOException { - DataInputStream zygoteInputStream = null; - BufferedWriter zygoteOutputWriter = null; + DataInputStream zygoteInputStream; + BufferedWriter zygoteOutputWriter; final LocalSocket zygoteSessionSocket = new LocalSocket(); if (zygoteSocketAddress == null) { @@ -357,8 +349,6 @@ public class ZygoteProcess { /** * Queries the zygote for the list of ABIS it supports. - * - * @throws ZygoteStartFailedEx if the query failed. */ @GuardedBy("mLock") private static List<String> getAbiList(BufferedWriter writer, DataInputStream inputStream) @@ -411,52 +401,24 @@ public class ZygoteProcess { * the child or -1 on failure, followed by boolean to * indicate whether a wrapper process was used. */ - String msgStr = Integer.toString(args.size()) + "\n" - + String.join("\n", args) + "\n"; - - // Should there be a timeout on this? - Process.ProcessStartResult result = new Process.ProcessStartResult(); + String msgStr = args.size() + "\n" + String.join("\n", args) + "\n"; - // TODO (chriswailes): Move branch body into separate function. if (useUsapPool && mUsapPoolEnabled && isValidUsapCommand(args)) { - LocalSocket usapSessionSocket = null; - try { - usapSessionSocket = zygoteState.getUsapSessionSocket(); - - final BufferedWriter usapWriter = - new BufferedWriter( - new OutputStreamWriter(usapSessionSocket.getOutputStream()), - Zygote.SOCKET_BUFFER_SIZE); - final DataInputStream usapReader = - new DataInputStream(usapSessionSocket.getInputStream()); - - usapWriter.write(msgStr); - usapWriter.flush(); - - result.pid = usapReader.readInt(); - // USAPs can't be used to spawn processes that need wrappers. - result.usingWrapper = false; - - if (result.pid < 0) { - throw new ZygoteStartFailedEx("USAP specialization failed"); - } - - return result; + return attemptUsapSendArgsAndGetResult(zygoteState, msgStr); } catch (IOException ex) { // If there was an IOException using the USAP pool we will log the error and // attempt to start the process through the Zygote. Log.e(LOG_TAG, "IO Exception while communicating with USAP pool - " - + ex.getMessage()); - } finally { - try { - usapSessionSocket.close(); - } catch (IOException ex) { - Log.e(LOG_TAG, "Failed to close USAP session socket: " + ex.getMessage()); - } + + ex.getMessage()); } } + return attemptZygoteSendArgsAndGetResult(zygoteState, msgStr); + } + + private Process.ProcessStartResult attemptZygoteSendArgsAndGetResult( + ZygoteState zygoteState, String msgStr) throws ZygoteStartFailedEx { try { final BufferedWriter zygoteWriter = zygoteState.mZygoteOutputWriter; final DataInputStream zygoteInputStream = zygoteState.mZygoteInputStream; @@ -467,20 +429,48 @@ public class ZygoteProcess { // Always read the entire result from the input stream to avoid leaving // bytes in the stream for future process starts to accidentally stumble // upon. + Process.ProcessStartResult result = new Process.ProcessStartResult(); result.pid = zygoteInputStream.readInt(); result.usingWrapper = zygoteInputStream.readBoolean(); + + if (result.pid < 0) { + throw new ZygoteStartFailedEx("fork() failed"); + } + + return result; } catch (IOException ex) { zygoteState.close(); Log.e(LOG_TAG, "IO Exception while communicating with Zygote - " + ex.toString()); throw new ZygoteStartFailedEx(ex); } + } - if (result.pid < 0) { - throw new ZygoteStartFailedEx("fork() failed"); + private Process.ProcessStartResult attemptUsapSendArgsAndGetResult( + ZygoteState zygoteState, String msgStr) + throws ZygoteStartFailedEx, IOException { + try (LocalSocket usapSessionSocket = zygoteState.getUsapSessionSocket()) { + final BufferedWriter usapWriter = + new BufferedWriter( + new OutputStreamWriter(usapSessionSocket.getOutputStream()), + Zygote.SOCKET_BUFFER_SIZE); + final DataInputStream usapReader = + new DataInputStream(usapSessionSocket.getInputStream()); + + usapWriter.write(msgStr); + usapWriter.flush(); + + Process.ProcessStartResult result = new Process.ProcessStartResult(); + result.pid = usapReader.readInt(); + // USAPs can't be used to spawn processes that need wrappers. + result.usingWrapper = false; + + if (result.pid >= 0) { + return result; + } else { + throw new ZygoteStartFailedEx("USAP specialization failed"); + } } - - return result; } /** @@ -557,7 +547,7 @@ public class ZygoteProcess { boolean useUnspecializedAppProcessPool, @Nullable String[] extraArgs) throws ZygoteStartFailedEx { - ArrayList<String> argsForZygote = new ArrayList<String>(); + ArrayList<String> argsForZygote = new ArrayList<>(); // --runtime-args, --setuid=, --setgid=, // and --setgroups= must go first @@ -627,17 +617,7 @@ public class ZygoteProcess { } if (packagesForUid != null && packagesForUid.length > 0) { - final StringBuilder sb = new StringBuilder(); - sb.append("--packages-for-uid="); - - // TODO (chriswailes): Replace with String.join - for (int i = 0; i < packagesForUid.length; ++i) { - if (i != 0) { - sb.append(','); - } - sb.append(packagesForUid[i]); - } - argsForZygote.add(sb.toString()); + argsForZygote.add("--packages-for-uid=" + String.join(",", packagesForUid)); } if (sandboxId != null) { @@ -647,9 +627,7 @@ public class ZygoteProcess { argsForZygote.add(processClass); if (extraArgs != null) { - for (String arg : extraArgs) { - argsForZygote.add(arg); - } + Collections.addAll(argsForZygote, extraArgs); } synchronized(mLock) { @@ -671,11 +649,13 @@ public class ZygoteProcess { Boolean.parseBoolean(USAP_POOL_ENABLED_DEFAULT)); } - if (origVal != mUsapPoolEnabled) { + boolean valueChanged = origVal != mUsapPoolEnabled; + + if (valueChanged) { Log.i(LOG_TAG, "usapPoolEnabled = " + mUsapPoolEnabled); } - return origVal != mUsapPoolEnabled; + return valueChanged; } private boolean mIsFirstPropCheck = true; @@ -805,10 +785,10 @@ public class ZygoteProcess { if (state == null || state.isClosed()) { Slog.e(LOG_TAG, "Can't set API blacklist exemptions: no zygote connection"); return false; - } - if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) { + } else if (!sendIfEmpty && mApiBlacklistExemptions.isEmpty()) { return true; } + try { state.mZygoteOutputWriter.write(Integer.toString(mApiBlacklistExemptions.size() + 1)); state.mZygoteOutputWriter.newLine(); @@ -832,17 +812,15 @@ public class ZygoteProcess { } private void maybeSetHiddenApiAccessLogSampleRate(ZygoteState state) { - if (state == null || state.isClosed()) { - return; - } - if (mHiddenApiAccessLogSampleRate == -1) { + if (state == null || state.isClosed() || mHiddenApiAccessLogSampleRate == -1) { return; } + try { state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-log-sampling-rate=" - + Integer.toString(mHiddenApiAccessLogSampleRate)); + + mHiddenApiAccessLogSampleRate); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); @@ -855,17 +833,15 @@ public class ZygoteProcess { } private void maybeSetHiddenApiAccessStatslogSampleRate(ZygoteState state) { - if (state == null || state.isClosed()) { - return; - } - if (mHiddenApiAccessStatslogSampleRate == -1) { + if (state == null || state.isClosed() || mHiddenApiAccessStatslogSampleRate == -1) { return; } + try { state.mZygoteOutputWriter.write(Integer.toString(1)); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.write("--hidden-api-statslog-sampling-rate=" - + Integer.toString(mHiddenApiAccessStatslogSampleRate)); + + mHiddenApiAccessStatslogSampleRate); state.mZygoteOutputWriter.newLine(); state.mZygoteOutputWriter.flush(); int status = state.mZygoteInputStream.readInt(); @@ -942,8 +918,8 @@ public class ZygoteProcess { * Only the app zygote supports this function. * TODO preloadPackageForAbi() can probably be removed and the callers an use this instead. */ - public boolean preloadApp(ApplicationInfo appInfo, String abi) throws ZygoteStartFailedEx, - IOException { + public boolean preloadApp(ApplicationInfo appInfo, String abi) + throws ZygoteStartFailedEx, IOException { synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.mZygoteOutputWriter.write("2"); @@ -971,10 +947,10 @@ public class ZygoteProcess { * Instructs the zygote to pre-load the classes and native libraries at the given paths * for the specified abi. Not all zygotes support this function. */ - public boolean preloadPackageForAbi(String packagePath, String libsPath, String libFileName, - String cacheKey, String abi) throws ZygoteStartFailedEx, - IOException { - synchronized(mLock) { + public boolean preloadPackageForAbi( + String packagePath, String libsPath, String libFileName, String cacheKey, String abi) + throws ZygoteStartFailedEx, IOException { + synchronized (mLock) { ZygoteState state = openZygoteSocketIfNeeded(abi); state.mZygoteOutputWriter.write("5"); state.mZygoteOutputWriter.newLine(); @@ -1049,8 +1025,7 @@ public class ZygoteProcess { try { Thread.sleep(ZYGOTE_CONNECT_RETRY_DELAY_MS); - } catch (InterruptedException ie) { - } + } catch (InterruptedException ignored) { } } Slog.wtf(LOG_TAG, "Failed to connect to Zygote through socket " + zygoteSocketAddress.getName()); diff --git a/core/java/android/content/DynamicAndroidClient.java b/core/java/android/os/image/DynamicSystemClient.java index 571cba429ea9..33a6ee888d0a 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.lang.ref.WeakReference; 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 @@ public class DynamicAndroidClient { @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 @@ public class DynamicAndroidClient { /** 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 @@ public class DynamicAndroidClient { /** 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 class DynamicAndroidClient { 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 @@ public class DynamicAndroidClient { * 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 @@ public class DynamicAndroidClient { * @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 @@ public class DynamicAndroidClient { 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 @@ public class DynamicAndroidClient { } } - 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 class DynamicAndroidClient { } 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 @@ public class DynamicAndroidClient { 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 @@ public class DynamicAndroidClient { * 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 @@ public class DynamicAndroidClient { } /** - * 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 @@ public class DynamicAndroidClient { } /** - * 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 @@ public class DynamicAndroidClient { } /** - * 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 index 5238896016ee..0458c2a8b735 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 @@ public class DynamicAndroidManager { * @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 @@ public class DynamicAndroidManager { } } /** - * 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 @@ public class DynamicAndroidManager { * 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 @@ public class DynamicAndroidManager { * @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 @@ public class DynamicAndroidManager { } } - /** @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 @@ public class DynamicAndroidManager { } } - /** @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 @@ public class DynamicAndroidManager { } /** - * 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 @@ public class DynamicAndroidManager { } /** - * 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 index 0b28799c8dd0..15f5b68e354b 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 @@ interface IDynamicAndroidService 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 d4908caea9ed..53c7edace9c2 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -73,6 +73,7 @@ import android.os.Bundle; 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; @@ -875,7 +876,8 @@ public final class Settings { /** * Activity Action: Show screen for controlling app usage properties for an app. - * Input: Intent's extra EXTRA_PACKAGE_NAME must specify the application package name. + * Input: Intent's extra {@link android.content.Intent#EXTRA_PACKAGE_NAME} must specify the + * application package name. * Output: Nothing. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) @@ -12599,12 +12601,11 @@ public final class Settings { /** * 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 +12615,22 @@ public final class Settings { /** * 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 +12640,9 @@ public final class Settings { 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 +13631,7 @@ public final class Settings { 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 df113979bacf..fb07abaa34a1 100644 --- a/core/java/android/service/contentcapture/ContentCaptureService.java +++ b/core/java/android/service/contentcapture/ContentCaptureService.java @@ -298,12 +298,12 @@ public abstract class ContentCaptureService extends Service { /** * 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 @@ public abstract class ContentCaptureService extends Service { 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 6ecd82f50fdb..fb6061916d99 100644 --- a/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java +++ b/core/java/android/service/contentcapture/ContentCaptureServiceInfo.java @@ -139,6 +139,7 @@ public final class ContentCaptureServiceInfo { mSettingsActivity = settingsActivity; } + @NonNull public ServiceInfo getServiceInfo() { return mServiceInfo; } diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 23607ebe78fe..333868a2f08a 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -476,7 +476,7 @@ public abstract class NotificationListenerService extends Service { * @param hideSilentStatusIcons whether or not status bar icons should be hidden for silent * notifications */ - public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { + public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) { // optional } @@ -2255,7 +2255,7 @@ public abstract class NotificationListenerService extends Service { } break; case MSG_ON_STATUS_BAR_ICON_BEHAVIOR_CHANGED: { - onStatusBarIconsBehaviorChanged((Boolean) msg.obj); + onSilentStatusBarIconsVisibilityChanged((Boolean) msg.obj); } break; } } diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index de10ffb80bee..da6ef4cb591e 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -52,14 +52,14 @@ public class FeatureFlagUtils { 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/util/StatsLog.java b/core/java/android/util/StatsLog.java index bf46e95c7b09..30d3d7d069b5 100644 --- a/core/java/android/util/StatsLog.java +++ b/core/java/android/util/StatsLog.java @@ -22,6 +22,7 @@ import static android.Manifest.permission.PACKAGE_USAGE_STATS; import android.Manifest; import android.annotation.NonNull; import android.annotation.RequiresPermission; +import android.annotation.SystemApi; import android.app.IActivityManager; import android.content.Context; import android.os.IStatsManager; @@ -199,6 +200,16 @@ public final class StatsLog extends StatsLogInternal { } } + /** + * Write an event to stats log using the raw format. + * + * @param buffer The encoded buffer of data to write.. + * @param size The number of bytes from the buffer to write. + * @hide + */ + @SystemApi + public static native void writeRaw(@NonNull byte[] buffer, int size); + private static void enforceDumpCallingPermission(Context context) { context.enforceCallingPermission(android.Manifest.permission.DUMP, "Need DUMP permission."); } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index cd075bf65e4a..0043d3258772 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -88,10 +88,10 @@ public final class SurfaceControl implements Parcelable { 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 final class SurfaceControl implements Parcelable { 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 @@ public final class SurfaceControl implements Parcelable { @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 @@ public final class SurfaceControl implements Parcelable { * 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 @@ public final class SurfaceControl implements Parcelable { /** * 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 @@ public final class SurfaceControl implements Parcelable { 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 @@ public final class SurfaceControl implements Parcelable { } 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 @@ public final class SurfaceControl implements Parcelable { * @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 @@ public final class SurfaceControl implements Parcelable { * * @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 @@ public final class SurfaceControl implements Parcelable { * @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 @@ public final class SurfaceControl implements Parcelable { } /** - * 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 @@ public final class SurfaceControl implements Parcelable { } /** - * 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 ee8d66313ea2..e931448652c0 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -491,7 +491,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb 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 a4d80dcfe7d2..4851476e3d70 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -142,7 +142,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * 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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @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; /** @@ -300,7 +300,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769377) protected static final int FLAG_USE_CHILD_DRAWING_ORDER = 0x400; /** @@ -314,7 +314,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * * {@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 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager * 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 35ed7bfa2ce6..46a59f09eca7 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -54,6 +54,16 @@ public interface WindowManagerPolicyConstants { 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 a3e65496bcd0..9e546a80dfd3 100644 --- a/core/java/android/view/contentcapture/ContentCaptureManager.java +++ b/core/java/android/view/contentcapture/ContentCaptureManager.java @@ -32,6 +32,7 @@ import android.os.Handler; 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 @@ public final class ContentCaptureManager { 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. @@ -243,6 +246,7 @@ public final class ContentCaptureManager { @UiThread public void onActivityCreated(@NonNull IBinder applicationToken, @NonNull ComponentName activityComponent, int flags) { + if (mOptions.lite) return; synchronized (mLock) { mFlags |= flags; getMainContentCaptureSession().start(applicationToken, activityComponent, mFlags); @@ -252,18 +256,21 @@ public final class ContentCaptureManager { /** @hide */ @UiThread public void onActivityResumed() { + if (mOptions.lite) return; getMainContentCaptureSession().notifySessionLifecycle(/* started= */ true); } /** @hide */ @UiThread public void onActivityPaused() { + if (mOptions.lite) return; getMainContentCaptureSession().notifySessionLifecycle(/* started= */ false); } /** @hide */ @UiThread public void onActivityDestroyed() { + if (mOptions.lite) return; getMainContentCaptureSession().destroy(); } @@ -276,6 +283,7 @@ public final class ContentCaptureManager { */ @UiThread public void flush(@FlushReason int reason) { + if (mOptions.lite) return; getMainContentCaptureSession().flush(reason); } @@ -285,7 +293,7 @@ public final class ContentCaptureManager { */ @Nullable public ComponentName getServiceComponentName() { - if (!isContentCaptureEnabled()) return null; + if (!isContentCaptureEnabled() && !mOptions.lite) return null; final SyncResultReceiver resultReceiver = new SyncResultReceiver(SYNC_CALLS_TIMEOUT_MS); try { @@ -297,6 +305,35 @@ public final class ContentCaptureManager { } /** + * 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 + */ + // TODO: use "lite" options as it's done by activities from the content capture service + @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: @@ -311,6 +348,8 @@ public final class ContentCaptureManager { * </ul> */ public boolean isContentCaptureEnabled() { + if (mOptions.lite) return false; + final MainContentCaptureSession mainSession; synchronized (mLock) { mainSession = mMainSession; @@ -365,7 +404,7 @@ public final class ContentCaptureManager { 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 6d41b289460a..ed1ca2a48850 100644 --- a/core/java/android/view/contentcapture/ContentCaptureSession.java +++ b/core/java/android/view/contentcapture/ContentCaptureSession.java @@ -135,11 +135,18 @@ public abstract class ContentCaptureSession implements AutoCloseable { 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 e3b0372a8cc7..15fbaa2d7dab 100644 --- a/core/java/android/view/contentcapture/IContentCaptureManager.aidl +++ b/core/java/android/view/contentcapture/IContentCaptureManager.aidl @@ -67,4 +67,9 @@ oneway interface IContentCaptureManager { * 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 666af5968f69..790b8f9dde46 100644 --- a/core/java/android/view/contentcapture/MainContentCaptureSession.java +++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java @@ -230,7 +230,8 @@ public final class MainContentCaptureSession extends ContentCaptureSession { /** * 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 cb44f79465ef..0f2e702ecd0d 100644 --- a/core/java/android/view/textclassifier/TextClassifierImpl.java +++ b/core/java/android/view/textclassifier/TextClassifierImpl.java @@ -86,7 +86,8 @@ public final class TextClassifierImpl implements TextClassifier { 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 702b5075e1f0..54fff9b532f8 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -237,7 +237,7 @@ public class ChooserActivity extends ResolverActivity { if (DEBUG) { Log.d(TAG, "CHOOSER_TARGET_SERVICE_WATCHDOG_TIMEOUT; unbinding services"); } - if (isDestroyed()) { + if (mChooserListAdapter == null || isDestroyed()) { break; } unbindRemainingServices(); @@ -822,6 +822,7 @@ public class ChooserActivity extends ResolverActivity { 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); diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java index 5c144d3b5752..0a83fcc6db61 100644 --- a/core/java/com/android/internal/infra/AbstractRemoteService.java +++ b/core/java/com/android/internal/infra/AbstractRemoteService.java @@ -481,7 +481,11 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I @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/os/ZygoteConfig.java b/core/java/com/android/internal/os/ZygoteConfig.java index c8ff51e77866..c6af8c2f4316 100644 --- a/core/java/com/android/internal/os/ZygoteConfig.java +++ b/core/java/com/android/internal/os/ZygoteConfig.java @@ -24,14 +24,14 @@ package com.android.internal.os; public class ZygoteConfig { /** If {@code true}, enables the unspecialized app process (USAP) pool feature */ - public static final String USAP_POOL_ENABLED = "blastula_pool_enabled"; + public static final String USAP_POOL_ENABLED = "usap_pool_enabled"; /** The threshold used to determine if the pool should be refilled */ - public static final String USAP_POOL_REFILL_THRESHOLD = "blastula_refill_threshold"; + public static final String USAP_POOL_REFILL_THRESHOLD = "usap_refill_threshold"; /** The maximum number of processes to keep in the USAP pool */ - public static final String USAP_POOL_SIZE_MAX = "blastula_pool_size_max"; + public static final String USAP_POOL_SIZE_MAX = "usap_pool_size_max"; /** The minimum number of processes to keep in the USAP pool */ - public static final String USAP_POOL_SIZE_MIN = "blastula_pool_size_min"; + public static final String USAP_POOL_SIZE_MIN = "usap_pool_size_min"; } diff --git a/core/java/com/android/internal/os/ZygoteServer.java b/core/java/com/android/internal/os/ZygoteServer.java index 3f3aba9b6682..5d1911b9c29a 100644 --- a/core/java/com/android/internal/os/ZygoteServer.java +++ b/core/java/com/android/internal/os/ZygoteServer.java @@ -353,6 +353,8 @@ class ZygoteServer { return null; } + Log.i(TAG, "USAP Pool status change: " + (newStatus ? "ENABLED" : "DISABLED")); + mUsapPoolEnabled = newStatus; if (newStatus) { diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index 41e2fc84593e..b36c3fa79251 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -42,7 +42,7 @@ interface ILockSettings { 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 30f4d6fe417a..dd48c15e836b 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -669,17 +669,25 @@ public class LockPatternUtils { /** * 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 @@ public class LockPatternUtils { } onAfterChangingPassword(userHandle); + return true; } /** @@ -726,19 +735,28 @@ public class LockPatternUtils { /** * 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 @@ public class LockPatternUtils { 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 @@ public class LockPatternUtils { reportPatternWasChosen(userId); onAfterChangingPassword(userId); + return true; } private void updateCryptoUserInfo(int userId) { @@ -873,17 +892,20 @@ public class LockPatternUtils { * 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 @@ public class LockPatternUtils { * @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 @@ public class LockPatternUtils { 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.bp b/core/jni/Android.bp index cd34d2e1b441..664f7f47cf18 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -1,10 +1,10 @@ genrule { - name: "android_util_StatsLog.cpp", + name: "android_util_StatsLogInternal.cpp", tools: ["stats-log-api-gen"], - cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLog.cpp", + cmd: "$(location stats-log-api-gen) --jni $(genDir)/android_util_StatsLogInternal.cpp", out: [ - "android_util_StatsLog.cpp", + "android_util_StatsLogInternal.cpp", ], } @@ -111,6 +111,7 @@ cc_library_shared { "android_util_Binder.cpp", "android_util_EventLog.cpp", "android_util_Log.cpp", + "android_util_StatsLog.cpp", "android_util_MemoryIntArray.cpp", "android_util_PathParser.cpp", "android_util_Process.cpp", @@ -306,7 +307,7 @@ cc_library_shared { "server_configurable_flags", ], - generated_sources: ["android_util_StatsLog.cpp"], + generated_sources: ["android_util_StatsLogInternal.cpp"], local_include_dirs: ["android/graphics"], export_include_dirs: [ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 20bed1b34940..ccd0b666865e 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -127,6 +127,7 @@ extern int register_android_app_admin_SecurityLog(JNIEnv* env); extern int register_android_content_AssetManager(JNIEnv* env); extern int register_android_util_EventLog(JNIEnv* env); extern int register_android_util_StatsLog(JNIEnv* env); +extern int register_android_util_StatsLogInternal(JNIEnv* env); extern int register_android_util_Log(JNIEnv* env); extern int register_android_util_MemoryIntArray(JNIEnv* env); extern int register_android_util_PathParser(JNIEnv* env); @@ -1400,6 +1401,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_util_MemoryIntArray), REG_JNI(register_android_util_PathParser), REG_JNI(register_android_util_StatsLog), + REG_JNI(register_android_util_StatsLogInternal), REG_JNI(register_android_app_admin_SecurityLog), REG_JNI(register_android_content_AssetManager), REG_JNI(register_android_content_StringBlock), diff --git a/core/jni/android_util_StatsLog.cpp b/core/jni/android_util_StatsLog.cpp new file mode 100644 index 000000000000..e749d34035dd --- /dev/null +++ b/core/jni/android_util_StatsLog.cpp @@ -0,0 +1,69 @@ +/* + * 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. + */ + +#define LOG_NAMESPACE "StatsLog.tag." +#define LOG_TAG "StatsLog_println" + +#include <assert.h> +#include <cutils/properties.h> + +#include "jni.h" +#include <nativehelper/JNIHelp.h> +#include "utils/misc.h" +#include "core_jni_helpers.h" +#include "stats_event_list.h" + +namespace android { + +static void android_util_StatsLog_writeRaw(JNIEnv* env, jobject clazz, jbyteArray buf, jint size) +{ + if (buf == NULL) { + return; + } + jint actualSize = env->GetArrayLength(buf); + if (actualSize < size) { + return; + } + + jbyte* bufferArray = env->GetByteArrayElements(buf, NULL); + if (bufferArray == NULL) { + return; + } + const uint32_t statsEventTag = 1937006964; + struct iovec vec[2]; + vec[0].iov_base = (void*) &statsEventTag; + vec[0].iov_len = sizeof(statsEventTag); + vec[1].iov_base = (void*) bufferArray; + vec[1].iov_len = size; + write_to_statsd(vec, 2); + + env->ReleaseByteArrayElements(buf, bufferArray, 0); +} + +/* + * JNI registration. + */ +static const JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "writeRaw", "([BI)V", (void*) android_util_StatsLog_writeRaw }, +}; + +int register_android_util_StatsLog(JNIEnv* env) +{ + return RegisterMethodsOrDie(env, "android/util/StatsLog", gMethods, NELEM(gMethods)); +} + +}; // namespace android diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 4a6c72bda283..94f96babaf90 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -126,6 +126,41 @@ static struct { 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 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, 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 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz, 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 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl } 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 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (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 @@ int register_android_view_SurfaceControl(JNIEnv* env) 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 25caafb2bf65..b4be3f599604 100644 --- a/core/proto/android/app/settings_enums.proto +++ b/core/proto/android/app/settings_enums.proto @@ -2316,4 +2316,7 @@ enum PageId { // 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 305fc9729046..cb8ece7070be 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 dc742d57b147..67506cbc12bc 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 14edf6fe1aa3..14202f2d48d4 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 24fd3a8718bb..79bf73861bef 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> @@ -1584,7 +1584,7 @@ <!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=50] --> <string name="face_error_hw_not_available">Face hardware not available.</string> <!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] --> - <string name="face_error_timeout">Face time out reached. Try again.</string> + <string name="face_error_timeout">Face timeout reached. Try again.</string> <!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=50] --> <string name="face_error_no_space">Face can\u2019t be stored.</string> <!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] --> @@ -1596,11 +1596,11 @@ <!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=50] --> <string name="face_error_lockout_permanent">Too many attempts. Facial authentication disabled.</string> <!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] --> - <string name="face_error_unable_to_process">Try again.</string> + <string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string> <!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=50] --> - <string name="face_error_not_enrolled">No face enrolled.</string> + <string name="face_error_not_enrolled">You haven\u2019t set up face authentication.</string> <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=60] --> - <string name="face_error_hw_not_present">This device does not have a face authentication sensor.</string> + <string name="face_error_hw_not_present">Face authentication is not supported on this device.</string> <!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] --> <string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string> @@ -3283,18 +3283,36 @@ <string name="dump_heap_notification"><xliff:g id="proc">%1$s</xliff:g> exceeded memory limit</string> + <!-- Notification text to tell the user that a heap dump that they initiated for a process is ready [CHAR LIMIT=NONE] --> + <string name="dump_heap_ready_notification"> + <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> heap dump ready</string> + <!-- Notification details to tell the user that a process has exceeded its memory limit. --> <string name="dump_heap_notification_detail">Heap dump collected. Tap to share.</string> <!-- Title of dialog prompting the user to share a heap dump. --> <string name="dump_heap_title">Share heap dump?</string> - <!-- Text of dialog prompting the user to share a heap dump. --> - <string name="dump_heap_text">The process <xliff:g id="proc">%1$s</xliff:g> has exceeded - its process memory limit of <xliff:g id="size">%2$s</xliff:g>. A heap dump is available + <!-- Text of dialog prompting the user to share a heap dump for an application [CHAR LIMIT=NONE] --> + <string name="dump_heap_text">The + <xliff:g id="proc" example="com.android.example">%1$s</xliff:g> process has exceeded + its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available for you to share with its developer. Be careful: this heap dump can contain any of your personal information that the application has access to.</string> + <!-- Text of dialog prompting the user to share a heap dump for a system process [CHAR LIMIT=NONE] --> + <string name="dump_heap_system_text">The + <xliff:g id="proc" example="Android System">%1$s</xliff:g> process has exceeded + its memory limit of <xliff:g id="size" example="350MB">%2$s</xliff:g>. A heap dump is available + for you to share. Be careful: this heap dump can contain any sensitive personal information + that the process has access to.</string> + + <!-- Text of dialog prompting the user to share a heap dump that they initiated [CHAR LIMIT=NONE] --> + <string name="dump_heap_ready_text">A heap dump of + <xliff:g id="proc" example="com.android.example">%1$s</xliff:g>\u2019s process is available + for you to share. Be careful: this heap dump may contain any sensitive personal information + that the process has access to.</string> + <!-- Displayed in the title of the chooser for things to do with text that is to be sent to another application. For example, I can send text through SMS or IM. A dialog with those choices would be shown, @@ -5302,6 +5320,21 @@ <string name="battery_saver_sticky_disabled_notification_title">Battery Saver won\u2019t reactivate until battery low again</string> <!-- Summary of notification letting users know why battery saver didn't turn back on automatically after the device was unplugged [CHAR_LIMIT=NONE] --> <string name="battery_saver_sticky_disabled_notification_summary">Battery has been charged to a sufficient level. Battery Saver won\u2019t reactivate until the battery is low again.</string> + <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] --> + <string name="battery_saver_charged_notification_title" product="default">Phone <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string> + <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] --> + <string name="battery_saver_charged_notification_title" product="tablet">Tablet <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string> + <!-- Title of notification letting users know the battery level at the time the notification was posted [CHAR_LIMIT=80] --> + <string name="battery_saver_charged_notification_title" product="device">Device <xliff:g id="charge level" example="90%">%1$s</xliff:g> charged</string> + <!-- Summary of notification letting users know that battery saver is now off [CHAR_LIMIT=NONE] --> + <string name="battery_saver_off_notification_summary">Battery Saver is off. Features no longer restricted.</string> + <!-- Alternative summary of notification letting users know that battery saver has been turned off. + If it's easy to translate the difference between "Battery Saver turned off. Features no longer restricted." + and "Battery Saver is off. Features no longer restricted." into the target language, + then translate "Battery Saver turned off. Features no longer restricted." + If the translation doesn't make a difference or the difference is hard to capture in the target language, + then translate "Battery Saver is off. Features no longer restricted." instead. [CHAR_LIMIT=NONE] --> + <string name="battery_saver_off_alternative_notification_summary">Battery Saver turned off. Features no longer restricted.</string> <!-- Description of media type: folder or directory that contains additional files. [CHAR LIMIT=32] --> <string name="mime_type_folder">Folder</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 93c845873c85..012f736d5ee3 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2115,8 +2115,11 @@ <java-symbol type="string" name="device_storage_monitor_notification_channel" /> <java-symbol type="string" name="dlg_ok" /> <java-symbol type="string" name="dump_heap_notification" /> + <java-symbol type="string" name="dump_heap_ready_notification" /> <java-symbol type="string" name="dump_heap_notification_detail" /> <java-symbol type="string" name="dump_heap_text" /> + <java-symbol type="string" name="dump_heap_ready_text" /> + <java-symbol type="string" name="dump_heap_system_text" /> <java-symbol type="string" name="dump_heap_title" /> <java-symbol type="string" name="factorytest_failed" /> <java-symbol type="string" name="factorytest_no_action" /> @@ -2832,6 +2835,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. --> @@ -3649,6 +3653,9 @@ <java-symbol type="string" name="battery_saver_notification_channel_name" /> <java-symbol type="string" name="battery_saver_sticky_disabled_notification_title" /> <java-symbol type="string" name="battery_saver_sticky_disabled_notification_summary" /> + <java-symbol type="string" name="battery_saver_charged_notification_title" /> + <java-symbol type="string" name="battery_saver_off_notification_summary" /> + <java-symbol type="string" name="battery_saver_off_alternative_notification_summary" /> <java-symbol type="string" name="dynamic_mode_notification_channel_name" /> <java-symbol type="string" name="dynamic_mode_notification_title" /> <java-symbol type="string" name="dynamic_mode_notification_summary" /> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index 85947bde5bc4..8fc6a9694586 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -129,7 +129,7 @@ public class SettingsBackupTest { 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 72d1ab1c9d0c..e1ccd7523eba 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 @@ public class LegacyIntentClassificationFactoryTest { null, null, null, - null); + null, + 0, + 0); List<LabeledIntent> intents = mLegacyIntentClassificationFactory.create( InstrumentationRegistry.getContext(), @@ -98,7 +100,9 @@ public class LegacyIntentClassificationFactoryTest { 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 ccf8607b84d9..2e97e638ba57 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 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - createRemoteActionTemplates()); + createRemoteActionTemplates(), + 0, + 0); List<LabeledIntent> intents = mTemplateClassificationIntentFactory.create( @@ -121,7 +123,9 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - createRemoteActionTemplates()); + createRemoteActionTemplates(), + 0, + 0); List<LabeledIntent> intents = mTemplateClassificationIntentFactory.create( @@ -156,7 +160,9 @@ public class TemplateClassificationIntentFactoryTest { null, null, null, - null); + null, + 0, + 0); mTemplateClassificationIntentFactory.create( InstrumentationRegistry.getContext(), @@ -189,7 +195,9 @@ public class TemplateClassificationIntentFactoryTest { 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 185fa0750ff1..8c2375eaaf4c 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 @@ public class ChooserActivityTest { 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 @@ public class ChooserActivityTest { 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 a0d14f94bdbe..afb50714a93d 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -308,6 +308,8 @@ applications that come with the platform <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 @@ applications that come with the platform <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/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java index 9db7533044e2..b6d8fa19fca8 100644 --- a/graphics/java/android/graphics/text/MeasuredText.java +++ b/graphics/java/android/graphics/text/MeasuredText.java @@ -42,7 +42,7 @@ import libcore.util.NativeAllocationRegistry; * String text = "Hello, Android."; * MeasuredText mt = new MeasuredText.Builder(text.toCharArray()) * .appendStyleRun(paint, 7, false) // Use paint for "Hello, " - * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Hello, " + * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Android." * .build(); * </code> * </pre> diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java index 8507c8344b6c..538406180367 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 @@ public final class GnssClock implements Parcelable { 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 @@ public final class GnssClock implements Parcelable { private double mDriftNanosPerSecond; private double mDriftUncertaintyNanosPerSecond; private int mHardwareClockDiscontinuityCount; + private long mElapsedRealtimeNanos; + private long mElapsedRealtimeUncertaintyNanos; /** * @hide @@ -74,6 +80,8 @@ public final class GnssClock implements Parcelable { mDriftNanosPerSecond = clock.mDriftNanosPerSecond; mDriftUncertaintyNanosPerSecond = clock.mDriftUncertaintyNanosPerSecond; mHardwareClockDiscontinuityCount = clock.mHardwareClockDiscontinuityCount; + mElapsedRealtimeNanos = clock.mElapsedRealtimeNanos; + mElapsedRealtimeUncertaintyNanos = clock.mElapsedRealtimeUncertaintyNanos; } /** @@ -167,6 +175,7 @@ public final class GnssClock implements Parcelable { * <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 @@ public final class GnssClock implements Parcelable { * @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 @@ public final class GnssClock implements Parcelable { * * <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 @@ public final class GnssClock implements Parcelable { * @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 @@ public final class GnssClock implements Parcelable { * <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 @@ public final class GnssClock implements Parcelable { * @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 @@ public final class GnssClock implements Parcelable { } /** + * 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 @@ public final class GnssClock implements Parcelable { 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 @@ public final class GnssClock implements Parcelable { parcel.writeDouble(mDriftNanosPerSecond); parcel.writeDouble(mDriftUncertaintyNanosPerSecond); parcel.writeInt(mHardwareClockDiscontinuityCount); + parcel.writeLong(mElapsedRealtimeNanos); + parcel.writeLong(mElapsedRealtimeUncertaintyNanos); } @Override @@ -514,6 +614,16 @@ public final class GnssClock implements Parcelable { "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 @@ public final class GnssClock implements Parcelable { 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 e5fd0d342e9d..b4be21987cf7 100644 --- a/location/java/com/android/internal/location/GpsNetInitiatedHandler.java +++ b/location/java/com/android/internal/location/GpsNetInitiatedHandler.java @@ -238,6 +238,8 @@ public class GpsNetInitiatedHandler { * 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 @@ public class GpsNetInitiatedHandler { && ((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/apex/java/android/media/MediaController2.java b/media/apex/java/android/media/MediaController2.java index 2743a34d3f55..1e8438ec9fe8 100644 --- a/media/apex/java/android/media/MediaController2.java +++ b/media/apex/java/android/media/MediaController2.java @@ -22,8 +22,8 @@ import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; import static android.media.MediaConstants.KEY_SESSION2LINK; import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -329,7 +329,7 @@ public class MediaController2 implements AutoCloseable { MediaController2.this, command, args); if (resultReceiver != null) { if (result == null) { - resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null); + resultReceiver.send(RESULT_INFO_SKIPPED, null); } else { resultReceiver.send(result.getResultCode(), result.getResultData()); } diff --git a/media/apex/java/android/media/MediaSession2.java b/media/apex/java/android/media/MediaSession2.java index d63de098ecee..a900d8745006 100644 --- a/media/apex/java/android/media/MediaSession2.java +++ b/media/apex/java/android/media/MediaSession2.java @@ -22,8 +22,8 @@ import static android.media.MediaConstants.KEY_PID; import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE; import static android.media.MediaConstants.KEY_SESSION2LINK; import static android.media.MediaConstants.KEY_TOKEN_EXTRAS; -import static android.media.Session2Command.RESULT_ERROR_UNKNOWN_ERROR; -import static android.media.Session2Command.RESULT_INFO_SKIPPED; +import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR; +import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED; import static android.media.Session2Token.TYPE_SESSION; import android.annotation.NonNull; @@ -415,7 +415,7 @@ public class MediaSession2 implements AutoCloseable { MediaSession2.this, controllerInfo, command, args); if (resultReceiver != null) { if (result == null) { - resultReceiver.send(Session2Command.RESULT_INFO_SKIPPED, null); + resultReceiver.send(RESULT_INFO_SKIPPED, null); } else { resultReceiver.send(result.getResultCode(), result.getResultData()); } diff --git a/media/apex/java/android/media/Session2Command.java b/media/apex/java/android/media/Session2Command.java index 6822ea56b5e8..7f73dc123063 100644 --- a/media/apex/java/android/media/Session2Command.java +++ b/media/apex/java/android/media/Session2Command.java @@ -48,22 +48,6 @@ public final class Session2Command implements Parcelable { */ public static final int COMMAND_CODE_CUSTOM = 0; - /** - * Result code representing that the command is skipped or canceled. For an example, a seek - * command can be skipped if it is followed by another seek command. - */ - public static final int RESULT_INFO_SKIPPED = 1; - - /** - * Result code representing that the command is successfully completed. - */ - public static final int RESULT_SUCCESS = 0; - - /** - * Result code represents that call is ended with an unknown error. - */ - public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; - public static final @android.annotation.NonNull Parcelable.Creator<Session2Command> CREATOR = new Parcelable.Creator<Session2Command>() { @Override @@ -185,6 +169,22 @@ public final class Session2Command implements Parcelable { private final Bundle mResultData; /** + * Result code representing that the command is skipped or canceled. For an example, a seek + * command can be skipped if it is followed by another seek command. + */ + public static final int RESULT_INFO_SKIPPED = 1; + + /** + * Result code representing that the command is successfully completed. + */ + public static final int RESULT_SUCCESS = 0; + + /** + * Result code represents that call is ended with an unknown error. + */ + public static final int RESULT_ERROR_UNKNOWN_ERROR = -1; + + /** * Constructor of {@link Result}. * * @param resultCode result code diff --git a/media/java/android/media/MediaDrm.java b/media/java/android/media/MediaDrm.java index 005f2d47367b..a08aec3ed20c 100644 --- a/media/java/android/media/MediaDrm.java +++ b/media/java/android/media/MediaDrm.java @@ -552,6 +552,13 @@ public final class MediaDrm implements AutoCloseable { */ 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 @@ public final class MediaDrm implements AutoCloseable { 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/projection/OWNERS b/media/java/android/media/projection/OWNERS new file mode 100644 index 000000000000..7e7335d68d3b --- /dev/null +++ b/media/java/android/media/projection/OWNERS @@ -0,0 +1 @@ +michaelwr@google.com diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index e1dc40636ca5..1f2480ba0b47 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -148,6 +148,7 @@ LIBANDROID { 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 index 13d96ac3906e..16aca1bd07c5 100644 --- a/packages/DynamicAndroidInstallationService/Android.mk +++ b/packages/DynamicSystemInstallationService/Android.mk @@ -8,7 +8,7 @@ LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, res) 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 index 32acad4d5ab0..291111713977 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 index e69de29bb2d1..e69de29bb2d1 100644 --- a/packages/DynamicAndroidInstallationService/MODULE_LICENSE_APACHE2 +++ b/packages/DynamicSystemInstallationService/MODULE_LICENSE_APACHE2 diff --git a/packages/DynamicAndroidInstallationService/NOTICE b/packages/DynamicSystemInstallationService/NOTICE index c5b1efa7aac7..c5b1efa7aac7 100644 --- a/packages/DynamicAndroidInstallationService/NOTICE +++ b/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 index acf1567ab7fe..acf1567ab7fe 100644 --- a/packages/DynamicAndroidInstallationService/res/drawable/ic_system_update_googblue_24dp.xml +++ b/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 index 03c7c28c7036..a72e4e2c1b74 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 index dd1be897b2ea..38576ee47283 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 @@ public class BootCompletedReceiver extends BroadcastReceiver { 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 index d942babf78a6..df2c57181904 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; - -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; +package com.android.dynsystem; + import static android.os.AsyncTask.Status.FINISHED; import static android.os.AsyncTask.Status.PENDING; import static android.os.AsyncTask.Status.RUNNING; - -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 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.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.NotificationManager; 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.lang.ref.WeakReference; 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service } } - private DynamicAndroidManager mDynAndroid; + private DynamicSystemManager mDynSystem; private NotificationManager mNM; private long mSystemSize; @@ -130,7 +130,7 @@ public class DynamicAndroidInstallationService extends Service prepareNotification(); - mDynAndroid = (DynamicAndroidManager) getSystemService(Context.DYNAMIC_ANDROID_SERVICE); + mDynSystem = (DynamicSystemManager) getSystemService(Context.DYNAMIC_SYSTEM_SERVICE); } @Override @@ -156,8 +156,8 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service } 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 @@ public class DynamicAndroidInstallationService extends Service } 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service } 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service } 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 @@ public class DynamicAndroidInstallationService extends Service 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 @@ public class DynamicAndroidInstallationService extends Service } } - 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 @@ public class DynamicAndroidInstallationService extends Service } 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 index 03fc7739fcce..052fc0a109b3 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 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { 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 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { 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 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { Thread thread = new Thread(() -> { mInstallationSession = - mDynamicAndroid.startInstallation(mSystemSize, mUserdataSize); + mDynSystem.startInstallation(mSystemSize, mUserdataSize); }); @@ -106,12 +106,12 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { 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 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> { ? 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 index c18c4fe689c9..f05930f8ec07 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 @@ public class VerificationActivity extends Activity { 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 b34f445d91f5..b025df44738e 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 class BatterySaverUtils { */ 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 a33f9a8709d9..de7202cc63f9 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 @@ class SettingsProtoDumpUtil { 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 9e46ad6061eb..7337cdb81ebf 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 @@ package com.android.providers.settings; 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.ContentValues; 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 @@ public class SettingsProvider extends ContentProvider { } 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 @@ public class SettingsProvider extends ContentProvider { 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 441f88c193d6..d6e61ebbbd6e 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 3d2f570bde87..0a0530c056af 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 @@ public interface VolumeDialogController { boolean areCaptionsEnabled(); void setCaptionsEnabled(boolean isEnabled); + boolean isCaptionStreamOptedOut(); void getCaptionsComponentState(boolean fromTooltip); diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml index 5714556ae8a3..2f2f84a97434 100644 --- a/packages/SystemUI/res-keyguard/values/strings.xml +++ b/packages/SystemUI/res-keyguard/values/strings.xml @@ -444,15 +444,15 @@ number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. <!-- Minutes displayed in words on the typographic clock face. [CHAR LIMIT=20] --> <string-array name="type_clock_minutes"> <item>O\u2019Clock</item> - <item>O\u2019One</item> - <item>O\u2019Two</item> - <item>O\u2019Three</item> - <item>O\u2019Four</item> - <item>O\u2019Five</item> - <item>O\u2019Six</item> - <item>O\u2019Seven</item> - <item>O\u2019Eight</item> - <item>O\u2019Nine</item> + <item>Oh One</item> + <item>Oh Two</item> + <item>Oh Three</item> + <item>Oh Four</item> + <item>Oh Five</item> + <item>Oh Six</item> + <item>Oh Seven</item> + <item>Oh Eight</item> + <item>Oh Nine</item> <item>Ten</item> <item>Eleven</item> <item>Twelve</item> 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 000000000000..30843ec70f91 --- /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 6c8110b31c17..a02962e5e1e6 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 1d0a24274b12..d1c80c43b3e9 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 27d2bcdc05b4..e0bcf2435948 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 265c62012250..62309fdd2fcd 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 ce65b5a3a3a3..fd92e9e72d2e 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 android.widget.TextClock; 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.io.PrintWriter; 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 @@ public class KeyguardClockSwitch extends RelativeLayout { * * 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 @@ public class KeyguardClockSwitch extends RelativeLayout { @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 @@ public class KeyguardClockSwitch extends RelativeLayout { return mClockView.getTextSize(); } - public void refresh() { - mClockView.refresh(); - } - /** - * Notifies that time tick alarm from doze service fired. + * Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm. */ - public void dozeTimeTick() { + public void refresh() { + mClockView.refresh(); if (mClockPlugin != null) { mClockPlugin.onTimeTick(); } @@ -293,9 +314,9 @@ public class KeyguardClockSwitch extends RelativeLayout { } } - 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 9dd97170437d..ae8bc528ab6a 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.Log; 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 @@ public class KeyguardDisplayManager { private final MediaRouter mMediaRouter; private final DisplayManager mDisplayService; + private final InjectionInflationController mInjectableInflater; private final Context mContext; private boolean mShowing; @@ -75,8 +79,10 @@ public class KeyguardDisplayManager { } }; - 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 @@ public class KeyguardDisplayManager { 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 @@ public class KeyguardDisplayManager { 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 @@ public class KeyguardDisplayManager { } }; - 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 @@ public class KeyguardDisplayManager { 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 808e264258da..0369e4c0aea6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -214,7 +214,6 @@ public class KeyguardStatusView extends GridLayout implements 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 870ac8778f76..32c1242b695d 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 @@ public class BubbleClockController implements ClockPlugin { @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 7401819fde4d..34b2fd86f648 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 @@ public class StretchAnalogClockController implements ClockPlugin { @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 14e910f41cab..8e3afd8bcae0 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.GradientDrawable; 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 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList 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 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList 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 6c4be0617043..c243899c6bc9 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 @@ public class DozeMachine { 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 031f56266ea4..7189a48fed1f 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 @@ public class DozeTriggers implements DozeMachine.Part { } 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 477e7d7ebf72..d1939d0fddb0 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 @@ class ImageProcessHelper { 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 676e59428075..d70d0d80c681 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.BiometricUnlockController; 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 @@ public class KeyguardViewMediator extends SystemUI { 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/media/OWNERS b/packages/SystemUI/src/com/android/systemui/media/OWNERS new file mode 100644 index 000000000000..69ea57bfd397 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/OWNERS @@ -0,0 +1 @@ +per-file MediaProjectionPermissionActivity.java = michaelwr@google.com diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java index be63bad47d4a..aeaceb0c11e5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java @@ -79,7 +79,7 @@ public class NotificationListener extends NotificationListenerWithPlugins { } }); NotificationManager noMan = mContext.getSystemService(NotificationManager.class); - onStatusBarIconsBehaviorChanged(noMan.shouldHideSilentStatusBarIcons()); + onSilentStatusBarIconsVisibilityChanged(noMan.shouldHideSilentStatusBarIcons()); } @Override @@ -144,7 +144,7 @@ public class NotificationListener extends NotificationListenerWithPlugins { } @Override - public void onStatusBarIconsBehaviorChanged(boolean hideSilentStatusIcons) { + public void onSilentStatusBarIconsVisibilityChanged(boolean hideSilentStatusIcons) { for (NotificationSettingsListener listener : mSettingsListeners) { listener.onStatusBarIconsBehaviorChanged(hideSilentStatusIcons); } 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 813faa9ee4ed..520df9797cc3 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.Configuration; 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.VelocityTracker; 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 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd } } }; + 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 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd 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 class NotificationStackScrollLayout extends ViewGroup implements ScrollAd public void updateClipping() { boolean clipped = mRequestedClipBounds != null && !mInHeadsUpPinnedMode && !mHeadsUpAnimatingAway; + boolean clipToOutline = false; if (mIsClipped != clipped) { mIsClipped = clipped; } @@ -1306,12 +1320,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd && 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 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd 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 5a7df1f21bbd..ca452093eb20 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 @@ package com.android.systemui.statusbar.phone; 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.provider.Settings; 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 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { } }; + private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class); + public BiometricUnlockController(Context context, DozeScrimController dozeScrimController, KeyguardViewMediator keyguardViewMediator, @@ -253,6 +258,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { Trace.endSection(); return; } + mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH) + .setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType))); startWakeAndUnlock(calculateMode(biometricSourceType)); } @@ -420,12 +427,16 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback { @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 class BiometricUnlockController extends KeyguardUpdateMonitorCallback { 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 ef82b3402b15..e9a96066f9fc 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.Rect; 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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav 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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } }; - 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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav 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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav getHomeButton().abortCurrentGesture(); } - private H mHandler = new H(); - public View getCurrentView() { return mCurrentView; } @@ -1193,23 +1162,23 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } @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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav 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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } } - 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 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav 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 979de07fce73..9ea8b64fa2b3 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 @@ public class NavigationPrototypeController extends ContentObserver { 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 253bdfb1a206..b902e43bbac6 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.ConfigurationController; 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 @@ public class NotificationPanelView extends PanelView implements 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 @@ public class NotificationPanelView extends PanelView implements @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 @@ public class NotificationPanelView extends PanelView implements // 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 @@ public class NotificationPanelView extends PanelView implements 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 a8ae5f65a2a0..96090571685e 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 @@ public class StatusBarWindowView extends FrameLayout { 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/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java index 3c8ed6ebf279..b53ff0e45cea 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java @@ -16,9 +16,11 @@ package com.android.systemui.statusbar.policy; +import android.annotation.NonNull; import android.app.ActivityManager; import android.content.Context; +import com.android.internal.util.Preconditions; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.settings.CurrentUserTracker; @@ -69,7 +71,8 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback } @Override - public void addCallback(Callback callback) { + public void addCallback(@NonNull Callback callback) { + Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449"); mCallbacks.add(callback); if (mCallbacks.size() != 0 && !mListening) { mListening = true; @@ -81,7 +84,8 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback } @Override - public void removeCallback(Callback callback) { + public void removeCallback(@NonNull Callback callback) { + Preconditions.checkNotNull(callback, "Callback must not be null. b/128895449"); if (mCallbacks.remove(callback) && mCallbacks.size() == 0 && mListening) { mListening = false; mKeyguardUpdateMonitor.removeCallback(this); diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index e6b6672d3544..7705e4ecfaea 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.InflateException; 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 @@ public class InjectionInflationController { * 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 000000000000..8ec66e4bcc30 --- /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 2fa8889a02f9..a3db533bb7d0 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 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa 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 cdda216c5220..bd7824df1d24 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 @@ public class VolumeDialogImpl implements VolumeDialog { 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 @@ public class VolumeDialogImpl implements VolumeDialog { } 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 @@ public class VolumeDialogImpl implements VolumeDialog { } 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 29505a2046bb..632b0c05e2c2 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.FrameLayout; 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 @@ public class KeyguardClockSwitchTest extends SysuiTestCase { @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 3582ab010413..31ea39cedf3b 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; 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 @@ public class KeyguardStatusViewTest extends SysuiTestCase { @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/NotificationListenerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java index 2a013560bcd3..1a1acdf4590c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationListenerTest.java @@ -129,7 +129,7 @@ public class NotificationListenerTest extends SysuiTestCase { mock(NotificationListener.NotificationSettingsListener.class); mListener.addNotificationSettingsListener(settingsListener); - mListener.onStatusBarIconsBehaviorChanged(true); + mListener.onSilentStatusBarIconsVisibilityChanged(true); verify(settingsListener).onStatusBarIconsBehaviorChanged(true); } 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 5a1f24a44b2f..1bcf8803b5cf 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 @@ public class NotificationTestHelper { 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 eec836fde7f5..dfe2913e4ea3 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 android.view.LayoutInflater; 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 @@ public class KeyguardPresentationTest extends SysuiTestCase { @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 6889c57d74df..232c6a25a708 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 android.testing.TestableLooper; 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.NotificationWakeUpCoordinator 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 @@ public class NotificationPanelViewTest extends SysuiTestCase { 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 a15e89c8bcdb..b5223445d127 100644 --- a/packages/overlays/Android.mk +++ b/packages/overlays/Android.mk @@ -39,7 +39,10 @@ LOCAL_REQUIRED_MODULES := \ 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 000000000000..410d6d87c61d --- /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 000000000000..970380f070e9 --- /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 000000000000..b353322aed9c --- /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 000000000000..1696ecfea4e4 --- /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 000000000000..2bc9a6aea9eb --- /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 000000000000..628fc1dd3aa7 --- /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 000000000000..7bd0a140bb1c --- /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 000000000000..201b9e94cfbc --- /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 000000000000..5f7e0eb62a46 --- /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 000000000000..aff82d836ae5 --- /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 000000000000..48c37695d4a1 --- /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 000000000000..8d38916a0541 --- /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 7447331b113d..95abd05ff011 100644 --- a/proto/src/metrics_constants/metrics_constants.proto +++ b/proto/src/metrics_constants/metrics_constants.proto @@ -74,6 +74,9 @@ message MetricsEvent { // 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 @@ message MetricsEvent { // 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 6368c632d5a0..f0b9234ff4a6 100644 --- a/services/art-profile +++ b/services/art-profile @@ -1136,7 +1136,7 @@ Lcom/android/server/DropBoxManagerService$4; 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$2;->getNextEntry(Ljava/lang/String;JL 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;->isTagEnabled(Ljava/lang/String;)Z 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 76d464d2acfe..87a265cf38d4 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.FgThread; 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 @@ public final class AutofillManagerService @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 @@ public final class AutofillManagerService 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 @@ public final class AutofillManagerService 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 @@ public final class AutofillManagerService + 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 @@ public final class AutofillManagerService 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 @@ public final class AutofillManagerService 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 ad5e6895ebf3..ff284dcabfd0 100644 --- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java +++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java @@ -40,6 +40,7 @@ import android.graphics.Rect; import android.metrics.LogMaker; import android.os.AsyncTask; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; @@ -83,7 +84,6 @@ import com.android.server.autofill.AutofillManagerService.AutofillCompatState; 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 +159,6 @@ final class AutofillManagerServiceImpl /** 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 +188,6 @@ final class AutofillManagerServiceImpl 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 +939,7 @@ final class AutofillManagerServiceImpl .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 +1096,7 @@ final class AutofillManagerServiceImpl @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 +1104,8 @@ final class AutofillManagerServiceImpl 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 +1135,8 @@ final class AutofillManagerServiceImpl } /** - * Called when the {@link #mAugmentedAutofillResolver} changed (among other places). + * Called when the {@link AutofillManagerService#mAugmentedAutofillResolver} + * changed (among other places). */ void updateRemoteAugmentedAutofillService() { synchronized (mLock) { @@ -1225,6 +1213,18 @@ final class AutofillManagerServiceImpl @GuardedBy("mLock") boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) { + if (Build.IS_USER && mMaster.mAugmentedAutofillResolver.isTemporary(mUserId)) { + final String serviceName = mMaster.mAugmentedAutofillResolver.getServiceName(mUserId); + final ComponentName component = ComponentName.unflattenFromString(serviceName); + final String servicePackage = component == null ? null : component.getPackageName(); + final String packageName = componentName.getPackageName(); + if (!packageName.equals(servicePackage)) { + Slog.w(TAG, "Ignoring package " + packageName + " for augmented autofill while " + + "using temporary service " + servicePackage); + return false; + } + } + return mAugmentedWhitelistHelper.isWhitelisted(componentName); } diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java index ac8f61b50192..c62794d3e3d2 100644 --- a/services/autofill/java/com/android/server/autofill/Session.java +++ b/services/autofill/java/com/android/server/autofill/Session.java @@ -2659,17 +2659,16 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState mAugmentedAutofillDestroyer = triggerAugmentedAutofillLocked(); if (mAugmentedAutofillDestroyer == null) { if (sVerbose) { - Slog.v(TAG, "canceling session " + id + " when server returned null and there is no" - + " AugmentedAutofill for user. AutofillableIds: " + autofillableIds); + Slog.v(TAG, "canceling session " + id + " when service returned null and it cannot " + + "be augmented. AutofillableIds: " + autofillableIds); } // Nothing to be done, but need to notify client. notifyUnavailableToClient(AutofillManager.STATE_FINISHED, autofillableIds); removeSelf(); } else { if (sVerbose) { - Slog.v(TAG, "keeping session " + id + " when server returned null but " - + "there is an AugmentedAutofill for user. AutofillableIds: " - + autofillableIds); + Slog.v(TAG, "keeping session " + id + " when service returned null but " + + "it can be augmented. AutofillableIds: " + autofillableIds); } mAugmentedAutofillableIds = autofillableIds; } @@ -2687,7 +2686,10 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState // Check if Smart Suggestions is supported... final @SmartSuggestionMode int supportedModes = mService .getSupportedSmartSuggestionModesLocked(); - if (supportedModes == 0) return null; + if (supportedModes == 0) { + if (sVerbose) Slog.v(TAG, "triggerAugmentedAutofillLocked(): no supported modes"); + return null; + } // ...then if the service is set for the user @@ -2712,14 +2714,6 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState return null; } - if (sVerbose) { - Slog.v(TAG, "calling Augmented Autofill Service (" - + remoteService.getComponentName().toShortString() + ") on view " - + mCurrentViewId + " using suggestion mode " - + getSmartSuggestionModeToString(mode) - + " when server returned null for session " + this.id); - } - final boolean isWhitelisted = mService .isWhitelistedForAugmentedAutofillLocked(mComponentName); @@ -2733,12 +2727,20 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState if (!isWhitelisted) { if (sVerbose) { - Slog.v(TAG, mComponentName.toShortString() + " is not whitelisted for " - + "augmented autofill"); + Slog.v(TAG, "triggerAugmentedAutofillLocked(): " + + ComponentName.flattenToShortString(mComponentName) + " not whitelisted "); } return null; } + if (sVerbose) { + Slog.v(TAG, "calling Augmented Autofill Service (" + + ComponentName.flattenToShortString(remoteService.getComponentName()) + + ") on view " + mCurrentViewId + " using suggestion mode " + + getSmartSuggestionModeToString(mode) + + " when server returned null for session " + this.id); + } + final ViewState viewState = mViewStates.get(mCurrentViewId); viewState.setState(ViewState.STATE_TRIGGERED_AUGMENTED_AUTOFILL); final AutofillValue currentValue = viewState.getCurrentValue(); diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCaptureManagerService.java index 9995d8e4d893..b2760e037f44 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 @@ package com.android.server.contentcapture; 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.infra.AbstractRemoteService; 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 @@ public final class ContentCaptureManagerService extends } @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 @@ public final class ContentCaptureManagerService extends 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 @@ public final class ContentCaptureManagerService extends 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 @@ public final class ContentCaptureManagerService extends 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 d7d97b39959f..d9097369ba3b 100644 --- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java +++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java @@ -40,6 +40,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.ServiceInfo; import android.os.Binder; +import android.os.Build; import android.os.Bundle; import android.os.IBinder; import android.os.UserHandle; @@ -74,7 +75,7 @@ final class ContentCapturePerUserService 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 +88,8 @@ final class ContentCapturePerUserService * 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 +137,10 @@ final class ContentCapturePerUserService } 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 +188,40 @@ final class ContentCapturePerUserService } 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 +300,12 @@ final class ContentCapturePerUserService 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 +319,6 @@ final class ContentCapturePerUserService 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 +346,18 @@ final class ContentCapturePerUserService 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. */ @@ -430,8 +456,13 @@ final class ContentCapturePerUserService } @GuardedBy("mLock") + @Nullable ContentCaptureOptions getOptionsForPackageLocked(@NonNull String packageName) { if (!mWhitelistHelper.isWhitelisted(packageName)) { + if (packageName.equals(getServicePackageName())) { + if (mMaster.verbose) Slog.v(mTag, "getOptionsForPackage() lite for " + packageName); + return new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel); + } if (mMaster.verbose) { Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted"); } @@ -440,6 +471,14 @@ final class ContentCapturePerUserService final ArraySet<ComponentName> whitelistedComponents = mWhitelistHelper .getWhitelistedComponents(packageName); + if (Build.IS_USER && isTemporaryServiceSetLocked()) { + final String servicePackageName = getServicePackageName(); + if (!packageName.equals(servicePackageName)) { + Slog.w(mTag, "Ignoring package " + packageName + + " while using temporary service " + servicePackageName); + return null; + } + } ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel, mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs, mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize, @@ -518,12 +557,16 @@ final class ContentCapturePerUserService @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") + ")"); + } + synchronized (mLock) { + mWhitelistHelper.setWhitelist(packages, activities); } - 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 da198362f5cb..9b2c05f7fa79 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.service.contentcapture.SnapshotData; 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 class ContentCaptureServerSession { 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 @@ final class ContentCaptureServerSession { 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 @@ final class ContentCaptureServerSession { */ @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 @@ final class ContentCaptureServerSession { 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 @@ final class ContentCaptureServerSession { } // 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 @@ final class ContentCaptureServerSession { */ @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 2ce5059244a1..df9ccbc499ba 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 @@ final class RemoteContentCaptureService mIdleUnbindTimeoutMs = idleUnbindTimeoutMs; // Bind right away, which will trigger a onConnected() on service's - scheduleBind(); + ensureBoundLocked(); } @Override // from AbstractRemoteService @@ -89,6 +89,10 @@ final class RemoteContentCaptureService } } + 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 index b02bfb111727..f5bd11cea779 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.GsiProgress; 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 @@ public class DynamicAndroidService extends IDynamicAndroidService.Stub implement 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 b89223b5cbda..f0244c303360 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -3597,10 +3597,18 @@ public class LocationManagerService extends ILocationManager.Stub { 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 @@ public class LocationManagerService extends ILocationManager.Stub { } } - 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 10b67c1047cf..2e5dd3b0941e 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 @@ public class AppOpsService extends IAppOpsService.Stub { } scheduleWriteLocked(); } + uidState.evalForegroundOps(mOpModeWatchers); } String[] uidPackageNames = getPackagesForUid(uid); @@ -2414,8 +2415,6 @@ public class AppOpsService extends IAppOpsService.Stub { 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 @@ public class AppOpsService extends IAppOpsService.Stub { 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 @@ public class AppOpsService extends IAppOpsService.Stub { } } } + 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/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java index 3e48445dfb36..c60dd6ca130a 100644 --- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java @@ -1251,8 +1251,6 @@ public abstract class BiometricServiceBase extends SystemService if (getCurrentClient() instanceof InternalRemovalClient || getCurrentClient() instanceof InternalEnumerateClient) { Slog.w(getTag(), "User switched while performing cleanup"); - removeClient(getCurrentClient()); - clearEnumerateState(); } updateActiveGroup(userId, null); doTemplateCleanupForUser(userId); diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java index 4289a25e5b3a..54a4ad42fd99 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.IRadioService; 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 @@ public class BroadcastRadioService extends SystemService { 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 @@ public class BroadcastRadioService extends SystemService { 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 @@ public class BroadcastRadioService extends SystemService { @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 954c0013fbe4..b8810c8f379f 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 @@ package com.android.server.broadcastradio.hal2; 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 @@ import java.util.stream.Collectors; 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(); - } - - List<String> list = manager.listByInterface(fqName); - if (list == null) { - Slog.e(TAG, "Didn't get interface list from HIDL Service Manager"); - return Collections.emptyList(); + Slog.e(TAG, "failed to get HIDL Service Manager"); + return; } - 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 @@ public class BroadcastRadioService { 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 @@ public class BroadcastRadioService { @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 816ba0b51355..832f8e1c9205 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.NonNull; 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.IBroadcastRadio; 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 @@ class RadioModule { } } + 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 32f34b8378ce..3010324488b8 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.pm.ParceledListSlice; 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 @@ public final class DisplayManagerService extends SystemService { 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 430203de8268..ed894ee0bee8 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 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem 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 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem } /** + * 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 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem 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 @@ public abstract class AbstractMasterSystemService<M extends AbstractMasterSystem 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 0c5fb7998c78..3e134b266a88 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 @@ public class LockSettingsService extends ILockSettings.Stub { } 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 @@ public class LockSettingsService extends ILockSettings.Stub { 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 @@ public class LockSettingsService extends ILockSettings.Stub { // 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 @@ public class LockSettingsService extends ILockSettings.Stub { } 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 @@ public class LockSettingsService extends ILockSettings.Stub { } 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 @@ public class LockSettingsService extends ILockSettings.Stub { synchronized (mSpManager) { if (isSyntheticPasswordBasedCredentialLocked(userId)) { spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, - requestedQuality, userId); + requestedQuality, userId, allowUntrustedChange); return; } } @@ -1410,7 +1414,7 @@ public class LockSettingsService extends ILockSettings.Stub { initializeSyntheticPasswordLocked(currentHandle.hash, savedCredential, currentHandle.type, requestedQuality, userId); spBasedSetLockCredentialInternalLocked(credential, credentialType, savedCredential, - requestedQuality, userId); + requestedQuality, userId, allowUntrustedChange); return; } } @@ -1705,7 +1709,7 @@ public class LockSettingsService extends ILockSettings.Stub { 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 @@ public class LockSettingsService extends ILockSettings.Stub { 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 @@ public class LockSettingsService extends ILockSettings.Stub { /* 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 @@ public class LockSettingsService extends ILockSettings.Stub { @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 @@ public class LockSettingsService extends ILockSettings.Stub { 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/media/projection/OWNERS b/services/core/java/com/android/server/media/projection/OWNERS new file mode 100644 index 000000000000..7e7335d68d3b --- /dev/null +++ b/services/core/java/com/android/server/media/projection/OWNERS @@ -0,0 +1 @@ +michaelwr@google.com diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index ca3c826d77dd..e43fc1f057b0 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 @@ public class NotificationManagerService extends SystemService { 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 @@ public class NotificationManagerService extends SystemService { } } + 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 b0d2704196a6..15ed06311758 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 @@ final class OverlayManagerServiceImpl { 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 @@ final class OverlayManagerServiceImpl { mSettings.init(overlayPackage.packageName, newUserId, overlayPackage.overlayTarget, + overlayPackage.targetOverlayableName, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, @@ -331,6 +335,7 @@ final class OverlayManagerServiceImpl { } mSettings.init(packageName, userId, overlayPackage.overlayTarget, + overlayPackage.targetOverlayableName, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, overlayPackage.overlayCategory); @@ -395,7 +400,7 @@ final class OverlayManagerServiceImpl { 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 2b4ec03b98fd..667dfa19af15 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 @@ final class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { 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 class OverlayManagerSettings { 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 class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { } 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 @@ final class OverlayManagerSettings { 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 @@ final class OverlayManagerSettings { 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 e36ac23d6473..40f2a2b9dcc2 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 @@ public class PermissionManagerService { 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 @@ public class PermissionManagerService { shouldBeRevoked = !shouldBeGranted; } } else { - shouldBeRestricted = isLegacyStoragePermission; + shouldBeHidden = isLegacyStoragePermission; shouldBeFixed = isLegacyStoragePermission; if (shouldBeFixed) { @@ -1636,7 +1636,12 @@ public class PermissionManagerService { 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 5a32aa0539ec..55af3571f63a 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 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Start home. mActivityTaskManagerInternal.startHomeOnDisplay(mCurrentUserId, "startDockOrHome", - displayId, fromHomeKey); + displayId, true /* allowInstrumenting */, fromHomeKey); } /** @@ -5214,13 +5214,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { 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 9b427f5cfd5c..cfe11bfb4347 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 @@ public final class PowerManagerService extends SystemService } @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 @@ public final class PowerManagerService extends SystemService // 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 @@ public final class PowerManagerService extends SystemService } @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 61daca7c93bc..fe0b9a6acc85 100644 --- a/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java +++ b/services/core/java/com/android/server/power/batterysaver/BatterySaverStateMachine.java @@ -45,6 +45,7 @@ import com.android.server.EventLogTags; import com.android.server.power.BatterySaverStateMachineProto; import java.io.PrintWriter; +import java.text.NumberFormat; /** * Decides when to enable / disable battery saver. @@ -188,7 +189,7 @@ public class BatterySaverStateMachine { @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 +249,7 @@ public class BatterySaverStateMachine { /** @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 +265,7 @@ public class BatterySaverStateMachine { /** @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 +305,7 @@ public class BatterySaverStateMachine { 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 +368,8 @@ public class BatterySaverStateMachine { 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); @@ -791,7 +792,7 @@ public class BatterySaverStateMachine { manager.notify(DYNAMIC_MODE_NOTIFICATION_ID, buildNotification(DYNAMIC_MODE_NOTIF_CHANNEL_ID, - R.string.dynamic_mode_notification_title, + mContext.getResources().getString(R.string.dynamic_mode_notification_title), R.string.dynamic_mode_notification_summary, Intent.ACTION_POWER_USAGE_SUMMARY)); } @@ -801,10 +802,13 @@ public class BatterySaverStateMachine { ensureNotificationChannelExists(manager, BATTERY_SAVER_NOTIF_CHANNEL_ID, R.string.battery_saver_notification_channel_name); + final String percentage = NumberFormat.getPercentInstance() + .format((double) mBatteryLevel / 100.0); manager.notify(STICKY_AUTO_DISABLED_NOTIFICATION_ID, buildNotification(BATTERY_SAVER_NOTIF_CHANNEL_ID, - R.string.battery_saver_sticky_disabled_notification_title, - R.string.battery_saver_sticky_disabled_notification_summary, + mContext.getResources().getString( + R.string.battery_saver_charged_notification_title, percentage), + R.string.battery_saver_off_notification_summary, Settings.ACTION_BATTERY_SAVER_SETTINGS)); } @@ -816,7 +820,7 @@ public class BatterySaverStateMachine { manager.createNotificationChannel(channel); } - private Notification buildNotification(@NonNull String channelId, @StringRes int titleId, + private Notification buildNotification(@NonNull String channelId, @NonNull String title, @StringRes int summaryId, @NonNull String intentAction) { Resources res = mContext.getResources(); Intent intent = new Intent(intentAction); @@ -827,11 +831,12 @@ public class BatterySaverStateMachine { return new Notification.Builder(mContext, channelId) .setSmallIcon(R.drawable.ic_battery) - .setContentTitle(res.getString(titleId)) + .setContentTitle(title) .setContentText(summary) .setContentIntent(batterySaverIntent) .setStyle(new Notification.BigTextStyle().bigText(summary)) .setOnlyAlertOnce(true) + .setAutoCancel(true) .build(); } diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java index b262a006a545..fc7646f8ae4e 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 @@ public abstract class ActivityTaskManagerInternal { * - 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 c91ee8e2f286..b8e6b0c6fe9a 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 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub { @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/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java index d69ae3d5c3c0..24b02133ff3c 100644 --- a/services/core/java/com/android/server/wm/RecentTasks.java +++ b/services/core/java/com/android/server/wm/RecentTasks.java @@ -845,6 +845,11 @@ class RecentTasks { return mService.mAmInternal.getCurrentProfileIds(); } + @VisibleForTesting + boolean isUserRunning(int userId, int flags) { + return mService.mAmInternal.isUserRunning(userId, flags); + } + /** * @return the list of recent tasks for presentation. */ @@ -861,7 +866,7 @@ class RecentTasks { boolean getTasksAllowed, boolean getDetailedTasks, int userId, int callingUid) { final boolean withExcluded = (flags & RECENT_WITH_EXCLUDED) != 0; - if (!mService.mAmInternal.isUserRunning(userId, FLAG_AND_UNLOCKED)) { + if (!isUserRunning(userId, FLAG_AND_UNLOCKED)) { Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents"); return new ArrayList<>(); } @@ -881,7 +886,7 @@ class RecentTasks { if (isVisibleRecentTask(tr)) { numVisibleTasks++; - if (isInVisibleRange(tr, numVisibleTasks)) { + if (isInVisibleRange(tr, numVisibleTasks, withExcluded)) { // Fall through } else { // Not in visible range @@ -908,51 +913,43 @@ class RecentTasks { continue; } - // Return the entry if desired by the caller. We always return - // the first entry, because callers always expect this to be the - // foreground app. We may filter others if the caller has - // not supplied RECENT_WITH_EXCLUDED and there is some reason - // we should exclude the entry. - - if (i == 0 - || withExcluded - || (tr.intent == null) - || ((tr.intent.getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) - == 0)) { - if (!getTasksAllowed) { - // If the caller doesn't have the GET_TASKS permission, then only - // allow them to see a small subset of tasks -- their own and home. - if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); - continue; - } - } - if (tr.autoRemoveRecents && tr.getTopActivity() == null) { - // Don't include auto remove tasks that are finished or finishing. - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "Skipping, auto-remove without activity: " + tr); - continue; - } - if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) { - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "Skipping, unavail real act: " + tr); + if (!getTasksAllowed) { + // If the caller doesn't have the GET_TASKS permission, then only + // allow them to see a small subset of tasks -- their own and home. + if (!tr.isActivityTypeHome() && tr.effectiveUid != callingUid) { + if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr); continue; } + } - if (!tr.mUserSetupComplete) { - // Don't include task launched while user is not done setting-up. - if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, - "Skipping, user setup not complete: " + tr); - continue; + if (tr.autoRemoveRecents && tr.getTopActivity() == null) { + // Don't include auto remove tasks that are finished or finishing. + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "Skipping, auto-remove without activity: " + tr); + } + continue; + } + if ((flags & RECENT_IGNORE_UNAVAILABLE) != 0 && !tr.isAvailable) { + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "Skipping, unavail real act: " + tr); } + continue; + } - final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr); - if (!getDetailedTasks) { - rti.baseIntent.replaceExtras((Bundle)null); + if (!tr.mUserSetupComplete) { + // Don't include task launched while user is not done setting-up. + if (DEBUG_RECENTS) { + Slog.d(TAG_RECENTS, "Skipping, user setup not complete: " + tr); } + continue; + } - res.add(rti); + final ActivityManager.RecentTaskInfo rti = createRecentTaskInfo(tr); + if (!getDetailedTasks) { + rti.baseIntent.replaceExtras((Bundle) null); } + + res.add(rti); } return res; } @@ -994,7 +991,7 @@ class RecentTasks { final TaskRecord tr = mTasks.get(i); if (isVisibleRecentTask(tr)) { numVisibleTasks++; - if (isInVisibleRange(tr, numVisibleTasks)) { + if (isInVisibleRange(tr, numVisibleTasks, false /* skipExcludedCheck */)) { res.put(tr.taskId, true); } } @@ -1215,7 +1212,8 @@ class RecentTasks { continue; } else { numVisibleTasks++; - if (isInVisibleRange(task, numVisibleTasks) || !isTrimmable(task)) { + if (isInVisibleRange(task, numVisibleTasks, false /* skipExcludedCheck */) + || !isTrimmable(task)) { // Keep visible tasks in range i++; continue; @@ -1329,14 +1327,17 @@ class RecentTasks { /** * @return whether the given visible task is within the policy range. */ - private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks) { - // Keep the last most task even if it is excluded from recents - final boolean isExcludeFromRecents = - (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) - == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; - if (isExcludeFromRecents) { - if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); - return numVisibleTasks == 1; + private boolean isInVisibleRange(TaskRecord task, int numVisibleTasks, + boolean skipExcludedCheck) { + if (!skipExcludedCheck) { + // Keep the most recent task even if it is excluded from recents + final boolean isExcludeFromRecents = + (task.getBaseIntent().getFlags() & FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + == FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; + if (isExcludeFromRecents) { + if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\texcludeFromRecents=true"); + return numVisibleTasks == 1; + } } if (mMinNumVisibleTasks >= 0 && numVisibleTasks <= mMinNumVisibleTasks) { diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index 24cf7f127e18..46b5f3ab38f9 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 @@ class RootActivityContainer extends ConfigurationContainer } 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 @@ class RootActivityContainer extends ConfigurationContainer * 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 @@ class RootActivityContainer extends ConfigurationContainer 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 e0d85e876476..4379b7cdace6 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 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { 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 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable { 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 beb3d82c05fb..6fe8b43db139 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 @@ class TaskSnapshotController { 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 dddc6b755db0..166a33d7a560 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.WindowManagerDebugConfig.TAG_WM; 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 @@ class WallpaperController { 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 63dca62104a1..d5fbd2b316e7 100644 --- a/services/core/jni/com_android_server_VibratorService.cpp +++ b/services/core/jni/com_android_server_VibratorService.cpp @@ -96,7 +96,7 @@ bool isValidEffect(jlong effect) { } 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 @@ static jlong vibratorPerformEffect(JNIEnv*, jobject, jlong effect, jint strength } 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/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 65a7eec60f63..7df7ef3bae87 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -998,8 +998,9 @@ struct GnssMeasurementCallback : public IGnssMeasurementCallback_V2_0 { template<class T> size_t getMeasurementCount(const T& data); - jobject translateGnssClock( - JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock); + template<class T> + void translateGnssClock(JavaObject& object, const T& data); + void setMeasurementData(JNIEnv* env, jobject clock, jobjectArray measurementArray); }; @@ -1025,12 +1026,12 @@ template<class T> void GnssMeasurementCallback::translateAndSetGnssData(const T& data) { JNIEnv* env = getJniEnv(); - jobject clock; - jobjectArray measurementArray; + JavaObject gnssClockJavaObject(env, "android/location/GnssClock"); + translateGnssClock(gnssClockJavaObject, data); + jobject clock = gnssClockJavaObject.get(); - clock = translateGnssClock(env, &data.clock); size_t count = getMeasurementCount(data); - measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count); + jobjectArray measurementArray = translateAllGnssMeasurements(env, data.measurements.data(), count); setMeasurementData(env, clock, measurementArray); env->DeleteLocalRef(clock); @@ -1124,43 +1125,59 @@ void GnssMeasurementCallback::translateSingleGnssMeasurement SET(ConstellationType, static_cast<int32_t>(measurement_V2_0->constellation)); } -jobject GnssMeasurementCallback::translateGnssClock( - JNIEnv* env, const IGnssMeasurementCallback_V1_0::GnssClock* clock) { - JavaObject object(env, "android/location/GnssClock"); +template<class T> +void GnssMeasurementCallback::translateGnssClock(JavaObject& object, const T& data) { + translateGnssClock(object, data.clock); +} - uint32_t flags = static_cast<uint32_t>(clock->gnssClockFlags); +template<> +void GnssMeasurementCallback::translateGnssClock( + JavaObject& object, const IGnssMeasurementCallback_V1_0::GnssClock& clock) { + uint32_t flags = static_cast<uint32_t>(clock.gnssClockFlags); if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_LEAP_SECOND)) { - SET(LeapSecond, static_cast<int32_t>(clock->leapSecond)); + SET(LeapSecond, static_cast<int32_t>(clock.leapSecond)); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_TIME_UNCERTAINTY)) { - SET(TimeUncertaintyNanos, clock->timeUncertaintyNs); + SET(TimeUncertaintyNanos, clock.timeUncertaintyNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_FULL_BIAS)) { - SET(FullBiasNanos, clock->fullBiasNs); + SET(FullBiasNanos, clock.fullBiasNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS)) { - SET(BiasNanos, clock->biasNs); + SET(BiasNanos, clock.biasNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_BIAS_UNCERTAINTY)) { - SET(BiasUncertaintyNanos, clock->biasUncertaintyNs); + SET(BiasUncertaintyNanos, clock.biasUncertaintyNs); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT)) { - SET(DriftNanosPerSecond, clock->driftNsps); + SET(DriftNanosPerSecond, clock.driftNsps); } if (flags & static_cast<uint32_t>(GnssClockFlags::HAS_DRIFT_UNCERTAINTY)) { - SET(DriftUncertaintyNanosPerSecond, clock->driftUncertaintyNsps); + SET(DriftUncertaintyNanosPerSecond, clock.driftUncertaintyNsps); } - SET(TimeNanos, clock->timeNs); - SET(HardwareClockDiscontinuityCount, clock->hwClockDiscontinuityCount); + SET(TimeNanos, clock.timeNs); + SET(HardwareClockDiscontinuityCount, clock.hwClockDiscontinuityCount); +} - return object.get(); +template<> +void GnssMeasurementCallback::translateGnssClock( + JavaObject& object, const IGnssMeasurementCallback_V2_0::GnssData& data) { + auto elapsedRealtime = data.elapsedRealtime; + uint16_t flags = static_cast<uint16_t>(elapsedRealtime.flags); + if (flags & ElapsedRealtimeFlags::HAS_TIMESTAMP_NS) { + SET(ElapsedRealtimeNanos, static_cast<uint64_t>(elapsedRealtime.timestampNs)); + } + if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) { + SET(ElapsedRealtimeUncertaintyNanos, static_cast<uint64_t>(elapsedRealtime.timeUncertaintyNs)); + } + translateGnssClock(object, data.clock); } template<class T> diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2d014718a47b..633367ab2fe8 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 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { 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 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // 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 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } 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 419f52cff578..d4ccb0b77bca 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -849,7 +849,7 @@ public final class SystemServer { 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 @@ public final class SystemServer { 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 2e5efbd1deef..212d2a845254 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 @@ public class BatterySaverStateMachineTest { 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 @@ public class BatterySaverStateMachineTest { @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 @@ public class BatterySaverStateMachineTest { .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 @@ public class BatterySaverStateMachineTest { @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 @@ public class BatterySaverStateMachineTest { // 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 @@ public class BatterySaverStateMachineTest { // 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 index 149428443fa1..4a9dd9776a1b 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 94d21ddeaa2b..ca4330fa7a5d 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 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { 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 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { 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 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { 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 @@ public class CachedSyntheticPasswordTests extends SyntheticPasswordTests { 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 6e0ba3cb366c..255e694bffaf 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { // 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { 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 6a07a45ed360..58055e58fce3 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { : 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { "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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { // 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 class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 @@ public class SyntheticPasswordTests extends BaseLockSettingsServiceTests { 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 a8da80efa35f..426122a830f1 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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { 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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { 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 23bae8881aa1..de4fb9855bc4 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.os.SystemClock; 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 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnIntentStarted() throws Exception { Intent intent = new Intent("action 1"); @@ -128,6 +130,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnIntentFailed() throws Exception { testOnIntentStarted(); @@ -143,6 +146,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunched() throws Exception { testOnIntentStarted(); @@ -154,6 +158,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchFinished() throws Exception { testOnActivityLaunched(); @@ -168,6 +173,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchCancelled() throws Exception { testOnActivityLaunched(); @@ -181,6 +187,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchedTrampoline() throws Exception { testOnIntentStarted(); @@ -197,6 +204,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchFinishedTrampoline() throws Exception { testOnActivityLaunchedTrampoline(); @@ -211,6 +219,7 @@ public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase { } @Test + @FlakyTest(bugId = 129138370) public void testOnActivityLaunchCancelledTrampoline() throws Exception { testOnActivityLaunchedTrampoline(); diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java index 68e7470b8763..08e6ce4287a5 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java @@ -16,6 +16,7 @@ package com.android.server.wm; +import static android.app.ActivityManager.RECENT_WITH_EXCLUDED; import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; @@ -29,7 +30,9 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_DOCUMENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; @@ -512,6 +515,52 @@ public class RecentTasksTest extends ActivityTestsBase { } @Test + public void testVisibleTasks_excludedFromRecents_firstTaskNotVisible() { + // Create some set of tasks, some of which are visible and some are not + TaskRecord homeTask = setTaskActivityType( + createTaskBuilder("com.android.pkg1", ".HomeTask").build(), + ACTIVITY_TYPE_HOME); + homeTask.mUserSetupComplete = true; + mRecentTasks.add(homeTask); + TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTask1.mUserSetupComplete = true; + mRecentTasks.add(excludedTask1); + + // Expect that the first visible excluded-from-recents task is visible + assertGetRecentTasksOrder(0 /* flags */, excludedTask1); + } + + @Test + public void testVisibleTasks_excludedFromRecents_withExcluded() { + // Create some set of tasks, some of which are visible and some are not + TaskRecord t1 = createTaskBuilder("com.android.pkg1", ".Task1").build(); + t1.mUserSetupComplete = true; + mRecentTasks.add(t1); + TaskRecord homeTask = setTaskActivityType( + createTaskBuilder("com.android.pkg1", ".HomeTask").build(), + ACTIVITY_TYPE_HOME); + homeTask.mUserSetupComplete = true; + mRecentTasks.add(homeTask); + TaskRecord excludedTask1 = createTaskBuilder(".ExcludedTask1") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTask1.mUserSetupComplete = true; + mRecentTasks.add(excludedTask1); + TaskRecord excludedTask2 = createTaskBuilder(".ExcludedTask2") + .setFlags(FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) + .build(); + excludedTask2.mUserSetupComplete = true; + mRecentTasks.add(excludedTask2); + TaskRecord t2 = createTaskBuilder("com.android.pkg2", ".Task1").build(); + t2.mUserSetupComplete = true; + mRecentTasks.add(t2); + + assertGetRecentTasksOrder(RECENT_WITH_EXCLUDED, t2, excludedTask2, excludedTask1, t1); + } + + @Test public void testVisibleTasks_minNum() { mRecentTasks.setOnlyTestVisibleRange(); mRecentTasks.setParameters(5 /* min */, -1 /* max */, 25 /* ms */); @@ -830,7 +879,7 @@ public class RecentTasksTest extends ActivityTestsBase { } /** - * Ensures that the recent tasks list is in the provided order. Note that the expected tasks + * Ensures that the raw recent tasks list is in the provided order. Note that the expected tasks * should be ordered from least to most recent. */ private void assertRecentTasksOrder(TaskRecord... expectedTasks) { @@ -841,6 +890,22 @@ public class RecentTasksTest extends ActivityTestsBase { } } + /** + * Ensures that the recent tasks list is in the provided order. Note that the expected tasks + * should be ordered from least to most recent. + */ + private void assertGetRecentTasksOrder(int getRecentTaskFlags, TaskRecord... expectedTasks) { + doNothing().when(mRecentTasks).loadUserRecentsLocked(anyInt()); + doReturn(true).when(mRecentTasks).isUserRunning(anyInt(), anyInt()); + List<RecentTaskInfo> infos = mRecentTasks.getRecentTasks(MAX_VALUE, getRecentTaskFlags, + true /* getTasksAllowed */, false /* getDetailedTasks */, + TEST_USER_0_ID, 0).getList(); + assertTrue(expectedTasks.length == infos.size()); + for (int i = 0; i < infos.size(); i++) { + assertTrue(expectedTasks[i].taskId == infos.get(i).taskId); + } + } + private void assertNotRestoreTask(Runnable action) { // Verify stack count doesn't change because task with fullscreen mode and standard type // would have its own stack. @@ -1018,7 +1083,7 @@ public class RecentTasksTest extends ActivityTestsBase { @Override protected RecentTasks createRecentTasks() { - return new TestRecentTasks(this, mTaskPersister); + return spy(new TestRecentTasks(this, mTaskPersister)); } @Override diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java index 81553a3bc0f8..afa35b4d4de3 100644 --- a/telephony/java/android/telephony/AccessNetworkConstants.java +++ b/telephony/java/android/telephony/AccessNetworkConstants.java @@ -18,6 +18,7 @@ package android.telephony; 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 @@ public final class AccessNetworkConstants { * @hide */ @SystemApi + @TestApi public static final int TRANSPORT_TYPE_WWAN = 1; /** @@ -58,6 +60,7 @@ public final class AccessNetworkConstants { * @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 5f9ef3c0c601..0a9b90465a48 100755 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1543,6 +1543,21 @@ public class CarrierConfigManager { "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 @@ public class CarrierConfigManager { "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 @@ -2667,6 +2702,14 @@ public class CarrierConfigManager { "cdma_enhanced_roaming_indicator_for_home_network_int_array"; /** + * Determines whether wifi calling location privacy policy is shown. + * + * @hide + */ + public static final String KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL = + "show_wfc_location_privacy_policy_bool"; + + /** * Indicates use 3GPP application to replace 3GPP2 application even if it's a CDMA/CDMA-LTE * phone, becasue some carriers's CSIM application is present but not supported. * @hide @@ -2917,6 +2960,7 @@ public class CarrierConfigManager { 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 +3026,9 @@ public class CarrierConfigManager { 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); @@ -3073,6 +3119,7 @@ public class CarrierConfigManager { }); sDefaults.putStringArray(KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY, new String[0]); sDefaults.putBoolean(KEY_USE_USIM_BOOL, false); + sDefaults.putBoolean(KEY_SHOW_WFC_LOCATION_PRIVACY_POLICY_BOOL, true); sDefaults.putBoolean(KEY_AUTO_CANCEL_CS_REJECT_NOTIFICATION, false); sDefaults.putBoolean(KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN, false); diff --git a/telephony/java/android/telephony/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index 8eb345ac258a..fbf488e590fd 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 @@ import java.util.Objects; * @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 @@ public final class DataSpecificRegistrationStates implements Parcelable{ /** * 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 @@ public final class DataSpecificRegistrationStates implements Parcelable{ dest.writeBoolean(isDcNrRestricted); dest.writeBoolean(isNrAvailable); dest.writeBoolean(isEnDcAvailable); - lteVopsSupportInfo.writeToParcel(dest, flags); + mLteVopsSupportInfo.writeToParcel(dest, flags); } @Override @@ -98,7 +116,7 @@ public final class DataSpecificRegistrationStates implements Parcelable{ .append(" isDcNrRestricted = " + isDcNrRestricted) .append(" isNrAvailable = " + isNrAvailable) .append(" isEnDcAvailable = " + isEnDcAvailable) - .append(lteVopsSupportInfo.toString()) + .append(mLteVopsSupportInfo.toString()) .append(" }") .toString(); } @@ -106,41 +124,41 @@ public final class DataSpecificRegistrationStates implements Parcelable{ @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 ee45f0761e0b..ec9f078367b8 100644 --- a/telephony/java/android/telephony/LteVopsSupportInfo.java +++ b/telephony/java/android/telephony/LteVopsSupportInfo.java @@ -18,6 +18,7 @@ package android.telephony; import android.annotation.IntDef; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -30,6 +31,7 @@ import java.util.Objects; * @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 9145b2532817..1dc29979dc61 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -20,6 +20,7 @@ import android.annotation.IntDef; 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 @@ import java.util.stream.Collectors; * @hide */ @SystemApi +@TestApi public final class NetworkRegistrationInfo implements Parcelable { /** * Network domain @@ -174,10 +176,10 @@ public final class NetworkRegistrationInfo implements Parcelable { 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 @@ public final class NetworkRegistrationInfo implements Parcelable { 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 @@ public final class NetworkRegistrationInfo implements Parcelable { 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 @@ public final class NetworkRegistrationInfo implements Parcelable { 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 @@ public final class NetworkRegistrationInfo implements Parcelable { * @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 @@ public final class NetworkRegistrationInfo implements Parcelable { ? 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 final class NetworkRegistrationInfo implements Parcelable { 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 @@ public final class NetworkRegistrationInfo implements Parcelable { && 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 @@ public final class NetworkRegistrationInfo implements Parcelable { 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 @@ public final class NetworkRegistrationInfo implements Parcelable { * * @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 df31f50d28a4..a794ba12f202 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -1132,7 +1132,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + @TestApi public void setVoiceRoamingType(@RoamingType int type) { NetworkRegistrationInfo regState = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); @@ -1153,7 +1153,7 @@ public class ServiceState implements Parcelable { } /** @hide */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) + @TestApi public void setDataRoamingType(@RoamingType int type) { NetworkRegistrationInfo regState = getNetworkRegistrationInfo( NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN); @@ -1855,6 +1855,7 @@ public class ServiceState implements Parcelable { /** * @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 0d4d654ae25c..5df7bf717aed 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -7082,6 +7082,35 @@ public class TelephonyManager { } /** + * 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 index d8ce5b43e4d6..18a533a46273 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 @@ import java.util.Objects; * 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 class VoiceSpecificRegistrationStates implements Parcelable{ */ 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 @@ public class VoiceSpecificRegistrationStates implements Parcelable{ @Override public String toString() { - return "VoiceSpecificRegistrationStates {" + return "VoiceSpecificRegistrationInfo {" + " mCssSupported=" + cssSupported + " mRoamingIndicator=" + roamingIndicator + " mSystemIsInPrl=" + systemIsInPrl @@ -87,11 +104,11 @@ public class VoiceSpecificRegistrationStates implements Parcelable{ 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 class VoiceSpecificRegistrationStates implements Parcelable{ } - 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 10cc99e3e98e..d98f8d832166 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1707,6 +1707,11 @@ interface ITelephony { */ 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 6765316a304b..a87e2f57bb5f 100644 --- a/test-mock/api/test-current.txt +++ b/test-mock/api/test-current.txt @@ -3,6 +3,7 @@ package android.test.mock { 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/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp index 5725f0cdae6e..4ce4406211ce 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -31,6 +31,7 @@ cc_binary_host { shared_libs: [ "libstats_proto_host", "libprotobuf-cpp-full", + "libbase", ], proto: { diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp index a8d970edaa85..e66ead7ec340 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -49,7 +49,9 @@ AtomDecl::AtomDecl(const AtomDecl& that) exclusiveField(that.exclusiveField), uidField(that.uidField), whitelisted(that.whitelisted), - binaryFields(that.binaryFields) {} + binaryFields(that.binaryFields), + hasModule(that.hasModule), + moduleName(that.moduleName) {} AtomDecl::AtomDecl(int c, const string& n, const string& m) :code(c), @@ -391,7 +393,12 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { AtomDecl atomDecl(atomField->number(), atomField->name(), atom->name()); if (atomField->options().GetExtension(os::statsd::allow_from_any_uid) == true) { - atomDecl.whitelisted = true; + atomDecl.whitelisted = true; + } + + if (atomField->options().HasExtension(os::statsd::log_from_module)) { + atomDecl.hasModule = true; + atomDecl.moduleName = atomField->options().GetExtension(os::statsd::log_from_module); } vector<java_type_t> signature; @@ -399,25 +406,49 @@ int collate_atoms(const Descriptor *descriptor, Atoms *atoms) { if (atomDecl.primaryFields.size() != 0 && atomDecl.exclusiveField == 0) { errorCount++; } - atoms->signatures.insert(signature); + + // Add the signature if does not already exist. + auto signature_to_modules_it = atoms->signatures_to_modules.find(signature); + if (signature_to_modules_it == atoms->signatures_to_modules.end()) { + set<string> modules; + if (atomDecl.hasModule) { + modules.insert(atomDecl.moduleName); + } + atoms->signatures_to_modules[signature] = modules; + } else { + if (atomDecl.hasModule) { + signature_to_modules_it->second.insert(atomDecl.moduleName); + } + } atoms->decls.insert(atomDecl); AtomDecl nonChainedAtomDecl(atomField->number(), atomField->name(), atom->name()); vector<java_type_t> nonChainedSignature; if (get_non_chained_node(atom, &nonChainedAtomDecl, &nonChainedSignature)) { - atoms->non_chained_signatures.insert(nonChainedSignature); + auto it = atoms->non_chained_signatures_to_modules.find(signature); + if (it == atoms->non_chained_signatures_to_modules.end()) { + set<string> modules_non_chained; + if (atomDecl.hasModule) { + modules_non_chained.insert(atomDecl.moduleName); + } + atoms->non_chained_signatures_to_modules[nonChainedSignature] = modules_non_chained; + } else { + if (atomDecl.hasModule) { + it->second.insert(atomDecl.moduleName); + } + } atoms->non_chained_decls.insert(nonChainedAtomDecl); } } if (dbg) { printf("signatures = [\n"); - for (set<vector<java_type_t>>::const_iterator it = - atoms->signatures.begin(); - it != atoms->signatures.end(); it++) { + for (map<vector<java_type_t>, set<string>>::const_iterator it = + atoms->signatures_to_modules.begin(); + it != atoms->signatures_to_modules.end(); it++) { printf(" "); - for (vector<java_type_t>::const_iterator jt = it->begin(); - jt != it->end(); jt++) { + for (vector<java_type_t>::const_iterator jt = it->first.begin(); + jt != it->first.end(); jt++) { printf(" %d", (int)*jt); } printf("\n"); diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h index 6b86b862dfad..44746c96df1b 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -93,6 +93,9 @@ struct AtomDecl { vector<int> binaryFields; + bool hasModule = false; + string moduleName; + AtomDecl(); AtomDecl(const AtomDecl& that); AtomDecl(int code, const string& name, const string& message); @@ -104,10 +107,10 @@ struct AtomDecl { }; struct Atoms { - set<vector<java_type_t>> signatures; + map<vector<java_type_t>, set<string>> signatures_to_modules; set<AtomDecl> decls; set<AtomDecl> non_chained_decls; - set<vector<java_type_t>> non_chained_signatures; + map<vector<java_type_t>, set<string>> non_chained_signatures_to_modules; }; /** diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp index 0270c72ff240..daee6d6be048 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -12,6 +12,8 @@ #include <stdlib.h> #include <string.h> +#include "android-base/strings.h" + using namespace google::protobuf; using namespace std; @@ -20,6 +22,10 @@ namespace stats_log_api_gen { int maxPushedAtomId = 2; +const string DEFAULT_MODULE_NAME = "DEFAULT"; +const string DEFAULT_CPP_NAMESPACE = "android,util"; +const string DEFAULT_CPP_HEADER_IMPORT = "statslog.h"; + using android::os::statsd::Atom; /** @@ -97,40 +103,27 @@ java_type_name(java_type_t type) } } -static int write_stats_log_cpp(FILE *out, const Atoms &atoms, - const AtomDecl &attributionDecl) { - // Print prelude - fprintf(out, "// This file is autogenerated\n"); - fprintf(out, "\n"); - - fprintf(out, "#include <mutex>\n"); - fprintf(out, "#include <chrono>\n"); - fprintf(out, "#include <thread>\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "#include <cutils/properties.h>\n"); - fprintf(out, "#endif\n"); - fprintf(out, "#include <stats_event_list.h>\n"); - fprintf(out, "#include <log/log.h>\n"); - fprintf(out, "#include <statslog.h>\n"); - fprintf(out, "#include <utils/SystemClock.h>\n"); - fprintf(out, "\n"); +static bool atom_needed_for_module(const AtomDecl& atomDecl, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return atomDecl.hasModule && (moduleName == atomDecl.moduleName); +} - fprintf(out, "namespace android {\n"); - fprintf(out, "namespace util {\n"); - fprintf(out, "// the single event tag id for all stats logs\n"); - fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); - fprintf(out, "#ifdef __ANDROID__\n"); - fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); - fprintf(out, "#else\n"); - fprintf(out, "const static bool kStatsdEnabled = false;\n"); - fprintf(out, "#endif\n"); +static bool signature_needed_for_module(const set<string>& modules, const string& moduleName) { + if (moduleName == DEFAULT_MODULE_NAME) { + return true; + } + return modules.find(moduleName) != modules.end(); +} +static void write_atoms_info_cpp(FILE *out, const Atoms &atoms) { std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed", - "audio_state_changed", - "call_state_changed", - "phone_signal_strength_changed", - "mobile_bytes_transfer_by_fg_bg", - "mobile_bytes_transfer"}; + "audio_state_changed", + "call_state_changed", + "phone_signal_strength_changed", + "mobile_bytes_transfer_by_fg_bg", + "mobile_bytes_transfer"}; fprintf(out, "const std::set<int> " "AtomsInfo::kNotTruncatingTimestampAtomWhiteList = {\n"); @@ -256,6 +249,56 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, "const std::map<int, std::vector<int>> " "AtomsInfo::kBytesFieldAtoms = " "getBinaryFieldAtoms();\n"); +} + +// Writes namespaces for the cpp and header files, returning the number of namespaces written. +void write_namespace(FILE* out, const string& cppNamespaces) { + vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); + for (string cppNamespace : cppNamespaceVec) { + fprintf(out, "namespace %s {\n", cppNamespace.c_str()); + } +} + +// Writes namespace closing brackets for cpp and header files. +void write_closing_namespace(FILE* out, const string& cppNamespaces) { + vector<string> cppNamespaceVec = android::base::Split(cppNamespaces, ","); + for (auto it = cppNamespaceVec.rbegin(); it != cppNamespaceVec.rend(); ++it) { + fprintf(out, "} // namespace %s\n", it->c_str()); + } +} + +static int write_stats_log_cpp(FILE *out, const Atoms &atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace, + const string& importHeader) { + // Print prelude + fprintf(out, "// This file is autogenerated\n"); + fprintf(out, "\n"); + + fprintf(out, "#include <mutex>\n"); + fprintf(out, "#include <chrono>\n"); + fprintf(out, "#include <thread>\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, "#include <cutils/properties.h>\n"); + fprintf(out, "#endif\n"); + fprintf(out, "#include <stats_event_list.h>\n"); + fprintf(out, "#include <log/log.h>\n"); + fprintf(out, "#include <%s>\n", importHeader.c_str()); + fprintf(out, "#include <utils/SystemClock.h>\n"); + fprintf(out, "\n"); + + write_namespace(out, cppNamespace); + fprintf(out, "// the single event tag id for all stats logs\n"); + fprintf(out, "const static int kStatsEventTag = 1937006964;\n"); + fprintf(out, "#ifdef __ANDROID__\n"); + fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n"); + fprintf(out, "#else\n"); + fprintf(out, "const static bool kStatsdEnabled = false;\n"); + fprintf(out, "#endif\n"); + + // AtomsInfo is only used by statsd internally and is not needed for other modules. + if (moduleName == DEFAULT_MODULE_NAME) { + write_atoms_info_cpp(out, atoms); + } fprintf(out, "int64_t lastRetryTimestampNs = -1;\n"); fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n"); @@ -263,15 +306,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, // Print write methods fprintf(out, "\n"); - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "try_stats_write(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -303,8 +350,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " stats_event_list event(kStatsEventTag);\n"); fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (const auto &chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -387,15 +434,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, "\n"); } - for (set<vector<java_type_t>>::const_iterator signature = atoms.signatures.begin(); - signature != atoms.signatures.end(); signature++) { + for (auto signature_to_modules_it = atoms.signatures_to_modules.begin(); + signature_to_modules_it != atoms.signatures_to_modules.end(); signature_to_modules_it++) { + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_to_modules_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "stats_write(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -429,8 +480,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " ret = try_stats_write(code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -468,15 +519,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, "\n"); } - for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin(); - signature != atoms.non_chained_signatures.end(); signature++) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "try_stats_write_non_chained(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); argIndex++; } @@ -488,8 +543,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " stats_event_list event(kStatsEventTag);\n"); fprintf(out, " event << android::elapsedRealtimeNano();\n\n"); fprintf(out, " event << code;\n\n"); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (argIndex == 1) { fprintf(out, " event.begin();\n\n"); fprintf(out, " event.begin();\n"); @@ -522,15 +577,19 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, "\n"); } - for (set<vector<java_type_t>>::const_iterator signature = atoms.non_chained_signatures.begin(); - signature != atoms.non_chained_signatures.end(); signature++) { + for (auto signature_it = atoms.non_chained_signatures_to_modules.begin(); + signature_it != atoms.non_chained_signatures_to_modules.end(); signature_it++) { + if (!signature_needed_for_module(signature_it->second, moduleName)) { + continue; + } + vector<java_type_t> signature = signature_it->first; int argIndex; fprintf(out, "int\n"); fprintf(out, "stats_write_non_chained(int32_t code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex); argIndex++; } @@ -543,8 +602,8 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, fprintf(out, " ret = try_stats_write_non_chained(code"); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { fprintf(out, ", arg%d", argIndex); argIndex++; } @@ -572,8 +631,7 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, // Print footer fprintf(out, "\n"); - fprintf(out, "} // namespace util\n"); - fprintf(out, "} // namespace android\n"); + write_closing_namespace(out, cppNamespace); return 0; } @@ -623,14 +681,23 @@ static void write_cpp_usage( } static void write_cpp_method_header( - FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures, - const AtomDecl &attributionDecl) { - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + FILE* out, + const string& method_name, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl, const string& moduleName) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + // Skip if this signature is not needed for the module. + if (!signature_needed_for_module(signature_to_modules_it->second, moduleName)) { + continue; + } + + vector<java_type_t> signature = signature_to_modules_it->first; fprintf(out, "int %s(int32_t code", method_name.c_str()); int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_STRING) { @@ -659,7 +726,8 @@ static void write_cpp_method_header( } static int -write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl) +write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributionDecl, + const string& moduleName, const string& cppNamespace) { // Print prelude fprintf(out, "// This file is autogenerated\n"); @@ -672,8 +740,7 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "#include <set>\n"); fprintf(out, "\n"); - fprintf(out, "namespace android {\n"); - fprintf(out, "namespace util {\n"); + write_namespace(out, cppNamespace); fprintf(out, "\n"); fprintf(out, "/*\n"); fprintf(out, " * API For logging statistics events.\n"); @@ -691,6 +758,10 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio // Print atom constants for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } string constant = make_constant_name(atom->name); fprintf(out, "\n"); fprintf(out, " /**\n"); @@ -720,6 +791,11 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "//\n\n"); for (set<AtomDecl>::const_iterator atom = atoms.decls.begin(); atom != atoms.decls.end(); atom++) { + // Skip if the atom is not needed for the module. + if (!atom_needed_for_module(*atom, moduleName)) { + continue; + } + for (vector<AtomField>::const_iterator field = atom->fields.begin(); field != atom->fields.end(); field++) { if (field->javaType == JAVA_TYPE_ENUM) { @@ -747,47 +823,51 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio fprintf(out, "};\n"); fprintf(out, "\n"); - fprintf(out, "struct StateAtomFieldOptions {\n"); - fprintf(out, " std::vector<int> primaryFields;\n"); - fprintf(out, " int exclusiveField;\n"); - fprintf(out, "};\n"); - fprintf(out, "\n"); + // This metadata is only used by statsd, which uses the default libstatslog. + if (moduleName == DEFAULT_MODULE_NAME) { - fprintf(out, "struct AtomsInfo {\n"); - fprintf(out, - " const static std::set<int> " - "kNotTruncatingTimestampAtomWhiteList;\n"); - fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); - fprintf(out, - " const static std::set<int> kAtomsWithAttributionChain;\n"); - fprintf(out, - " const static std::map<int, StateAtomFieldOptions> " - "kStateAtomsFieldOptions;\n"); - fprintf(out, - " const static std::map<int, std::vector<int>> " - "kBytesFieldAtoms;"); - fprintf(out, - " const static std::set<int> kWhitelistedAtoms;\n"); - fprintf(out, "};\n"); + fprintf(out, "struct StateAtomFieldOptions {\n"); + fprintf(out, " std::vector<int> primaryFields;\n"); + fprintf(out, " int exclusiveField;\n"); + fprintf(out, "};\n"); + fprintf(out, "\n"); - fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", - maxPushedAtomId); + fprintf(out, "struct AtomsInfo {\n"); + fprintf(out, + " const static std::set<int> " + "kNotTruncatingTimestampAtomWhiteList;\n"); + fprintf(out, " const static std::map<int, int> kAtomsWithUidField;\n"); + fprintf(out, + " const static std::set<int> kAtomsWithAttributionChain;\n"); + fprintf(out, + " const static std::map<int, StateAtomFieldOptions> " + "kStateAtomsFieldOptions;\n"); + fprintf(out, + " const static std::map<int, std::vector<int>> " + "kBytesFieldAtoms;"); + fprintf(out, + " const static std::set<int> kWhitelistedAtoms;\n"); + fprintf(out, "};\n"); + + fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n", + maxPushedAtomId); + } // Print write methods fprintf(out, "//\n"); fprintf(out, "// Write methods\n"); fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write", atoms.signatures, attributionDecl); + write_cpp_method_header(out, "stats_write", atoms.signatures_to_modules, attributionDecl, + moduleName); fprintf(out, "//\n"); fprintf(out, "// Write flattened methods\n"); fprintf(out, "//\n"); - write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures, - attributionDecl); + write_cpp_method_header(out, "stats_write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl, moduleName); fprintf(out, "\n"); - fprintf(out, "} // namespace util\n"); - fprintf(out, "} // namespace android\n"); + write_closing_namespace(out, cppNamespace); return 0; } @@ -812,15 +892,19 @@ static void write_java_usage(FILE* out, const string& method_name, const string& } static void write_java_method( - FILE* out, const string& method_name, const set<vector<java_type_t>>& signatures, - const AtomDecl &attributionDecl) { - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + FILE* out, + const string& method_name, + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { + + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; fprintf(out, " /** @hide */\n"); fprintf(out, " public static native int %s(int code", method_name.c_str()); int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { fprintf(out, ", %s[] %s", @@ -837,15 +921,17 @@ static void write_java_method( } } -static void write_java_work_source_method(FILE* out, const set<vector<java_type_t>>& signatures) { +static void write_java_work_source_method(FILE* out, + const map<vector<java_type_t>, set<string>>& signatures_to_modules) { fprintf(out, "\n // WorkSource methods.\n"); - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; // Determine if there is Attribution in this signature. int attributionArg = -1; int argIndexMax = 0; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { argIndexMax++; if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { if (attributionArg > -1) { @@ -865,8 +951,8 @@ static void write_java_work_source_method(FILE* out, const set<vector<java_type_ fprintf(out, " /** @hide */\n"); fprintf(out, " public static void write(int code"); int argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { fprintf(out, ", WorkSource ws"); } else { @@ -974,9 +1060,10 @@ write_stats_log_java(FILE* out, const Atoms& atoms, const AtomDecl &attributionD // Print write methods fprintf(out, " // Write methods\n"); - write_java_method(out, "write", atoms.signatures, attributionDecl); - write_java_method(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl); - write_java_work_source_method(out, atoms.signatures); + write_java_method(out, "write", atoms.signatures_to_modules, attributionDecl); + write_java_method(out, "write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl); + write_java_work_source_method(out, atoms.signatures_to_modules); fprintf(out, "}\n"); @@ -1154,19 +1241,20 @@ static void write_key_value_map_jni(FILE* out) { static int write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp_method_name, - const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl) -{ + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { // Print write methods - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; int argIndex; fprintf(out, "static int\n"); fprintf(out, "%s(JNIEnv* env, jobject clazz UNUSED, jint code", - jni_function_name(java_method_name, *signature).c_str()); + jni_function_name(java_method_name, signature).c_str()); argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { fprintf(out, ", %s %s", jni_array_type_name(chainField.javaType), @@ -1187,8 +1275,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp argIndex = 1; bool hadStringOrChain = false; bool isKeyValuePairAtom = false; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_STRING) { hadStringOrChain = true; fprintf(out, " const char* str%d;\n", argIndex); @@ -1288,8 +1376,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp argIndex = 1; fprintf(out, "\n int ret = android::util::%s(code", cpp_method_name.c_str()); - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) { for (auto chainField : attributionDecl.fields) { if (chainField.javaType == JAVA_TYPE_INT) { @@ -1316,8 +1404,8 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp // Clean up strings argIndex = 1; - for (vector<java_type_t>::const_iterator arg = signature->begin(); - arg != signature->end(); arg++) { + for (vector<java_type_t>::const_iterator arg = signature.begin(); + arg != signature.end(); arg++) { if (*arg == JAVA_TYPE_STRING) { fprintf(out, " if (str%d != NULL) {\n", argIndex); fprintf(out, " env->ReleaseStringUTFChars(arg%d, str%d);\n", @@ -1357,13 +1445,15 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp } void write_jni_registration(FILE* out, const string& java_method_name, - const set<vector<java_type_t>>& signatures, const AtomDecl &attributionDecl) { - for (set<vector<java_type_t>>::const_iterator signature = signatures.begin(); - signature != signatures.end(); signature++) { + const map<vector<java_type_t>, set<string>>& signatures_to_modules, + const AtomDecl &attributionDecl) { + for (auto signature_to_modules_it = signatures_to_modules.begin(); + signature_to_modules_it != signatures_to_modules.end(); signature_to_modules_it++) { + vector<java_type_t> signature = signature_to_modules_it->first; fprintf(out, " { \"%s\", \"%s\", (void*)%s },\n", java_method_name.c_str(), - jni_function_signature(*signature, attributionDecl).c_str(), - jni_function_name(java_method_name, *signature).c_str()); + jni_function_signature(signature, attributionDecl).c_str(), + jni_function_name(java_method_name, signature).c_str()); } } @@ -1388,25 +1478,26 @@ write_stats_log_jni(FILE* out, const Atoms& atoms, const AtomDecl &attributionDe fprintf(out, "namespace android {\n"); fprintf(out, "\n"); - write_stats_log_jni(out, "write", "stats_write", atoms.signatures, attributionDecl); + write_stats_log_jni(out, "write", "stats_write", atoms.signatures_to_modules, attributionDecl); write_stats_log_jni(out, "write_non_chained", "stats_write_non_chained", - atoms.non_chained_signatures, attributionDecl); + atoms.non_chained_signatures_to_modules, attributionDecl); // Print registration function table fprintf(out, "/*\n"); fprintf(out, " * JNI registration.\n"); fprintf(out, " */\n"); fprintf(out, "static const JNINativeMethod gRegisterMethods[] = {\n"); - write_jni_registration(out, "write", atoms.signatures, attributionDecl); - write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures, attributionDecl); + write_jni_registration(out, "write", atoms.signatures_to_modules, attributionDecl); + write_jni_registration(out, "write_non_chained", atoms.non_chained_signatures_to_modules, + attributionDecl); fprintf(out, "};\n"); fprintf(out, "\n"); // Print registration function - fprintf(out, "int register_android_util_StatsLog(JNIEnv* env) {\n"); + fprintf(out, "int register_android_util_StatsLogInternal(JNIEnv* env) {\n"); fprintf(out, " return RegisterMethodsOrDie(\n"); fprintf(out, " env,\n"); - fprintf(out, " \"android/util/StatsLog\",\n"); + fprintf(out, " \"android/util/StatsLogInternal\",\n"); fprintf(out, " gRegisterMethods, NELEM(gRegisterMethods));\n"); fprintf(out, "}\n"); @@ -1426,6 +1517,10 @@ print_usage() fprintf(stderr, " --help this message\n"); fprintf(stderr, " --java FILENAME the java file to output\n"); fprintf(stderr, " --jni FILENAME the jni file to output\n"); + fprintf(stderr, " --module NAME optional, module name to generate outputs for\n"); + fprintf(stderr, " --namespace COMMA,SEP,NAMESPACE required for cpp/header with module\n"); + fprintf(stderr, " comma separated namespace of the files\n"); + fprintf(stderr, " --importHeader NAME required for cpp/jni to say which header to import\n"); } /** @@ -1439,6 +1534,10 @@ run(int argc, char const*const* argv) string javaFilename; string jniFilename; + string moduleName = DEFAULT_MODULE_NAME; + string cppNamespace = DEFAULT_CPP_NAMESPACE; + string cppHeaderImport = DEFAULT_CPP_HEADER_IMPORT; + int index = 1; while (index < argc) { if (0 == strcmp("--help", argv[index])) { @@ -1472,6 +1571,27 @@ run(int argc, char const*const* argv) return 1; } jniFilename = argv[index]; + } else if (0 == strcmp("--module", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + moduleName = argv[index]; + } else if (0 == strcmp("--namespace", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + cppNamespace = argv[index]; + } else if (0 == strcmp("--importHeader", argv[index])) { + index++; + if (index >= argc) { + print_usage(); + return 1; + } + cppHeaderImport = argv[index]; } index++; } @@ -1503,8 +1623,18 @@ run(int argc, char const*const* argv) fprintf(stderr, "Unable to open file for write: %s\n", cppFilename.c_str()); return 1; } + // If this is for a specific module, the namespace must also be provided. + if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) { + fprintf(stderr, "Must supply --namespace if supplying a specific module\n"); + return 1; + } + // If this is for a specific module, the header file to import must also be provided. + if (moduleName != DEFAULT_MODULE_NAME && cppHeaderImport == DEFAULT_CPP_HEADER_IMPORT) { + fprintf(stderr, "Must supply --headerImport if supplying a specific module\n"); + return 1; + } errorCount = android::stats_log_api_gen::write_stats_log_cpp( - out, atoms, attributionDecl); + out, atoms, attributionDecl, moduleName, cppNamespace, cppHeaderImport); fclose(out); } @@ -1515,8 +1645,12 @@ run(int argc, char const*const* argv) fprintf(stderr, "Unable to open file for write: %s\n", headerFilename.c_str()); return 1; } + // If this is for a specific module, the namespace must also be provided. + if (moduleName != DEFAULT_MODULE_NAME && cppNamespace == DEFAULT_CPP_NAMESPACE) { + fprintf(stderr, "Must supply --namespace if supplying a specific module\n"); + } errorCount = android::stats_log_api_gen::write_stats_log_header( - out, atoms, attributionDecl); + out, atoms, attributionDecl, moduleName, cppNamespace); fclose(out); } diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto index 24ebf4de031a..c3e703826be5 100644 --- a/tools/stats_log_api_gen/test.proto +++ b/tools/stats_log_api_gen/test.proto @@ -213,4 +213,24 @@ message ListedAtoms { // by whitelisted sources NonWhitelistedAtom non_whitelisted_atom = 2; } +} + +message ModuleOneAtom { + optional int32 field = 1; +} + +message ModuleTwoAtom { + optional int32 field = 1; +} + +message NoModuleAtom { + optional string field = 1; +} + +message ModuleAtoms { + oneof event { + ModuleOneAtom module_one_atom = 1 [(android.os.statsd.log_from_module) = "module1"]; + ModuleTwoAtom module_two_atom = 2 [(android.os.statsd.log_from_module) = "module2"]; + NoModuleAtom no_module_atom = 3; + } }
\ No newline at end of file diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp index dc585c1c5dd1..bcf18ae8bf19 100644 --- a/tools/stats_log_api_gen/test_collation.cpp +++ b/tools/stats_log_api_gen/test_collation.cpp @@ -32,7 +32,7 @@ using std::vector; * Return whether the set contains a vector of the elements provided. */ static bool -set_contains_vector(const set<vector<java_type_t>>& s, int count, ...) +set_contains_vector(const map<vector<java_type_t>, set<string>>& s, int count, ...) { va_list args; vector<java_type_t> v; @@ -86,17 +86,17 @@ TEST(CollationTest, CollateStats) { int errorCount = collate_atoms(Event::descriptor(), &atoms); EXPECT_EQ(0, errorCount); - EXPECT_EQ(3ul, atoms.signatures.size()); + EXPECT_EQ(3ul, atoms.signatures_to_modules.size()); // IntAtom, AnotherIntAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT); // OutOfOrderAtom - EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures, JAVA_TYPE_INT, JAVA_TYPE_INT); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT, JAVA_TYPE_INT); // AllTypesAtom EXPECT_SET_CONTAINS_SIGNATURE( - atoms.signatures, + atoms.signatures_to_modules, JAVA_TYPE_ATTRIBUTION_CHAIN, // AttributionChain JAVA_TYPE_DOUBLE, // double JAVA_TYPE_FLOAT, // float @@ -228,8 +228,7 @@ TEST(CollationTest, FailOnBadBinaryFieldAtom) { TEST(CollationTest, PassOnWhitelistedAtom) { Atoms atoms; - int errorCount = - collate_atoms(ListedAtoms::descriptor(), &atoms); + int errorCount = collate_atoms(ListedAtoms::descriptor(), &atoms); EXPECT_EQ(errorCount, 0); EXPECT_EQ(atoms.decls.size(), 2ul); } @@ -246,5 +245,46 @@ TEST(CollationTest, RecogniseWhitelistedAtom) { } } +TEST(CollationTest, PassOnLogFromModuleAtom) { + Atoms atoms; + int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms); + EXPECT_EQ(errorCount, 0); + EXPECT_EQ(atoms.decls.size(), 3ul); +} + +TEST(CollationTest, RecognizeModuleAtom) { + Atoms atoms; + int errorCount = collate_atoms(ModuleAtoms::descriptor(), &atoms); + EXPECT_EQ(errorCount, 0); + EXPECT_EQ(atoms.decls.size(), 3ul); + for (const auto& atomDecl: atoms.decls) { + if (atomDecl.code == 1) { + EXPECT_TRUE(atomDecl.hasModule); + EXPECT_EQ(atomDecl.moduleName, "module1"); + } else if (atomDecl.code == 2) { + EXPECT_TRUE(atomDecl.hasModule); + EXPECT_EQ(atomDecl.moduleName, "module2"); + } else { + EXPECT_FALSE(atomDecl.hasModule); + } + } + + EXPECT_EQ(atoms.signatures_to_modules.size(), 2u); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_INT); + EXPECT_SET_CONTAINS_SIGNATURE(atoms.signatures_to_modules, JAVA_TYPE_STRING); + for (auto signature_to_modules_it : atoms.signatures_to_modules) { + vector<java_type_t> signature = signature_to_modules_it.first; + if (signature[0] == JAVA_TYPE_STRING) { + EXPECT_EQ(signature_to_modules_it.second.size(), 0u); + } else if (signature[0] == JAVA_TYPE_INT) { + set<string> modules = signature_to_modules_it.second; + EXPECT_EQ(modules.size(), 2u); + // Assert that the set contains "module1" and "module2". + EXPECT_NE(modules.find("module1"), modules.end()); + EXPECT_NE(modules.find("module2"), modules.end()); + } + } +} + } // namespace stats_log_api_gen } // namespace android
\ No newline at end of file diff --git a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java index 01176f223fe2..e59516485112 100644 --- a/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java +++ b/wifi/java/android/net/wifi/WifiUsabilityStatsEntry.java @@ -345,7 +345,7 @@ public final class WifiUsabilityStatsEntry implements Parcelable { } /** 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 37d5f0ac1a8b..e1d82f8d3a09 100644 --- a/wifi/java/android/net/wifi/rtt/ResponderLocation.java +++ b/wifi/java/android/net/wifi/rtt/ResponderLocation.java @@ -1169,6 +1169,8 @@ public final class ResponderLocation implements Parcelable { * (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 @@ public final class ResponderLocation implements Parcelable { * (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 cd60f029dcce..5184152bce34 100644 --- a/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java +++ b/wifi/tests/src/android/net/wifi/WifiUsabilityStatsEntryTest.java @@ -116,6 +116,6 @@ public class WifiUsabilityStatsEntryTest { assertEquals(expected.getCellularSignalStrengthDbm(), actual.getCellularSignalStrengthDbm()); assertEquals(expected.getCellularSignalStrengthDb(), actual.getCellularSignalStrengthDb()); - assertEquals(expected.getIsSameRegisteredCell(), actual.getIsSameRegisteredCell()); + assertEquals(expected.isSameRegisteredCell(), actual.isSameRegisteredCell()); } } |