Merge "Fix issue with animations that couldn't be started" into pi-dev
diff --git a/Android.mk b/Android.mk
index e2f88e8..b630c3f 100644
--- a/Android.mk
+++ b/Android.mk
@@ -869,11 +869,27 @@
$(eval $(call copy-one-file,frameworks/base/config/hiddenapi-blacklist.txt,\
$(INTERNAL_PLATFORM_HIDDENAPI_BLACKLIST)))
+# Automatically add all methods which match the following signatures.
+# These need to be greylisted in order to allow applications to write their
+# own serializers.
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): REGEX_SERIALIZATION := \
+ "readObject\(Ljava/io/ObjectInputStream;\)V" \
+ "readObjectNoData\(\)V" \
+ "readResolve\(\)Ljava/lang/Object;" \
+ "serialVersionUID:J" \
+ "serialPersistentFields:\[Ljava/io/ObjectStreamField;" \
+ "writeObject\(Ljava/io/ObjectOutputStream;\)V" \
+ "writeReplace\(\)Ljava/lang/Object;"
+$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): PRIVATE_API := $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
# Temporarily merge light greylist from two files. Vendor list will become dark
# grey once we remove the UI toast.
$(INTERNAL_PLATFORM_HIDDENAPI_LIGHT_GREYLIST): frameworks/base/config/hiddenapi-light-greylist.txt \
- frameworks/base/config/hiddenapi-vendor-list.txt
- sort $^ > $@
+ frameworks/base/config/hiddenapi-vendor-list.txt \
+ $(INTERNAL_PLATFORM_PRIVATE_DEX_API_FILE)
+ sort frameworks/base/config/hiddenapi-light-greylist.txt \
+ frameworks/base/config/hiddenapi-vendor-list.txt \
+ <(grep -E "\->("$(subst $(space),"|",$(REGEX_SERIALIZATION))")$$" $(PRIVATE_API)) \
+ > $@
# Generate dark greylist as private API minus (blacklist plus light greylist).
diff --git a/api/current.txt b/api/current.txt
index be5e3e7..dda00ba 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6261,6 +6261,7 @@
method public void addOnColorsChangedListener(android.app.WallpaperManager.OnColorsChangedListener, android.os.Handler);
method public void clear() throws java.io.IOException;
method public void clear(int) throws java.io.IOException;
+ method public void clearWallpaper();
method public void clearWallpaperOffsets(android.os.IBinder);
method public void forgetLoadedWallpaper();
method public android.graphics.drawable.Drawable getBuiltInDrawable();
@@ -6287,6 +6288,7 @@
method public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean) throws java.io.IOException;
method public int setBitmap(android.graphics.Bitmap, android.graphics.Rect, boolean, int) throws java.io.IOException;
+ method public void setDisplayPadding(android.graphics.Rect);
method public void setResource(int) throws java.io.IOException;
method public int setResource(int, int) throws java.io.IOException;
method public void setStream(java.io.InputStream) throws java.io.IOException;
@@ -7041,7 +7043,8 @@
method public int getBackoffPolicy();
method public android.content.ClipData getClipData();
method public int getClipGrantFlags();
- method public long getEstimatedNetworkBytes();
+ method public long getEstimatedNetworkDownloadBytes();
+ method public long getEstimatedNetworkUploadBytes();
method public android.os.PersistableBundle getExtras();
method public long getFlexMillis();
method public int getId();
@@ -7058,8 +7061,10 @@
method public long getTriggerContentMaxDelay();
method public long getTriggerContentUpdateDelay();
method public android.app.job.JobInfo.TriggerContentUri[] getTriggerContentUris();
+ method public boolean isImportantWhileForeground();
method public boolean isPeriodic();
method public boolean isPersisted();
+ method public boolean isPrefetch();
method public boolean isRequireBatteryNotLow();
method public boolean isRequireCharging();
method public boolean isRequireDeviceIdle();
@@ -7085,15 +7090,15 @@
method public android.app.job.JobInfo build();
method public android.app.job.JobInfo.Builder setBackoffCriteria(long, int);
method public android.app.job.JobInfo.Builder setClipData(android.content.ClipData, int);
- method public android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long);
+ method public android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long, long);
method public android.app.job.JobInfo.Builder setExtras(android.os.PersistableBundle);
method public android.app.job.JobInfo.Builder setImportantWhileForeground(boolean);
- method public android.app.job.JobInfo.Builder setIsPrefetch(boolean);
method public android.app.job.JobInfo.Builder setMinimumLatency(long);
method public android.app.job.JobInfo.Builder setOverrideDeadline(long);
method public android.app.job.JobInfo.Builder setPeriodic(long);
method public android.app.job.JobInfo.Builder setPeriodic(long, long);
method public android.app.job.JobInfo.Builder setPersisted(boolean);
+ method public android.app.job.JobInfo.Builder setPrefetch(boolean);
method public android.app.job.JobInfo.Builder setRequiredNetwork(android.net.NetworkRequest);
method public android.app.job.JobInfo.Builder setRequiredNetworkType(int);
method public android.app.job.JobInfo.Builder setRequiresBatteryNotLow(boolean);
@@ -7163,10 +7168,11 @@
public final class JobWorkItem implements android.os.Parcelable {
ctor public JobWorkItem(android.content.Intent);
- ctor public JobWorkItem(android.content.Intent, long);
+ ctor public JobWorkItem(android.content.Intent, long, long);
method public int describeContents();
method public int getDeliveryCount();
- method public long getEstimatedNetworkBytes();
+ method public long getEstimatedNetworkDownloadBytes();
+ method public long getEstimatedNetworkUploadBytes();
method public android.content.Intent getIntent();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.app.job.JobWorkItem> CREATOR;
@@ -7328,6 +7334,20 @@
field public static final android.os.Parcelable.Creator<android.app.usage.ConfigurationStats> CREATOR;
}
+ public final class EventStats implements android.os.Parcelable {
+ ctor public EventStats(android.app.usage.EventStats);
+ method public void add(android.app.usage.EventStats);
+ method public int describeContents();
+ method public int getCount();
+ method public int getEventType();
+ method public long getFirstTimeStamp();
+ method public long getLastTimeStamp();
+ method public long getLastTimeUsed();
+ method public long getTotalTime();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.app.usage.EventStats> CREATOR;
+ }
+
public final class ExternalStorageStats implements android.os.Parcelable {
method public int describeContents();
method public long getAppBytes();
@@ -7433,6 +7453,8 @@
field public static final int MOVE_TO_BACKGROUND = 2; // 0x2
field public static final int MOVE_TO_FOREGROUND = 1; // 0x1
field public static final int NONE = 0; // 0x0
+ field public static final int SCREEN_INTERACTIVE = 15; // 0xf
+ field public static final int SCREEN_NON_INTERACTIVE = 16; // 0x10
field public static final int SHORTCUT_INVOCATION = 8; // 0x8
field public static final int STANDBY_BUCKET_CHANGED = 11; // 0xb
field public static final int USER_INTERACTION = 7; // 0x7
@@ -7456,6 +7478,7 @@
method public boolean isAppInactive(java.lang.String);
method public java.util.Map<java.lang.String, android.app.usage.UsageStats> queryAndAggregateUsageStats(long, long);
method public java.util.List<android.app.usage.ConfigurationStats> queryConfigurations(int, long, long);
+ method public java.util.List<android.app.usage.EventStats> queryEventStats(int, long, long);
method public android.app.usage.UsageEvents queryEvents(long, long);
method public android.app.usage.UsageEvents queryEventsForSelf(long, long);
method public java.util.List<android.app.usage.UsageStats> queryUsageStats(int, long, long);
@@ -9882,6 +9905,8 @@
field public static final java.lang.String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE";
field public static final java.lang.String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
field public static final java.lang.String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED";
+ field public static final java.lang.String ACTION_MY_PACKAGE_SUSPENDED = "android.intent.action.MY_PACKAGE_SUSPENDED";
+ field public static final java.lang.String ACTION_MY_PACKAGE_UNSUSPENDED = "android.intent.action.MY_PACKAGE_UNSUSPENDED";
field public static final java.lang.String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL";
field public static final java.lang.String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT";
field public static final java.lang.String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE";
@@ -10042,6 +10067,7 @@
field public static final java.lang.String EXTRA_SPLIT_NAME = "android.intent.extra.SPLIT_NAME";
field public static final java.lang.String EXTRA_STREAM = "android.intent.extra.STREAM";
field public static final java.lang.String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
+ field public static final java.lang.String EXTRA_SUSPENDED_PACKAGE_EXTRAS = "android.intent.extra.SUSPENDED_PACKAGE_EXTRAS";
field public static final java.lang.String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
field public static final java.lang.String EXTRA_TEXT = "android.intent.extra.TEXT";
field public static final java.lang.String EXTRA_TITLE = "android.intent.extra.TITLE";
@@ -11155,7 +11181,7 @@
method public abstract android.content.res.Resources getResourcesForApplication(java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract android.content.pm.ServiceInfo getServiceInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException;
method public abstract java.util.List<android.content.pm.SharedLibraryInfo> getSharedLibraries(int);
- method public android.os.PersistableBundle getSuspendedPackageAppExtras();
+ method public android.os.Bundle getSuspendedPackageAppExtras();
method public abstract android.content.pm.FeatureInfo[] getSystemAvailableFeatures();
method public abstract java.lang.String[] getSystemSharedLibraryNames();
method public abstract java.lang.CharSequence getText(java.lang.String, int, android.content.pm.ApplicationInfo);
@@ -13302,14 +13328,9 @@
method public void rotate(float);
method public final void rotate(float, float, float);
method public int save();
- method public deprecated int save(int);
- method public deprecated int saveLayer(android.graphics.RectF, android.graphics.Paint, int);
method public int saveLayer(android.graphics.RectF, android.graphics.Paint);
- method public deprecated int saveLayer(float, float, float, float, android.graphics.Paint, int);
method public int saveLayer(float, float, float, float, android.graphics.Paint);
- method public deprecated int saveLayerAlpha(android.graphics.RectF, int, int);
method public int saveLayerAlpha(android.graphics.RectF, int);
- method public deprecated int saveLayerAlpha(float, float, float, float, int, int);
method public int saveLayerAlpha(float, float, float, float, int);
method public void scale(float, float);
method public final void scale(float, float, float, float);
@@ -13319,12 +13340,6 @@
method public void setMatrix(android.graphics.Matrix);
method public void skew(float, float);
method public void translate(float, float);
- field public static final int ALL_SAVE_FLAG = 31; // 0x1f
- field public static final deprecated int CLIP_SAVE_FLAG = 2; // 0x2
- field public static final deprecated int CLIP_TO_LAYER_SAVE_FLAG = 16; // 0x10
- field public static final deprecated int FULL_COLOR_LAYER_SAVE_FLAG = 8; // 0x8
- field public static final deprecated int HAS_ALPHA_LAYER_SAVE_FLAG = 4; // 0x4
- field public static final deprecated int MATRIX_SAVE_FLAG = 1; // 0x1
}
public static final class Canvas.EdgeType extends java.lang.Enum {
@@ -15793,6 +15808,7 @@
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Integer> CONTROL_MAX_REGIONS_AWB;
field public static final android.hardware.camera2.CameraCharacteristics.Key<android.util.Range<java.lang.Integer>> CONTROL_POST_RAW_SENSITIVITY_BOOST_RANGE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> DEPTH_DEPTH_IS_EXCLUSIVE;
+ field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> DISTORTION_CORRECTION_AVAILABLE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> EDGE_AVAILABLE_EDGE_MODES;
field public static final android.hardware.camera2.CameraCharacteristics.Key<java.lang.Boolean> FLASH_INFO_AVAILABLE;
field public static final android.hardware.camera2.CameraCharacteristics.Key<int[]> HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
@@ -16029,6 +16045,9 @@
field public static final int CONTROL_SCENE_MODE_THEATRE = 7; // 0x7
field public static final int CONTROL_VIDEO_STABILIZATION_MODE_OFF = 0; // 0x0
field public static final int CONTROL_VIDEO_STABILIZATION_MODE_ON = 1; // 0x1
+ field public static final int DISTORTION_CORRECTION_MODE_FAST = 1; // 0x1
+ field public static final int DISTORTION_CORRECTION_MODE_HIGH_QUALITY = 2; // 0x2
+ field public static final int DISTORTION_CORRECTION_MODE_OFF = 0; // 0x0
field public static final int EDGE_MODE_FAST = 1; // 0x1
field public static final int EDGE_MODE_HIGH_QUALITY = 2; // 0x2
field public static final int EDGE_MODE_OFF = 0; // 0x0
@@ -16181,6 +16200,7 @@
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
field public static final android.os.Parcelable.Creator<android.hardware.camera2.CaptureRequest> CREATOR;
+ field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> DISTORTION_CORRECTION_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> EDGE_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> FLASH_MODE;
field public static final android.hardware.camera2.CaptureRequest.Key<java.lang.Integer> HOT_PIXEL_MODE;
@@ -16263,6 +16283,7 @@
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_POST_RAW_SENSITIVITY_BOOST;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_SCENE_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> CONTROL_VIDEO_STABILIZATION_MODE;
+ field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> DISTORTION_CORRECTION_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> EDGE_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> FLASH_MODE;
field public static final android.hardware.camera2.CaptureResult.Key<java.lang.Integer> FLASH_STATE;
@@ -32037,7 +32058,6 @@
field public static final java.lang.String BASE_OS;
field public static final java.lang.String CODENAME;
field public static final java.lang.String INCREMENTAL;
- field public static final int MIN_SUPPORTED_TARGET_SDK_INT;
field public static final int PREVIEW_SDK_INT;
field public static final java.lang.String RELEASE;
field public static final deprecated java.lang.String SDK;
@@ -38324,10 +38344,8 @@
method public void shutdown();
}
- public static abstract class SEService.SecureElementListener extends android.os.Binder {
- ctor public SEService.SecureElementListener();
- method public android.os.IBinder asBinder();
- method public void serviceConnected();
+ public static abstract interface SEService.SecureElementListener {
+ method public abstract void onServiceConnected();
}
public class Session {
@@ -38337,9 +38355,7 @@
method public android.se.omapi.Reader getReader();
method public boolean isClosed();
method public android.se.omapi.Channel openBasicChannel(byte[], byte) throws java.io.IOException;
- method public android.se.omapi.Channel openBasicChannel(byte[]) throws java.io.IOException;
method public android.se.omapi.Channel openLogicalChannel(byte[], byte) throws java.io.IOException;
- method public android.se.omapi.Channel openLogicalChannel(byte[]) throws java.io.IOException;
}
}
@@ -38607,6 +38623,7 @@
method public boolean isDigestsSpecified();
method public boolean isInvalidatedByBiometricEnrollment();
method public boolean isRandomizedEncryptionRequired();
+ method public boolean isTrustedUserPresenceRequired();
method public boolean isUserAuthenticationRequired();
method public boolean isUserAuthenticationValidWhileOnBody();
method public boolean isUserConfirmationRequired();
@@ -38625,6 +38642,7 @@
method public android.security.keystore.KeyProtection.Builder setKeyValidityStart(java.util.Date);
method public android.security.keystore.KeyProtection.Builder setRandomizedEncryptionRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setSignaturePaddings(java.lang.String...);
+ method public android.security.keystore.KeyProtection.Builder setTrustedUserPresenceRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationRequired(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidWhileOnBody(boolean);
method public android.security.keystore.KeyProtection.Builder setUserAuthenticationValidityDurationSeconds(int);
@@ -41562,7 +41580,6 @@
field public static final java.lang.String KEY_EDITABLE_ENHANCED_4G_LTE_BOOL = "editable_enhanced_4g_lte_bool";
field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_BOOL = "editable_voicemail_number_bool";
field public static final java.lang.String KEY_EDITABLE_VOICEMAIL_NUMBER_SETTING_BOOL = "editable_voicemail_number_setting_bool";
- field public static final java.lang.String KEY_ENABLE_APPS_STRING_ARRAY = "enable_apps_string_array";
field public static final java.lang.String KEY_ENABLE_DIALER_KEY_VIBRATION_BOOL = "enable_dialer_key_vibration_bool";
field public static final java.lang.String KEY_FORCE_HOME_NETWORK_BOOL = "force_home_network_bool";
field public static final java.lang.String KEY_GSM_DTMF_TONE_DELAY_INT = "gsm_dtmf_tone_delay_int";
@@ -42363,12 +42380,11 @@
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isConcurrentVoiceAndDataSupported();
- method public deprecated boolean isDataEnabled();
+ method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
method public boolean isSmsCapable();
method public deprecated boolean isTtyModeSupported();
- method public boolean isUserMobileDataEnabled();
method public boolean isVoiceCapable();
method public boolean isVoicemailVibrationEnabled(android.telecom.PhoneAccountHandle);
method public boolean isWorldPhone();
@@ -42379,13 +42395,12 @@
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
method public void sendVisualVoicemailSms(java.lang.String, int, java.lang.String, android.app.PendingIntent);
- method public deprecated void setDataEnabled(boolean);
+ method public void setDataEnabled(boolean);
method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
method public void setNetworkSelectionModeAutomatic();
method public boolean setNetworkSelectionModeManual(java.lang.String, boolean);
method public boolean setOperatorBrandOverride(java.lang.String);
method public boolean setPreferredNetworkTypeToGlobal();
- method public void setUserMobileDataEnabled(boolean);
method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
method public boolean setVoiceMailNumber(java.lang.String, java.lang.String);
method public deprecated void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
@@ -42660,6 +42675,7 @@
field public static final int EMBEDDED_SUBSCRIPTION_RESULT_OK = 0; // 0x0
field public static final int EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR = 1; // 0x1
field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
+ field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
field public static final java.lang.String META_DATA_CARRIER_ICON = "android.telephony.euicc.carriericon";
}
diff --git a/api/removed.txt b/api/removed.txt
index 64a9c3f..9fe25c9 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -54,6 +54,24 @@
}
+package android.app.job {
+
+ public class JobInfo implements android.os.Parcelable {
+ method public deprecated long getEstimatedNetworkBytes();
+ }
+
+ public static final class JobInfo.Builder {
+ method public deprecated android.app.job.JobInfo.Builder setEstimatedNetworkBytes(long);
+ method public deprecated android.app.job.JobInfo.Builder setIsPrefetch(boolean);
+ }
+
+ public final class JobWorkItem implements android.os.Parcelable {
+ ctor public deprecated JobWorkItem(android.content.Intent, long);
+ method public deprecated long getEstimatedNetworkBytes();
+ }
+
+}
+
package android.app.usage {
public final class StorageStats implements android.os.Parcelable {
@@ -150,6 +168,17 @@
public class Canvas {
method public deprecated boolean clipRegion(android.graphics.Region, android.graphics.Region.Op);
method public deprecated boolean clipRegion(android.graphics.Region);
+ method public deprecated int save(int);
+ method public deprecated int saveLayer(android.graphics.RectF, android.graphics.Paint, int);
+ method public deprecated int saveLayer(float, float, float, float, android.graphics.Paint, int);
+ method public deprecated int saveLayerAlpha(android.graphics.RectF, int, int);
+ method public deprecated int saveLayerAlpha(float, float, float, float, int, int);
+ field public static final int ALL_SAVE_FLAG = 31; // 0x1f
+ field public static final deprecated int CLIP_SAVE_FLAG = 2; // 0x2
+ field public static final deprecated int CLIP_TO_LAYER_SAVE_FLAG = 16; // 0x10
+ field public static final deprecated int FULL_COLOR_LAYER_SAVE_FLAG = 8; // 0x8
+ field public static final deprecated int HAS_ALPHA_LAYER_SAVE_FLAG = 4; // 0x4
+ field public static final deprecated int MATRIX_SAVE_FLAG = 1; // 0x1
}
public final class ImageDecoder implements java.lang.AutoCloseable {
diff --git a/api/system-current.txt b/api/system-current.txt
index e049f53..5568dba 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -400,10 +400,8 @@
}
public class WallpaperManager {
- method public void clearWallpaper();
method public void clearWallpaper(int, int);
method public void setDisplayOffset(android.os.IBinder, int, int);
- method public void setDisplayPadding(android.graphics.Rect);
method public boolean setWallpaperComponent(android.content.ComponentName);
}
@@ -5503,7 +5501,6 @@
field public static final int EUICC_OTA_NOT_NEEDED = 4; // 0x4
field public static final int EUICC_OTA_STATUS_UNAVAILABLE = 5; // 0x5
field public static final int EUICC_OTA_SUCCEEDED = 3; // 0x3
- field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
field public static final java.lang.String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS = "android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTIONS";
}
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index a35570b..a458c07 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -199,11 +199,6 @@
sp<MetricsManager> newMetricsManager =
new MetricsManager(key, config, mTimeBaseSec, mUidMap,
mAnomalyAlarmMonitor, mPeriodicAlarmMonitor);
- auto it = mMetricsManagers.find(key);
- if (it == mMetricsManagers.end() && mMetricsManagers.size() > StatsdStats::kMaxConfigCount) {
- ALOGE("Can't accept more configs!");
- return;
- }
if (newMetricsManager->isConfigValid()) {
mUidMap->OnConfigUpdated(key);
@@ -213,7 +208,6 @@
mUidMap->addListener(newMetricsManager.get());
}
mMetricsManagers[key] = newMetricsManager;
- // Why doesn't this work? mMetricsManagers.insert({key, std::move(newMetricsManager)});
VLOG("StatsdConfig valid");
} else {
// If there is any error in the config, don't use it.
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 99611f4..2095649 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -111,13 +111,14 @@
BluetoothEnabledStateChanged bluetooth_enabled_state_changed = 67;
BluetoothConnectionStateChanged bluetooth_connection_state_changed = 68;
BluetoothA2dpAudioStateChanged bluetooth_a2dp_audio_state_changed = 69;
- UsbConnectorStateChanged usb_connector_changed = 70;
+ UsbConnectorStateChanged usb_connector_state_changed = 70;
SpeakerImpedanceReported speaker_impedance_reported = 71;
HardwareFailed hardware_failed = 72;
PhysicalDropDetected physical_drop_detected = 73;
ChargeCyclesReported charge_cycles_reported = 74;
MobileConnectionStateChanged mobile_connection_state_changed = 75;
MobileRadioTechnologyChanged mobile_radio_technology_changed = 76;
+ UsbDeviceAttached usb_device_attached = 77;
}
// Pulled events will start at field 10000.
@@ -291,7 +292,7 @@
* Logs when a sensor state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message SensorStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -329,7 +330,7 @@
* Logs when a sync manager sync state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message SyncStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -348,7 +349,7 @@
* Logs when a job scheduler job state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message ScheduledJobStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -365,7 +366,7 @@
// The reason a job has stopped.
// This is only applicable when the state is FINISHED.
- // The default value is CANCELED.
+ // The default value is STOP_REASON_UNKNOWN.
optional android.app.job.StopReasonEnum stop_reason = 4;
}
@@ -373,7 +374,7 @@
* Logs when the audio state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message AudioStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -381,6 +382,8 @@
enum State {
OFF = 0;
ON = 1;
+ // RESET indicates all audio stopped. Used when it (re)starts (e.g. after it crashes).
+ RESET = 2;
}
optional State state = 2;
}
@@ -389,7 +392,7 @@
* Logs when the video codec state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message MediaCodecActivityChanged {
repeated AttributionNode attribution_node = 1;
@@ -397,6 +400,8 @@
enum State {
OFF = 0;
ON = 1;
+ // RESET indicates all mediaCodec stopped. Used when it (re)starts (e.g. after it crashes).
+ RESET = 2;
}
optional State state = 2;
}
@@ -405,7 +410,7 @@
* Logs when the flashlight state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message FlashlightStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -413,6 +418,8 @@
enum State {
OFF = 0;
ON = 1;
+ // RESET indicates all flashlight stopped. Used when it (re)starts (e.g. after it crashes).
+ RESET = 2;
}
optional State state = 2;
}
@@ -421,7 +428,7 @@
* Logs when the camera state changes.
*
* Logged from:
- * frameworks/base/core/java/com/android/internal/os/BatteryStatsImpl.java
+ * frameworks/base/services/core/java/com/android/server/am/BatteryStatsService.java
*/
message CameraStateChanged {
repeated AttributionNode attribution_node = 1;
@@ -429,6 +436,8 @@
enum State {
OFF = 0;
ON = 1;
+ // RESET indicates all camera stopped. Used when it (re)starts (e.g. after it crashes).
+ RESET = 2;
}
optional State state = 2;
}
@@ -966,6 +975,21 @@
optional int32 sim_slot_index = 2;
}
+/**
+ * Logs the VID and PID of any connected USB devices.
+ *
+ * Notes if any Audio, HID (input buttons/mouse/keyboard), or Storage interfaces are present.
+ *
+ * Logged by Vendor.
+ */
+message UsbDeviceAttached {
+ optional int32 vid = 1;
+ optional int32 pid = 2;
+ optional bool has_audio = 3;
+ optional bool has_hid = 4;
+ optional bool has_storage = 5;
+}
+
/**
* Logs when Bluetooth is enabled and disabled.
@@ -1103,6 +1127,8 @@
optional int32 confidence_pctg = 1;
// Peak acceleration of the drop, in 1/1000s of a g.
optional int32 accel_peak_thousandths_g = 2;
+ // Duration of freefall in ms
+ optional int32 freefall_time_millis = 3;
}
/**
diff --git a/cmds/statsd/src/condition/CombinationConditionTracker.cpp b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
index 3661d2b..60a4b23 100644
--- a/cmds/statsd/src/condition/CombinationConditionTracker.cpp
+++ b/cmds/statsd/src/condition/CombinationConditionTracker.cpp
@@ -149,9 +149,9 @@
}
}
+ ConditionState newCondition =
+ evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
if (!mSliced) {
- ConditionState newCondition =
- evaluateCombinationCondition(mChildren, mLogicalOperation, nonSlicedConditionCache);
bool nonSlicedChanged = (mNonSlicedConditionState != newCondition);
mNonSlicedConditionState = newCondition;
@@ -172,7 +172,7 @@
break;
}
}
- nonSlicedConditionCache[mIndex] = ConditionState::kUnknown;
+ nonSlicedConditionCache[mIndex] = newCondition;
VLOG("CombinationPredicate %lld sliced may changed? %d", (long long)mConditionId,
conditionChangedCache[mIndex] == true);
}
diff --git a/cmds/statsd/src/condition/SimpleConditionTracker.cpp b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
index 73efb39..87104a3 100644
--- a/cmds/statsd/src/condition/SimpleConditionTracker.cpp
+++ b/cmds/statsd/src/condition/SimpleConditionTracker.cpp
@@ -289,9 +289,15 @@
// The event doesn't match this condition. So we just report existing condition values.
conditionChangedCache[mIndex] = false;
if (mSliced) {
- // if the condition result is sliced. metrics won't directly get value from the
- // cache, so just set any value other than kNotEvaluated.
+ // if the condition result is sliced. The overall condition is true if any of the sliced
+ // condition is true
conditionCache[mIndex] = mInitialValue;
+ for (const auto& slicedCondition : mSlicedConditionState) {
+ if (slicedCondition.second > 0) {
+ conditionCache[mIndex] = ConditionState::kTrue;
+ break;
+ }
+ }
} else {
const auto& itr = mSlicedConditionState.find(DEFAULT_DIMENSION_KEY);
if (itr == mSlicedConditionState.end()) {
diff --git a/cmds/statsd/src/condition/StateTracker.cpp b/cmds/statsd/src/condition/StateTracker.cpp
index fe1740b..1965ce6 100644
--- a/cmds/statsd/src/condition/StateTracker.cpp
+++ b/cmds/statsd/src/condition/StateTracker.cpp
@@ -141,7 +141,7 @@
// one keys matched.
HashableDimensionKey primaryKey;
HashableDimensionKey state;
- if (!filterValues(mPrimaryKeys, event.getValues(), &primaryKey) ||
+ if ((mPrimaryKeys.size() > 0 && !filterValues(mPrimaryKeys, event.getValues(), &primaryKey)) ||
!filterValues(mOutputDimensions, event.getValues(), &state)) {
ALOGE("Failed to filter fields in the event?? panic now!");
conditionCache[mIndex] =
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index f5310a4..ff25091 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -14,9 +14,13 @@
* limitations under the License.
*/
+#define DEBUG false // STOPSHIP if true
+#include "Log.h"
+
#include "config/ConfigManager.h"
#include "storage/StorageManager.h"
+#include "guardrail/StatsdStats.h"
#include "stats_util.h"
#include <android-base/file.h>
@@ -68,24 +72,37 @@
{
lock_guard <mutex> lock(mMutex);
- auto it = mConfigs.find(key);
-
const int numBytes = config.ByteSize();
vector<uint8_t> buffer(numBytes);
config.SerializeToArray(&buffer[0], numBytes);
- const bool isDuplicate =
- it != mConfigs.end() &&
- StorageManager::hasIdenticalConfig(key, buffer);
+ auto uidIt = mConfigs.find(key.GetUid());
+ // GuardRail: Limit the number of configs per uid.
+ if (uidIt != mConfigs.end()) {
+ auto it = uidIt->second.find(key);
+ if (it == uidIt->second.end() &&
+ uidIt->second.size() >= StatsdStats::kMaxConfigCountPerUid) {
+ ALOGE("ConfigManager: uid %d has exceeded the config count limit", key.GetUid());
+ return;
+ }
+ }
- // Update saved file on disk. We still update timestamp of file when
- // there exists a duplicate configuration to avoid garbage collection.
+ // Check if it's a duplicate config.
+ if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end() &&
+ StorageManager::hasIdenticalConfig(key, buffer)) {
+ // This is a duplicate config.
+ ALOGI("ConfigManager This is a duplicate config %s", key.ToString().c_str());
+ // Update saved file on disk. We still update timestamp of file when
+ // there exists a duplicate configuration to avoid garbage collection.
+ update_saved_configs_locked(key, buffer, numBytes);
+ return;
+ }
+
+ // Update saved file on disk.
update_saved_configs_locked(key, buffer, numBytes);
- if (isDuplicate) return;
-
- // Add to set
- mConfigs.insert(key);
+ // Add to set.
+ mConfigs[key.GetUid()].insert(key);
for (sp<ConfigListener> listener : mListeners) {
broadcastList.push_back(listener);
@@ -113,11 +130,10 @@
{
lock_guard <mutex> lock(mMutex);
- auto it = mConfigs.find(key);
- if (it != mConfigs.end()) {
+ auto uidIt = mConfigs.find(key.GetUid());
+ if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
// Remove from map
- mConfigs.erase(it);
-
+ uidIt->second.erase(key);
for (sp<ConfigListener> listener : mListeners) {
broadcastList.push_back(listener);
}
@@ -150,18 +166,20 @@
{
lock_guard <mutex> lock(mMutex);
- for (auto it = mConfigs.begin(); it != mConfigs.end();) {
+ auto uidIt = mConfigs.find(uid);
+ if (uidIt == mConfigs.end()) {
+ return;
+ }
+
+ for (auto it = uidIt->second.begin(); it != uidIt->second.end(); ++it) {
// Remove from map
- if (it->GetUid() == uid) {
remove_saved_configs(*it);
removed.push_back(*it);
mConfigReceivers.erase(*it);
- it = mConfigs.erase(it);
- } else {
- it++;
- }
}
+ mConfigs.erase(uidIt);
+
for (sp<ConfigListener> listener : mListeners) {
broadcastList.push_back(listener);
}
@@ -182,17 +200,16 @@
{
lock_guard <mutex> lock(mMutex);
-
- for (auto it = mConfigs.begin(); it != mConfigs.end();) {
- // Remove from map
- removed.push_back(*it);
- auto receiverIt = mConfigReceivers.find(*it);
- if (receiverIt != mConfigReceivers.end()) {
- mConfigReceivers.erase(*it);
+ for (auto uidIt = mConfigs.begin(); uidIt != mConfigs.end();) {
+ for (auto it = uidIt->second.begin(); it != uidIt->second.end();) {
+ // Remove from map
+ removed.push_back(*it);
+ it = uidIt->second.erase(it);
}
- it = mConfigs.erase(it);
+ uidIt = mConfigs.erase(uidIt);
}
+ mConfigReceivers.clear();
for (sp<ConfigListener> listener : mListeners) {
broadcastList.push_back(listener);
}
@@ -211,8 +228,10 @@
lock_guard<mutex> lock(mMutex);
vector<ConfigKey> ret;
- for (auto it = mConfigs.cbegin(); it != mConfigs.cend(); ++it) {
- ret.push_back(*it);
+ for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
+ for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
+ ret.push_back(*it);
+ }
}
return ret;
}
@@ -231,13 +250,15 @@
void ConfigManager::Dump(FILE* out) {
lock_guard<mutex> lock(mMutex);
- fprintf(out, "CONFIGURATIONS (%d)\n", (int)mConfigs.size());
+ fprintf(out, "CONFIGURATIONS\n");
fprintf(out, " uid name\n");
- for (const auto& key : mConfigs) {
- fprintf(out, " %6d %lld\n", key.GetUid(), (long long)key.GetId());
- auto receiverIt = mConfigReceivers.find(key);
- if (receiverIt != mConfigReceivers.end()) {
- fprintf(out, " -> received by PendingIntent as binder\n");
+ for (auto uidIt = mConfigs.cbegin(); uidIt != mConfigs.cend(); ++uidIt) {
+ for (auto it = uidIt->second.cbegin(); it != uidIt->second.cend(); ++it) {
+ fprintf(out, " %6d %lld\n", it->GetUid(), (long long)it->GetId());
+ auto receiverIt = mConfigReceivers.find(*it);
+ if (receiverIt != mConfigReceivers.end()) {
+ fprintf(out, " -> received by PendingIntent as binder\n");
+ }
}
}
}
@@ -255,331 +276,6 @@
StorageManager::writeFile(file_name.c_str(), &buffer[0], numBytes);
}
-StatsdConfig build_fake_config() {
- // HACK: Hard code a test metric for counting screen on events...
- StatsdConfig config;
- config.set_id(12345);
-
- int WAKE_LOCK_TAG_ID = 1111; // put a fake id here to make testing easier.
- int WAKE_LOCK_UID_KEY_ID = 1;
- int WAKE_LOCK_NAME_KEY = 3;
- int WAKE_LOCK_STATE_KEY = 4;
- int WAKE_LOCK_ACQUIRE_VALUE = 1;
- int WAKE_LOCK_RELEASE_VALUE = 0;
-
- int APP_USAGE_TAG_ID = 12345;
- int APP_USAGE_UID_KEY_ID = 1;
- int APP_USAGE_STATE_KEY = 2;
- int APP_USAGE_FOREGROUND = 1;
- int APP_USAGE_BACKGROUND = 0;
-
- int SCREEN_EVENT_TAG_ID = 29;
- int SCREEN_EVENT_STATE_KEY = 1;
- int SCREEN_EVENT_ON_VALUE = 2;
- int SCREEN_EVENT_OFF_VALUE = 1;
-
- int UID_PROCESS_STATE_TAG_ID = 27;
- int UID_PROCESS_STATE_UID_KEY = 1;
-
- int KERNEL_WAKELOCK_TAG_ID = 1004;
- int KERNEL_WAKELOCK_COUNT_KEY = 2;
- int KERNEL_WAKELOCK_NAME_KEY = 1;
-
- int DEVICE_TEMPERATURE_TAG_ID = 33;
- int DEVICE_TEMPERATURE_KEY = 1;
-
- // Count Screen ON events.
- CountMetric* metric = config.add_count_metric();
- metric->set_id(1); // METRIC_1
- metric->set_what(102); // "SCREEN_TURNED_ON"
- metric->set_bucket(ONE_MINUTE);
-
- // Anomaly threshold for screen-on count.
- // TODO(b/70627390): Uncomment once the bug is fixed.
- /*Alert* alert = config.add_alert();
- alert->set_id("ALERT_1");
- alert->set_metric_name("METRIC_1");
- alert->set_number_of_buckets(6);
- alert->set_trigger_if_sum_gt(10);
- alert->set_refractory_period_secs(30);
- Alert::IncidentdDetails* details = alert->mutable_incidentd_details();
- details->add_section(12);
- details->add_section(13);*/
-
- config.add_allowed_log_source("AID_ROOT");
- config.add_allowed_log_source("AID_SYSTEM");
- config.add_allowed_log_source("AID_BLUETOOTH");
- config.add_allowed_log_source("com.android.statsd.dogfood");
- config.add_allowed_log_source("com.android.systemui");
-
- // Count process state changes, slice by uid.
- metric = config.add_count_metric();
- metric->set_id(2); // "METRIC_2"
- metric->set_what(104);
- metric->set_bucket(ONE_MINUTE);
- FieldMatcher* dimensions = metric->mutable_dimensions_in_what();
- dimensions->set_field(UID_PROCESS_STATE_TAG_ID);
- dimensions->add_child()->set_field(UID_PROCESS_STATE_UID_KEY);
-
- // Anomaly threshold for background count.
- // TODO(b/70627390): Uncomment once the bug is fixed.
- /*
- alert = config.add_alert();
- alert->set_id("ALERT_2");
- alert->set_metric_name("METRIC_2");
- alert->set_number_of_buckets(4);
- alert->set_trigger_if_sum_gt(30);
- alert->set_refractory_period_secs(20);
- details = alert->mutable_incidentd_details();
- details->add_section(14);
- details->add_section(15);*/
-
- // Count process state changes, slice by uid, while SCREEN_IS_OFF
- metric = config.add_count_metric();
- metric->set_id(3);
- metric->set_what(104);
- metric->set_bucket(ONE_MINUTE);
-
- dimensions = metric->mutable_dimensions_in_what();
- dimensions->set_field(UID_PROCESS_STATE_TAG_ID);
- dimensions->add_child()->set_field(UID_PROCESS_STATE_UID_KEY);
- metric->set_condition(202);
-
- // Count wake lock, slice by uid, while SCREEN_IS_ON and app in background
- metric = config.add_count_metric();
- metric->set_id(4);
- metric->set_what(107);
- metric->set_bucket(ONE_MINUTE);
- dimensions = metric->mutable_dimensions_in_what();
- dimensions->set_field(WAKE_LOCK_TAG_ID);
- dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
-
-
- metric->set_condition(204);
- MetricConditionLink* link = metric->add_links();
- link->set_condition(203);
- link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
- link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
- link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
-
- // Duration of an app holding any wl, while screen on and app in background, slice by uid
- DurationMetric* durationMetric = config.add_duration_metric();
- durationMetric->set_id(5);
- durationMetric->set_bucket(ONE_MINUTE);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
- dimensions = durationMetric->mutable_dimensions_in_what();
- dimensions->set_field(WAKE_LOCK_TAG_ID);
- dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- durationMetric->set_what(205);
- durationMetric->set_condition(204);
- link = durationMetric->add_links();
- link->set_condition(203);
- link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
- link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
- link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
-
- // max Duration of an app holding any wl, while screen on and app in background, slice by uid
- durationMetric = config.add_duration_metric();
- durationMetric->set_id(6);
- durationMetric->set_bucket(ONE_MINUTE);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
- dimensions = durationMetric->mutable_dimensions_in_what();
- dimensions->set_field(WAKE_LOCK_TAG_ID);
- dimensions->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- durationMetric->set_what(205);
- durationMetric->set_condition(204);
- link = durationMetric->add_links();
- link->set_condition(203);
- link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
- link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
- link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
-
- // Duration of an app holding any wl, while screen on and app in background
- durationMetric = config.add_duration_metric();
- durationMetric->set_id(7);
- durationMetric->set_bucket(ONE_MINUTE);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_MAX_SPARSE);
- durationMetric->set_what(205);
- durationMetric->set_condition(204);
- link = durationMetric->add_links();
- link->set_condition(203);
- link->mutable_fields_in_what()->set_field(WAKE_LOCK_TAG_ID);
- link->mutable_fields_in_what()->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- link->mutable_fields_in_condition()->set_field(APP_USAGE_TAG_ID);
- link->mutable_fields_in_condition()->add_child()->set_field(APP_USAGE_UID_KEY_ID);
-
-
- // Duration of screen on time.
- durationMetric = config.add_duration_metric();
- durationMetric->set_id(8);
- durationMetric->set_bucket(ONE_MINUTE);
- durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
- durationMetric->set_what(201);
-
- // Anomaly threshold for background count.
- // TODO(b/70627390): Uncomment once the bug is fixed.
- /*
- alert = config.add_alert();
- alert->set_id(308);
- alert->set_metric_id(8);
- alert->set_number_of_buckets(4);
- alert->set_trigger_if_sum_gt(2000000000); // 2 seconds
- alert->set_refractory_period_secs(120);
- details = alert->mutable_incidentd_details();
- details->add_section(-1);*/
-
- // Value metric to count KERNEL_WAKELOCK when screen turned on
- ValueMetric* valueMetric = config.add_value_metric();
- valueMetric->set_id(11);
- valueMetric->set_what(109);
- valueMetric->mutable_value_field()->set_field(KERNEL_WAKELOCK_TAG_ID);
- valueMetric->mutable_value_field()->add_child()->set_field(KERNEL_WAKELOCK_COUNT_KEY);
- valueMetric->set_condition(201);
- dimensions = valueMetric->mutable_dimensions_in_what();
- dimensions->set_field(KERNEL_WAKELOCK_TAG_ID);
- dimensions->add_child()->set_field(KERNEL_WAKELOCK_NAME_KEY);
- // This is for testing easier. We should never set bucket size this small.
- durationMetric->set_bucket(ONE_MINUTE);
-
- // Add an EventMetric to log process state change events.
- EventMetric* eventMetric = config.add_event_metric();
- eventMetric->set_id(9);
- eventMetric->set_what(102); // "SCREEN_TURNED_ON"
-
- // Add an GaugeMetric.
- GaugeMetric* gaugeMetric = config.add_gauge_metric();
- gaugeMetric->set_id(10);
- gaugeMetric->set_what(101);
- auto gaugeFieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
- gaugeFieldMatcher->set_field(DEVICE_TEMPERATURE_TAG_ID);
- gaugeFieldMatcher->add_child()->set_field(DEVICE_TEMPERATURE_KEY);
- durationMetric->set_bucket(ONE_MINUTE);
-
- // Event matchers.
- AtomMatcher* temperatureAtomMatcher = config.add_atom_matcher();
- temperatureAtomMatcher->set_id(101); // "DEVICE_TEMPERATURE"
- temperatureAtomMatcher->mutable_simple_atom_matcher()->set_atom_id(
- DEVICE_TEMPERATURE_TAG_ID);
-
- AtomMatcher* eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(102); // "SCREEN_TURNED_ON"
- SimpleAtomMatcher* simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(SCREEN_EVENT_TAG_ID);
- FieldValueMatcher* fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
- fieldValueMatcher->set_field(SCREEN_EVENT_STATE_KEY);
- fieldValueMatcher->set_eq_int(SCREEN_EVENT_ON_VALUE);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(103); // "SCREEN_TURNED_OFF"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(SCREEN_EVENT_TAG_ID);
- fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
- fieldValueMatcher->set_field(SCREEN_EVENT_STATE_KEY);
- fieldValueMatcher->set_eq_int(SCREEN_EVENT_OFF_VALUE);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(104); // "PROCESS_STATE_CHANGE"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(UID_PROCESS_STATE_TAG_ID);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(105); // "APP_GOES_BACKGROUND"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(APP_USAGE_TAG_ID);
- fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
- fieldValueMatcher->set_field(APP_USAGE_STATE_KEY);
- fieldValueMatcher->set_eq_int(APP_USAGE_BACKGROUND);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(106); // "APP_GOES_FOREGROUND"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(APP_USAGE_TAG_ID);
- fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
- fieldValueMatcher->set_field(APP_USAGE_STATE_KEY);
- fieldValueMatcher->set_eq_int(APP_USAGE_FOREGROUND);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(107); // "APP_GET_WL"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(WAKE_LOCK_TAG_ID);
- fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
- fieldValueMatcher->set_field(WAKE_LOCK_STATE_KEY);
- fieldValueMatcher->set_eq_int(WAKE_LOCK_ACQUIRE_VALUE);
-
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(108); //"APP_RELEASE_WL"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(WAKE_LOCK_TAG_ID);
- fieldValueMatcher = simpleAtomMatcher->add_field_value_matcher();
- fieldValueMatcher->set_field(WAKE_LOCK_STATE_KEY);
- fieldValueMatcher->set_eq_int(WAKE_LOCK_RELEASE_VALUE);
-
- // pulled events
- eventMatcher = config.add_atom_matcher();
- eventMatcher->set_id(109); // "KERNEL_WAKELOCK"
- simpleAtomMatcher = eventMatcher->mutable_simple_atom_matcher();
- simpleAtomMatcher->set_atom_id(KERNEL_WAKELOCK_TAG_ID);
-
- // Predicates.............
- Predicate* predicate = config.add_predicate();
- predicate->set_id(201); // "SCREEN_IS_ON"
- SimplePredicate* simplePredicate = predicate->mutable_simple_predicate();
- simplePredicate->set_start(102); // "SCREEN_TURNED_ON"
- simplePredicate->set_stop(103);
- simplePredicate->set_count_nesting(false);
-
- predicate = config.add_predicate();
- predicate->set_id(202); // "SCREEN_IS_OFF"
- simplePredicate = predicate->mutable_simple_predicate();
- simplePredicate->set_start(103);
- simplePredicate->set_stop(102); // "SCREEN_TURNED_ON"
- simplePredicate->set_count_nesting(false);
-
- predicate = config.add_predicate();
- predicate->set_id(203); // "APP_IS_BACKGROUND"
- simplePredicate = predicate->mutable_simple_predicate();
- simplePredicate->set_start(105);
- simplePredicate->set_stop(106);
- FieldMatcher* predicate_dimension1 = simplePredicate->mutable_dimensions();
- predicate_dimension1->set_field(APP_USAGE_TAG_ID);
- predicate_dimension1->add_child()->set_field(APP_USAGE_UID_KEY_ID);
- simplePredicate->set_count_nesting(false);
-
- predicate = config.add_predicate();
- predicate->set_id(204); // "APP_IS_BACKGROUND_AND_SCREEN_ON"
- Predicate_Combination* combination_predicate = predicate->mutable_combination();
- combination_predicate->set_operation(LogicalOperation::AND);
- combination_predicate->add_predicate(203);
- combination_predicate->add_predicate(201);
-
- predicate = config.add_predicate();
- predicate->set_id(205); // "WL_HELD_PER_APP_PER_NAME"
- simplePredicate = predicate->mutable_simple_predicate();
- simplePredicate->set_start(107);
- simplePredicate->set_stop(108);
- FieldMatcher* predicate_dimension = simplePredicate->mutable_dimensions();
- predicate_dimension1->set_field(WAKE_LOCK_TAG_ID);
- predicate_dimension->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- predicate_dimension->add_child()->set_field(WAKE_LOCK_NAME_KEY);
- simplePredicate->set_count_nesting(true);
-
- predicate = config.add_predicate();
- predicate->set_id(206); // "WL_HELD_PER_APP"
- simplePredicate = predicate->mutable_simple_predicate();
- simplePredicate->set_start(107);
- simplePredicate->set_stop(108);
- simplePredicate->set_initial_value(SimplePredicate_InitialValue_FALSE);
- predicate_dimension = simplePredicate->mutable_dimensions();
- predicate_dimension->set_field(WAKE_LOCK_TAG_ID);
- predicate_dimension->add_child()->set_field(WAKE_LOCK_UID_KEY_ID);
- simplePredicate->set_count_nesting(true);
-
- return config;
-}
-
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/config/ConfigManager.h b/cmds/statsd/src/config/ConfigManager.h
index 9a38188a..611c342 100644
--- a/cmds/statsd/src/config/ConfigManager.h
+++ b/cmds/statsd/src/config/ConfigManager.h
@@ -36,9 +36,6 @@
/**
* Keeps track of which configurations have been set from various sources.
- *
- * TODO: Store the configs persistently too.
- * TODO: Dump method for debugging.
*/
class ConfigManager : public virtual android::RefBase {
public:
@@ -125,9 +122,9 @@
void remove_saved_configs(const ConfigKey& key);
/**
- * Config keys that have been set.
+ * Maps from uid to the config keys that have been set.
*/
- std::set<ConfigKey> mConfigs;
+ std::map<int, std::set<ConfigKey>> mConfigs;
/**
* Each config key can be subscribed by up to one receiver, specified as IBinder from
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 7675888..7f8755b 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -78,17 +78,17 @@
~StatsdStats(){};
// TODO: set different limit if the device is low ram.
- const static int kDimensionKeySizeSoftLimit = 300;
- const static int kDimensionKeySizeHardLimit = 500;
+ const static int kDimensionKeySizeSoftLimit = 500;
+ const static int kDimensionKeySizeHardLimit = 800;
// Per atom dimension key size limit
static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
- const static int kMaxConfigCount = 10;
+ const static int kMaxConfigCountPerUid = 10;
const static int kMaxAlertCountPerConfig = 100;
- const static int kMaxConditionCountPerConfig = 200;
- const static int kMaxMetricCountPerConfig = 300;
- const static int kMaxMatcherCountPerConfig = 500;
+ const static int kMaxConditionCountPerConfig = 300;
+ const static int kMaxMetricCountPerConfig = 1000;
+ const static int kMaxMatcherCountPerConfig = 800;
// The max number of old config stats we keep.
const static int kMaxIceBoxSize = 20;
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index 8e8a529..afa5140 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -117,7 +117,8 @@
}
}
-void CountMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
+void CountMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+ const uint64_t eventTime) {
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index ef738ac..fd9f0e0 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -61,7 +61,7 @@
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index c6b9405..c28bb88 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -169,7 +169,8 @@
// 1. If combination condition, logical operation is AND, only one sliced child predicate.
// 2. No condition in dimension
// 3. The links covers all dimension fields in the sliced child condition predicate.
-void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(const uint64_t eventTime) {
+void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt1(bool condition,
+ const uint64_t eventTime) {
if (mMetric2ConditionLinks.size() != 1 ||
!mHasLinksToAllConditionDimensionsInTracker ||
!mDimensionsInCondition.empty()) {
@@ -241,7 +242,8 @@
// SlicedConditionChange optimization case 2:
// 1. If combination condition, logical operation is AND, only one sliced child predicate.
// 2. Has dimensions_in_condition and it equals to the output dimensions of the sliced predicate.
-void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(const uint64_t eventTime) {
+void DurationMetricProducer::onSlicedConditionMayChangeLocked_opt2(bool condition,
+ const uint64_t eventTime) {
if (mMetric2ConditionLinks.size() > 1 || !mSameConditionDimensionsInTracker) {
return;
}
@@ -322,7 +324,8 @@
}
}
-void DurationMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
+void DurationMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+ const uint64_t eventTime) {
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
flushIfNeededLocked(eventTime);
@@ -333,20 +336,20 @@
bool changeDimTrackable = mWizard->IsChangedDimensionTrackable(mConditionTrackerIndex);
if (changeDimTrackable && mHasLinksToAllConditionDimensionsInTracker &&
mDimensionsInCondition.empty()) {
- onSlicedConditionMayChangeLocked_opt1(eventTime);
+ onSlicedConditionMayChangeLocked_opt1(overallCondition, eventTime);
return;
}
if (changeDimTrackable && mSameConditionDimensionsInTracker &&
mMetric2ConditionLinks.size() <= 1) {
- onSlicedConditionMayChangeLocked_opt2(eventTime);
+ onSlicedConditionMayChangeLocked_opt2(overallCondition, eventTime);
return;
}
// Now for each of the on-going event, check if the condition has changed for them.
for (auto& whatIt : mCurrentSlicedDurationTrackerMap) {
for (auto& pair : whatIt.second) {
- pair.second->onSlicedConditionMayChange(eventTime);
+ pair.second->onSlicedConditionMayChange(overallCondition, eventTime);
}
}
@@ -372,7 +375,7 @@
if (newTracker != nullptr) {
newTracker->setEventKey(MetricDimensionKey(
whatIt.first, conditionDimension));
- newTracker->onSlicedConditionMayChange(eventTime);
+ newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
whatIt.second[conditionDimension] = std::move(newTracker);
}
}
@@ -398,7 +401,7 @@
if (newTracker != nullptr) {
newTracker->setEventKey(
MetricDimensionKey(whatIt.first, conditionDimension));
- newTracker->onSlicedConditionMayChange(eventTime);
+ newTracker->onSlicedConditionMayChange(overallCondition, eventTime);
whatIt.second[conditionDimension] = std::move(newTracker);
}
}
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 985749d..75f2391 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -68,10 +68,10 @@
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
- void onSlicedConditionMayChangeLocked_opt1(const uint64_t eventTime);
- void onSlicedConditionMayChangeLocked_opt2(const uint64_t eventTime);
+ void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const uint64_t eventTime);
+ void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const uint64_t eventTime);
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index bd8b293..42a5a3a 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -79,7 +79,8 @@
mProto->clear();
}
-void EventMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
+void EventMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+ const uint64_t eventTime) {
}
std::unique_ptr<std::vector<uint8_t>> serializeProtoLocked(ProtoOutputStream& protoOutput) {
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index d6f81fd..93c6c9a 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -53,7 +53,7 @@
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
void dropDataLocked(const uint64_t dropTimeNs) override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index f08d54a..f0e0df1 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -115,8 +115,9 @@
mStatsPullerManager->RegisterReceiver(mPullTagId, this, bucketSizeMills);
}
- VLOG("metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
- (long long)mBucketSizeNs, (long long)mStartTimeNs);
+ VLOG("Gauge metric %lld created. bucket size %lld start_time: %lld sliced %d",
+ (long long)metric.id(), (long long)mBucketSizeNs, (long long)mStartTimeNs,
+ mConditionSliced);
}
// for testing
@@ -155,7 +156,7 @@
void GaugeMetricProducer::onDumpReportLocked(const uint64_t dumpTimeNs,
ProtoOutputStream* protoOutput) {
- VLOG("gauge metric %lld report now...", (long long)mMetricId);
+ VLOG("Gauge metric %lld report now...", (long long)mMetricId);
flushIfNeededLocked(dumpTimeNs);
if (mPastBuckets.empty()) {
@@ -168,7 +169,7 @@
for (const auto& pair : mPastBuckets) {
const MetricDimensionKey& dimensionKey = pair.first;
- VLOG(" dimension key %s", dimensionKey.toString().c_str());
+ VLOG("Gauge dimension key %s", dimensionKey.toString().c_str());
uint64_t wrapperToken =
protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
@@ -221,8 +222,9 @@
}
}
protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] includes %d atoms.", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (int)bucket.mGaugeAtoms.size());
+ VLOG("Gauge \t bucket [%lld - %lld] includes %d atoms.",
+ (long long)bucket.mBucketStartNs, (long long)bucket.mBucketEndNs,
+ (int)bucket.mGaugeAtoms.size());
}
protoOutput->end(wrapperToken);
}
@@ -233,27 +235,6 @@
}
void GaugeMetricProducer::pullLocked() {
- vector<std::shared_ptr<LogEvent>> allData;
- if (!mStatsPullerManager->Pull(mPullTagId, &allData)) {
- ALOGE("Stats puller failed for tag: %d", mPullTagId);
- return;
- }
- for (const auto& data : allData) {
- onMatchedLogEventLocked(0, *data);
- }
-}
-
-void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
- const uint64_t eventTime) {
- VLOG("Metric %lld onConditionChanged", (long long)mMetricId);
- flushIfNeededLocked(eventTime);
- mCondition = conditionMet;
-
- // Push mode. No need to proactively pull the gauge data.
- if (mPullTagId == -1) {
- return;
- }
-
bool triggerPuller = false;
switch(mSamplingType) {
// When the metric wants to do random sampling and there is already one gauge atom for the
@@ -275,17 +256,37 @@
vector<std::shared_ptr<LogEvent>> allData;
if (!mStatsPullerManager->Pull(mPullTagId, &allData)) {
- ALOGE("Stats puller failed for tag: %d", mPullTagId);
+ ALOGE("Gauge Stats puller failed for tag: %d", mPullTagId);
return;
}
+
for (const auto& data : allData) {
onMatchedLogEventLocked(0, *data);
}
- flushIfNeededLocked(eventTime);
}
-void GaugeMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
- VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
+void GaugeMetricProducer::onConditionChangedLocked(const bool conditionMet,
+ const uint64_t eventTime) {
+ VLOG("GaugeMetric %lld onConditionChanged", (long long)mMetricId);
+ flushIfNeededLocked(eventTime);
+ mCondition = conditionMet;
+
+ if (mPullTagId != -1) {
+ pullLocked();
+ } // else: Push mode. No need to proactively pull the gauge data.
+}
+
+void GaugeMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+ const uint64_t eventTime) {
+ VLOG("GaugeMetric %lld onSlicedConditionMayChange overall condition %d", (long long)mMetricId,
+ overallCondition);
+ flushIfNeededLocked(eventTime);
+ // If the condition is sliced, mCondition is true if any of the dimensions is true. And we will
+ // pull for every dimension.
+ mCondition = overallCondition;
+ if (mPullTagId != -1) {
+ pullLocked();
+ } // else: Push mode. No need to proactively pull the gauge data.
}
std::shared_ptr<vector<FieldValue>> GaugeMetricProducer::getGaugeFields(const LogEvent& event) {
@@ -337,7 +338,7 @@
uint64_t eventTimeNs = event.GetElapsedTimestampNs();
mTagId = event.GetTagId();
if (eventTimeNs < mCurrentBucketStartTimeNs) {
- VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
+ VLOG("Gauge Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
return;
}
@@ -403,8 +404,8 @@
uint64_t currentBucketEndTimeNs = getCurrentBucketEndTimeNs();
if (eventTimeNs < currentBucketEndTimeNs) {
- VLOG("eventTime is %lld, less than next bucket start time %lld", (long long)eventTimeNs,
- (long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
+ VLOG("Gauge eventTime is %lld, less than next bucket start time %lld",
+ (long long)eventTimeNs, (long long)(mCurrentBucketStartTimeNs + mBucketSizeNs));
return;
}
@@ -414,7 +415,7 @@
int64_t numBucketsForward = 1 + (eventTimeNs - currentBucketEndTimeNs) / mBucketSizeNs;
mCurrentBucketStartTimeNs = currentBucketEndTimeNs + (numBucketsForward - 1) * mBucketSizeNs;
mCurrentBucketNum += numBucketsForward;
- VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
+ VLOG("Gauge metric %lld: new bucket start time: %lld", (long long)mMetricId,
(long long)mCurrentBucketStartTimeNs);
}
@@ -433,7 +434,7 @@
info.mGaugeAtoms = slice.second;
auto& bucketList = mPastBuckets[slice.first];
bucketList.push_back(info);
- VLOG("gauge metric %lld, dump key value: %s", (long long)mMetricId,
+ VLOG("Gauge gauge metric %lld, dump key value: %s", (long long)mMetricId,
slice.first.toString().c_str());
}
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 4b543f8..9605b13 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -100,7 +100,7 @@
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
@@ -155,6 +155,7 @@
const size_t mDimensionHardLimit;
FRIEND_TEST(GaugeMetricProducerTest, TestWithCondition);
+ FRIEND_TEST(GaugeMetricProducerTest, TestWithSlicedCondition);
FRIEND_TEST(GaugeMetricProducerTest, TestNoCondition);
FRIEND_TEST(GaugeMetricProducerTest, TestPushedEventsWithUpgrade);
FRIEND_TEST(GaugeMetricProducerTest, TestPulledWithUpgrade);
diff --git a/cmds/statsd/src/metrics/MetricProducer.cpp b/cmds/statsd/src/metrics/MetricProducer.cpp
index f4495a1..bf529c8 100644
--- a/cmds/statsd/src/metrics/MetricProducer.cpp
+++ b/cmds/statsd/src/metrics/MetricProducer.cpp
@@ -33,7 +33,6 @@
bool condition;
ConditionKey conditionKey;
-
std::unordered_set<HashableDimensionKey> dimensionKeysInCondition;
if (mConditionSliced) {
for (const auto& link : mMetric2ConditionLinks) {
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index 4983f96..0b3d677 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -98,9 +98,9 @@
onConditionChangedLocked(condition, eventTime);
}
- void onSlicedConditionMayChange(const uint64_t eventTime) {
+ void onSlicedConditionMayChange(bool overallCondition, const uint64_t eventTime) {
std::lock_guard<std::mutex> lock(mMutex);
- onSlicedConditionMayChangeLocked(eventTime);
+ onSlicedConditionMayChangeLocked(overallCondition, eventTime);
}
bool isConditionSliced() const {
@@ -163,7 +163,8 @@
protected:
virtual void onConditionChangedLocked(const bool condition, const uint64_t eventTime) = 0;
- virtual void onSlicedConditionMayChangeLocked(const uint64_t eventTime) = 0;
+ virtual void onSlicedConditionMayChangeLocked(bool overallCondition,
+ const uint64_t eventTime) = 0;
virtual void onDumpReportLocked(const uint64_t dumpTimeNs,
android::util::ProtoOutputStream* protoOutput) = 0;
virtual size_t byteSizeLocked() const = 0;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index c773d4f..1be082a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -326,7 +326,8 @@
// notification, and the metric can query the sliced conditions that are
// interesting to it.
} else {
- mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(eventTime);
+ mAllMetricProducers[metricIndex]->onSlicedConditionMayChange(conditionCache[i],
+ eventTime);
}
}
}
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index ed4d7e4..e19e236 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -134,7 +134,8 @@
}
}
-void ValueMetricProducer::onSlicedConditionMayChangeLocked(const uint64_t eventTime) {
+void ValueMetricProducer::onSlicedConditionMayChangeLocked(bool overallCondition,
+ const uint64_t eventTime) {
VLOG("Metric %lld onSlicedConditionMayChange", (long long)mMetricId);
}
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index c4477b3..796e83a 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -93,7 +93,7 @@
void onConditionChangedLocked(const bool conditionMet, const uint64_t eventTime) override;
// Internal interface to handle sliced condition change.
- void onSlicedConditionMayChangeLocked(const uint64_t eventTime) override;
+ void onSlicedConditionMayChangeLocked(bool overallCondition, const uint64_t eventTime) override;
// Internal function to calculate the current used bytes.
size_t byteSizeLocked() const override;
diff --git a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
index ddfb8cc..4132703 100644
--- a/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/DurationTracker.h
@@ -92,7 +92,7 @@
const bool stopAll) = 0;
virtual void noteStopAll(const uint64_t eventTime) = 0;
- virtual void onSlicedConditionMayChange(const uint64_t timestamp) = 0;
+ virtual void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) = 0;
virtual void onConditionChanged(bool condition, const uint64_t timestamp) = 0;
// Flush stale buckets if needed, and return true if the tracker has no on-going duration
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
index df9e6ae..15d9619 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.cpp
@@ -245,7 +245,8 @@
return flushCurrentBucket(eventTimeNs, output);
}
-void MaxDurationTracker::onSlicedConditionMayChange(const uint64_t timestamp) {
+void MaxDurationTracker::onSlicedConditionMayChange(bool overallCondition,
+ const uint64_t timestamp) {
// Now for each of the on-going event, check if the condition has changed for them.
for (auto& pair : mInfos) {
if (pair.second.state == kStopped) {
diff --git a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
index 32d42fa..884e8ac 100644
--- a/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/MaxDurationTracker.h
@@ -53,7 +53,7 @@
const uint64_t& eventTimeNs,
std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
- void onSlicedConditionMayChange(const uint64_t timestamp) override;
+ void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) override;
void onConditionChanged(bool condition, const uint64_t timestamp) override;
int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
index da79217..50db9a0 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.cpp
@@ -214,7 +214,8 @@
return flushCurrentBucket(eventTimeNs, output);
}
-void OringDurationTracker::onSlicedConditionMayChange(const uint64_t timestamp) {
+void OringDurationTracker::onSlicedConditionMayChange(bool overallCondition,
+ const uint64_t timestamp) {
vector<pair<HashableDimensionKey, int>> startedToPaused;
vector<pair<HashableDimensionKey, int>> pausedToStarted;
if (!mStarted.empty()) {
diff --git a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
index ca8abfe..987e28e 100644
--- a/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
+++ b/cmds/statsd/src/metrics/duration_helper/OringDurationTracker.h
@@ -45,7 +45,7 @@
const bool stopAll) override;
void noteStopAll(const uint64_t eventTime) override;
- void onSlicedConditionMayChange(const uint64_t timestamp) override;
+ void onSlicedConditionMayChange(bool overallCondition, const uint64_t timestamp) override;
void onConditionChanged(bool condition, const uint64_t timestamp) override;
bool flushCurrentBucket(
diff --git a/cmds/statsd/tests/ConfigManager_test.cpp b/cmds/statsd/tests/ConfigManager_test.cpp
index 90c3a2f..838745e 100644
--- a/cmds/statsd/tests/ConfigManager_test.cpp
+++ b/cmds/statsd/tests/ConfigManager_test.cpp
@@ -64,16 +64,6 @@
const int64_t testConfigId = 12345;
-TEST(ConfigManagerTest, TestFakeConfig) {
- auto metricsManager = std::make_unique<MetricsManager>(
- ConfigKey(0, testConfigId), build_fake_config(), 1000, new UidMap(),
- new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
- [](const sp<IStatsCompanionService>&){}),
- new AlarmMonitor(10, [](const sp<IStatsCompanionService>&, int64_t){},
- [](const sp<IStatsCompanionService>&){}));
- EXPECT_TRUE(metricsManager->isConfigValid());
-}
-
/**
* Test the addOrUpdate and remove methods
*/
diff --git a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
index a75d6c8..2583c95 100644
--- a/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/GaugeMetricProducer_test.cpp
@@ -338,6 +338,82 @@
->mValue.int_value);
}
+TEST(GaugeMetricProducerTest, TestWithSlicedCondition) {
+ const int conditionTag = 65;
+ GaugeMetric metric;
+ metric.set_id(1111111);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_gauge_fields_filter()->set_include_all(true);
+ metric.set_condition(StringToId("APP_DIED"));
+ auto dim = metric.mutable_dimensions_in_what();
+ dim->set_field(tagId);
+ dim->add_child()->set_field(1);
+
+ dim = metric.mutable_dimensions_in_condition();
+ dim->set_field(conditionTag);
+ dim->add_child()->set_field(1);
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ EXPECT_CALL(*wizard, query(_, _, _, _, _, _))
+ .WillRepeatedly(
+ Invoke([](const int conditionIndex, const ConditionKey& conditionParameters,
+ const vector<Matcher>& dimensionFields, const bool isSubsetDim,
+ const bool isPartialLink,
+ std::unordered_set<HashableDimensionKey>* dimensionKeySet) {
+ dimensionKeySet->clear();
+ int pos[] = {1, 0, 0};
+ Field f(conditionTag, pos, 0);
+ HashableDimensionKey key;
+ key.mutableValues()->emplace_back(f, Value((int32_t)1000000));
+ dimensionKeySet->insert(key);
+
+ return ConditionState::kTrue;
+ }));
+
+ shared_ptr<MockStatsPullerManager> pullerManager =
+ make_shared<StrictMock<MockStatsPullerManager>>();
+ EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
+ EXPECT_CALL(*pullerManager, Pull(tagId, _))
+ .WillOnce(Invoke([](int tagId, vector<std::shared_ptr<LogEvent>>* data) {
+ data->clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ event->write(1000);
+ event->write(100);
+ event->init();
+ data->push_back(event);
+ return true;
+ }));
+
+ GaugeMetricProducer gaugeProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
+ pullerManager);
+ gaugeProducer.setBucketSize(60 * NS_PER_SEC);
+
+ gaugeProducer.onSlicedConditionMayChange(true, bucketStartTimeNs + 8);
+
+ EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ const auto& key = gaugeProducer.mCurrentSlicedBucket->begin()->first;
+ EXPECT_EQ(1UL, key.getDimensionKeyInWhat().getValues().size());
+ EXPECT_EQ(1000, key.getDimensionKeyInWhat().getValues()[0].mValue.int_value);
+
+ EXPECT_EQ(1UL, key.getDimensionKeyInCondition().getValues().size());
+ EXPECT_EQ(1000000, key.getDimensionKeyInCondition().getValues()[0].mValue.int_value);
+
+ EXPECT_EQ(0UL, gaugeProducer.mPastBuckets.size());
+
+ vector<shared_ptr<LogEvent>> allData;
+ allData.clear();
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event->write(1000);
+ event->write(110);
+ event->init();
+ allData.push_back(event);
+ gaugeProducer.onDataPulled(allData);
+
+ EXPECT_EQ(1UL, gaugeProducer.mCurrentSlicedBucket->size());
+ EXPECT_EQ(1UL, gaugeProducer.mPastBuckets.size());
+}
+
TEST(GaugeMetricProducerTest, TestAnomalyDetection) {
sp<AlarmMonitor> alarmMonitor;
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
diff --git a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
index 13cdb0b..817dcae 100644
--- a/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
+++ b/cmds/statsd/tests/metrics/OringDurationTracker_test.cpp
@@ -209,7 +209,7 @@
tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
- tracker.onSlicedConditionMayChange(eventStartTimeNs + 5);
+ tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
@@ -249,9 +249,9 @@
tracker.noteStart(kEventKey1, true, eventStartTimeNs, key1);
// condition to false; record duration 5n
- tracker.onSlicedConditionMayChange(eventStartTimeNs + 5);
+ tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 5);
// condition to true.
- tracker.onSlicedConditionMayChange(eventStartTimeNs + 1000);
+ tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 1000);
// 2nd duration: 1000ns
tracker.noteStop(kEventKey1, eventStartTimeNs + durationTimeNs, false);
@@ -291,7 +291,7 @@
tracker.noteStop(kEventKey1, eventStartTimeNs + 3, false);
- tracker.onSlicedConditionMayChange(eventStartTimeNs + 15);
+ tracker.onSlicedConditionMayChange(true, eventStartTimeNs + 15);
tracker.noteStop(kEventKey1, eventStartTimeNs + 2003, false);
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0afc1ce..4a4e36a 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -369,6 +369,7 @@
Landroid/bluetooth/BluetoothGatt;->mAuthRetryState:I
Landroid/bluetooth/BluetoothGatt;->refresh()Z
Landroid/bluetooth/BluetoothHeadset;->close()V
+Landroid/bluetooth/BluetoothMapClient;->sendMessage(Landroid/bluetooth/BluetoothDevice;[Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)Z
Landroid/bluetooth/BluetoothPan;->isTetheringOn()Z
Landroid/bluetooth/BluetoothPan;->setBluetoothTethering(Z)V
Landroid/bluetooth/BluetoothUuid;->RESERVED_UUIDS:[Landroid/os/ParcelUuid;
@@ -822,56 +823,24 @@
Landroid/hardware/usb/UsbRequest;->mLength:I
Landroid/hardware/usb/UsbRequest;->mNativeContext:J
Landroid/icu/impl/CurrencyData;-><init>()V
-Landroid/icu/impl/number/DecimalFormatProperties;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/impl/number/DecimalFormatProperties;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/impl/TimeZoneGenericNames;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/icu/text/ArabicShaping;->isAlefMaksouraChar(C)Z
Landroid/icu/text/ArabicShaping;->isSeenTailFamilyChar(C)I
Landroid/icu/text/ArabicShaping;->isTailChar(C)Z
Landroid/icu/text/ArabicShaping;->isYehHamzaChar(C)Z
-Landroid/icu/text/DateFormat;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/icu/text/DateFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/DateFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/icu/text/DateIntervalFormat;-><init>()V
-Landroid/icu/text/DateIntervalFormat;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V
-Landroid/icu/text/DecimalFormat_ICU58_Android;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/DecimalFormat_ICU58_Android;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/text/DecimalFormat;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/icu/text/DecimalFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/DecimalFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/DecimalFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/text/MessageFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/MessageFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/text/NumberFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/NumberFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/text/PluralFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/PluralRules$FixedDecimal;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/PluralRules$FixedDecimal;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/text/PluralRules;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/PluralRules;->writeObject(Ljava/io/ObjectOutputStream;)V
Landroid/icu/text/RuleBasedCollator;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/text/RuleBasedNumberFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/RuleBasedNumberFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/text/SelectFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/SimpleDateFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/SimpleDateFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
Landroid/icu/text/SpoofChecker$ScriptSet;->and(I)V
Landroid/icu/text/SpoofChecker$ScriptSet;-><init>()V
Landroid/icu/text/SpoofChecker$ScriptSet;->isFull()Z
Landroid/icu/text/SpoofChecker$ScriptSet;->setAll()V
-Landroid/icu/text/TimeZoneFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/text/TimeZoneFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
Landroid/icu/text/TimeZoneNames$DefaultTimeZoneNames$FactoryImpl;-><init>()V
Landroid/icu/text/Transliterator;->createFromRules(Ljava/lang/String;Ljava/lang/String;I)Landroid/icu/text/Transliterator;
Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
-Landroid/icu/util/Calendar;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/util/Calendar;->writeObject(Ljava/io/ObjectOutputStream;)V
-Landroid/icu/util/ChineseCalendar;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/util/IslamicCalendar;->readObject(Ljava/io/ObjectInputStream;)V
-Landroid/icu/util/SimpleTimeZone;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/inputmethodservice/InputMethodService;->mExtractEditText:Landroid/inputmethodservice/ExtractEditText;
Landroid/location/CountryDetector;->detectCountry()Landroid/location/Country;
Landroid/location/Country;->getCountryIso()Ljava/lang/String;
@@ -1989,7 +1958,6 @@
Landroid/util/Pools$SynchronizedPool;-><init>(I)V
Landroid/util/Rational;->mDenominator:I
Landroid/util/Rational;->mNumerator:I
-Landroid/util/Rational;->readObject(Ljava/io/ObjectInputStream;)V
Landroid/util/Singleton;->mInstance:Ljava/lang/Object;
Landroid/util/Slog;->d(Ljava/lang/String;Ljava/lang/String;)I
Landroid/util/SparseIntArray;->mKeys:[I
@@ -2838,8 +2806,6 @@
Lcom/android/okhttp/OkHttpClient;->dns:Lcom/android/okhttp/Dns;
Lcom/android/okhttp/OkHttpClient;->setProtocols(Ljava/util/List;)Lcom/android/okhttp/OkHttpClient;
Lcom/android/okhttp/OkHttpClient;->setRetryOnConnectionFailure(Z)V
-Lcom/android/okhttp/okio/ByteString;->readObject(Ljava/io/ObjectInputStream;)V
-Lcom/android/okhttp/okio/ByteString;->writeObject(Ljava/io/ObjectOutputStream;)V
Lcom/android/okhttp/Request;->headers:Lcom/android/okhttp/Headers;
Lcom/android/okhttp/Request;->method:Ljava/lang/String;
Lcom/android/okhttp/Request;->url:Lcom/android/okhttp/HttpUrl;
@@ -2942,20 +2908,14 @@
Ldalvik/system/VMRuntime;->vmLibrary()Ljava/lang/String;
Ldalvik/system/VMStack;->getCallingClassLoader()Ljava/lang/ClassLoader;
Ldalvik/system/VMStack;->getStackClass2()Ljava/lang/Class;
-Ljava/awt/font/NumericShaper;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/beans/PropertyChangeSupport;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/beans/PropertyChangeSupport;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/io/FileDescriptor;->descriptor:I
Ljava/io/FileDescriptor;->getInt$()I
Ljava/io/FileDescriptor;->setInt$(I)V
Ljava/io/FileInputStream;->fd:Ljava/io/FileDescriptor;
Ljava/io/FileOutputStream;->fd:Ljava/io/FileDescriptor;
-Ljava/io/File;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/io/File;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/io/ObjectStreamClass;->getConstructorId(Ljava/lang/Class;)J
Ljava/io/ObjectStreamClass;->newInstance(Ljava/lang/Class;J)Ljava/lang/Object;
Ljava/io/ObjectStreamClass;->newInstance()Ljava/lang/Object;
-Ljava/io/UncheckedIOException;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/lang/AbstractStringBuilder;->value:[C
Ljava/lang/Boolean;->value:Z
Ljava/lang/Byte;->value:B
@@ -2976,11 +2936,8 @@
Ljava/lang/Daemons;->start()V
Ljava/lang/Daemons;->stop()V
Ljava/lang/Double;->value:D
-Ljava/lang/Enum;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/lang/Float;->value:F
Ljava/lang/Integer;->value:I
-Ljava/lang/invoke/MethodType;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/lang/invoke/MethodType;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/lang/Long;->value:J
Ljava/lang/ref/FinalizerReference;->add(Ljava/lang/Object;)V
Ljava/lang/ref/FinalizerReference;->head:Ljava/lang/ref/FinalizerReference;
@@ -2996,10 +2953,6 @@
Ljava/lang/Runtime;->load(Ljava/lang/String;Ljava/lang/ClassLoader;)V
Ljava/lang/Runtime;->nativeLoad(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;
Ljava/lang/Short;->value:S
-Ljava/lang/StringBuffer;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/lang/StringBuffer;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/lang/StringBuilder;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/lang/StringBuilder;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/lang/String;-><init>(II[C)V
Ljava/lang/System;-><init>()V
Ljava/lang/Thread;->daemon:Z
@@ -3023,16 +2976,9 @@
Ljava/lang/Throwable;->cause:Ljava/lang/Throwable;
Ljava/lang/Throwable;->detailMessage:Ljava/lang/String;
Ljava/lang/Throwable;->nativeFillInStackTrace()Ljava/lang/Object;
-Ljava/lang/Throwable;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/lang/Throwable;->stackTrace:[Ljava/lang/StackTraceElement;
Ljava/lang/Throwable;->suppressedExceptions:Ljava/util/List;
-Ljava/lang/Throwable;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/lang/Void;-><init>()V
-Ljava/math/BigDecimal;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/math/BigDecimal;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/math/BigInteger;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/math/BigInteger;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/math/MathContext;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/net/Authenticator;->theAuthenticator:Ljava/net/Authenticator;
Ljava/net/DatagramSocket;->impl:Ljava/net/DatagramSocketImpl;
Ljava/net/HttpCookie;->httpOnly:Z
@@ -3044,8 +2990,6 @@
Ljava/net/Inet6Address$Inet6AddressHolder;->scope_id_set:Z
Ljava/net/Inet6Address$Inet6AddressHolder;->scope_ifname:Ljava/net/NetworkInterface;
Ljava/net/Inet6Address;-><init>()V
-Ljava/net/Inet6Address;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/net/Inet6Address;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/net/InetAddress;->clearDnsCache()V
Ljava/net/InetAddress;->holder:Ljava/net/InetAddress$InetAddressHolder;
Ljava/net/InetAddress$InetAddressHolder;->address:I
@@ -3054,19 +2998,11 @@
Ljava/net/InetAddress$InetAddressHolder;->originalHostName:Ljava/lang/String;
Ljava/net/InetAddress;->isNumeric(Ljava/lang/String;)Z
Ljava/net/InetAddress;->parseNumericAddress(Ljava/lang/String;)Ljava/net/InetAddress;
-Ljava/net/InetAddress;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/net/InetAddress;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/net/InetSocketAddress;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/net/InetSocketAddress;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/net/Socket;->getFileDescriptor$()Ljava/io/FileDescriptor;
Ljava/net/Socket;->impl:Ljava/net/SocketImpl;
Ljava/net/URI;->host:Ljava/lang/String;
-Ljava/net/URI;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/net/URI;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/net/URL;->handler:Ljava/net/URLStreamHandler;
Ljava/net/URL;->handlers:Ljava/util/Hashtable;
-Ljava/net/URL;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/net/URL;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/nio/Buffer;->address:J
Ljava/nio/Buffer;->capacity:I
Ljava/nio/Buffer;->_elementSizeShift:I
@@ -3077,168 +3013,37 @@
Ljava/nio/ByteBuffer;->offset:I
Ljava/nio/charset/CharsetEncoder;->canEncode(Ljava/nio/CharBuffer;)Z
Ljava/nio/DirectByteBuffer;-><init>(JI)V
-Ljava/nio/file/DirectoryIteratorException;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/nio/NIOAccess;->getBaseArray(Ljava/nio/Buffer;)Ljava/lang/Object;
Ljava/nio/NIOAccess;->getBaseArrayOffset(Ljava/nio/Buffer;)I
Ljava/nio/NIOAccess;->getBasePointer(Ljava/nio/Buffer;)J
-Ljava/security/cert/CertificateRevokedException;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/security/cert/CertificateRevokedException;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/security/cert/CertPathValidatorException;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/security/CodeSigner;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/security/GuardedObject;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/security/Provider;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/security/SignedObject;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/security/spec/ECParameterSpec;->getCurveName()Ljava/lang/String;
Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V
-Ljava/security/Timestamp;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/text/ChoiceFormat;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/text/DateFormat;->is24Hour:Ljava/lang/Boolean;
-Ljava/text/DateFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/text/DateFormatSymbols;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/text/DecimalFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/text/DecimalFormatSymbols;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/text/DecimalFormatSymbols;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/text/DecimalFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/text/MessageFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/text/NumberFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/text/NumberFormat;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/text/SimpleDateFormat;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/AbstractChronology;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/HijrahChronology;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/HijrahDate;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/IsoChronology;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/JapaneseChronology;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/JapaneseDate;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/JapaneseEra;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/MinguoChronology;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/MinguoDate;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/ThaiBuddhistChronology;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/chrono/ThaiBuddhistDate;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/Duration;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/time/Duration;->toSeconds()Ljava/math/BigDecimal;
-Ljava/time/Instant;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/LocalDate;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/LocalDateTime;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/LocalTime;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/MonthDay;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/time/OffsetDateTime;-><init>(Ljava/time/LocalDateTime;Ljava/time/ZoneOffset;)V
-Ljava/time/OffsetDateTime;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/OffsetTime;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/Period;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/temporal/ValueRange;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/temporal/WeekFields;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/YearMonth;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/Year;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/ZonedDateTime;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/ZoneId;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/ZoneOffset;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/zone/ZoneOffsetTransition;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/zone/ZoneOffsetTransitionRule;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/time/zone/ZoneRules;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/ArrayDeque;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/ArrayDeque;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/ArrayList;->elementData:[Ljava/lang/Object;
-Ljava/util/ArrayList;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/util/ArrayList;->size:I
Ljava/util/ArrayList$SubList;->parent:Ljava/util/AbstractList;
Ljava/util/ArrayList$SubList;->parentOffset:I
Ljava/util/ArrayList$SubList;->size:I
-Ljava/util/ArrayList;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Arrays$ArrayList;->a:[Ljava/lang/Object;
-Ljava/util/BitSet;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/BitSet;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/Calendar;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/Calendar;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Calendar;->zone:Ljava/util/TimeZone;
Ljava/util/Collections$EmptyList;-><init>()V
-Ljava/util/Collections$SetFromMap;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/util/Collections$SynchronizedCollection;->c:Ljava/util/Collection;
-Ljava/util/Collections$SynchronizedCollection;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Collections$SynchronizedMap;->m:Ljava/util/Map;
-Ljava/util/Collections$SynchronizedMap;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Collections$UnmodifiableCollection;->c:Ljava/util/Collection;
Ljava/util/Collections$UnmodifiableMap;->m:Ljava/util/Map;
-Ljava/util/concurrent/atomic/AtomicReferenceArray;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/atomic/DoubleAccumulator;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/atomic/DoubleAdder;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/atomic/LongAccumulator;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/atomic/LongAdder;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/util/concurrent/ConcurrentHashMap$BaseIterator;->hasMoreElements()Z
-Ljava/util/concurrent/ConcurrentHashMap;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/ConcurrentHashMap;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/ConcurrentLinkedDeque;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/ConcurrentLinkedDeque;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/ConcurrentLinkedQueue;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/ConcurrentLinkedQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/ConcurrentSkipListMap;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/ConcurrentSkipListMap;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/CopyOnWriteArrayList;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/CopyOnWriteArrayList;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/ForkJoinTask;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/ForkJoinTask;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/concurrent/FutureTask;->callable:Ljava/util/concurrent/Callable;
-Ljava/util/concurrent/LinkedBlockingDeque;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/LinkedBlockingDeque;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/concurrent/LinkedBlockingQueue;->capacity:I
-Ljava/util/concurrent/LinkedBlockingQueue;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/LinkedBlockingQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/LinkedTransferQueue;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/LinkedTransferQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/locks/ReentrantLock$Sync;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/locks/ReentrantReadWriteLock$Sync;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/locks/StampedLock;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/PriorityBlockingQueue;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/PriorityBlockingQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/SynchronousQueue;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/concurrent/SynchronousQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/concurrent/ThreadLocalRandom;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/Date;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/Date;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/EnumMap;->keyType:Ljava/lang/Class;
-Ljava/util/EnumMap;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/EnumMap;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/EnumSet;->elementType:Ljava/lang/Class;
-Ljava/util/EnumSet;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/GregorianCalendar;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/util/HashMap$HashIterator;->hasNext()Z
-Ljava/util/HashMap;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/HashMap;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/HashSet;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/HashSet;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/Hashtable;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/Hashtable;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/IdentityHashMap;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/IdentityHashMap;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/InvalidPropertiesFormatException;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/InvalidPropertiesFormatException;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/LinkedHashMap;->eldest()Ljava/util/Map$Entry;
Ljava/util/LinkedHashMap$LinkedHashIterator;->hasNext()Z
-Ljava/util/LinkedList;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/LinkedList;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/Locale;->createConstant(Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
-Ljava/util/Locale;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/Locale;->readResolve()Ljava/lang/Object;
-Ljava/util/Locale;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/logging/LogRecord;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/logging/LogRecord;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/prefs/NodeChangeEvent;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/prefs/NodeChangeEvent;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/prefs/PreferenceChangeEvent;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/prefs/PreferenceChangeEvent;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/PriorityQueue;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/PriorityQueue;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/Random;->readObject(Ljava/io/ObjectInputStream;)V
Ljava/util/Random;->seedUniquifier()J
-Ljava/util/Random;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/regex/Matcher;->appendPos:I
-Ljava/util/regex/Pattern;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/SimpleTimeZone;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/SimpleTimeZone;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/TreeMap;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/TreeMap;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/TreeSet;->readObject(Ljava/io/ObjectInputStream;)V
-Ljava/util/TreeSet;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljava/util/Vector;->writeObject(Ljava/io/ObjectOutputStream;)V
Ljava/util/zip/Deflater;->buf:[B
Ljava/util/zip/Deflater;->finished:Z
Ljava/util/zip/Deflater;->finish:Z
@@ -3254,23 +3059,11 @@
Ljava/util/zip/Inflater;->off:I
Ljava/util/zip/ZipEntry;-><init>(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V
Ljava/util/zip/ZipFile;->jzfile:J
-Ljavax/crypto/SealedObject;->readObject(Ljava/io/ObjectInputStream;)V
Ljavax/net/ssl/SSLServerSocketFactory;->defaultServerSocketFactory:Ljavax/net/ssl/SSLServerSocketFactory;
Ljavax/net/ssl/SSLSocketFactory;->defaultSocketFactory:Ljavax/net/ssl/SSLSocketFactory;
-Ljavax/security/auth/Subject;->readObject(Ljava/io/ObjectInputStream;)V
-Ljavax/security/auth/Subject$SecureSet;->readObject(Ljava/io/ObjectInputStream;)V
-Ljavax/security/auth/Subject$SecureSet;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljavax/security/auth/Subject;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljavax/security/auth/x500/X500Principal;->readObject(Ljava/io/ObjectInputStream;)V
-Ljavax/security/auth/x500/X500Principal;->writeObject(Ljava/io/ObjectOutputStream;)V
-Ljavax/xml/datatype/DatatypeConfigurationException;->readObject(Ljava/io/ObjectInputStream;)V
-Ljavax/xml/namespace/QName;->readObject(Ljava/io/ObjectInputStream;)V
Llibcore/util/ZoneInfo;->mTransitions:[J
-Llibcore/util/ZoneInfo;->readObject(Ljava/io/ObjectInputStream;)V
Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>(Ljavax/net/ssl/SSLSocketFactory;)V
Lorg/apache/http/conn/ssl/SSLSocketFactory;-><init>()V
Lorg/json/JSONArray;->values:Ljava/util/List;
Lorg/json/JSONObject;->writeTo(Lorg/json/JSONStringer;)V
Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
-Lsun/security/util/ObjectIdentifier;->readObject(Ljava/io/ObjectInputStream;)V
-Lsun/security/util/ObjectIdentifier;->writeObject(Ljava/io/ObjectOutputStream;)V
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 3047cdb..289a4dd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -959,8 +959,10 @@
* @hide
*/
static public boolean isHighEndGfx() {
- return !isLowRamDeviceStatic() &&
- !Resources.getSystem().getBoolean(com.android.internal.R.bool.config_avoidGfxAccel);
+ return !isLowRamDeviceStatic()
+ && !RoSystemProperties.CONFIG_AVOID_GFX_ACCEL
+ && !Resources.getSystem()
+ .getBoolean(com.android.internal.R.bool.config_avoidGfxAccel);
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f01eee4..1df724e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -30,12 +30,15 @@
import android.app.assist.AssistContent;
import android.app.assist.AssistStructure;
import android.app.backup.BackupAgent;
+import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityLifecycleItem.LifecycleState;
+import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ActivityResultItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.PendingTransactionActions;
import android.app.servertransaction.PendingTransactionActions.StopInfo;
import android.app.servertransaction.TransactionExecutor;
+import android.app.servertransaction.TransactionExecutorHelper;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
@@ -520,6 +523,10 @@
return activityInfo.persistableMode == ActivityInfo.PERSIST_ACROSS_REBOOTS;
}
+ public boolean isVisibleFromServer() {
+ return activity != null && activity.mVisibleFromServer;
+ }
+
public String toString() {
ComponentName componentName = intent != null ? intent.getComponent() : null;
return "ActivityRecord{"
@@ -1797,6 +1804,7 @@
// message is handled.
transaction.recycle();
}
+ // TODO(lifecycler): Recycle locally scheduled transactions.
break;
}
Object obj = msg.obj;
@@ -2755,6 +2763,11 @@
}
}
+ @Override
+ TransactionExecutor getTransactionExecutor() {
+ return mTransactionExecutor;
+ }
+
void sendMessage(int what, Object obj) {
sendMessage(what, obj, 0, 0, false);
}
@@ -4723,15 +4736,22 @@
return;
}
- // TODO(b/73747058): Investigate converting this to use transaction to relaunch.
- handleRelaunchActivityInner(r, 0 /* configChanges */, null /* pendingResults */,
- null /* pendingIntents */, null /* pendingActions */, prevState != ON_RESUME,
- r.overrideConfig, "handleRelaunchActivityLocally");
- // Restore back to the previous state before relaunch if needed.
- if (prevState != r.getLifecycleState()) {
- mTransactionExecutor.cycleToPath(r, prevState);
- }
+ // Initialize a relaunch request.
+ final MergedConfiguration mergedConfiguration = new MergedConfiguration(
+ r.createdConfig != null ? r.createdConfig : mConfiguration,
+ r.overrideConfig);
+ final ActivityRelaunchItem activityRelaunchItem = ActivityRelaunchItem.obtain(
+ null /* pendingResults */, null /* pendingIntents */, 0 /* configChanges */,
+ mergedConfiguration, r.mPreserveWindow);
+ // Make sure to match the existing lifecycle state in the end of the transaction.
+ final ActivityLifecycleItem lifecycleRequest =
+ TransactionExecutorHelper.getLifecycleRequestForCurrentState(r);
+ // Schedule the transaction.
+ final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
+ transaction.addCallback(activityRelaunchItem);
+ transaction.setLifecycleStateRequest(lifecycleRequest);
+ executeTransaction(transaction);
}
private void handleRelaunchActivityInner(ActivityClientRecord r, int configChanges,
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index f38c80c..a68136b 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2167,15 +2167,16 @@
@Override
public PersistableBundle getSuspendedPackageAppExtras(String packageName) {
try {
- return mPM.getPackageSuspendedAppExtras(packageName, mContext.getUserId());
+ return mPM.getSuspendedPackageAppExtras(packageName, mContext.getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
- public PersistableBundle getSuspendedPackageAppExtras() {
- return getSuspendedPackageAppExtras(mContext.getOpPackageName());
+ public Bundle getSuspendedPackageAppExtras() {
+ final PersistableBundle extras = getSuspendedPackageAppExtras(mContext.getOpPackageName());
+ return extras != null ? new Bundle(extras.deepCopy()) : null;
}
@Override
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index 961bca2..925080e 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -17,6 +17,7 @@
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.PendingTransactionActions;
+import android.app.servertransaction.TransactionExecutor;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.content.res.Configuration;
@@ -43,6 +44,22 @@
sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
+ /**
+ * Execute transaction immediately without scheduling it. This is used for local requests, so
+ * it will also recycle the transaction.
+ */
+ void executeTransaction(ClientTransaction transaction) {
+ transaction.preExecute(this);
+ getTransactionExecutor().execute(transaction);
+ transaction.recycle();
+ }
+
+ /**
+ * Get the {@link TransactionExecutor} that will be performing lifecycle transitions and
+ * callbacks for activities.
+ */
+ abstract TransactionExecutor getTransactionExecutor();
+
abstract void sendMessage(int what, Object obj);
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 99efecd..e1a02fa 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -94,6 +94,7 @@
void registerUidObserver(in IUidObserver observer, int which, int cutpoint,
String callingPackage);
void unregisterUidObserver(in IUidObserver observer);
+ boolean isUidActive(int uid, String callingPackage);
// =============== End of transactions used on native side as well ============================
// Special low-level communication with activity manager.
@@ -322,12 +323,14 @@
/**
* Informs ActivityManagerService that the keyguard is showing.
*
- * @param showing True if the keyguard is showing, false otherwise.
+ * @param showingKeyguard True if the keyguard is showing, false otherwise.
+ * @param showingAod True if AOD is showing, false otherwise.
* @param secondaryDisplayShowing The displayId of the secondary display on which the keyguard
* is showing, or INVALID_DISPLAY if there is no such display. Only meaningful if
* showing is true.
*/
- void setLockScreenShown(boolean showing, int secondaryDisplayShowing);
+ void setLockScreenShown(boolean showingKeyguard, boolean showingAod,
+ int secondaryDisplayShowing);
boolean finishActivityAffinity(in IBinder token);
// This is not public because you need to be very careful in how you
// manage your activity to make sure it is always the uid you expect.
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 19240e2..465340f 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -57,10 +57,7 @@
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.service.wallpaper.WallpaperService;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -444,6 +441,9 @@
synchronized (this) {
mCachedWallpaper = null;
mCachedWallpaperUserId = 0;
+ if (mDefaultWallpaper != null) {
+ mDefaultWallpaper.recycle();
+ }
mDefaultWallpaper = null;
}
}
@@ -915,9 +915,14 @@
/**
* Get the primary colors of a wallpaper.
*
- * <p>You can expect null if:
- * • Colors are still being processed by the system.
- * • A live wallpaper doesn't implement {@link WallpaperService.Engine#onComputeColors()}.
+ * <p>This method can return {@code null} when:
+ * <ul>
+ * <li>Colors are still being processed by the system.</li>
+ * <li>The user has chosen to use a live wallpaper: live wallpapers might not
+ * implement
+ * {@link android.service.wallpaper.WallpaperService.Engine#onComputeColors()
+ * WallpaperService.Engine#onComputeColors()}.</li>
+ * </ul>
*
* @param which Wallpaper type. Must be either {@link #FLAG_SYSTEM} or
* {@link #FLAG_LOCK}.
@@ -929,7 +934,7 @@
}
/**
- * Get the primary colors of a wallpaper
+ * Get the primary colors of the wallpaper configured in the given user.
* @param which wallpaper type. Must be either {@link #FLAG_SYSTEM} or
* {@link #FLAG_LOCK}
* @param userId Owner of the wallpaper.
@@ -1559,11 +1564,13 @@
* Specify extra padding that the wallpaper should have outside of the display.
* That is, the given padding supplies additional pixels the wallpaper should extend
* outside of the display itself.
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER_HINTS}.
+ *
* @param padding The number of pixels the wallpaper should extend beyond the display,
* on its left, top, right, and bottom sides.
- * @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_HINTS)
public void setDisplayPadding(Rect padding) {
try {
@@ -1600,11 +1607,11 @@
}
/**
- * Clear the wallpaper.
+ * Reset all wallpaper to the factory default.
*
- * @hide
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#SET_WALLPAPER}.
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER)
public void clearWallpaper() {
clearWallpaper(FLAG_LOCK, mContext.getUserId());
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 8dbb9f0..3015398 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -8755,6 +8755,7 @@
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.MANAGE_USERS)
public boolean isDeviceProvisioned() {
try {
return mService.isDeviceProvisioned();
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index ee13880..02afcc7 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -65,7 +65,6 @@
NETWORK_TYPE_UNMETERED,
NETWORK_TYPE_NOT_ROAMING,
NETWORK_TYPE_CELLULAR,
- NETWORK_TYPE_METERED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface NetworkType {}
@@ -253,7 +252,7 @@
/**
* @hide
*/
- public static final int FLAG_IS_PREFETCH = 1 << 2;
+ public static final int FLAG_PREFETCH = 1 << 2;
/**
* This job needs to be exempted from the app standby throttling. Only the system (UID 1000)
@@ -296,7 +295,8 @@
private final boolean hasEarlyConstraint;
private final boolean hasLateConstraint;
private final NetworkRequest networkRequest;
- private final long networkBytes;
+ private final long networkDownloadBytes;
+ private final long networkUploadBytes;
private final long minLatencyMillis;
private final long maxExecutionDelayMillis;
private final boolean isPeriodic;
@@ -317,30 +317,28 @@
}
/**
- * Bundle of extras which are returned to your application at execution time.
+ * @see JobInfo.Builder#setExtras(PersistableBundle)
*/
public @NonNull PersistableBundle getExtras() {
return extras;
}
/**
- * Bundle of transient extras which are returned to your application at execution time,
- * but not persisted by the system.
+ * @see JobInfo.Builder#setTransientExtras(Bundle)
*/
public @NonNull Bundle getTransientExtras() {
return transientExtras;
}
/**
- * ClipData of information that is returned to your application at execution time,
- * but not persisted by the system.
+ * @see JobInfo.Builder#setClipData(ClipData, int)
*/
public @Nullable ClipData getClipData() {
return clipData;
}
/**
- * Permission grants that go along with {@link #getClipData}.
+ * @see JobInfo.Builder#setClipData(ClipData, int)
*/
public int getClipGrantFlags() {
return clipGrantFlags;
@@ -369,32 +367,28 @@
}
/**
- * Whether this job requires that the device be charging (or be a non-battery-powered
- * device connected to permanent power, such as Android TV devices).
+ * @see JobInfo.Builder#setRequiresCharging(boolean)
*/
public boolean isRequireCharging() {
return (constraintFlags & CONSTRAINT_FLAG_CHARGING) != 0;
}
/**
- * Whether this job needs the device's battery level to not be at below the critical threshold.
+ * @see JobInfo.Builder#setRequiresBatteryNotLow(boolean)
*/
public boolean isRequireBatteryNotLow() {
return (constraintFlags & CONSTRAINT_FLAG_BATTERY_NOT_LOW) != 0;
}
/**
- * Whether this job requires that the user <em>not</em> be interacting with the device.
- *
- * <p class="note">This is <em>not</em> the same as "doze" or "device idle";
- * it is purely about the user's direct interactions.</p>
+ * @see JobInfo.Builder#setRequiresDeviceIdle(boolean)
*/
public boolean isRequireDeviceIdle() {
return (constraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0;
}
/**
- * Whether this job needs the device's storage to not be low.
+ * @see JobInfo.Builder#setRequiresStorageNotLow(boolean)
*/
public boolean isRequireStorageNotLow() {
return (constraintFlags & CONSTRAINT_FLAG_STORAGE_NOT_LOW) != 0;
@@ -410,6 +404,7 @@
/**
* Which content: URIs must change for the job to be scheduled. Returns null
* if there are none required.
+ * @see JobInfo.Builder#addTriggerContentUri(TriggerContentUri)
*/
public @Nullable TriggerContentUri[] getTriggerContentUris() {
return triggerContentUris;
@@ -418,6 +413,7 @@
/**
* When triggering on content URI changes, this is the delay from when a change
* is detected until the job is scheduled.
+ * @see JobInfo.Builder#setTriggerContentUpdateDelay(long)
*/
public long getTriggerContentUpdateDelay() {
return triggerContentUpdateDelay;
@@ -426,6 +422,7 @@
/**
* When triggering on content URI changes, this is the maximum delay we will
* use before scheduling the job.
+ * @see JobInfo.Builder#setTriggerContentMaxDelay(long)
*/
public long getTriggerContentMaxDelay() {
return triggerContentMaxDelay;
@@ -466,28 +463,59 @@
}
/**
- * Return the estimated size of network traffic that will be performed by
+ * @deprecated replaced by {@link #getEstimatedNetworkDownloadBytes()} and
+ * {@link #getEstimatedNetworkUploadBytes()}.
+ * @removed
+ */
+ @Deprecated
+ public @BytesLong long getEstimatedNetworkBytes() {
+ if (networkDownloadBytes == NETWORK_BYTES_UNKNOWN
+ && networkUploadBytes == NETWORK_BYTES_UNKNOWN) {
+ return NETWORK_BYTES_UNKNOWN;
+ } else if (networkDownloadBytes == NETWORK_BYTES_UNKNOWN) {
+ return networkUploadBytes;
+ } else if (networkUploadBytes == NETWORK_BYTES_UNKNOWN) {
+ return networkDownloadBytes;
+ } else {
+ return networkDownloadBytes + networkUploadBytes;
+ }
+ }
+
+ /**
+ * Return the estimated size of download traffic that will be performed by
* this job, in bytes.
*
- * @return Estimated size of network traffic, or
+ * @return Estimated size of download traffic, or
* {@link #NETWORK_BYTES_UNKNOWN} when unknown.
- * @see Builder#setEstimatedNetworkBytes(long)
+ * @see Builder#setEstimatedNetworkBytes(long, long)
*/
- public @BytesLong long getEstimatedNetworkBytes() {
- return networkBytes;
+ public @BytesLong long getEstimatedNetworkDownloadBytes() {
+ return networkDownloadBytes;
+ }
+
+ /**
+ * Return the estimated size of upload traffic that will be performed by
+ * this job, in bytes.
+ *
+ * @return Estimated size of upload traffic, or
+ * {@link #NETWORK_BYTES_UNKNOWN} when unknown.
+ * @see Builder#setEstimatedNetworkBytes(long, long)
+ */
+ public @BytesLong long getEstimatedNetworkUploadBytes() {
+ return networkUploadBytes;
}
/**
* Set for a job that does not recur periodically, to specify a delay after which the job
* will be eligible for execution. This value is not set if the job recurs periodically.
+ * @see JobInfo.Builder#setMinimumLatency(long)
*/
public long getMinLatencyMillis() {
return minLatencyMillis;
}
/**
- * See {@link Builder#setOverrideDeadline(long)}. This value is not set if the job recurs
- * periodically.
+ * @see JobInfo.Builder#setOverrideDeadline(long)
*/
public long getMaxExecutionDelayMillis() {
return maxExecutionDelayMillis;
@@ -495,13 +523,15 @@
/**
* Track whether this job will repeat with a given period.
+ * @see JobInfo.Builder#setPeriodic(long)
+ * @see JobInfo.Builder#setPeriodic(long, long)
*/
public boolean isPeriodic() {
return isPeriodic;
}
/**
- * @return Whether or not this job should be persisted across device reboots.
+ * @see JobInfo.Builder#setPersisted(boolean)
*/
public boolean isPersisted() {
return isPersisted;
@@ -510,6 +540,8 @@
/**
* Set to the interval between occurrences of this job. This value is <b>not</b> set if the
* job does not recur periodically.
+ * @see JobInfo.Builder#setPeriodic(long)
+ * @see JobInfo.Builder#setPeriodic(long, long)
*/
public long getIntervalMillis() {
return intervalMillis;
@@ -518,6 +550,8 @@
/**
* Flex time for this job. Only valid if this is a periodic job. The job can
* execute at any time in a window of flex length at the end of the period.
+ * @see JobInfo.Builder#setPeriodic(long)
+ * @see JobInfo.Builder#setPeriodic(long, long)
*/
public long getFlexMillis() {
return flexMillis;
@@ -527,6 +561,7 @@
* The amount of time the JobScheduler will wait before rescheduling a failed job. This value
* will be increased depending on the backoff policy specified at job creation time. Defaults
* to 30 seconds, minimum is currently 10 seconds.
+ * @see JobInfo.Builder#setBackoffCriteria(long, int)
*/
public long getInitialBackoffMillis() {
return initialBackoffMillis;
@@ -534,12 +569,27 @@
/**
* Return the backoff policy of this job.
+ * @see JobInfo.Builder#setBackoffCriteria(long, int)
*/
public @BackoffPolicy int getBackoffPolicy() {
return backoffPolicy;
}
/**
+ * @see JobInfo.Builder#setImportantWhileForeground(boolean)
+ */
+ public boolean isImportantWhileForeground() {
+ return (flags & FLAG_IMPORTANT_WHILE_FOREGROUND) != 0;
+ }
+
+ /**
+ * @see JobInfo.Builder#setPrefetch(boolean)
+ */
+ public boolean isPrefetch() {
+ return (flags & FLAG_PREFETCH) != 0;
+ }
+
+ /**
* User can specify an early constraint of 0L, which is valid, so we keep track of whether the
* function was called at all.
* @hide
@@ -610,7 +660,10 @@
if (!Objects.equals(networkRequest, j.networkRequest)) {
return false;
}
- if (networkBytes != j.networkBytes) {
+ if (networkDownloadBytes != j.networkDownloadBytes) {
+ return false;
+ }
+ if (networkUploadBytes != j.networkUploadBytes) {
return false;
}
if (minLatencyMillis != j.minLatencyMillis) {
@@ -673,7 +726,8 @@
if (networkRequest != null) {
hashCode = 31 * hashCode + networkRequest.hashCode();
}
- hashCode = 31 * hashCode + Long.hashCode(networkBytes);
+ hashCode = 31 * hashCode + Long.hashCode(networkDownloadBytes);
+ hashCode = 31 * hashCode + Long.hashCode(networkUploadBytes);
hashCode = 31 * hashCode + Long.hashCode(minLatencyMillis);
hashCode = 31 * hashCode + Long.hashCode(maxExecutionDelayMillis);
hashCode = 31 * hashCode + Boolean.hashCode(isPeriodic);
@@ -708,7 +762,8 @@
} else {
networkRequest = null;
}
- networkBytes = in.readLong();
+ networkDownloadBytes = in.readLong();
+ networkUploadBytes = in.readLong();
minLatencyMillis = in.readLong();
maxExecutionDelayMillis = in.readLong();
isPeriodic = in.readInt() == 1;
@@ -737,7 +792,8 @@
triggerContentUpdateDelay = b.mTriggerContentUpdateDelay;
triggerContentMaxDelay = b.mTriggerContentMaxDelay;
networkRequest = b.mNetworkRequest;
- networkBytes = b.mNetworkBytes;
+ networkDownloadBytes = b.mNetworkDownloadBytes;
+ networkUploadBytes = b.mNetworkUploadBytes;
minLatencyMillis = b.mMinLatencyMillis;
maxExecutionDelayMillis = b.mMaxExecutionDelayMillis;
isPeriodic = b.mIsPeriodic;
@@ -780,7 +836,8 @@
} else {
out.writeInt(0);
}
- out.writeLong(networkBytes);
+ out.writeLong(networkDownloadBytes);
+ out.writeLong(networkUploadBytes);
out.writeLong(minLatencyMillis);
out.writeLong(maxExecutionDelayMillis);
out.writeInt(isPeriodic ? 1 : 0);
@@ -914,7 +971,8 @@
// Requirements.
private int mConstraintFlags;
private NetworkRequest mNetworkRequest;
- private long mNetworkBytes = NETWORK_BYTES_UNKNOWN;
+ private long mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN;
+ private long mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN;
private ArrayList<TriggerContentUri> mTriggerContentUris;
private long mTriggerContentUpdateDelay = -1;
private long mTriggerContentMaxDelay = -1;
@@ -965,6 +1023,7 @@
/**
* Set optional extras. This is persisted, so we only allow primitive types.
* @param extras Bundle containing extras you want the scheduler to hold on to for you.
+ * @see JobInfo#getExtras()
*/
public Builder setExtras(@NonNull PersistableBundle extras) {
mExtras = extras;
@@ -979,6 +1038,7 @@
* {@link android.app.job.JobInfo.Builder#build()} is called.</p>
*
* @param extras Bundle containing extras you want the scheduler to hold on to for you.
+ * @see JobInfo#getTransientExtras()
*/
public Builder setTransientExtras(@NonNull Bundle extras) {
mTransientExtras = extras;
@@ -1006,6 +1066,8 @@
* a combination of {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION},
* {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, and
* {@link android.content.Intent#FLAG_GRANT_PREFIX_URI_PERMISSION}.
+ * @see JobInfo#getClipData()
+ * @see JobInfo#getClipGrantFlags()
*/
public Builder setClipData(@Nullable ClipData clip, int grantFlags) {
mClipData = clip;
@@ -1096,6 +1158,16 @@
}
/**
+ * @deprecated replaced by
+ * {@link #setEstimatedNetworkBytes(long, long)}.
+ * @removed
+ */
+ @Deprecated
+ public Builder setEstimatedNetworkBytes(@BytesLong long networkBytes) {
+ return setEstimatedNetworkBytes(networkBytes, NETWORK_BYTES_UNKNOWN);
+ }
+
+ /**
* Set the estimated size of network traffic that will be performed by
* this job, in bytes.
* <p>
@@ -1112,23 +1184,30 @@
* <li>A job that synchronizes email could end up using an extreme range
* of data, from under 1KB when nothing has changed, to dozens of MB
* when there are new emails with attachments. Jobs that cannot provide
- * reasonable estimates should leave this estimated value undefined.
+ * reasonable estimates should use the sentinel value
+ * {@link JobInfo#NETWORK_BYTES_UNKNOWN}.
* </ul>
* Note that the system may choose to delay jobs with large network
* usage estimates when the device has a poor network connection, in
* order to save battery.
+ * <p>
+ * The values provided here only reflect the traffic that will be
+ * performed by the base job; if you're using {@link JobWorkItem} then
+ * you also need to define the network traffic used by each work item
+ * when constructing them.
*
- * @param networkBytes The estimated size of network traffic that will
- * be performed by this job, in bytes. This value only
- * reflects the traffic that will be performed by the base
- * job; if you're using {@link JobWorkItem} then you also
- * need to define the network traffic used by each work item
- * when constructing them.
- * @see JobInfo#getEstimatedNetworkBytes()
- * @see JobWorkItem#JobWorkItem(android.content.Intent, long)
+ * @param downloadBytes The estimated size of network traffic that will
+ * be downloaded by this job, in bytes.
+ * @param uploadBytes The estimated size of network traffic that will be
+ * uploaded by this job, in bytes.
+ * @see JobInfo#getEstimatedNetworkDownloadBytes()
+ * @see JobInfo#getEstimatedNetworkUploadBytes()
+ * @see JobWorkItem#JobWorkItem(android.content.Intent, long, long)
*/
- public Builder setEstimatedNetworkBytes(@BytesLong long networkBytes) {
- mNetworkBytes = networkBytes;
+ public Builder setEstimatedNetworkBytes(@BytesLong long downloadBytes,
+ @BytesLong long uploadBytes) {
+ mNetworkDownloadBytes = downloadBytes;
+ mNetworkUploadBytes = uploadBytes;
return this;
}
@@ -1146,6 +1225,7 @@
*
* @param requiresCharging Pass {@code true} to require that the device be
* charging in order to run the job.
+ * @see JobInfo#isRequireCharging()
*/
public Builder setRequiresCharging(boolean requiresCharging) {
mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_CHARGING)
@@ -1159,6 +1239,7 @@
* is not low, which is generally the point where the user is given a "low battery"
* warning.
* @param batteryNotLow Whether or not the device's battery level must not be low.
+ * @see JobInfo#isRequireBatteryNotLow()
*/
public Builder setRequiresBatteryNotLow(boolean batteryNotLow) {
mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_BATTERY_NOT_LOW)
@@ -1183,6 +1264,7 @@
*
* @param requiresDeviceIdle Pass {@code true} to prevent the job from running
* while the device is being used interactively.
+ * @see JobInfo#isRequireDeviceIdle()
*/
public Builder setRequiresDeviceIdle(boolean requiresDeviceIdle) {
mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_DEVICE_IDLE)
@@ -1196,6 +1278,7 @@
* in a low storage state, which is generally the point where the user is given a
* "low storage" warning.
* @param storageNotLow Whether or not the device's available storage must not be low.
+ * @see JobInfo#isRequireStorageNotLow()
*/
public Builder setRequiresStorageNotLow(boolean storageNotLow) {
mConstraintFlags = (mConstraintFlags&~CONSTRAINT_FLAG_STORAGE_NOT_LOW)
@@ -1228,6 +1311,7 @@
* job}
*
* @param uri The content: URI to monitor.
+ * @see JobInfo#getTriggerContentUris()
*/
public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) {
if (mTriggerContentUris == null) {
@@ -1242,6 +1326,7 @@
* the job is scheduled. If there are more changes during that time, the delay
* will be reset to start at the time of the most recent change.
* @param durationMs Delay after most recent content change, in milliseconds.
+ * @see JobInfo#getTriggerContentUpdateDelay()
*/
public Builder setTriggerContentUpdateDelay(long durationMs) {
mTriggerContentUpdateDelay = durationMs;
@@ -1252,6 +1337,7 @@
* Set the maximum total delay (in milliseconds) that is allowed from the first
* time a content change is detected until the job is scheduled.
* @param durationMs Delay after initial content change, in milliseconds.
+ * @see JobInfo#getTriggerContentMaxDelay()
*/
public Builder setTriggerContentMaxDelay(long durationMs) {
mTriggerContentMaxDelay = durationMs;
@@ -1265,6 +1351,8 @@
* Setting this function on the builder with {@link #setMinimumLatency(long)} or
* {@link #setOverrideDeadline(long)} will result in an error.
* @param intervalMillis Millisecond interval for which this job will repeat.
+ * @see JobInfo#getIntervalMillis()
+ * @see JobInfo#getFlexMillis()
*/
public Builder setPeriodic(long intervalMillis) {
return setPeriodic(intervalMillis, intervalMillis);
@@ -1278,6 +1366,8 @@
* @param flexMillis Millisecond flex for this job. Flex is clamped to be at least
* {@link #getMinFlexMillis()} or 5 percent of the period, whichever is
* higher.
+ * @see JobInfo#getIntervalMillis()
+ * @see JobInfo#getFlexMillis()
*/
public Builder setPeriodic(long intervalMillis, long flexMillis) {
final long minPeriod = getMinPeriodMillis();
@@ -1309,6 +1399,7 @@
* {@link android.app.job.JobInfo.Builder#build()} is called.
* @param minLatencyMillis Milliseconds before which this job will not be considered for
* execution.
+ * @see JobInfo#getMinLatencyMillis()
*/
public Builder setMinimumLatency(long minLatencyMillis) {
mMinLatencyMillis = minLatencyMillis;
@@ -1322,6 +1413,7 @@
* this property on a periodic job, doing so will throw an
* {@link java.lang.IllegalArgumentException} when
* {@link android.app.job.JobInfo.Builder#build()} is called.
+ * @see JobInfo#getMaxExecutionDelayMillis()
*/
public Builder setOverrideDeadline(long maxExecutionDelayMillis) {
mMaxExecutionDelayMillis = maxExecutionDelayMillis;
@@ -1341,6 +1433,8 @@
* mode.
* @param initialBackoffMillis Millisecond time interval to wait initially when job has
* failed.
+ * @see JobInfo#getInitialBackoffMillis()
+ * @see JobInfo#getBackoffPolicy()
*/
public Builder setBackoffCriteria(long initialBackoffMillis,
@BackoffPolicy int backoffPolicy) {
@@ -1371,6 +1465,7 @@
*
* @param importantWhileForeground whether to relax doze restrictions for this job when the
* app is in the foreground. False by default.
+ * @see JobInfo#isImportantWhileForeground()
*/
public Builder setImportantWhileForeground(boolean importantWhileForeground) {
if (importantWhileForeground) {
@@ -1382,6 +1477,15 @@
}
/**
+ * @removed
+ * @deprecated replaced with {@link #setPrefetch(boolean)}
+ */
+ @Deprecated
+ public Builder setIsPrefetch(boolean isPrefetch) {
+ return setPrefetch(isPrefetch);
+ }
+
+ /**
* Setting this to true indicates that this job is designed to prefetch
* content that will make a material improvement to the experience of
* the specific user of this device. For example, fetching top headlines
@@ -1393,12 +1497,13 @@
* network when there is a surplus of metered data available. The system
* may also use this signal in combination with end user usage patterns
* to ensure data is prefetched before the user launches your app.
+ * @see JobInfo#isPrefetch()
*/
- public Builder setIsPrefetch(boolean isPrefetch) {
- if (isPrefetch) {
- mFlags |= FLAG_IS_PREFETCH;
+ public Builder setPrefetch(boolean prefetch) {
+ if (prefetch) {
+ mFlags |= FLAG_PREFETCH;
} else {
- mFlags &= (~FLAG_IS_PREFETCH);
+ mFlags &= (~FLAG_PREFETCH);
}
return this;
}
@@ -1408,6 +1513,7 @@
*
* @param isPersisted True to indicate that the job will be written to
* disk and loaded at boot.
+ * @see JobInfo#isPersisted()
*/
@RequiresPermission(android.Manifest.permission.RECEIVE_BOOT_COMPLETED)
public Builder setPersisted(boolean isPersisted) {
@@ -1427,7 +1533,7 @@
"constraints, this is not allowed.");
}
// Check that network estimates require network type
- if (mNetworkBytes > 0 && mNetworkRequest == null) {
+ if ((mNetworkDownloadBytes > 0 || mNetworkUploadBytes > 0) && mNetworkRequest == null) {
throw new IllegalArgumentException(
"Can't provide estimated network usage without requiring a network");
}
diff --git a/core/java/android/app/job/JobWorkItem.java b/core/java/android/app/job/JobWorkItem.java
index 1c46e8e..995f522 100644
--- a/core/java/android/app/job/JobWorkItem.java
+++ b/core/java/android/app/job/JobWorkItem.java
@@ -16,6 +16,8 @@
package android.app.job;
+import static android.app.job.JobInfo.NETWORK_BYTES_UNKNOWN;
+
import android.annotation.BytesLong;
import android.content.Intent;
import android.os.Parcel;
@@ -28,7 +30,8 @@
*/
final public class JobWorkItem implements Parcelable {
final Intent mIntent;
- final long mNetworkBytes;
+ final long mNetworkDownloadBytes;
+ final long mNetworkUploadBytes;
int mDeliveryCount;
int mWorkId;
Object mGrants;
@@ -41,22 +44,36 @@
*/
public JobWorkItem(Intent intent) {
mIntent = intent;
- mNetworkBytes = JobInfo.NETWORK_BYTES_UNKNOWN;
+ mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN;
+ mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN;
+ }
+
+ /**
+ * @deprecated replaced by {@link #JobWorkItem(Intent, long, long)}
+ * @removed
+ */
+ @Deprecated
+ public JobWorkItem(Intent intent, @BytesLong long networkBytes) {
+ this(intent, networkBytes, NETWORK_BYTES_UNKNOWN);
}
/**
* Create a new piece of work, which can be submitted to
* {@link JobScheduler#enqueue JobScheduler.enqueue}.
+ * <p>
+ * See {@link JobInfo.Builder#setEstimatedNetworkBytes(long, long)} for
+ * details about how to estimate network traffic.
*
* @param intent The general Intent describing this work.
- * @param networkBytes The estimated size of network traffic that will be
- * performed by this job work item, in bytes. See
- * {@link JobInfo.Builder#setEstimatedNetworkBytes(long)} for
- * details about how to estimate.
+ * @param downloadBytes The estimated size of network traffic that will be
+ * downloaded by this job work item, in bytes.
+ * @param uploadBytes The estimated size of network traffic that will be
+ * uploaded by this job work item, in bytes.
*/
- public JobWorkItem(Intent intent, @BytesLong long networkBytes) {
+ public JobWorkItem(Intent intent, @BytesLong long downloadBytes, @BytesLong long uploadBytes) {
mIntent = intent;
- mNetworkBytes = networkBytes;
+ mNetworkDownloadBytes = downloadBytes;
+ mNetworkUploadBytes = uploadBytes;
}
/**
@@ -67,14 +84,44 @@
}
/**
- * Return the estimated size of network traffic that will be performed by
+ * @deprecated replaced by {@link #getEstimatedNetworkDownloadBytes()} and
+ * {@link #getEstimatedNetworkUploadBytes()}.
+ * @removed
+ */
+ @Deprecated
+ public @BytesLong long getEstimatedNetworkBytes() {
+ if (mNetworkDownloadBytes == NETWORK_BYTES_UNKNOWN
+ && mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) {
+ return NETWORK_BYTES_UNKNOWN;
+ } else if (mNetworkDownloadBytes == NETWORK_BYTES_UNKNOWN) {
+ return mNetworkUploadBytes;
+ } else if (mNetworkUploadBytes == NETWORK_BYTES_UNKNOWN) {
+ return mNetworkDownloadBytes;
+ } else {
+ return mNetworkDownloadBytes + mNetworkUploadBytes;
+ }
+ }
+
+ /**
+ * Return the estimated size of download traffic that will be performed by
+ * this job, in bytes.
+ *
+ * @return Estimated size of download traffic, or
+ * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown.
+ */
+ public @BytesLong long getEstimatedNetworkDownloadBytes() {
+ return mNetworkDownloadBytes;
+ }
+
+ /**
+ * Return the estimated size of upload traffic that will be performed by
* this job work item, in bytes.
*
- * @return estimated size, or {@link JobInfo#NETWORK_BYTES_UNKNOWN} when
- * unknown.
+ * @return Estimated size of upload traffic, or
+ * {@link JobInfo#NETWORK_BYTES_UNKNOWN} when unknown.
*/
- public @BytesLong long getEstimatedNetworkBytes() {
- return mNetworkBytes;
+ public @BytesLong long getEstimatedNetworkUploadBytes() {
+ return mNetworkUploadBytes;
}
/**
@@ -128,9 +175,13 @@
sb.append(mWorkId);
sb.append(" intent=");
sb.append(mIntent);
- if (mNetworkBytes != JobInfo.NETWORK_BYTES_UNKNOWN) {
- sb.append(" networkBytes=");
- sb.append(mNetworkBytes);
+ if (mNetworkDownloadBytes != NETWORK_BYTES_UNKNOWN) {
+ sb.append(" downloadBytes=");
+ sb.append(mNetworkDownloadBytes);
+ }
+ if (mNetworkUploadBytes != NETWORK_BYTES_UNKNOWN) {
+ sb.append(" uploadBytes=");
+ sb.append(mNetworkUploadBytes);
}
if (mDeliveryCount != 0) {
sb.append(" dcount=");
@@ -151,7 +202,8 @@
} else {
out.writeInt(0);
}
- out.writeLong(mNetworkBytes);
+ out.writeLong(mNetworkDownloadBytes);
+ out.writeLong(mNetworkUploadBytes);
out.writeInt(mDeliveryCount);
out.writeInt(mWorkId);
}
@@ -173,7 +225,8 @@
} else {
mIntent = null;
}
- mNetworkBytes = in.readLong();
+ mNetworkDownloadBytes = in.readLong();
+ mNetworkUploadBytes = in.readLong();
mDeliveryCount = in.readInt();
mWorkId = in.readInt();
}
diff --git a/core/java/android/app/servertransaction/TransactionExecutorHelper.java b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
index 7e66fd7..01b13a2 100644
--- a/core/java/android/app/servertransaction/TransactionExecutorHelper.java
+++ b/core/java/android/app/servertransaction/TransactionExecutorHelper.java
@@ -26,7 +26,7 @@
import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
-import android.app.ActivityThread;
+import android.app.ActivityThread.ActivityClientRecord;
import android.util.IntArray;
import com.android.internal.annotations.VisibleForTesting;
@@ -124,7 +124,7 @@
* {@link ActivityLifecycleItem#UNDEFINED} if there is not path.
*/
@VisibleForTesting
- public int getClosestPreExecutionState(ActivityThread.ActivityClientRecord r,
+ public int getClosestPreExecutionState(ActivityClientRecord r,
int postExecutionState) {
switch (postExecutionState) {
case UNDEFINED:
@@ -147,7 +147,7 @@
* were provided or there is not path.
*/
@VisibleForTesting
- public int getClosestOfStates(ActivityThread.ActivityClientRecord r, int[] finalStates) {
+ public int getClosestOfStates(ActivityClientRecord r, int[] finalStates) {
if (finalStates == null || finalStates.length == 0) {
return UNDEFINED;
}
@@ -168,6 +168,27 @@
return closestState;
}
+ /** Get the lifecycle state request to match the current state in the end of a transaction. */
+ public static ActivityLifecycleItem getLifecycleRequestForCurrentState(ActivityClientRecord r) {
+ final int prevState = r.getLifecycleState();
+ final ActivityLifecycleItem lifecycleItem;
+ switch (prevState) {
+ // TODO(lifecycler): Extend to support all possible states.
+ case ON_PAUSE:
+ lifecycleItem = PauseActivityItem.obtain();
+ break;
+ case ON_STOP:
+ lifecycleItem = StopActivityItem.obtain(r.isVisibleFromServer(),
+ 0 /* configChanges */);
+ break;
+ default:
+ lifecycleItem = ResumeActivityItem.obtain(false /* isForward */);
+ break;
+ }
+
+ return lifecycleItem;
+ }
+
/**
* Check if there is a destruction involved in the path. We want to avoid a lifecycle sequence
* that involves destruction and recreation if there is another path.
diff --git a/core/java/android/app/usage/EventStats.java b/core/java/android/app/usage/EventStats.java
new file mode 100644
index 0000000..b799de9
--- /dev/null
+++ b/core/java/android/app/usage/EventStats.java
@@ -0,0 +1,182 @@
+/**
+ * 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.
+ */
+
+package android.app.usage;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Contains usage statistics for an event type for a specific
+ * time range.
+ */
+public final class EventStats implements Parcelable {
+
+ /**
+ * {@hide}
+ */
+ public int mEventType;
+
+ /**
+ * {@hide}
+ */
+ public long mBeginTimeStamp;
+
+ /**
+ * {@hide}
+ */
+ public long mEndTimeStamp;
+
+ /**
+ * Last time used by the user with an explicit action (notification, activity launch).
+ * {@hide}
+ */
+ public long mLastTimeUsed;
+
+ /**
+ * {@hide}
+ */
+ public long mTotalTime;
+
+ /**
+ * {@hide}
+ */
+ public int mCount;
+
+ /**
+ * {@hide}
+ */
+ public EventStats() {
+ }
+
+ public EventStats(EventStats stats) {
+ mEventType = stats.mEventType;
+ mBeginTimeStamp = stats.mBeginTimeStamp;
+ mEndTimeStamp = stats.mEndTimeStamp;
+ mLastTimeUsed = stats.mLastTimeUsed;
+ mTotalTime = stats.mTotalTime;
+ mCount = stats.mCount;
+ }
+
+ /**
+ * Return the type of event this is usage for. May be one of the event
+ * constants in {@link UsageEvents.Event}.
+ */
+ public int getEventType() {
+ return mEventType;
+ }
+
+ /**
+ * Get the beginning of the time range this {@link android.app.usage.EventStats} represents,
+ * measured in milliseconds since the epoch.
+ * <p/>
+ * See {@link System#currentTimeMillis()}.
+ */
+ public long getFirstTimeStamp() {
+ return mBeginTimeStamp;
+ }
+
+ /**
+ * Get the end of the time range this {@link android.app.usage.EventStats} represents,
+ * measured in milliseconds since the epoch.
+ * <p/>
+ * See {@link System#currentTimeMillis()}.
+ */
+ public long getLastTimeStamp() {
+ return mEndTimeStamp;
+ }
+
+ /**
+ * Get the last time this event was used, measured in milliseconds since the epoch.
+ * <p/>
+ * See {@link System#currentTimeMillis()}.
+ */
+ public long getLastTimeUsed() {
+ return mLastTimeUsed;
+ }
+
+ /**
+ * Return the number of times that this event occurred over the interval.
+ */
+ public int getCount() {
+ return mCount;
+ }
+
+ /**
+ * Get the total time this event was active, measured in milliseconds.
+ */
+ public long getTotalTime() {
+ return mTotalTime;
+ }
+
+ /**
+ * Add the statistics from the right {@link EventStats} to the left. The event type for
+ * both {@link UsageStats} objects must be the same.
+ * @param right The {@link EventStats} object to merge into this one.
+ * @throws java.lang.IllegalArgumentException if the event types of the two
+ * {@link UsageStats} objects are different.
+ */
+ public void add(EventStats right) {
+ if (mEventType != right.mEventType) {
+ throw new IllegalArgumentException("Can't merge EventStats for event #"
+ + mEventType + " with EventStats for event #" + right.mEventType);
+ }
+
+ // We use the mBeginTimeStamp due to a bug where UsageStats files can overlap with
+ // regards to their mEndTimeStamp.
+ if (right.mBeginTimeStamp > mBeginTimeStamp) {
+ mLastTimeUsed = Math.max(mLastTimeUsed, right.mLastTimeUsed);
+ }
+ mBeginTimeStamp = Math.min(mBeginTimeStamp, right.mBeginTimeStamp);
+ mEndTimeStamp = Math.max(mEndTimeStamp, right.mEndTimeStamp);
+ mTotalTime += right.mTotalTime;
+ mCount += right.mCount;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mEventType);
+ dest.writeLong(mBeginTimeStamp);
+ dest.writeLong(mEndTimeStamp);
+ dest.writeLong(mLastTimeUsed);
+ dest.writeLong(mTotalTime);
+ dest.writeInt(mCount);
+ }
+
+ public static final Creator<EventStats> CREATOR = new Creator<EventStats>() {
+ @Override
+ public EventStats createFromParcel(Parcel in) {
+ EventStats stats = new EventStats();
+ stats.mEventType = in.readInt();
+ stats.mBeginTimeStamp = in.readLong();
+ stats.mEndTimeStamp = in.readLong();
+ stats.mLastTimeUsed = in.readLong();
+ stats.mTotalTime = in.readLong();
+ stats.mCount = in.readInt();
+ return stats;
+ }
+
+ @Override
+ public EventStats[] newArray(int size) {
+ return new EventStats[size];
+ }
+ };
+}
diff --git a/core/java/android/app/usage/IUsageStatsManager.aidl b/core/java/android/app/usage/IUsageStatsManager.aidl
index d52bd37..00d8711 100644
--- a/core/java/android/app/usage/IUsageStatsManager.aidl
+++ b/core/java/android/app/usage/IUsageStatsManager.aidl
@@ -32,6 +32,8 @@
String callingPackage);
ParceledListSlice queryConfigurationStats(int bucketType, long beginTime, long endTime,
String callingPackage);
+ ParceledListSlice queryEventStats(int bucketType, long beginTime, long endTime,
+ String callingPackage);
UsageEvents queryEvents(long beginTime, long endTime, String callingPackage);
UsageEvents queryEventsForPackage(long beginTime, long endTime, String callingPackage);
void setAppInactive(String packageName, boolean inactive, int userId);
diff --git a/core/java/android/app/usage/TimeSparseArray.java b/core/java/android/app/usage/TimeSparseArray.java
index 5764fa8..9ef88e4 100644
--- a/core/java/android/app/usage/TimeSparseArray.java
+++ b/core/java/android/app/usage/TimeSparseArray.java
@@ -81,12 +81,17 @@
@Override
public void put(long key, E value) {
final long origKey = key;
- while (indexOfKey(key) >= 0) {
- key++;
- }
- if (origKey != key) {
- Slog.w(TAG, "Value " + value + " supposed to be inserted at " + origKey
- + " displaced to " + key);
+ int keyIndex = indexOfKey(key);
+ if (keyIndex >= 0) {
+ final long sz = size();
+ while (keyIndex < sz && keyAt(keyIndex) == key) {
+ key++;
+ keyIndex++;
+ }
+ if (key >= origKey + 10) {
+ Slog.w(TAG, "Value " + value + " supposed to be inserted at " + origKey
+ + " displaced to " + key);
+ }
}
super.put(key, value);
}
diff --git a/core/java/android/app/usage/UsageEvents.java b/core/java/android/app/usage/UsageEvents.java
index b354e81..a665652 100644
--- a/core/java/android/app/usage/UsageEvents.java
+++ b/core/java/android/app/usage/UsageEvents.java
@@ -139,6 +139,19 @@
@SystemApi
public static final int SLICE_PINNED = 14;
+ /**
+ * An event type denoting that the screen has gone in to an interactive state (turned
+ * on for full user interaction, not ambient display or other non-interactive state).
+ */
+ public static final int SCREEN_INTERACTIVE = 15;
+
+ /**
+ * An event type denoting that the screen has gone in to a non-interactive state
+ * (completely turned off or turned on only in a non-interactive state like ambient
+ * display).
+ */
+ public static final int SCREEN_NON_INTERACTIVE = 16;
+
/** @hide */
public static final int FLAG_IS_PACKAGE_INSTANT_APP = 1 << 0;
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 4744147..6feb527 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -301,6 +301,44 @@
}
/**
+ * Gets aggregated event stats for the given time range, aggregated by the specified interval.
+ * <p>The returned list will contain a {@link EventStats} object for each event type that
+ * is being aggregated and has data for an interval that is a subset of the time range given.
+ *
+ * <p>The current event types that will be aggregated here are:</p>
+ * <ul>
+ * <li>{@link UsageEvents.Event#SCREEN_INTERACTIVE}</li>
+ * <li>{@link UsageEvents.Event#SCREEN_NON_INTERACTIVE}</li>
+ * </ul>
+ *
+ * <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
+ *
+ * @param intervalType The time interval by which the stats are aggregated.
+ * @param beginTime The inclusive beginning of the range of stats to include in the results.
+ * @param endTime The exclusive end of the range of stats to include in the results.
+ * @return A list of {@link EventStats}
+ *
+ * @see #INTERVAL_DAILY
+ * @see #INTERVAL_WEEKLY
+ * @see #INTERVAL_MONTHLY
+ * @see #INTERVAL_YEARLY
+ * @see #INTERVAL_BEST
+ */
+ public List<EventStats> queryEventStats(int intervalType, long beginTime, long endTime) {
+ try {
+ @SuppressWarnings("unchecked")
+ ParceledListSlice<EventStats> slice = mService.queryEventStats(intervalType, beginTime,
+ endTime, mContext.getOpPackageName());
+ if (slice != null) {
+ return slice.getList();
+ }
+ } catch (RemoteException e) {
+ // fallthrough and return the empty list.
+ }
+ return Collections.emptyList();
+ }
+
+ /**
* Query for events in the given time range. Events are only kept by the system for a few
* days.
* <p> The caller must have {@link android.Manifest.permission#PACKAGE_USAGE_STATS} </p>
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index ce32278..02f0ded 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1814,6 +1814,17 @@
public static final String EXTRA_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";
/**
+ * Intent extra: A {@link Bundle} of extras for a package being suspended. Will be sent with
+ * {@link #ACTION_MY_PACKAGE_SUSPENDED}.
+ *
+ * @see #ACTION_MY_PACKAGE_SUSPENDED
+ * @see #ACTION_MY_PACKAGE_UNSUSPENDED
+ * @see PackageManager#isPackageSuspended()
+ * @see PackageManager#getSuspendedPackageAppExtras()
+ */
+ public static final String EXTRA_SUSPENDED_PACKAGE_EXTRAS = "android.intent.extra.SUSPENDED_PACKAGE_EXTRAS";
+
+ /**
* Intent extra: An app split name.
* <p>
* Type: String
@@ -2237,6 +2248,43 @@
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_PACKAGES_UNSUSPENDED = "android.intent.action.PACKAGES_UNSUSPENDED";
+
+ /**
+ * Broadcast Action: Sent to a package that has been suspended by the system. This is sent
+ * whenever a package is put into a suspended state or any of it's app extras change while
+ * in the suspended state.
+ * <p> Optionally includes the following extras:
+ * <ul>
+ * <li> {@link #EXTRA_SUSPENDED_PACKAGE_EXTRAS} which is a {@link Bundle} which will contain
+ * useful information for the app being suspended.
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system. <em>This will be delivered to {@link BroadcastReceiver} components declared in
+ * the manifest.</em>
+ *
+ * @see #ACTION_MY_PACKAGE_UNSUSPENDED
+ * @see #EXTRA_SUSPENDED_PACKAGE_EXTRAS
+ * @see PackageManager#isPackageSuspended()
+ * @see PackageManager#getSuspendedPackageAppExtras()
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MY_PACKAGE_SUSPENDED = "android.intent.action.MY_PACKAGE_SUSPENDED";
+
+ /**
+ * Broadcast Action: Sent to a package that has been unsuspended.
+ *
+ * <p class="note">This is a protected intent that can only be sent
+ * by the system. <em>This will be delivered to {@link BroadcastReceiver} components declared in
+ * the manifest.</em>
+ *
+ * @see #ACTION_MY_PACKAGE_SUSPENDED
+ * @see #EXTRA_SUSPENDED_PACKAGE_EXTRAS
+ * @see PackageManager#isPackageSuspended()
+ * @see PackageManager#getSuspendedPackageAppExtras()
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_MY_PACKAGE_UNSUSPENDED = "android.intent.action.MY_PACKAGE_UNSUSPENDED";
+
/**
* Broadcast Action: A user ID has been removed from the system. The user
* ID number is stored in the extra data under {@link #EXTRA_UID}.
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index d43d80f..1352b5e 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -278,7 +278,7 @@
boolean isPackageSuspendedForUser(String packageName, int userId);
- PersistableBundle getPackageSuspendedAppExtras(String pacakgeName, int userId);
+ PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId);
void setSuspendedPackageAppExtras(String packageName, in PersistableBundle appExtras,
int userId);
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 314eb98..491f0af 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -5513,7 +5513,7 @@
* Puts the package in a suspended state, where attempts at starting activities are denied.
*
* <p>It doesn't remove the data or the actual package file. The application's notifications
- * will be hidden, any of the it's started activities will be stopped and it will not be able to
+ * will be hidden, any of its started activities will be stopped and it will not be able to
* show toasts or dialogs or ring the device. When the user tries to launch a suspended app, a
* system dialog with the given {@code dialogMessage} will be shown instead.</p>
*
@@ -5577,11 +5577,26 @@
}
/**
- * Apps can query this to know if they have been suspended.
+ * Apps can query this to know if they have been suspended. A system app with the permission
+ * {@code android.permission.SUSPEND_APPS} can put any app on the device into a suspended state.
+ *
+ * <p>While in this state, the application's notifications will be hidden, any of its started
+ * activities will be stopped and it will not be able to show toasts or dialogs or ring the
+ * device. When the user tries to launch a suspended app, the system will, instead, show a
+ * dialog to the user informing them that they cannot use this app while it is suspended.
+ *
+ * <p>When an app is put into this state, the broadcast action
+ * {@link Intent#ACTION_MY_PACKAGE_SUSPENDED} will be delivered to any of its broadcast
+ * receivers that included this action in their intent-filters, <em>including manifest
+ * receivers.</em> Similarly, a broadcast action {@link Intent#ACTION_MY_PACKAGE_UNSUSPENDED}
+ * is delivered when a previously suspended app is taken out of this state.
+ * </p>
*
* @return {@code true} if the calling package has been suspended, {@code false} otherwise.
*
* @see #getSuspendedPackageAppExtras()
+ * @see Intent#ACTION_MY_PACKAGE_SUSPENDED
+ * @see Intent#ACTION_MY_PACKAGE_UNSUSPENDED
*/
public boolean isPackageSuspended() {
throw new UnsupportedOperationException("isPackageSuspended not implemented");
@@ -5602,7 +5617,7 @@
*/
@SystemApi
@RequiresPermission(Manifest.permission.SUSPEND_APPS)
- public PersistableBundle getSuspendedPackageAppExtras(String packageName) {
+ public @Nullable PersistableBundle getSuspendedPackageAppExtras(String packageName) {
throw new UnsupportedOperationException("getSuspendedPackageAppExtras not implemented");
}
@@ -5631,15 +5646,17 @@
* Returns any extra information supplied as {@code appExtras} to the system when the calling
* app was suspended.
*
- * <p> Note: This just returns whatever {@link PersistableBundle} was passed to the system via
- * {@code setPackagesSuspended(String[], boolean, PersistableBundle, PersistableBundle,
- * String)} when suspending the package, <em> which might be {@code null}. </em></p>
+ * <p>Note: If no extras were supplied to the system, this method will return {@code null}, even
+ * when the calling app has been suspended.</p>
*
- * @return A {@link PersistableBundle} containing the extras for the app, or {@code null} if the
+ * @return A {@link Bundle} containing the extras for the app, or {@code null} if the
* package is not currently suspended.
+ *
* @see #isPackageSuspended()
+ * @see Intent#ACTION_MY_PACKAGE_UNSUSPENDED
+ * @see Intent#ACTION_MY_PACKAGE_SUSPENDED
*/
- public @Nullable PersistableBundle getSuspendedPackageAppExtras() {
+ public @Nullable Bundle getSuspendedPackageAppExtras() {
throw new UnsupportedOperationException("getSuspendedPackageAppExtras not implemented");
}
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 56cba79..c6c676f 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -31,7 +31,7 @@
import java.util.regex.Pattern;
/**
- * This is a convience class that helps build SQL queries to be sent to
+ * This is a convenience class that helps build SQL queries to be sent to
* {@link SQLiteDatabase} objects.
*/
public class SQLiteQueryBuilder
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 390b83f..e6aaab1 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -3392,6 +3392,21 @@
public static final Key<Integer> LOGICAL_MULTI_CAMERA_SENSOR_SYNC_TYPE =
new Key<Integer>("android.logicalMultiCamera.sensorSyncType", int.class);
+ /**
+ * <p>List of distortion correction modes for {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode} that are
+ * supported by this camera device.</p>
+ * <p>No device is required to support this API; such devices will always list only 'OFF'.
+ * All devices that support this API will list both FAST and HIGH_QUALITY.</p>
+ * <p><b>Range of valid values:</b><br>
+ * Any value listed in {@link CaptureRequest#DISTORTION_CORRECTION_MODE android.distortionCorrection.mode}</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
+ */
+ @PublicKey
+ public static final Key<int[]> DISTORTION_CORRECTION_AVAILABLE_MODES =
+ new Key<int[]>("android.distortionCorrection.availableModes", int[].class);
+
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index 7669c01..7467c3a 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -2730,6 +2730,31 @@
public static final int TONEMAP_PRESET_CURVE_REC709 = 1;
//
+ // Enumeration values for CaptureRequest#DISTORTION_CORRECTION_MODE
+ //
+
+ /**
+ * <p>No distortion correction is applied.</p>
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
+ */
+ public static final int DISTORTION_CORRECTION_MODE_OFF = 0;
+
+ /**
+ * <p>Lens distortion correction is applied without reducing frame rate
+ * relative to sensor output. It may be the same as OFF if distortion correction would
+ * reduce frame rate relative to sensor.</p>
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
+ */
+ public static final int DISTORTION_CORRECTION_MODE_FAST = 1;
+
+ /**
+ * <p>High-quality distortion correction is applied, at the cost of
+ * possibly reduced frame rate relative to sensor output.</p>
+ * @see CaptureRequest#DISTORTION_CORRECTION_MODE
+ */
+ public static final int DISTORTION_CORRECTION_MODE_HIGH_QUALITY = 2;
+
+ //
// Enumeration values for CaptureResult#CONTROL_AE_STATE
//
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index b0cbec7..d36785a 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -3167,6 +3167,49 @@
public static final Key<Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR =
new Key<Float>("android.reprocess.effectiveExposureFactor", float.class);
+ /**
+ * <p>Mode of operation for the lens distortion correction block.</p>
+ * <p>The lens distortion correction block attempts to improve image quality by fixing
+ * radial, tangential, or other geometric aberrations in the camera device's optics. If
+ * available, the {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} field documents the lens's distortion parameters.</p>
+ * <p>OFF means no distortion correction is done.</p>
+ * <p>FAST/HIGH_QUALITY both mean camera device determined distortion correction will be
+ * applied. HIGH_QUALITY mode indicates that the camera device will use the highest-quality
+ * correction algorithms, even if it slows down capture rate. FAST means the camera device
+ * will not slow down capture rate when applying correction. FAST may be the same as OFF if
+ * any correction at all would slow down capture rate. Every output stream will have a
+ * similar amount of enhancement applied.</p>
+ * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
+ * applied to any RAW output. Metadata coordinates such as face rectangles or metering
+ * regions are also not affected by correction.</p>
+ * <p>Applications enabling distortion correction need to pay extra attention when converting
+ * image coordinates between corrected output buffers and the sensor array. For example, if
+ * the app supports tap-to-focus and enables correction, it then has to apply the distortion
+ * model described in {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} to the image buffer tap coordinates to properly
+ * calculate the tap position on the sensor active array to be used with
+ * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}. The same applies in reverse to detected face rectangles if
+ * they need to be drawn on top of the corrected output buffers.</p>
+ * <p><b>Possible values:</b>
+ * <ul>
+ * <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li>
+ * <li>{@link #DISTORTION_CORRECTION_MODE_FAST FAST}</li>
+ * <li>{@link #DISTORTION_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
+ * </ul></p>
+ * <p><b>Available values for this device:</b><br>
+ * {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AF_REGIONS
+ * @see CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES
+ * @see CameraCharacteristics#LENS_DISTORTION
+ * @see #DISTORTION_CORRECTION_MODE_OFF
+ * @see #DISTORTION_CORRECTION_MODE_FAST
+ * @see #DISTORTION_CORRECTION_MODE_HIGH_QUALITY
+ */
+ @PublicKey
+ public static final Key<Integer> DISTORTION_CORRECTION_MODE =
+ new Key<Integer>("android.distortionCorrection.mode", int.class);
+
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index 6331942..bb82260 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -4450,6 +4450,49 @@
public static final Key<Float> REPROCESS_EFFECTIVE_EXPOSURE_FACTOR =
new Key<Float>("android.reprocess.effectiveExposureFactor", float.class);
+ /**
+ * <p>Mode of operation for the lens distortion correction block.</p>
+ * <p>The lens distortion correction block attempts to improve image quality by fixing
+ * radial, tangential, or other geometric aberrations in the camera device's optics. If
+ * available, the {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} field documents the lens's distortion parameters.</p>
+ * <p>OFF means no distortion correction is done.</p>
+ * <p>FAST/HIGH_QUALITY both mean camera device determined distortion correction will be
+ * applied. HIGH_QUALITY mode indicates that the camera device will use the highest-quality
+ * correction algorithms, even if it slows down capture rate. FAST means the camera device
+ * will not slow down capture rate when applying correction. FAST may be the same as OFF if
+ * any correction at all would slow down capture rate. Every output stream will have a
+ * similar amount of enhancement applied.</p>
+ * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
+ * applied to any RAW output. Metadata coordinates such as face rectangles or metering
+ * regions are also not affected by correction.</p>
+ * <p>Applications enabling distortion correction need to pay extra attention when converting
+ * image coordinates between corrected output buffers and the sensor array. For example, if
+ * the app supports tap-to-focus and enables correction, it then has to apply the distortion
+ * model described in {@link CameraCharacteristics#LENS_DISTORTION android.lens.distortion} to the image buffer tap coordinates to properly
+ * calculate the tap position on the sensor active array to be used with
+ * {@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}. The same applies in reverse to detected face rectangles if
+ * they need to be drawn on top of the corrected output buffers.</p>
+ * <p><b>Possible values:</b>
+ * <ul>
+ * <li>{@link #DISTORTION_CORRECTION_MODE_OFF OFF}</li>
+ * <li>{@link #DISTORTION_CORRECTION_MODE_FAST FAST}</li>
+ * <li>{@link #DISTORTION_CORRECTION_MODE_HIGH_QUALITY HIGH_QUALITY}</li>
+ * </ul></p>
+ * <p><b>Available values for this device:</b><br>
+ * {@link CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES android.distortionCorrection.availableModes}</p>
+ * <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
+ *
+ * @see CaptureRequest#CONTROL_AF_REGIONS
+ * @see CameraCharacteristics#DISTORTION_CORRECTION_AVAILABLE_MODES
+ * @see CameraCharacteristics#LENS_DISTORTION
+ * @see #DISTORTION_CORRECTION_MODE_OFF
+ * @see #DISTORTION_CORRECTION_MODE_FAST
+ * @see #DISTORTION_CORRECTION_MODE_HIGH_QUALITY
+ */
+ @PublicKey
+ public static final Key<Integer> DISTORTION_CORRECTION_MODE =
+ new Key<Integer>("android.distortionCorrection.mode", int.class);
+
/*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
* End generated code
*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
diff --git a/core/java/android/hardware/fingerprint/FingerprintDialog.java b/core/java/android/hardware/fingerprint/FingerprintDialog.java
index 49835963..13b7064 100644
--- a/core/java/android/hardware/fingerprint/FingerprintDialog.java
+++ b/core/java/android/hardware/fingerprint/FingerprintDialog.java
@@ -71,7 +71,7 @@
* after this amount of time.
* @hide
*/
- public static final int HIDE_DIALOG_DELAY = 3000; // ms
+ public static final int HIDE_DIALOG_DELAY = 2000; // ms
/**
* @hide
*/
@@ -166,7 +166,9 @@
}
/**
- * Required: Set the text for the negative button.
+ * Required: Set the text for the negative button. This would typically be used as a
+ * "Cancel" button, but may be also used to show an alternative method for authentication,
+ * such as screen that asks for a backup password.
* @param text
* @return
*/
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 8048099c..a19ba19 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -1155,9 +1155,14 @@
@Override // binder call
public void onError(long deviceId, int error, int vendorCode) {
if (mExecutor != null) {
- mExecutor.execute(() -> {
- sendErrorResult(deviceId, error, vendorCode);
- });
+ // FingerprintDialog case, post a delayed runnable on the FingerprintManager handler
+ // that sends the error message after FingerprintDialog.HIDE_DIALOG_DELAY to send
+ // the error to the application.
+ mHandler.postDelayed(() -> {
+ mExecutor.execute(() -> {
+ sendErrorResult(deviceId, error, vendorCode);
+ });
+ }, FingerprintDialog.HIDE_DIALOG_DELAY);
} else {
mHandler.obtainMessage(MSG_ERROR, error, vendorCode, deviceId).sendToTarget();
}
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index ef58f94..ff5714b 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -17,7 +17,6 @@
package android.net;
import android.annotation.IntDef;
-import android.annotation.SystemApi;
import android.net.ConnectivityManager.NetworkCallback;
import android.os.Parcel;
import android.os.Parcelable;
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index f528d63..6ebb102 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1585,6 +1585,7 @@
public static final int STATE2_CAMERA_FLAG = 1<<21;
public static final int STATE2_BLUETOOTH_SCAN_FLAG = 1 << 20;
public static final int STATE2_CELLULAR_HIGH_TX_POWER_FLAG = 1 << 19;
+ public static final int STATE2_USB_DATA_LINK_FLAG = 1 << 18;
public static final int MOST_INTERESTING_STATES2 =
STATE2_POWER_SAVE_FLAG | STATE2_WIFI_ON_FLAG | STATE2_DEVICE_IDLE_MASK
@@ -2363,8 +2364,7 @@
SCREEN_BRIGHTNESS_NAMES, SCREEN_BRIGHTNESS_SHORT_NAMES),
};
- public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS
- = new BitDescription[] {
+ public static final BitDescription[] HISTORY_STATE2_DESCRIPTIONS = new BitDescription[] {
new BitDescription(HistoryItem.STATE2_POWER_SAVE_FLAG, "power_save", "ps"),
new BitDescription(HistoryItem.STATE2_VIDEO_ON_FLAG, "video", "v"),
new BitDescription(HistoryItem.STATE2_WIFI_RUNNING_FLAG, "wifi_running", "Ww"),
@@ -2375,6 +2375,7 @@
new String[] { "off", "light", "full", "???" },
new String[] { "off", "light", "full", "???" }),
new BitDescription(HistoryItem.STATE2_CHARGING_FLAG, "charging", "ch"),
+ new BitDescription(HistoryItem.STATE2_USB_DATA_LINK_FLAG, "usb_data", "Ud"),
new BitDescription(HistoryItem.STATE2_PHONE_IN_CALL_FLAG, "phone_in_call", "Pcl"),
new BitDescription(HistoryItem.STATE2_BLUETOOTH_ON_FLAG, "bluetooth", "b"),
new BitDescription(HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK,
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index e22c65f..8378a82 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -295,8 +295,10 @@
/**
* The current lowest supported value of app target SDK. Applications targeting
- * lower values will fail to install and run. Its possible values are defined
- * in {@link Build.VERSION_CODES}.
+ * lower values may not function on devices running this SDK version. Its possible
+ * values are defined in {@link Build.VERSION_CODES}.
+ *
+ * @hide
*/
public static final int MIN_SUPPORTED_TARGET_SDK_INT = SystemProperties.getInt(
"ro.build.version.min_supported_target_sdk", 0);
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 62bb385..e3c4870 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -2803,8 +2803,8 @@
Class<?> parcelableClass = Class.forName(name, false /* initialize */,
parcelableClassLoader);
if (!Parcelable.class.isAssignableFrom(parcelableClass)) {
- throw new BadParcelableException("Parcelable protocol requires that the "
- + "class implements Parcelable");
+ throw new BadParcelableException("Parcelable protocol requires subclassing "
+ + "from Parcelable on class " + name);
}
Field f = parcelableClass.getField("CREATOR");
if ((f.getModifiers() & Modifier.STATIC) == 0) {
diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java
index d3877ca..5c99f6c 100644
--- a/core/java/android/os/storage/VolumeInfo.java
+++ b/core/java/android/os/storage/VolumeInfo.java
@@ -269,22 +269,7 @@
return (mountFlags & MOUNT_FLAG_VISIBLE) != 0;
}
- public boolean isVisibleForRead(int userId) {
- if (type == TYPE_PUBLIC) {
- if (isPrimary() && mountUserId != userId) {
- // Primary physical is only visible to single user
- return false;
- } else {
- return isVisible();
- }
- } else if (type == TYPE_EMULATED) {
- return isVisible();
- } else {
- return false;
- }
- }
-
- public boolean isVisibleForWrite(int userId) {
+ public boolean isVisibleForUser(int userId) {
if (type == TYPE_PUBLIC && mountUserId == userId) {
return isVisible();
} else if (type == TYPE_EMULATED) {
@@ -294,6 +279,14 @@
}
}
+ public boolean isVisibleForRead(int userId) {
+ return isVisibleForUser(userId);
+ }
+
+ public boolean isVisibleForWrite(int userId) {
+ return isVisibleForUser(userId);
+ }
+
public File getPath() {
return (path != null) ? new File(path) : null;
}
@@ -409,9 +402,9 @@
* Build an intent to browse the contents of this volume. Only valid for
* {@link #TYPE_EMULATED} or {@link #TYPE_PUBLIC}.
*/
- public Intent buildBrowseIntent() {
+ public @Nullable Intent buildBrowseIntent() {
final Uri uri;
- if (type == VolumeInfo.TYPE_PUBLIC) {
+ if (type == VolumeInfo.TYPE_PUBLIC && mountUserId == UserHandle.myUserId()) {
uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid);
} else if (type == VolumeInfo.TYPE_EMULATED && isPrimary()) {
uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY,
diff --git a/core/java/android/provider/BlockedNumberContract.java b/core/java/android/provider/BlockedNumberContract.java
index 8aef012..67c6fb9 100644
--- a/core/java/android/provider/BlockedNumberContract.java
+++ b/core/java/android/provider/BlockedNumberContract.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
+import android.telecom.Log;
/**
* <p>
@@ -261,9 +262,16 @@
*/
@WorkerThread
public static boolean isBlocked(Context context, String phoneNumber) {
- final Bundle res = context.getContentResolver().call(
- AUTHORITY_URI, METHOD_IS_BLOCKED, phoneNumber, null);
- return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+ try {
+ final Bundle res = context.getContentResolver().call(
+ AUTHORITY_URI, METHOD_IS_BLOCKED, phoneNumber, null);
+ return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+ } catch (NullPointerException | IllegalArgumentException ex) {
+ // The content resolver can throw an NPE or IAE; we don't want to crash Telecom if
+ // either of these happen.
+ Log.w(null, "isBlocked: provider not ready.");
+ return false;
+ }
}
/**
@@ -297,9 +305,16 @@
* @return {@code true} if the current user can block numbers.
*/
public static boolean canCurrentUserBlockNumbers(Context context) {
- final Bundle res = context.getContentResolver().call(
- AUTHORITY_URI, METHOD_CAN_CURRENT_USER_BLOCK_NUMBERS, null, null);
- return res != null && res.getBoolean(RES_CAN_BLOCK_NUMBERS, false);
+ try {
+ final Bundle res = context.getContentResolver().call(
+ AUTHORITY_URI, METHOD_CAN_CURRENT_USER_BLOCK_NUMBERS, null, null);
+ return res != null && res.getBoolean(RES_CAN_BLOCK_NUMBERS, false);
+ } catch (NullPointerException | IllegalArgumentException ex) {
+ // The content resolver can throw an NPE or IAE; we don't want to crash Telecom if
+ // either of these happen.
+ Log.w(null, "canCurrentUserBlockNumbers: provider not ready.");
+ return false;
+ }
}
/**
@@ -368,8 +383,14 @@
* the provider unless {@link #endBlockSuppression(Context)} is called.
*/
public static void notifyEmergencyContact(Context context) {
- context.getContentResolver().call(
- AUTHORITY_URI, METHOD_NOTIFY_EMERGENCY_CONTACT, null, null);
+ try {
+ context.getContentResolver().call(
+ AUTHORITY_URI, METHOD_NOTIFY_EMERGENCY_CONTACT, null, null);
+ } catch (NullPointerException | IllegalArgumentException ex) {
+ // The content resolver can throw an NPE or IAE; we don't want to crash Telecom if
+ // either of these happen.
+ Log.w(null, "notifyEmergencyContact: provider not ready.");
+ }
}
/**
@@ -394,9 +415,16 @@
*/
public static boolean shouldSystemBlockNumber(Context context, String phoneNumber,
Bundle extras) {
- final Bundle res = context.getContentResolver().call(
- AUTHORITY_URI, METHOD_SHOULD_SYSTEM_BLOCK_NUMBER, phoneNumber, extras);
- return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+ try {
+ final Bundle res = context.getContentResolver().call(
+ AUTHORITY_URI, METHOD_SHOULD_SYSTEM_BLOCK_NUMBER, phoneNumber, extras);
+ return res != null && res.getBoolean(RES_NUMBER_IS_BLOCKED, false);
+ } catch (NullPointerException | IllegalArgumentException ex) {
+ // The content resolver can throw an NPE or IAE; we don't want to crash Telecom if
+ // either of these happen.
+ Log.w(null, "shouldSystemBlockNumber: provider not ready.");
+ return false;
+ }
}
/**
@@ -416,9 +444,16 @@
* @return {@code true} if should show emergency call notification. {@code false} otherwise.
*/
public static boolean shouldShowEmergencyCallNotification(Context context) {
- final Bundle res = context.getContentResolver().call(
- AUTHORITY_URI, METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION, null, null);
- return res != null && res.getBoolean(RES_SHOW_EMERGENCY_CALL_NOTIFICATION, false);
+ try {
+ final Bundle res = context.getContentResolver().call(
+ AUTHORITY_URI, METHOD_SHOULD_SHOW_EMERGENCY_CALL_NOTIFICATION, null, null);
+ return res != null && res.getBoolean(RES_SHOW_EMERGENCY_CALL_NOTIFICATION, false);
+ } catch (NullPointerException | IllegalArgumentException ex) {
+ // The content resolver can throw an NPE or IAE; we don't want to crash Telecom if
+ // either of these happen.
+ Log.w(null, "shouldShowEmergencyCallNotification: provider not ready.");
+ return false;
+ }
}
/**
@@ -436,9 +471,16 @@
public static boolean getEnhancedBlockSetting(Context context, String key) {
Bundle extras = new Bundle();
extras.putString(EXTRA_ENHANCED_SETTING_KEY, key);
- final Bundle res = context.getContentResolver().call(
- AUTHORITY_URI, METHOD_GET_ENHANCED_BLOCK_SETTING, null, extras);
- return res != null && res.getBoolean(RES_ENHANCED_SETTING_IS_ENABLED, false);
+ try {
+ final Bundle res = context.getContentResolver().call(
+ AUTHORITY_URI, METHOD_GET_ENHANCED_BLOCK_SETTING, null, extras);
+ return res != null && res.getBoolean(RES_ENHANCED_SETTING_IS_ENABLED, false);
+ } catch (NullPointerException | IllegalArgumentException ex) {
+ // The content resolver can throw an NPE or IAE; we don't want to crash Telecom if
+ // either of these happen.
+ Log.w(null, "getEnhancedBlockSetting: provider not ready.");
+ return false;
+ }
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index b58e5b3..70f343e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1348,10 +1348,18 @@
= "android.settings.NOTIFICATION_SETTINGS";
/**
+ * Activity Action: Show app listing settings, filtered by those that send notifications.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_ALL_APPS_NOTIFICATION_SETTINGS =
+ "android.settings.ALL_APPS_NOTIFICATION_SETTINGS";
+
+ /**
* Activity Action: Show notification settings for a single app.
* <p>
- * Input: {@link #EXTRA_APP_PACKAGE}, the package containing the channel to display.
- * Input: Optionally, {@link #EXTRA_CHANNEL_ID}, to highlight that channel.
+ * Input: {@link #EXTRA_APP_PACKAGE}, the package to display.
* <p>
* Output: Nothing.
*/
@@ -7793,6 +7801,14 @@
"low_power_warning_acknowledged";
/**
+ * 0 (default) Auto battery saver suggestion has not been suppressed. 1) it has been
+ * suppressed.
+ * @hide
+ */
+ public static final String SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION =
+ "suppress_auto_battery_saver_suggestion";
+
+ /**
* This are the settings to be backed up.
*
* NOTE: Settings are backed up and restored in the order they appear
diff --git a/core/java/android/se/omapi/Channel.java b/core/java/android/se/omapi/Channel.java
index 65ce67f..c8efede 100644
--- a/core/java/android/se/omapi/Channel.java
+++ b/core/java/android/se/omapi/Channel.java
@@ -47,7 +47,8 @@
private final SEService mService;
private final Object mLock = new Object();
- Channel(SEService service, Session session, ISecureElementChannel channel) {
+ Channel(@NonNull SEService service, @NonNull Session session,
+ @NonNull ISecureElementChannel channel) {
if (service == null || session == null || channel == null) {
throw new IllegalArgumentException("Parameters cannot be null");
}
@@ -158,7 +159,7 @@
* @throws SecurityException if the command is filtered by the security policy.
* @throws NullPointerException if command is NULL.
*/
- public @NonNull byte[] transmit(byte[] command) throws IOException {
+ public @NonNull byte[] transmit(@NonNull byte[] command) throws IOException {
if (!mService.isConnected()) {
throw new IllegalStateException("service not connected to system");
}
diff --git a/core/java/android/se/omapi/ISecureElementListener.aidl b/core/java/android/se/omapi/ISecureElementListener.aidl
index e0c6e04..e9dd181 100644
--- a/core/java/android/se/omapi/ISecureElementListener.aidl
+++ b/core/java/android/se/omapi/ISecureElementListener.aidl
@@ -24,8 +24,4 @@
* @hide
*/
interface ISecureElementListener {
- /**
- * Called by the framework when the service is connected.
- */
- void serviceConnected();
}
diff --git a/core/java/android/se/omapi/Reader.java b/core/java/android/se/omapi/Reader.java
index 3dec976..9be3da6 100644
--- a/core/java/android/se/omapi/Reader.java
+++ b/core/java/android/se/omapi/Reader.java
@@ -46,7 +46,7 @@
private final Object mLock = new Object();
- Reader(SEService service, String name, ISecureElementReader reader) {
+ Reader(@NonNull SEService service, @NonNull String name, @NonNull ISecureElementReader reader) {
if (reader == null || service == null || name == null) {
throw new IllegalArgumentException("Parameters cannot be null");
}
diff --git a/core/java/android/se/omapi/SEService.java b/core/java/android/se/omapi/SEService.java
index d59e86a..311dc4c 100644
--- a/core/java/android/se/omapi/SEService.java
+++ b/core/java/android/se/omapi/SEService.java
@@ -62,17 +62,32 @@
/**
* Interface to send call-backs to the application when the service is connected.
*/
- public abstract static class SecureElementListener extends ISecureElementListener.Stub {
+ public interface SecureElementListener {
+ /**
+ * Called by the framework when the service is connected.
+ */
+ void onServiceConnected();
+ }
+
+ /**
+ * Listener object that allows the notification of the caller if this
+ * SEService could be bound to the backend.
+ */
+ private class SEListener extends ISecureElementListener.Stub {
+ public SecureElementListener mListener = null;
+
@Override
public IBinder asBinder() {
return this;
}
- /**
- * Called by the framework when the service is connected.
- */
- public void serviceConnected() {};
+ public void onServiceConnected() {
+ if (mListener != null) {
+ mListener.onServiceConnected();
+ }
+ }
}
+ private SEListener mSEListener = new SEListener();
private static final String TAG = "OMAPI.SEService";
@@ -95,34 +110,28 @@
private final HashMap<String, Reader> mReaders = new HashMap<String, Reader>();
/**
- * Listener object that allows the notification of the caller if this
- * SEService could be bound to the backend.
- */
- private ISecureElementListener mSEListener;
-
- /**
* Establishes a new connection that can be used to connect to all the
* Secure Elements available in the system. The connection process can be
* quite long, so it happens in an asynchronous way. It is usable only if
* the specified listener is called or if isConnected() returns
* <code>true</code>. <br>
* The call-back object passed as a parameter will have its
- * serviceConnected() method called when the connection actually happen.
+ * onServiceConnected() method called when the connection actually happen.
*
* @param context
* the context of the calling application. Cannot be
* <code>null</code>.
* @param listener
- * a SecureElementListener object. Can be <code>null</code>.
+ * a SecureElementListener object.
*/
- public SEService(Context context, SecureElementListener listener) {
+ public SEService(@NonNull Context context, @NonNull SecureElementListener listener) {
if (context == null) {
throw new NullPointerException("context must not be null");
}
mContext = context;
- mSEListener = listener;
+ mSEListener.mListener = listener;
mConnection = new ServiceConnection() {
@@ -131,9 +140,7 @@
mSecureElementService = ISecureElementService.Stub.asInterface(service);
if (mSEListener != null) {
- try {
- mSEListener.serviceConnected();
- } catch (RemoteException ignore) { }
+ mSEListener.onServiceConnected();
}
Log.i(TAG, "Service onServiceConnected");
}
@@ -233,7 +240,7 @@
*
* @return String containing the OpenMobile API version (e.g. "3.0").
*/
- public String getVersion() {
+ public @NonNull String getVersion() {
return "3.2";
}
diff --git a/core/java/android/se/omapi/Session.java b/core/java/android/se/omapi/Session.java
index 3d8b74b..adfeddd 100644
--- a/core/java/android/se/omapi/Session.java
+++ b/core/java/android/se/omapi/Session.java
@@ -47,7 +47,8 @@
private final ISecureElementSession mSession;
private static final String TAG = "OMAPI.Session";
- Session(SEService service, ISecureElementSession session, Reader reader) {
+ Session(@NonNull SEService service, @NonNull ISecureElementSession session,
+ @NonNull Reader reader) {
if (service == null || reader == null || session == null) {
throw new IllegalArgumentException("Parameters cannot be null");
}
@@ -195,7 +196,8 @@
* supported by the device
* @return an instance of Channel if available or null.
*/
- public @Nullable Channel openBasicChannel(byte[] aid, byte p2) throws IOException {
+ public @Nullable Channel openBasicChannel(@Nullable byte[] aid, @Nullable byte p2)
+ throws IOException {
if (!mService.isConnected()) {
throw new IllegalStateException("service not connected to system");
}
@@ -223,32 +225,6 @@
}
/**
- * This method is provided to ease the development of mobile application and for compliancy
- * with existing applications.
- * This method is equivalent to openBasicChannel(aid, P2=0x00)
- *
- * @param aid the AID of the Applet to be selected on this channel, as a
- * byte array, or null if no Applet is to be selected.
- * @throws IOException if there is a communication problem to the reader or
- * the Secure Element.
- * @throws IllegalStateException if the Secure Element session is used after
- * being closed.
- * @throws IllegalArgumentException if the aid's length is not within 5 to
- * 16 (inclusive).
- * @throws SecurityException if the calling application cannot be granted
- * access to this AID or the default Applet on this
- * session.
- * @throws NoSuchElementException if the AID on the Secure Element is not available or cannot be
- * selected.
- * @throws UnsupportedOperationException if the given P2 parameter is not
- * supported by the device
- * @return an instance of Channel if available or null.
- */
- public @Nullable Channel openBasicChannel(byte[] aid) throws IOException {
- return openBasicChannel(aid, (byte) 0x00);
- }
-
- /**
* Open a logical channel with the Secure Element, selecting the Applet represented by
* the given AID. If the AID is null, which means no Applet is to be selected on this
* channel, the default Applet is used. It's up to the Secure Element to choose which
@@ -300,7 +276,8 @@
* @return an instance of Channel. Null if the Secure Element is unable to
* provide a new logical channel.
*/
- public @Nullable Channel openLogicalChannel(byte[] aid, byte p2) throws IOException {
+ public @Nullable Channel openLogicalChannel(@Nullable byte[] aid, @Nullable byte p2)
+ throws IOException {
if (!mService.isConnected()) {
throw new IllegalStateException("service not connected to system");
}
@@ -327,32 +304,4 @@
}
}
}
-
- /**
- * This method is provided to ease the development of mobile application and for compliancy
- * with existing applications.
- * This method is equivalent to openLogicalChannel(aid, P2=0x00)
- *
- * @param aid the AID of the Applet to be selected on this channel, as a
- * byte array.
- * @throws IOException if there is a communication problem to the reader or
- * the Secure Element.
- * @throws IllegalStateException if the Secure Element is used after being
- * closed.
- * @throws IllegalArgumentException if the aid's length is not within 5 to
- * 16 (inclusive).
- * @throws SecurityException if the calling application cannot be granted
- * access to this AID or the default Applet on this
- * session.
- * @throws NoSuchElementException if the AID on the Secure Element is not
- * available or cannot be selected or a logical channel is already
- * open to a non-multiselectable Applet.
- * @throws UnsupportedOperationException if the given P2 parameter is not
- * supported by the device.
- * @return an instance of Channel. Null if the Secure Element is unable to
- * provide a new logical channel.
- */
- public @Nullable Channel openLogicalChannel(byte[] aid) throws IOException {
- return openLogicalChannel(aid, (byte) 0x00);
- }
}
diff --git a/core/java/android/text/InputType.java b/core/java/android/text/InputType.java
index f38482e..7f903b6 100644
--- a/core/java/android/text/InputType.java
+++ b/core/java/android/text/InputType.java
@@ -24,7 +24,7 @@
* <h3>Examples</h3>
*
* <dl>
- * <dt>A password field with with the password visible to the user:
+ * <dt>A password field with the password visible to the user:
* <dd>inputType = TYPE_CLASS_TEXT |
* TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
*
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 9687009..eecdb74 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -37,7 +37,6 @@
private static final Map<String, String> DEFAULT_FLAGS;
static {
DEFAULT_FLAGS = new HashMap<>();
- DEFAULT_FLAGS.put("settings_battery_v2", "true");
DEFAULT_FLAGS.put("settings_battery_display_app_list", "false");
DEFAULT_FLAGS.put("settings_zone_picker_v2", "true");
DEFAULT_FLAGS.put("settings_about_phone_v2", "true");
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index d3b1e5c..df81a31 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -250,6 +250,18 @@
}
/**
+ * Destroys the HwuiContext without completely
+ * releasing the Surface.
+ * @hide
+ */
+ public void hwuiDestroy() {
+ if (mHwuiContext != null) {
+ mHwuiContext.destroy();
+ mHwuiContext = null;
+ }
+ }
+
+ /**
* Returns true if this object holds a valid surface.
*
* @return True if it holds a physical surface, so lockCanvas() will succeed.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 6393127..f6c669b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14927,10 +14927,6 @@
* ImageView with only the foreground image. The default implementation returns true; subclasses
* should override if they have cases which can be optimized.</p>
*
- * <p>The current implementation of the saveLayer and saveLayerAlpha methods in {@link Canvas}
- * necessitates that a View return true if it uses the methods internally without passing the
- * {@link Canvas#CLIP_TO_LAYER_SAVE_FLAG}.</p>
- *
* <p><strong>Note:</strong> The return value of this method is ignored if {@link
* #forceHasOverlappingRendering(boolean)} has been called on this view.</p>
*
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index abc19d0..abd33f3 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2220,7 +2220,7 @@
@IntDef(
flag = true,
value = {LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT,
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS,
+ LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER})
@interface LayoutInDisplayCutoutMode {}
@@ -2231,10 +2231,11 @@
* Defaults to {@link #LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT}.
*
* @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
- * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
+ * @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
* @see #LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
* @see DisplayCutout
- * @see android.R.attr#layoutInDisplayCutoutMode
+ * @see android.R.attr#windowLayoutInDisplayCutoutMode
+ * android:windowLayoutInDisplayCutoutMode
*/
@LayoutInDisplayCutoutMode
public int layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
@@ -2245,10 +2246,10 @@
* laid out such that it does not overlap with the {@link DisplayCutout} area.
*
* <p>
- * In practice, this means that if the window did not set FLAG_FULLSCREEN or
- * SYSTEM_UI_FLAG_FULLSCREEN, it can extend into the cutout area in portrait if the cutout
- * is at the top edge. Similarly for SYSTEM_UI_FLAG_HIDE_NAVIGATION and a cutout at the
- * bottom of the screen.
+ * In practice, this means that if the window did not set {@link #FLAG_FULLSCREEN} or
+ * {@link View#SYSTEM_UI_FLAG_FULLSCREEN}, it can extend into the cutout area in portrait
+ * if the cutout is at the top edge. Similarly for
+ * {@link View#SYSTEM_UI_FLAG_HIDE_NAVIGATION} and a cutout at the bottom of the screen.
* Otherwise (i.e. fullscreen or landscape) it is laid out such that it does not overlap the
* cutout area.
*
@@ -2258,6 +2259,9 @@
*
* @see DisplayCutout
* @see WindowInsets
+ * @see #layoutInDisplayCutoutMode
+ * @see android.R.attr#windowLayoutInDisplayCutoutMode
+ * android:windowLayoutInDisplayCutoutMode
*/
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT = 0;
@@ -2279,8 +2283,40 @@
* The window must make sure that no important content overlaps with the
* {@link DisplayCutout}.
*
+ * <p>
+ * In this mode, the window extends under cutouts on the short edge of the display in both
+ * portrait and landscape, regardless of whether the window is hiding the system bars:<br/>
+ * <img src="{@docRoot}reference/android/images/display_cutout/short_edge/fullscreen_top_no_letterbox.png"
+ * height="720"
+ * alt="Screenshot of a fullscreen activity on a display with a cutout at the top edge in
+ * portrait, no letterbox is applied."/>
+ *
+ * <img src="{@docRoot}reference/android/images/display_cutout/short_edge/landscape_top_no_letterbox.png"
+ * width="720"
+ * alt="Screenshot of an activity on a display with a cutout at the top edge in landscape,
+ * no letterbox is applied."/>
+ *
+ * <p>
+ * A cutout in the corner is considered to be on the short edge: <br/>
+ * <img src="{@docRoot}reference/android/images/display_cutout/short_edge/fullscreen_corner_no_letterbox.png"
+ * height="720"
+ * alt="Screenshot of a fullscreen activity on a display with a cutout in the corner in
+ * portrait, no letterbox is applied."/>
+ *
+ * <p>
+ * On the other hand, should the cutout be on the long edge of the display, a letterbox will
+ * be applied such that the window does not extend into the cutout on either long edge:
+ * <br/>
+ * <img src="{@docRoot}reference/android/images/display_cutout/short_edge/portrait_side_letterbox.png"
+ * height="720"
+ * alt="Screenshot of an activity on a display with a cutout on the long edge in portrait,
+ * letterbox is applied."/>
+ *
* @see DisplayCutout
* @see WindowInsets#getDisplayCutout()
+ * @see #layoutInDisplayCutoutMode
+ * @see android.R.attr#windowLayoutInDisplayCutoutMode
+ * android:windowLayoutInDisplayCutoutMode
*/
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES = 1;
@@ -2288,12 +2324,14 @@
* The window is never allowed to overlap with the DisplayCutout area.
*
* <p>
- * This should be used with windows that transiently set SYSTEM_UI_FLAG_FULLSCREEN to
- * avoid a relayout of the window when the flag is set or cleared.
+ * This should be used with windows that transiently set
+ * {@link View#SYSTEM_UI_FLAG_FULLSCREEN} or {@link View#SYSTEM_UI_FLAG_HIDE_NAVIGATION}
+ * to avoid a relayout of the window when the respective flag is set or cleared.
*
* @see DisplayCutout
- * @see View#SYSTEM_UI_FLAG_FULLSCREEN SYSTEM_UI_FLAG_FULLSCREEN
- * @see View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
+ * @see #layoutInDisplayCutoutMode
+ * @see android.R.attr#windowLayoutInDisplayCutoutMode
+ * android:windowLayoutInDisplayCutoutMode
*/
public static final int LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER = 2;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 01fd090..88300db 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -1819,13 +1819,22 @@
final View[] views = client.autofillClientFindViewsByAutofillIdTraversal(
Helper.toArray(ids));
+ ArrayList<AutofillId> failedIds = null;
+
for (int i = 0; i < itemCount; i++) {
final AutofillId id = ids.get(i);
final AutofillValue value = values.get(i);
final int viewId = id.getViewId();
final View view = views[i];
if (view == null) {
- Log.w(TAG, "autofill(): no View with id " + viewId);
+ // Most likely view has been removed after the initial request was sent to the
+ // the service; this is fine, but we need to update the view status in the
+ // server side so it can be triggered again.
+ Log.d(TAG, "autofill(): no View with id " + id);
+ if (failedIds == null) {
+ failedIds = new ArrayList<>();
+ }
+ failedIds.add(id);
continue;
}
if (id.isVirtual()) {
@@ -1859,12 +1868,28 @@
}
}
+ if (failedIds != null) {
+ if (sVerbose) {
+ Log.v(TAG, "autofill(): total failed views: " + failedIds);
+ }
+ try {
+ mService.setAutofillFailure(mSessionId, failedIds, mContext.getUserId());
+ } catch (RemoteException e) {
+ // In theory, we could ignore this error since it's not a big deal, but
+ // in reality, we rather crash the app anyways, as the failure could be
+ // a consequence of something going wrong on the server side...
+ e.rethrowFromSystemServer();
+ }
+ }
+
if (virtualValues != null) {
for (int i = 0; i < virtualValues.size(); i++) {
final View parent = virtualValues.keyAt(i);
final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
parent.autofill(childrenValues);
numApplied += childrenValues.size();
+ // TODO: we should provide a callback so the parent can call failures; something
+ // like notifyAutofillFailed(View view, int[] childrenIds);
}
}
diff --git a/core/java/android/view/autofill/IAutoFillManager.aidl b/core/java/android/view/autofill/IAutoFillManager.aidl
index 56f79ab..176df73 100644
--- a/core/java/android/view/autofill/IAutoFillManager.aidl
+++ b/core/java/android/view/autofill/IAutoFillManager.aidl
@@ -16,6 +16,8 @@
package android.view.autofill;
+import java.util.List;
+
import android.content.ComponentName;
import android.graphics.Rect;
import android.os.Bundle;
@@ -47,6 +49,7 @@
in AutofillId autoFillId, in Rect bounds, in AutofillValue value, int userId,
boolean hasCallback, int flags, in ComponentName componentName, int sessionId,
int action, boolean compatMode);
+ void setAutofillFailure(int sessionId, in List<AutofillId> ids, int userId);
void finishSession(int sessionId, int userId);
void cancelSession(int sessionId, int userId);
void setAuthenticationResult(in Bundle data, int sessionId, int authenticationId, int userId);
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index d0f9eee..6df1655 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -152,6 +152,14 @@
* will continue to load the resource as usual. Otherwise, the return
* response and data will be used.
*
+ * <p>This callback is invoked for a variety of URL schemes (e.g., {@code http(s):}, {@code
+ * data:}, {@code file:}, etc.), not only those schemes which send requests over the network.
+ * This is not called for {@code javascript:} URLs, {@code blob:} URLs, or for assets accessed
+ * via {@code file:///android_asset/} or {@code file:///android_res/} URLs.
+ *
+ * <p>In the case of redirects, this is only called for the initial resource URL, not any
+ * subsequent redirect URLs.
+ *
* <p class="note"><b>Note:</b> This method is called on a thread
* other than the UI thread so clients should exercise caution
* when accessing private data or the view system.
@@ -182,6 +190,14 @@
* will continue to load the resource as usual. Otherwise, the return
* response and data will be used.
*
+ * <p>This callback is invoked for a variety of URL schemes (e.g., {@code http(s):}, {@code
+ * data:}, {@code file:}, etc.), not only those schemes which send requests over the network.
+ * This is not called for {@code javascript:} URLs, {@code blob:} URLs, or for assets accessed
+ * via {@code file:///android_asset/} or {@code file:///android_res/} URLs.
+ *
+ * <p>In the case of redirects, this is only called for the initial resource URL, not any
+ * subsequent redirect URLs.
+ *
* <p class="note"><b>Note:</b> This method is called on a thread
* other than the UI thread so clients should exercise caution
* when accessing private data or the view system.
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 3775835..57d64b9 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4824,13 +4824,23 @@
return true;
}
+ private boolean tooLargeTextForMagnifier() {
+ final float magnifierContentHeight = Math.round(
+ mMagnifierAnimator.mMagnifier.getHeight()
+ / mMagnifierAnimator.mMagnifier.getZoom());
+ final Paint.FontMetrics fontMetrics = mTextView.getPaint().getFontMetrics();
+ final float glyphHeight = fontMetrics.descent - fontMetrics.ascent;
+ return glyphHeight > magnifierContentHeight;
+ }
+
protected final void updateMagnifier(@NonNull final MotionEvent event) {
if (mMagnifierAnimator == null) {
return;
}
final PointF showPosInView = new PointF();
- final boolean shouldShow = obtainMagnifierShowCoordinates(event, showPosInView);
+ final boolean shouldShow = !tooLargeTextForMagnifier()
+ && obtainMagnifierShowCoordinates(event, showPosInView);
if (shouldShow) {
// Make the cursor visible and stop blinking.
mRenderCursorRegardlessTiming = true;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 7b1acb1..39755aa 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -12474,9 +12474,8 @@
+ " before=" + before + " after=" + after + ": " + buffer);
}
- if (AccessibilityManager.getInstance(mContext).isEnabled()
- && !isPasswordInputType(getInputType()) && !hasPasswordTransformationMethod()) {
- mBeforeText = buffer.toString();
+ if (AccessibilityManager.getInstance(mContext).isEnabled() && (mTransformed != null)) {
+ mBeforeText = mTransformed.toString();
}
TextView.this.sendBeforeTextChanged(buffer, start, before, after);
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 514ff76..03dd77f 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -93,6 +93,7 @@
void noteVibratorOff(int uid);
void noteGpsChanged(in WorkSource oldSource, in WorkSource newSource);
void noteGpsSignalQuality(int signalLevel);
+ void noteUsbConnectionState(boolean connected);
void noteScreenState(int state);
void noteScreenBrightness(int brightness);
void noteUserActivity(int uid, int event);
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3c150c1..8117bf7 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -19,7 +19,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
-import android.app.job.JobProtoEnums;
import android.bluetooth.BluetoothActivityEnergyInfo;
import android.bluetooth.UidTraffic;
import android.content.ContentResolver;
@@ -767,6 +766,8 @@
int mCameraOnNesting;
StopwatchTimer mCameraOnTimer;
+ int mUsbDataState; // 0: unknown, 1: disconnected, 2: connected
+
int mGpsSignalQualityBin = -1;
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
protected final StopwatchTimer[] mGpsSignalQualityTimer =
@@ -5240,6 +5241,19 @@
}
}
+ public void noteUsbConnectionStateLocked(boolean connected) {
+ int newState = connected ? 2 : 1;
+ if (mUsbDataState != newState) {
+ mUsbDataState = newState;
+ if (connected) {
+ mHistoryCur.states2 |= HistoryItem.STATE2_USB_DATA_LINK_FLAG;
+ } else {
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_USB_DATA_LINK_FLAG;
+ }
+ addHistoryRecordLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
+ }
+ }
+
void stopAllPhoneSignalStrengthTimersLocked(int except) {
final long elapsedRealtime = mClocks.elapsedRealtime();
for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
@@ -5999,7 +6013,6 @@
if (strengthBin >= 0) {
if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
- StatsLog.write(StatsLog.WIFI_SIGNAL_STRENGTH_CHANGED, strengthBin);
}
mHistoryCur.states2 =
(mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
@@ -6010,6 +6023,7 @@
} else {
stopAllWifiSignalStrengthTimersLocked(-1);
}
+ StatsLog.write(StatsLog.WIFI_SIGNAL_STRENGTH_CHANGED, strengthBin);
mWifiSignalStrengthBin = strengthBin;
}
}
@@ -7250,25 +7264,17 @@
public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
- StatsLog.AUDIO_STATE_CHANGED__STATE__ON);
}
public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
if (mAudioTurnedOnTimer != null) {
mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
- if (!mAudioTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
- StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
- }
}
}
public void noteResetAudioLocked(long elapsedRealtimeMs) {
if (mAudioTurnedOnTimer != null) {
mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, getUid(), null,
- StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
}
}
@@ -7282,25 +7288,17 @@
public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null,
- StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__ON);
}
public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
if (mVideoTurnedOnTimer != null) {
mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
- if (!mVideoTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(),
- null, StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
- }
}
}
public void noteResetVideoLocked(long elapsedRealtimeMs) {
if (mVideoTurnedOnTimer != null) {
mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), null,
- StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
}
}
@@ -7314,25 +7312,17 @@
public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
- StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
}
public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
if (mFlashlightTurnedOnTimer != null) {
mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
- if (!mFlashlightTurnedOnTimer.isRunningLocked()) {
- StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
- StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
- }
}
}
public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
if (mFlashlightTurnedOnTimer != null) {
mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), null,
- StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
}
}
@@ -7346,25 +7336,17 @@
public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
- StatsLog.CAMERA_STATE_CHANGED__STATE__ON);
}
public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
if (mCameraTurnedOnTimer != null) {
mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
- if (!mCameraTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
- StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
- }
}
}
public void noteResetCameraLocked(long elapsedRealtimeMs) {
if (mCameraTurnedOnTimer != null) {
mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, getUid(), null,
- StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
}
}
@@ -10040,8 +10022,6 @@
DualTimer t = mSyncStats.startObject(name);
if (t != null) {
t.startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name,
- StatsLog.SYNC_STATE_CHANGED__STATE__ON);
}
}
@@ -10049,10 +10029,6 @@
DualTimer t = mSyncStats.stopObject(name);
if (t != null) {
t.stopRunningLocked(elapsedRealtimeMs);
- if (!t.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, getUid(), null, name,
- StatsLog.SYNC_STATE_CHANGED__STATE__OFF);
- }
}
}
@@ -10060,9 +10036,6 @@
DualTimer t = mJobStats.startObject(name);
if (t != null) {
t.startRunningLocked(elapsedRealtimeMs);
- StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
- name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
- JobProtoEnums.STOP_REASON_CANCELLED);
}
}
@@ -10070,11 +10043,6 @@
DualTimer t = mJobStats.stopObject(name);
if (t != null) {
t.stopRunningLocked(elapsedRealtimeMs);
- if (!t.isRunningLocked()) { // only tell statsd if truly stopped
- StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), null,
- name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
- stopReason);
- }
}
if (mBsi.mOnBatteryTimeBase.isRunning()) {
SparseIntArray types = mJobCompletions.get(name);
@@ -10182,10 +10150,6 @@
public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
DualTimer t = getSensorTimerLocked(sensor, /* create= */ true);
t.startRunningLocked(elapsedRealtimeMs);
- if (sensor != Sensor.GPS) {
- StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, getUid(), null, sensor,
- StatsLog.SENSOR_STATE_CHANGED__STATE__ON);
- }
}
public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
@@ -10193,10 +10157,6 @@
DualTimer t = getSensorTimerLocked(sensor, false);
if (t != null) {
t.stopRunningLocked(elapsedRealtimeMs);
- if (sensor != Sensor.GPS) {
- StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, getUid(), null,
- sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
- }
}
}
diff --git a/core/java/com/android/internal/os/RoSystemProperties.java b/core/java/com/android/internal/os/RoSystemProperties.java
index 89a4e17..dc660a4 100644
--- a/core/java/com/android/internal/os/RoSystemProperties.java
+++ b/core/java/com/android/internal/os/RoSystemProperties.java
@@ -31,6 +31,8 @@
SystemProperties.get("ro.control_privapp_permissions");
// ------ ro.config.* -------- //
+ public static final boolean CONFIG_AVOID_GFX_ACCEL =
+ SystemProperties.getBoolean("ro.config.avoid_gfx_accel", false);
public static final boolean CONFIG_LOW_RAM =
SystemProperties.getBoolean("ro.config.low_ram", false);
public static final boolean CONFIG_SMALL_BATTERY =
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index c71e505..c5be8e4 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -142,12 +142,24 @@
// Package names that are exempted from private API blacklisting
final ArraySet<String> mHiddenApiPackageWhitelist = new ArraySet<>();
+ // The list of carrier applications which should be disabled until used.
+ // This function suppresses update notifications for these pre-installed apps.
+ // In SubscriptionInfoUpdater, the listed applications are disabled until used when all of the
+ // following conditions are met.
+ // 1. Not currently carrier-privileged according to the inserted SIM
+ // 2. Pre-installed
+ // 3. In the default state (enabled but not explicitly)
+ // And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted
+ // that marks the app as carrier privileged. It also grants the app default permissions
+ // for Phone and Location. As such, apps MUST only ever be added to this list if they
+ // obtain user consent to access their location through other means.
+ final ArraySet<String> mDisabledUntilUsedPreinstalledCarrierApps = new ArraySet<>();
+
// These are the packages of carrier-associated apps which should be disabled until used until
// a SIM is inserted which grants carrier privileges to that carrier app.
final ArrayMap<String, List<String>> mDisabledUntilUsedPreinstalledCarrierAssociatedApps =
new ArrayMap<>();
-
final ArrayMap<String, ArraySet<String>> mPrivAppPermissions = new ArrayMap<>();
final ArrayMap<String, ArraySet<String>> mPrivAppDenyPermissions = new ArrayMap<>();
@@ -232,6 +244,10 @@
return mBackupTransportWhitelist;
}
+ public ArraySet<String> getDisabledUntilUsedPreinstalledCarrierApps() {
+ return mDisabledUntilUsedPreinstalledCarrierApps;
+ }
+
public ArrayMap<String, List<String>> getDisabledUntilUsedPreinstalledCarrierAssociatedApps() {
return mDisabledUntilUsedPreinstalledCarrierAssociatedApps;
}
@@ -630,6 +646,18 @@
associatedPkgs.add(pkgname);
}
XmlUtils.skipCurrentTag(parser);
+ } else if ("disabled-until-used-preinstalled-carrier-app".equals(name)
+ && allowAppConfigs) {
+ String pkgname = parser.getAttributeValue(null, "package");
+ if (pkgname == null) {
+ Slog.w(TAG,
+ "<disabled-until-used-preinstalled-carrier-app> without "
+ + "package in " + permFile + " at "
+ + parser.getPositionDescription());
+ } else {
+ mDisabledUntilUsedPreinstalledCarrierApps.add(pkgname);
+ }
+ XmlUtils.skipCurrentTag(parser);
} else if ("privapp-permissions".equals(name) && allowPrivappPermissions) {
// privapp permissions from system, vendor and product partitions are stored
// separately. This is to prevent xml files in the vendor partition from
diff --git a/core/proto/android/app/job/enums.proto b/core/proto/android/app/job/enums.proto
index 0f14f20..17bf4fb 100644
--- a/core/proto/android/app/job/enums.proto
+++ b/core/proto/android/app/job/enums.proto
@@ -24,6 +24,7 @@
// Reasons a job is stopped.
// Primarily used in android.app.job.JobParameters.java.
enum StopReasonEnum {
+ STOP_REASON_UNKNOWN = -1;
STOP_REASON_CANCELLED = 0;
STOP_REASON_CONSTRAINTS_NOT_SATISFIED = 1;
STOP_REASON_PREEMPT = 2;
diff --git a/core/proto/android/content/clipdata.proto b/core/proto/android/content/clipdata.proto
index aeeef97..cbc00a7 100644
--- a/core/proto/android/content/clipdata.proto
+++ b/core/proto/android/content/clipdata.proto
@@ -25,7 +25,7 @@
// An android.content.ClipData object.
message ClipDataProto {
- option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+ option (.android.msg_privacy).dest = DEST_LOCAL;
optional android.content.ClipDescriptionProto description = 1;
@@ -40,7 +40,7 @@
// An android.content.ClipData.Item object.
message Item {
- option (.android.msg_privacy).dest = DEST_EXPLICIT;
+ option (.android.msg_privacy).dest = DEST_LOCAL;
oneof data {
string html_text = 1;
diff --git a/core/proto/android/providers/settings.proto b/core/proto/android/providers/settings.proto
index 7f8bed5..76a3b5d 100644
--- a/core/proto/android/providers/settings.proto
+++ b/core/proto/android/providers/settings.proto
@@ -20,8 +20,9 @@
option java_multiple_files = true;
option java_outer_classname = "SettingsServiceProto";
-import "frameworks/base/core/proto/android/providers/settings/common.proto";
import "frameworks/base/core/proto/android/providers/settings/global.proto";
+import "frameworks/base/core/proto/android/providers/settings/secure.proto";
+import "frameworks/base/core/proto/android/providers/settings/system.proto";
import "frameworks/base/libs/incident/proto/android/privacy.proto";
message SettingsServiceDumpProto {
@@ -47,351 +48,6 @@
optional SystemSettingsProto system_settings = 3;
}
-// Note: it's a conscious decision to add each setting as a separate field. This
-// allows annotating each setting with its own privacy tag.
-message SecureSettingsProto {
- option (android.msg_privacy).dest = DEST_EXPLICIT;
-
- repeated SettingsOperationProto historical_operations = 1;
-
- optional SettingProto android_id = 2;
- optional SettingProto default_input_method = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto selected_input_method_subtype = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto input_methods_subtype_history = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto input_method_selector_visibility = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The currently selected voice interaction service flattened ComponentName.
- optional SettingProto voice_interaction_service = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The currently selected autofill service flattened ComponentName.
- optional SettingProto autofill_service = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Boolean indicating if Autofill supports field classification.
- optional SettingProto autofill_feature_field_classification = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto autofill_user_data_max_user_data_size = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto autofill_user_data_max_field_classification_ids_size = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto autofill_user_data_max_category_count = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto autofill_user_data_max_value_length = 13 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto autofill_user_data_min_value_length = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto user_setup_complete = 15 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Whether the current user has been set up via setup wizard (0 = false,
- // 1 = true). This value differs from USER_SETUP_COMPLETE in that it can be
- // reset back to 0 in case SetupWizard has been re-enabled on TV devices.
- optional SettingProto tv_user_setup_complete = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
- repeated SettingProto completed_categories = 17;
- optional SettingProto enabled_input_methods = 18 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto disabled_system_input_methods = 19 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_ime_with_hard_keyboard = 20 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto always_on_vpn_app = 21;
- optional SettingProto always_on_vpn_lockdown = 22 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto install_non_market_apps = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto unknown_sources_default_reversed = 24 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The degree of location access enabled by the user.
- optional SettingProto location_mode = 25 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The App or module that changes the location mode.
- optional SettingProto location_changer = 26 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Whether lock-to-app will lock the keyguard when exiting.
- optional SettingProto lock_to_app_exit_locked = 27 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lock_screen_lock_after_timeout = 28 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lock_screen_allow_private_notifications = 29 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lock_screen_allow_remote_input = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_note_about_notification_hiding = 31 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto trust_agents_initialized = 32 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto parental_control_enabled = 33 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto parental_control_last_update = 34 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto parental_control_redirect_url = 35 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto settings_classname = 36 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_enabled = 37 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_shortcut_enabled = 38 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_shortcut_on_lock_screen = 39 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_shortcut_dialog_shown = 40 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_shortcut_target_service = 41 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Setting specifying the accessibility service or feature to be toggled via
- // the accessibility button in the navigation bar. This is either a
- // flattened ComponentName or the class name of a system class implementing
- // a supported accessibility feature.
- optional SettingProto accessibility_button_target_component = 42 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto touch_exploration_enabled = 43 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // List of the enabled accessibility providers.
- optional SettingProto enabled_accessibility_services = 44;
- // List of the accessibility services to which the user has granted
- // permission to put the device into touch exploration mode.
- optional SettingProto touch_exploration_granted_accessibility_services = 45;
- // Uri of the slice that's presented on the keyguard. Defaults to a slice
- // with the date and next alarm.
- optional SettingProto keyguard_slice_uri = 46;
- // Whether to speak passwords while in accessibility mode.
- optional SettingProto accessibility_speak_password = 47 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_high_text_contrast_enabled = 48 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_display_magnification_enabled = 49 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_display_magnification_navbar_enabled = 50 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_display_magnification_scale = 51 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_soft_keyboard_mode = 52 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_enabled = 53 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_locale = 54 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_preset = 55 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_background_color = 56 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_foreground_color = 57 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_edge_type = 58 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_edge_color = 59 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_window_color = 60 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_typeface = 61 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_captioning_font_scale = 62 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_display_inversion_enabled = 63 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_display_daltonizer_enabled = 64 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Integer property that specifies the type of color space adjustment to perform.
- optional SettingProto accessibility_display_daltonizer = 65 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_autoclick_enabled = 66 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_autoclick_delay = 67 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accessibility_large_pointer_icon = 68 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto long_press_timeout = 69 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto multi_press_timeout = 70 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto enabled_print_services = 71;
- optional SettingProto disabled_print_services = 72;
- optional SettingProto display_density_forced = 73 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tts_default_rate = 74 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tts_default_pitch = 75 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tts_default_synth = 76 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tts_default_locale = 77 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tts_enabled_plugins = 78;
- optional SettingProto connectivity_release_pending_intent_delay_ms = 79 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto allowed_geolocation_origins = 80;
- optional SettingProto preferred_tty_mode = 81 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto enhanced_voice_privacy_enabled = 82 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tty_mode_enabled = 83 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto backup_enabled = 84 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto backup_auto_restore = 85 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto backup_provisioned = 86 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto backup_transport = 87 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto last_setup_shown = 88 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_global_search_activity = 89 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_num_promoted_sources = 90 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_max_results_to_display = 91 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_max_results_per_source = 92 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_web_results_override_limit = 93 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_promoted_source_deadline_millis = 94 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_source_timeout_millis = 95 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_prefill_millis = 96 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_max_stat_age_millis = 97 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_max_source_event_age_millis = 98 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_min_impressions_for_source_ranking = 99 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_min_clicks_for_source_ranking = 100 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_max_shortcuts_returned = 101 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_query_thread_core_pool_size = 102 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_query_thread_max_pool_size = 103 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_shortcut_refresh_core_pool_size = 104 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_shortcut_refresh_max_pool_size = 105 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_thread_keepalive_seconds = 106 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto search_per_source_concurrent_query_limit = 107 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Whether or not alert sounds are played on StorageManagerService events.
- optional SettingProto mount_play_notification_snd = 108 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto mount_ums_autostart = 109 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto mount_ums_prompt = 110 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto mount_ums_notify_enabled = 111 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto anr_show_background = 112 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_first_crash_dialog_dev_option = 113 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The ComponentName string of the service to be used as the voice
- // recognition service.
- optional SettingProto voice_recognition_service = 114 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto package_verifier_user_consent = 115 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto selected_spell_checker = 116 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto selected_spell_checker_subtype = 117 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto spell_checker_enabled = 118 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto incall_power_button_behavior = 119 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto incall_back_button_behavior = 120 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto wake_gesture_enabled = 121 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto doze_enabled = 122 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto doze_always_on = 123 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto doze_pulse_on_pick_up = 124 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto doze_pulse_on_long_press = 125 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto doze_pulse_on_double_tap = 126 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto ui_night_mode = 127 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screensaver_enabled = 128 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screensaver_components = 129 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screensaver_activate_on_dock = 130 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screensaver_activate_on_sleep = 131 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screensaver_default_component = 132 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto nfc_payment_default_component = 133 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto nfc_payment_foreground = 134 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sms_default_application = 135 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto dialer_default_application = 136 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto emergency_assistance_application = 137 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_structure_enabled = 138 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_screenshot_enabled = 139 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_disclosure_enabled = 140 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_rotation_suggestions = 141 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto num_rotation_suggestions_accepted = 142 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Read only list of the service components that the current user has
- // explicitly allowed to see and assist with all of the user's
- // notifications.
- optional SettingProto enabled_notification_assistant = 143 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto enabled_notification_listeners = 144 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto enabled_notification_policy_access_packages = 145 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Defines whether managed profile ringtones should be synced from its
- // parent profile.
- optional SettingProto sync_parent_sounds = 146 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto immersive_mode_confirmations = 147 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The query URI to find a print service to install.
- optional SettingProto print_service_search_uri = 148 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The query URI to find an NFC service to install.
- optional SettingProto payment_service_search_uri = 149 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The query URI to find an auto fill service to install.
- optional SettingProto autofill_service_search_uri = 150 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto skip_first_use_hints = 151 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto unsafe_volume_music_active_ms = 152 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lock_screen_show_notifications = 153 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tv_input_hidden_inputs = 154;
- optional SettingProto tv_input_custom_labels = 155;
- optional SettingProto usb_audio_automatic_routing_disabled = 156 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sleep_timeout = 157 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto double_tap_to_wake = 158 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // The current assistant component. It could be a voice interaction service,
- // or an activity that handles ACTION_ASSIST, or empty, which means using
- // the default handling.
- optional SettingProto assistant = 159 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto camera_gesture_disabled = 160 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto camera_double_tap_power_gesture_disabled = 161 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto camera_double_twist_to_flip_enabled = 162 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto camera_lift_trigger_enabled = 163 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_gesture_enabled = 164 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_gesture_sensitivity = 165 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_gesture_silence_alerts_enabled = 166 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_gesture_wake_enabled = 167 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto assist_gesture_setup_complete = 168 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto night_display_activated = 169 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto night_display_auto_mode = 170 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto night_display_color_temperature = 171 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto night_display_custom_start_time = 172 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto night_display_custom_end_time = 173 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto night_display_last_activated_time = 174 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto enabled_vr_listeners = 175 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto vr_display_mode = 176 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto carrier_apps_handled = 177 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto managed_profile_contact_remote_search = 178 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto automatic_storage_manager_enabled = 179 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto automatic_storage_manager_days_to_retain = 180 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto automatic_storage_manager_bytes_cleared = 181 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto automatic_storage_manager_last_run = 182 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto automatic_storage_manager_turned_off_by_policy = 183 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto system_navigation_keys_enabled = 184 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Holds comma-separated list of ordering of QuickSettings tiles.
- optional SettingProto qs_tiles = 185 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto instant_apps_enabled = 186 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto device_paired = 187 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto package_verifier_state = 188 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto cmas_additional_broadcast_pkg = 189 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto notification_badging = 190 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto qs_auto_added_tiles = 191 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lockdown_in_power_menu = 192 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto backup_manager_constants = 193;
- optional SettingProto backup_local_transport_parameters = 194;
- optional SettingProto bluetooth_on_while_driving = 195 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingsProto volume_hush_gesture = 196 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Please insert fields in the same order as in
- // frameworks/base/core/java/android/provider/Settings.java.
- // Next tag = 197
-}
-
-message SystemSettingsProto {
- option (android.msg_privacy).dest = DEST_EXPLICIT;
-
- repeated SettingsOperationProto historical_operations = 1;
-
- optional SettingProto end_button_behavior = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto advanced_settings = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto bluetooth_discoverability = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto bluetooth_discoverability_timeout = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto font_scale = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto system_locales = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto display_color_mode = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screen_off_timeout = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screen_brightness = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screen_brightness_for_vr = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screen_brightness_mode = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto screen_auto_brightness_adj = 13 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Determines which streams are affected by ringer mode changes. The stream
- // type's bit will be set to 1 if it should be muted when going into an
- // inaudible ringer mode.
- optional SettingProto mode_ringer_streams_affected = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto mute_streams_affected = 15 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto vibrate_on = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto vibrate_input_devices = 17 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto notification_vibration_intensity = 18 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto haptic_feedback_intensity = 19 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_ring = 20 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_system = 21 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_voice = 22 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_music = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_alarm = 24 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_notification = 25 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_bluetooth_sco = 26 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_accessibility = 27 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto volume_master = 28 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto master_mono = 29 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Whether silent mode should allow vibration feedback. This is used
- // internally in AudioService and the Sound settings activity to coordinate
- // decoupling of vibrate and silent modes. This setting will likely be
- // removed in a future release with support for audio/vibe feedback
- // profiles.
- // Not used anymore. On devices with vibrator, the user explicitly selects
- // silent or vibrate mode. Kept for use by legacy database upgrade code in
- // DatabaseHelper.
- optional SettingProto vibrate_in_silent = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Appended to various volume related settings to record the previous values
- // before the settings were affected by a silent/vibrate ringer mode change.
- optional SettingProto append_for_last_audible = 31 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto ringtone = 32;
- optional SettingProto ringtone_cache = 33;
- optional SettingProto notification_sound = 34;
- optional SettingProto notification_sound_cache = 35;
- optional SettingProto alarm_alert = 36;
- optional SettingProto alarm_alert_cache = 37;
- optional SettingProto media_button_receiver = 38;
- optional SettingProto text_auto_replace = 39 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto text_auto_caps = 40 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto text_auto_punctuate = 41 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto text_show_password = 42 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_gtalk_service_status = 43 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto time_12_24 = 44 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto date_format = 45 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto setup_wizard_has_run = 46 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto accelerometer_rotation = 47 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto user_rotation = 48 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto hide_rotation_lock_toggle_for_accessibility = 49 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto vibrate_when_ringing = 50 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto dtmf_tone_when_dialing = 51 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto dtmf_tone_type_when_dialing = 52 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto hearing_aid = 53 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto tty_mode = 54 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // User-selected RTT mode. When on, outgoing and incoming calls will be
- // answered as RTT calls when supported by the device and carrier. Boolean
- // value.
- optional SettingProto rtt_calling_mode = 55 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sound_effects_enabled = 56 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto haptic_feedback_enabled = 57 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto notification_light_pulse = 58 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Show pointer location on screen? 0 = no, 1 = yes.
- optional SettingProto pointer_location = 59 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_touches = 60 [ (android.privacy).dest = DEST_AUTOMATIC ];
- // Log raw orientation data from {@link
- // com.android.server.policy.WindowOrientationListener} for use with the
- // orientationplot.py tool.
- // 0 = no, 1 = yes
- optional SettingProto window_orientation_listener_log = 61 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lockscreen_sounds_enabled = 62 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lockscreen_disabled = 63 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sip_receive_calls = 64 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sip_call_options = 65 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sip_always = 66 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto sip_address_only = 67 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto pointer_speed = 68 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto lock_to_app_enabled = 69 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto egg_mode = 70 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto show_battery_percent = 71 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto when_to_make_wifi_calls = 72 [ (android.privacy).dest = DEST_AUTOMATIC ];
-
- // Please insert fields in the same order as in
- // frameworks/base/core/java/android/provider/Settings.java.
- // Next tag = 73;
-}
-
message SettingsProto {
// Enum values gotten from Settings.java
enum ScreenBrightnessMode {
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
new file mode 100644
index 0000000..cfb8980
--- /dev/null
+++ b/core/proto/android/providers/settings/secure.proto
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto2";
+package android.providers.settings;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/providers/settings/common.proto";
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+// Note: it's a conscious decision to add each setting as a separate field. This
+// allows annotating each setting with its own privacy tag.
+message SecureSettingsProto {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ repeated SettingsOperationProto historical_operations = 1;
+
+ message Accessibility {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // List of the enabled accessibility providers.
+ optional SettingProto enabled_accessibility_services = 2;
+ optional SettingProto autoclick_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto autoclick_delay = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Setting specifying the accessibility service or feature to be toggled via
+ // the accessibility button in the navigation bar. This is either a
+ // flattened ComponentName or the class name of a system class implementing
+ // a supported accessibility feature.
+ optional SettingProto button_target_component = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_enabled = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_locale = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_preset = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_background_color = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_foreground_color = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_edge_type = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_edge_color = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_window_color = 13 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_typeface = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto captioning_font_scale = 15 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_daltonizer_enabled = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Integer property that specifies the type of color space adjustment to perform.
+ optional SettingProto display_daltonizer = 17 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_inversion_enabled = 18 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_magnification_enabled = 19 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_magnification_navbar_enabled = 20 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_magnification_scale = 21 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto high_text_contrast_enabled = 22 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto large_pointer_icon = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto shortcut_enabled = 24 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto shortcut_on_lock_screen = 25 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto shortcut_dialog_shown = 26 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto shortcut_target_service = 27 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto soft_keyboard_mode = 28 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Whether to speak passwords while in accessibility mode.
+ optional SettingProto speak_password = 29 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto touch_exploration_enabled = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // List of the accessibility services to which the user has granted
+ // permission to put the device into touch exploration mode.
+ optional SettingProto touch_exploration_granted_accessibility_services = 31;
+ }
+ optional Accessibility accessibility = 2;
+
+ // Origins for which browsers should allow geolocation by default.
+ // The value is a space-separated list of origins.
+ optional SettingProto allowed_geolocation_origins = 3;
+
+ message AlwaysOnVpn {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto app = 1;
+ optional SettingProto lockdown = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional AlwaysOnVpn always_on_vpn = 4;
+
+ optional SettingProto android_id = 5;
+ optional SettingProto anr_show_background = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Assist {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // The current assistant component. It could be a voice interaction service,
+ // or an activity that handles ACTION_ASSIST, or empty, which means using
+ // the default handling.
+ optional SettingProto assistant = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto structure_enabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto screenshot_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto disclosure_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto gesture_enabled = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto gesture_sensitivity = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto gesture_silence_alerts_enabled = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto gesture_wake_enabled = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto gesture_setup_complete = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Assist assist = 7;
+
+ message Autofill {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // The currently selected autofill service flattened ComponentName.
+ optional SettingProto service = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Boolean indicating if Autofill supports field classification.
+ optional SettingProto feature_field_classification = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto user_data_max_user_data_size = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto user_data_max_field_classification_ids_size = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto user_data_max_category_count = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto user_data_max_value_length = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto user_data_min_value_length = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // The query URI to find an auto fill service to install.
+ optional SettingProto service_search_uri = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Autofill autofill = 8;
+
+ message AutomaticStorageManager {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto days_to_retain = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto bytes_cleared = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto last_run = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto turned_off_by_policy = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional AutomaticStorageManager automatic_storage_manager = 9;
+
+ message Backup {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto auto_restore = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto provisioned = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto transport = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto manager_constants = 5;
+ optional SettingProto local_transport_parameters = 6;
+ }
+ optional Backup backup = 10;
+
+ optional SettingProto bluetooth_on_while_driving = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Camera {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto gesture_disabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto double_tap_power_gesture_disabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto double_twist_to_flip_enabled = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto lift_trigger_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Camera camera = 12;
+
+ optional SettingProto carrier_apps_handled = 13 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto cmas_additional_broadcast_pkg = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ repeated SettingProto completed_categories = 15;
+ optional SettingProto connectivity_release_pending_intent_delay_ms = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto device_paired = 17 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto dialer_default_application = 18 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_density_forced = 19 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto double_tap_to_wake = 20 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Doze {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto always_on = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto pulse_on_pick_up = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto pulse_on_long_press = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto pulse_on_double_tap = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Doze doze = 21;
+
+ optional SettingProto emergency_assistance_application = 22 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto enhanced_voice_privacy_enabled = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto immersive_mode_confirmations = 24 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Incall {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto power_button_behavior = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto back_button_behavior = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Incall incall = 25;
+
+ message InputMethods {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto default_input_method = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto disabled_system_input_methods = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto enabled_input_methods = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto method_selector_visibility = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto subtype_history = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto selected_input_method_subtype = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_ime_with_hard_keyboard = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional InputMethods input_methods = 26;
+
+ optional SettingProto install_non_market_apps = 27 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto instant_apps_enabled = 28 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Uri of the slice that's presented on the keyguard. Defaults to a slice
+ // with the date and next alarm.
+ optional SettingProto keyguard_slice_uri = 29;
+ optional SettingProto last_setup_shown = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Location {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // The degree of location access enabled by the user.
+ optional SettingProto mode = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // The App or module that changes the location mode.
+ optional SettingProto changer = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Location location = 31;
+
+ message LockScreen {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto lock_after_timeout = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto allow_private_notifications = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto allow_remote_input = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_notifications = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional LockScreen lock_screen = 32;
+
+ // Whether lock-to-app will lock the keyguard when exiting.
+ optional SettingProto lock_to_app_exit_locked = 33 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto lockdown_in_power_menu = 34 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto long_press_timeout = 35 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message ManagedProfile {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto contact_remote_search = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional ManagedProfile managed_profile = 36;
+
+ message Mount {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Whether or not alert sounds are played on StorageManagerService events.
+ optional SettingProto play_notification_snd = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto ums_autostart = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto ums_prompt = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto ums_notify_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Mount mount = 37;
+
+ optional SettingProto multi_press_timeout = 38 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message NfcPayment {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto default_component = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Whether NFC payment is handled by the foreground application or a default.
+ optional SettingProto foreground = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // The query URI to find an NFC service to install.
+ optional SettingProto payment_service_search_uri = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional NfcPayment nfc_payment = 39;
+
+ message NightDisplay {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto activated = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto auto_mode = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto color_temperature = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto custom_start_time = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto custom_end_time = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto last_activated_time = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional NightDisplay night_display = 40;
+
+ message Notification {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Read only list of the service components that the current user has
+ // explicitly allowed to see and assist with all of the user's
+ // notifications.
+ // "enabled_notification_assistant" in code.
+ optional SettingProto enabled_assistant = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto enabled_listeners = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto enabled_policy_access_packages = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto badging = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_note_about_notification_hiding = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Notification notification = 41;
+
+ message PackageVerifier {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto user_consent = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto state = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional PackageVerifier package_verifier = 42;
+
+ message ParentalControl {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto last_update = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto redirect_url = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional ParentalControl parental_control = 43;
+
+ message PrintService {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // The query URI to find a print service to install.
+ optional SettingProto search_uri = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto disabled_print_services = 2;
+ optional SettingProto enabled_print_services = 3;
+ }
+ optional PrintService print_service = 44;
+
+ message QuickSettings {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Holds comma-separated list of ordering of QuickSettings tiles.
+ optional SettingProto tiles = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto auto_added_tiles = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional QuickSettings qs = 45;
+
+ message Rotation {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto show_rotation_suggestions = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto num_rotation_suggestions_accepted = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Rotation rotation = 46;
+
+ message Screensaver {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto components = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto activate_on_dock = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto activate_on_sleep = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto default_component = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Screensaver screensaver = 47;
+
+ message Search {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto global_search_activity = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto num_promoted_sources = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto max_results_to_display = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto max_results_per_source = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto web_results_override_limit = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto promoted_source_deadline_millis = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto source_timeout_millis = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto prefill_millis = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto max_stat_age_millis = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto max_source_event_age_millis = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto min_impressions_for_source_ranking = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto min_clicks_for_source_ranking = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto max_shortcuts_returned = 13 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto query_thread_core_pool_size = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto query_thread_max_pool_size = 15 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto shortcut_refresh_core_pool_size = 16 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto shortcut_refresh_max_pool_size = 17 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto thread_keepalive_seconds = 18 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto per_source_concurrent_query_limit = 19 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Search search = 48;
+
+ message SpellChecker {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // "selected_spell_checker" in code.
+ optional SettingProto selected = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // "selected_spell_checker_subtype" in code.
+ optional SettingProto selected_subtype = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional SpellChecker spell_checker = 49;
+
+ optional SettingProto settings_classname = 50 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_first_crash_dialog_dev_option = 51 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto skip_first_use_hints = 52 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto sleep_timeout = 53 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto sms_default_application = 54 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Defines whether managed profile ringtones should be synced from its
+ // parent profile.
+ optional SettingProto sync_parent_sounds = 55 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto system_navigation_keys_enabled = 56 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto trust_agents_initialized = 57 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Tts {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto default_rate = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto default_pitch = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto default_synth = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto default_locale = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto enabled_plugins = 5;
+ }
+ optional Tts tts = 58;
+
+ message Tty {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto tty_mode_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // The preferred TTY mode:
+ // 0 = TTy Off, CDMA default
+ // 1 = TTY Full
+ // 2 = TTY HCO
+ // 3 = TTY VCO
+ optional SettingProto preferred_tty_mode = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Tty tty = 59;
+
+ message Tv {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Whether the current user has been set up via setup wizard (0 = false,
+ // 1 = true). This value differs from USER_SETUP_COMPLETE in that it can be
+ // reset back to 0 in case SetupWizard has been re-enabled on TV devices.
+ optional SettingProto user_setup_complete = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto input_hidden_inputs = 2;
+ optional SettingProto input_custom_labels = 3;
+ }
+ optional Tv tv = 60;
+
+ optional SettingProto ui_night_mode = 61 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto unknown_sources_default_reversed = 62 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto usb_audio_automatic_routing_disabled = 63 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Whether the current user has been set up via setup wizard (0 = false, 1 = true)
+ optional SettingProto user_setup_complete = 64 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Voice {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // The currently selected voice interaction service flattened ComponentName.
+ optional SettingProto interaction_service = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // The ComponentName string of the service to be used as the voice
+ // recognition service.
+ optional SettingProto recognition_service = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Voice voice = 65;
+
+ message Volume {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // What behavior should be invoked when the volume hush gesture is triggered
+ // One of VOLUME_HUSH_OFF, VOLUME_HUSH_VIBRATE, VOLUME_HUSH_MUTE.
+ optional SettingProto hush_gesture = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Persisted playback time after a user confirmation of an unsafe volume level.
+ optional SettingProto unsafe_volume_music_active_ms = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Volume volume = 66;
+
+ message Vr {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto display_mode = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto enabled_listeners = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Vr vr = 67;
+
+ optional SettingProto wake_gesture_enabled = 68 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ // Please insert fields in alphabetical order and group them into messages
+ // if possible (to avoid reaching the method limit).
+ // Next tag = 69;
+}
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
new file mode 100644
index 0000000..6b6edd2
--- /dev/null
+++ b/core/proto/android/providers/settings/system.proto
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+syntax = "proto2";
+package android.providers.settings;
+
+option java_multiple_files = true;
+
+import "frameworks/base/core/proto/android/providers/settings/common.proto";
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+// Note: it's a conscious decision to add each setting as a separate field. This
+// allows annotating each setting with its own privacy tag.
+message SystemSettingsProto {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ repeated SettingsOperationProto historical_operations = 1;
+
+ optional SettingProto advanced_settings = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Alarm {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // "alarm_alert" in code.
+ optional SettingProto default_uri = 1;
+ optional SettingProto alert_cache = 2;
+ }
+ optional Alarm alarm = 3;
+
+ message Bluetooth {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Whether remote devices may discover and/or connect to this device:
+ // 2 -- discoverable and connectable
+ // 1 -- connectable but not discoverable
+ // 0 -- neither connectable nor discoverable
+ optional SettingProto discoverability = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto discoverability_timeout_secs = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Bluetooth bluetooth = 4;
+
+ optional SettingProto date_format = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto display_color_mode = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message DevOptions {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Show pointer location on screen? 0 = no, 1 = yes. "pointer_location
+ // in code.
+ optional SettingProto pointer_location = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_touches = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Log raw orientation data from {@link
+ // com.android.server.policy.WindowOrientationListener} for use with the
+ // orientationplot.py tool.
+ // 0 = no, 1 = yes
+ optional SettingProto window_orientation_listener_log = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional DevOptions developer_options = 7;
+
+ message DtmfTone {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // "dtmf_tone_when_dialing" in code.
+ optional SettingProto play_when_dialing = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // "dtmf_tone_type_when_dialing" in code.
+ optional SettingProto type_played_when_dialing = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional DtmfTone dtmf_tone = 8;
+
+ optional SettingProto egg_mode = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto end_button_behavior = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto font_scale = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message HapticFeedback {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto intensity = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional HapticFeedback haptic_feedback = 12;
+
+ // Whether the hearing aid is enabled. The value is boolean (1 or 0).
+ optional SettingProto hearing_aid = 13 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto lock_to_app_enabled = 14 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Lockscreen {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto sounds_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto disabled = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Lockscreen lockscreen = 15;
+
+ // The system default media button event receiver.
+ optional SettingProto media_button_receiver = 16;
+
+ message Notification {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto sound = 1;
+ optional SettingProto sound_cache = 2;
+ optional SettingProto light_pulse = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto vibration_intensity = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Notification notification = 17;
+
+ optional SettingProto pointer_speed = 18 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Ringtone {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // "ringtone" in code. The system-wide default ringtone URI.
+ optional SettingProto default_uri = 1;
+ optional SettingProto cache = 2;
+ }
+ optional Ringtone ringtone = 19;
+
+ message Rotation {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ // Control whether the accelerometer will be used to change screen
+ // orientation. If 0, it will not be used unless explicitly requested
+ // by the application; if 1, it will be used by default unless
+ // explicitly disabled by the application.
+ optional SettingProto accelerometer_rotation = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Default screen rotation when no other policy applies.
+ // When accelerometer_rotation is zero and no on-screen Activity expresses a
+ // preference, this rotation value will be used. Must be one of the
+ // {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
+ optional SettingProto user_rotation = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Control whether the rotation lock toggle in the System UI should be hidden.
+ // Typically this is done for accessibility purposes to make it harder for
+ // the user to accidentally toggle the rotation lock while the display rotation
+ // has been locked for accessibility.
+ // If 0, then rotation lock toggle is not hidden for accessibility (although it may be
+ // unavailable for other reasons). If 1, then the rotation lock toggle is hidden.
+ optional SettingProto hide_rotation_lock_toggle_for_accessibility = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Rotation rotation = 20;
+
+ // User-selected RTT mode. When on, outgoing and incoming calls will be
+ // answered as RTT calls when supported by the device and carrier. Boolean
+ // value.
+ optional SettingProto rtt_calling_mode = 21 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Screen {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto off_timeout = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto brightness = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto brightness_for_vr = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto brightness_mode = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto auto_brightness_adj = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Screen screen = 22;
+
+ optional SettingProto setup_wizard_has_run = 23 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_battery_percent = 24 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_gtalk_service_status = 25 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Sip {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto receive_calls = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto call_options = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto always = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto address_only = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Sip sip = 26;
+
+ optional SettingProto sound_effects_enabled = 27 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto system_locales = 28 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Text {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto auto_replace = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto auto_caps = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto auto_punctuate = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_password = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Text text = 29;
+
+ optional SettingProto time_12_24 = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto tty_mode = 31 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ message Vibrate {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto on = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto input_devices = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Whether silent mode should allow vibration feedback. This is used
+ // internally in AudioService and the Sound settings activity to coordinate
+ // decoupling of vibrate and silent modes. This setting will likely be
+ // removed in a future release with support for audio/vibe feedback
+ // profiles.
+ // Not used anymore. On devices with vibrator, the user explicitly selects
+ // silent or vibrate mode. Kept for use by legacy database upgrade code in
+ // DatabaseHelper.
+ optional SettingProto in_silent = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto when_ringing = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Vibrate vibrate = 32;
+
+ message Volume {
+ option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+ optional SettingProto ring = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto system = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto voice = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto music = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto alarm = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto notification = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto bluetooth_sco = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto accessibility = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto master = 9 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto master_mono = 10 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Determines which streams are affected by ringer mode changes. The stream
+ // type's bit will be set to 1 if it should be muted when going into an
+ // inaudible ringer mode.
+ optional SettingProto mode_ringer_streams_affected = 11 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // Which streams are affected by mute. The stream type's bit should be set
+ // to 1 if it should be muted when a mute request is received.
+ optional SettingProto mute_streams_affected = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ }
+ optional Volume volume = 33;
+
+ optional SettingProto when_to_make_wifi_calls = 34 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ // Please insert fields in alphabetical order and group them into messages
+ // if possible (to avoid reaching the method limit).
+ // Next tag = 35;
+}
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 8d4b56c..bb8ce81 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -578,6 +578,12 @@
optional .android.os.PersistableBundleProto extras = 14;
optional .android.os.BundleProto transient_extras = 15;
+ // ClipData of information that is returned to the application at
+ // execution time, but not persisted by the system. This is provided by
+ // the app and the main purpose of providing a ClipData is to allow
+ // granting of URI permissions for data associated with the clip. The
+ // exact kind of permission grant to perform is specified in the flags
+ // field.
optional .android.content.ClipDataProto clip_data = 16;
optional GrantedUriPermissionsDumpProto granted_uri_permissions = 17;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index c4d3667..1c3448b 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -89,6 +89,8 @@
<protected-broadcast android:name="android.intent.action.OVERLAY_REMOVED" />
<protected-broadcast android:name="android.intent.action.OVERLAY_PRIORITY_CHANGED" />
<protected-broadcast android:name="android.intent.action.USER_ACTIVITY_NOTIFICATION" />
+ <protected-broadcast android:name="android.intent.action.MY_PACKAGE_SUSPENDED" />
+ <protected-broadcast android:name="android.intent.action.MY_PACKAGE_UNSUSPENDED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGED" />
<protected-broadcast android:name="android.os.action.POWER_SAVE_MODE_CHANGING" />
@@ -4229,6 +4231,16 @@
android:exported="false">
</receiver>
+ <receiver android:name="com.android.server.am.BatteryStatsService$UsbConnectionReceiver"
+ android:exported="false">
+ <intent-filter>
+ <action android:name="android.intent.action.BOOT_COMPLETED" />
+ </intent-filter>
+ <intent-filter>
+ <action android:name="android.hardware.usb.action.USB_STATE" />
+ </intent-filter>
+ </receiver>
+
<service android:name="android.hardware.location.GeofenceHardwareService"
android:permission="android.permission.LOCATION_HARDWARE"
android:exported="false" />
diff --git a/core/res/res/values-land/dimens.xml b/core/res/res/values-land/dimens.xml
index 265eaaf..351bd81 100644
--- a/core/res/res/values-land/dimens.xml
+++ b/core/res/res/values-land/dimens.xml
@@ -29,7 +29,10 @@
<!-- Height of the status bar -->
<dimen name="status_bar_height">@dimen/status_bar_height_landscape</dimen>
-
+ <!-- Height of area above QQS where battery/time go -->
+ <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
+ <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
+ <dimen name="quick_qs_total_height">152dp</dimen>
<!-- Default height of an action bar. -->
<dimen name="action_bar_default_height">40dip</dimen>
<!-- Vertical padding around action bar icons. -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 3135455..aceba08 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2123,44 +2123,48 @@
<!-- Controls how the window is laid out if there is a {@code DisplayCutout}.
<p>
Defaults to {@code default}.
-
- @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
- @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
- @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
- @see android.view.DisplayCutout
- @see android.R.attr#layoutInDisplayCutoutMode -->
+ <p>
+ See also
+ {@link android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode
+ WindowManager.LayoutParams.layoutInDisplayCutoutMode},
+ {@link android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT},
+ {@link android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES},
+ {@link android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER},
+ and {@link android.view.DisplayCutout DisplayCutout}
+ -->
<attr name="windowLayoutInDisplayCutoutMode">
- <!-- The window is allowed to extend into the {@code DisplayCutout} area, only if the
- {@code DisplayCutout} is fully contained within a system bar. Otherwise, the window is
- laid out such that it does not overlap with the {@code DisplayCutout} area.
-
- @see android.view.DisplayCutout
- @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
+ <!-- <p>
+ The window is allowed to extend into the <code>DisplayCutout</code> area, only if
+ the <code>DisplayCutout</code> is fully contained within a system bar. Otherwise, the
+ window is laid out such that it does not overlap with the <code>DisplayCutout</code>
+ area.
+ <p>
+ Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT</code>.
-->
<enum name="default" value="0" />
- <!--
- The window is always allowed to extend into the {@code DisplayCutout} areas on the short
- edges of the screen even if fullscreen or in landscape.
- The window will never extend into a {@link DisplayCutout} area on the long edges of the
- screen.
+ <!-- <p>
+ The window is always allowed to extend into the <code>DisplayCutout</code> areas on the
+ short edges of the screen even if fullscreen or in landscape.
+ The window will never extend into a <code>DisplayCutout</code> area on the long edges of
+ the screen.
<p>
The window must make sure that no important content overlaps with the
- {@link DisplayCutout}.
-
- @see android.view.DisplayCutout
- @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
+ <code>DisplayCutout</code>.
+ <p>
+ Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES</code>.
-->
<enum name="shortEdges" value="1" />
- <!-- Use {@code shortEdges} instead. This is temporarily here to unblock pushing the SDK
- until all usages have been migrated to {@code shortEdges} -->
+ <!-- Use <code>shortEdges</code> instead. This is temporarily here to unblock pushing
+ the SDK until all usages have been migrated to <code>shortEdges</code> -->
<enum name="always" value="1" />
- <!-- The window is never allowed to overlap with the DisplayCutout area.
+ <!-- <p>
+ The window is never allowed to overlap with the <code>DisplayCutout</code> area.
<p>
- This should be used with windows that transiently set {@code SYSTEM_UI_FLAG_FULLSCREEN}
- to avoid a relayout of the window when the flag is set or cleared.
-
- @see android.view.DisplayCutout
- @see android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
+ This should be used with windows that transiently set
+ <code>SYSTEM_UI_FLAG_FULLSCREEN</code> to avoid a relayout of the window when the
+ flag is set or cleared.
+ <p>
+ Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER</code>.
-->
<enum name="never" value="2" />
</attr>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 55c17b9..66d25df 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1095,6 +1095,9 @@
<!-- Display low battery warning when battery level dips to this value -->
<integer name="config_lowBatteryWarningLevel">15</integer>
+ <!-- The default suggested battery % at which we enable battery saver automatically. -->
+ <integer name="config_lowBatteryAutoTriggerDefaultLevel">15</integer>
+
<!-- Close low battery warning when battery level reaches the lowBatteryWarningLevel
plus this -->
<integer name="config_lowBatteryCloseWarningBump">5</integer>
@@ -2365,19 +2368,6 @@
<item>com.android.inputmethod.latin</item>
</string-array>
- <!-- The list of carrier applications which should be disabled until used.
- This function suppresses update notifications for these pre-installed apps.
- In SubscriptionInfoUpdater, the listed applications are disabled until used when all of the
- following conditions are met.
- 1. Not currently carrier-privileged according to the inserted SIM
- 2. Pre-installed
- 3. In the default state (enabled but not explicitly)
- And SubscriptionInfoUpdater undoes this and marks the app enabled when a SIM is inserted
- that marks the app as carrier privileged. It also grants the app default permissions
- for Phone and Location. As such, apps MUST only ever be added to this list if they
- obtain user consent to access their location through other means. -->
- <string-array name="config_disabledUntilUsedPreinstalledCarrierApps" translatable="false" />
-
<!-- The list of classes that should be added to the notification ranking pipeline.
See {@link com.android.server.notification.NotificationSignalExtractor}
If you add a new extractor to this list make sure to update
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 75f8013..2f7ae27 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1233,7 +1233,6 @@
<java-symbol type="array" name="supported_locales" />
<java-symbol type="array" name="config_cdma_dun_supported_types" />
<java-symbol type="array" name="config_disabledUntilUsedPreinstalledImes" />
- <java-symbol type="array" name="config_disabledUntilUsedPreinstalledCarrierApps" />
<java-symbol type="array" name="config_callBarringMMI" />
<java-symbol type="array" name="config_globalActionsList" />
<java-symbol type="array" name="config_telephonyEuiccDeviceCapabilities" />
@@ -1660,6 +1659,7 @@
<java-symbol type="dimen" name="navigation_bar_height_landscape_car_mode" />
<java-symbol type="dimen" name="navigation_bar_width_car_mode" />
<java-symbol type="dimen" name="status_bar_height" />
+ <java-symbol type="dimen" name="quick_qs_offset_height" />
<java-symbol type="dimen" name="quick_qs_total_height" />
<java-symbol type="drawable" name="ic_jog_dial_sound_off" />
<java-symbol type="drawable" name="ic_jog_dial_sound_on" />
@@ -3312,4 +3312,6 @@
<java-symbol type="string" name="notification_app_name_system" />
<java-symbol type="string" name="notification_app_name_settings" />
+ <java-symbol type="integer" name="config_lowBatteryAutoTriggerDefaultLevel" />
+
</resources>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 6ef773a..2a3fcad 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -586,7 +586,8 @@
Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
Settings.Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT,
- Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED);
+ Settings.Secure.LOW_POWER_WARNING_ACKNOWLEDGED,
+ Settings.Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION);
@Test
public void systemSettingsBackedUpOrBlacklisted() {
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index bacddf14..a4a1b94 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -64,6 +64,7 @@
<hidden-api-whitelisted-app package="com.android.gallery" />
<hidden-api-whitelisted-app package="com.android.hotspot2" />
<hidden-api-whitelisted-app package="com.android.keychain" />
+ <hidden-api-whitelisted-app package="com.android.launcher3" />
<hidden-api-whitelisted-app package="com.android.location.fused" />
<hidden-api-whitelisted-app package="com.android.managedprovisioning" />
<hidden-api-whitelisted-app package="com.android.mms.service" />
diff --git a/data/keyboards/Android.mk b/data/keyboards/Android.mk
index 2daef0c..7949c77 100644
--- a/data/keyboards/Android.mk
+++ b/data/keyboards/Android.mk
@@ -28,7 +28,7 @@
validatekeymaps := $(HOST_OUT_EXECUTABLES)/validatekeymaps$(HOST_EXECUTABLE_SUFFIX)
$(LOCAL_BUILT_MODULE): PRIVATE_VALIDATEKEYMAPS := $(validatekeymaps)
$(LOCAL_BUILT_MODULE) : $(framework_keylayouts) $(framework_keycharmaps) $(framework_keyconfigs) | $(validatekeymaps)
- $(hide) -q $(PRIVATE_VALIDATEKEYMAPS) $^
+ $(hide) $(PRIVATE_VALIDATEKEYMAPS) -q $^
$(hide) mkdir -p $(dir $@) && touch $@
# Run validatekeymaps uncondionally for platform build.
diff --git a/docs/html/reference/images/display_cutout/default_mode/fullscreen_letterbox.png b/docs/html/reference/images/display_cutout/default_mode/fullscreen_letterbox.png
new file mode 100644
index 0000000..8602290
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/default_mode/fullscreen_letterbox.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/default_mode/landscape.png b/docs/html/reference/images/display_cutout/default_mode/landscape.png
new file mode 100644
index 0000000..be112f4
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/default_mode/landscape.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/default_mode/landscape_corner.png b/docs/html/reference/images/display_cutout/default_mode/landscape_corner.png
new file mode 100644
index 0000000..7aa92b4
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/default_mode/landscape_corner.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/default_mode/portrait.png b/docs/html/reference/images/display_cutout/default_mode/portrait.png
new file mode 100644
index 0000000..6392ad5
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/default_mode/portrait.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/default_mode/portrait_corner.png b/docs/html/reference/images/display_cutout/default_mode/portrait_corner.png
new file mode 100644
index 0000000..dc8e6d0
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/default_mode/portrait_corner.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/never_mode/landscape.png b/docs/html/reference/images/display_cutout/never_mode/landscape.png
new file mode 100644
index 0000000..be112f4
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/never_mode/landscape.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/never_mode/portrait_top_letterbox.png b/docs/html/reference/images/display_cutout/never_mode/portrait_top_letterbox.png
new file mode 100644
index 0000000..fc7dfcf
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/never_mode/portrait_top_letterbox.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/fullscreen_corner_no_letterbox.png b/docs/html/reference/images/display_cutout/short_edge/fullscreen_corner_no_letterbox.png
new file mode 100644
index 0000000..09f942d
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/fullscreen_corner_no_letterbox.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/fullscreen_side_letterbox.png b/docs/html/reference/images/display_cutout/short_edge/fullscreen_side_letterbox.png
new file mode 100644
index 0000000..9aafc58
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/fullscreen_side_letterbox.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/fullscreen_top_no_letterbox.png b/docs/html/reference/images/display_cutout/short_edge/fullscreen_top_no_letterbox.png
new file mode 100644
index 0000000..75e913b
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/fullscreen_top_no_letterbox.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/landscape_corner.png b/docs/html/reference/images/display_cutout/short_edge/landscape_corner.png
new file mode 100644
index 0000000..d9e0f99
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/landscape_corner.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/landscape_sideboxed.png b/docs/html/reference/images/display_cutout/short_edge/landscape_sideboxed.png
new file mode 100644
index 0000000..9d44493
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/landscape_sideboxed.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/landscape_top_no_letterbox.png b/docs/html/reference/images/display_cutout/short_edge/landscape_top_no_letterbox.png
new file mode 100644
index 0000000..ac023c5
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/landscape_top_no_letterbox.png
Binary files differ
diff --git a/docs/html/reference/images/display_cutout/short_edge/portrait_side_letterbox.png b/docs/html/reference/images/display_cutout/short_edge/portrait_side_letterbox.png
new file mode 100644
index 0000000..50228db
--- /dev/null
+++ b/docs/html/reference/images/display_cutout/short_edge/portrait_side_letterbox.png
Binary files differ
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index 5dc4463..71ee6c2 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -41,13 +41,19 @@
/**
* Should only be assigned in constructors (or setBitmap if software canvas),
* freed by NativeAllocation.
+ * @hide
*/
protected long mNativeCanvasWrapper;
/**
* Used to determine when compatibility scaling is in effect.
+ * @hide
*/
protected int mScreenDensity = Bitmap.DENSITY_NONE;
+
+ /**
+ * @hide
+ */
protected int mDensity = Bitmap.DENSITY_NONE;
private boolean mAllowHwBitmapsInSwMode = false;
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index b0bc102..7080657 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -47,6 +47,7 @@
* Canvas and Drawables</a> developer guide.</p></div>
*/
public class Canvas extends BaseCanvas {
+ private static int sCompatiblityVersion = 0;
/** @hide */
public static boolean sCompatibilityRestore = false;
/** @hide */
@@ -306,7 +307,7 @@
/**
* Restore the current matrix when restore() is called.
- *
+ * @removed
* @deprecated Use the flagless version of {@link #save()}, {@link #saveLayer(RectF, Paint)} or
* {@link #saveLayerAlpha(RectF, int)}. For saveLayer() calls the matrix
* was always restored for {@link #isHardwareAccelerated() Hardware accelerated}
@@ -318,6 +319,7 @@
/**
* Restore the current clip when restore() is called.
*
+ * @removed
* @deprecated Use the flagless version of {@link #save()}, {@link #saveLayer(RectF, Paint)} or
* {@link #saveLayerAlpha(RectF, int)}. For saveLayer() calls the clip
* was always restored for {@link #isHardwareAccelerated() Hardware accelerated}
@@ -329,6 +331,7 @@
/**
* The layer requires a per-pixel alpha channel.
*
+ * @removed
* @deprecated This flag is ignored. Use the flagless version of {@link #saveLayer(RectF, Paint)}
* {@link #saveLayerAlpha(RectF, int)}.
*/
@@ -337,6 +340,7 @@
/**
* The layer requires full 8-bit precision for each color channel.
*
+ * @removed
* @deprecated This flag is ignored. Use the flagless version of {@link #saveLayer(RectF, Paint)}
* {@link #saveLayerAlpha(RectF, int)}.
*/
@@ -349,6 +353,7 @@
* <code>saveLayerAlpha()</code> variants. Not passing this flag generally
* triggers extremely poor performance with hardware accelerated rendering.
*
+ * @removed
* @deprecated This flag results in poor performance and the same effect can be achieved with
* a single layer or multiple draw commands with different clips.
*
@@ -362,6 +367,7 @@
* call to <code>saveLayer()</code> and <code>saveLayerAlpha()</code>
* variants.
*
+ * @removed There are no visible methods remaining that use this flag
* <p class="note"><strong>Note:</strong> all methods that accept this flag
* have flagless versions that are equivalent to passing this flag.
*/
@@ -393,6 +399,7 @@
* restore() is made, those calls will be forgotten, and the settings that
* existed before the save() will be reinstated.
*
+ * @removed
* @deprecated Use {@link #save()} instead.
* @param saveFlags flag bits that specify which parts of the Canvas state
* to save/restore
@@ -424,6 +431,7 @@
* {@link Paint#getColorFilter() ColorFilter} are applied when the
* offscreen bitmap is drawn back when restore() is called.
*
+ * @removed
* @deprecated Use {@link #saveLayer(RectF, Paint)} instead.
* @param bounds May be null. The maximum size the offscreen bitmap
* needs to be (in local coordinates)
@@ -473,8 +481,10 @@
/**
* Helper version of saveLayer() that takes 4 values rather than a RectF.
*
+ * @removed
* @deprecated Use {@link #saveLayer(float, float, float, float, Paint)} instead.
*/
+ @Deprecated
public int saveLayer(float left, float top, float right, float bottom, @Nullable Paint paint,
@Saveflags int saveFlags) {
return nSaveLayer(mNativeCanvasWrapper, left, top, right, bottom,
@@ -510,6 +520,7 @@
* The {@code alpha} parameter is applied when the offscreen bitmap is
* drawn back when restore() is called.
*
+ * @removed
* @deprecated Use {@link #saveLayerAlpha(RectF, int)} instead.
* @param bounds The maximum size the offscreen bitmap needs to be
* (in local coordinates)
@@ -542,8 +553,10 @@
/**
* Helper for saveLayerAlpha() that takes 4 values instead of a RectF.
*
+ * @removed
* @deprecated Use {@link #saveLayerAlpha(float, float, float, float, int)} instead.
*/
+ @Deprecated
public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
@Saveflags int saveFlags) {
alpha = Math.min(255, Math.max(0, alpha));
@@ -738,6 +751,14 @@
return m;
}
+ private static void checkValidClipOp(@NonNull Region.Op op) {
+ if (sCompatiblityVersion >= Build.VERSION_CODES.P
+ && op != Region.Op.INTERSECT && op != Region.Op.DIFFERENCE) {
+ throw new IllegalArgumentException(
+ "Invalid Region.Op - only INTERSECT and DIFFERENCE are allowed");
+ }
+ }
+
/**
* Modify the current clip with the specified rectangle.
*
@@ -750,9 +771,13 @@
* are intended to only expand the clip as a result of a restore operation. This enables a view
* parent to clip a canvas to clearly define the maximal drawing area of its children. The
* recommended alternative calls are {@link #clipRect(RectF)} and {@link #clipOutRect(RectF)};
+ *
+ * As of API Level API level {@value Build.VERSION_CODES#P} only {@link Region.Op#INTERSECT} and
+ * {@link Region.Op#DIFFERENCE} are valid Region.Op parameters.
*/
@Deprecated
public boolean clipRect(@NonNull RectF rect, @NonNull Region.Op op) {
+ checkValidClipOp(op);
return nClipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
op.nativeInt);
}
@@ -770,9 +795,13 @@
* are intended to only expand the clip as a result of a restore operation. This enables a view
* parent to clip a canvas to clearly define the maximal drawing area of its children. The
* recommended alternative calls are {@link #clipRect(Rect)} and {@link #clipOutRect(Rect)};
+ *
+ * As of API Level API level {@value Build.VERSION_CODES#P} only {@link Region.Op#INTERSECT} and
+ * {@link Region.Op#DIFFERENCE} are valid Region.Op parameters.
*/
@Deprecated
public boolean clipRect(@NonNull Rect rect, @NonNull Region.Op op) {
+ checkValidClipOp(op);
return nClipRect(mNativeCanvasWrapper, rect.left, rect.top, rect.right, rect.bottom,
op.nativeInt);
}
@@ -846,10 +875,14 @@
* parent to clip a canvas to clearly define the maximal drawing area of its children. The
* recommended alternative calls are {@link #clipRect(float,float,float,float)} and
* {@link #clipOutRect(float,float,float,float)};
+ *
+ * As of API Level API level {@value Build.VERSION_CODES#P} only {@link Region.Op#INTERSECT} and
+ * {@link Region.Op#DIFFERENCE} are valid Region.Op parameters.
*/
@Deprecated
public boolean clipRect(float left, float top, float right, float bottom,
@NonNull Region.Op op) {
+ checkValidClipOp(op);
return nClipRect(mNativeCanvasWrapper, left, top, right, bottom, op.nativeInt);
}
@@ -932,9 +965,13 @@
* parent to clip a canvas to clearly define the maximal drawing area of its children. The
* recommended alternative calls are {@link #clipPath(Path)} and
* {@link #clipOutPath(Path)};
+ *
+ * As of API Level API level {@value Build.VERSION_CODES#P} only {@link Region.Op#INTERSECT} and
+ * {@link Region.Op#DIFFERENCE} are valid Region.Op parameters.
*/
@Deprecated
public boolean clipPath(@NonNull Path path, @NonNull Region.Op op) {
+ checkValidClipOp(op);
return nClipPath(mNativeCanvasWrapper, path.readOnlyNI(), op.nativeInt);
}
@@ -1220,7 +1257,10 @@
}
/** @hide */
- public static void setCompatibilityVersion(int apiLevel) { nSetCompatibilityVersion(apiLevel); }
+ public static void setCompatibilityVersion(int apiLevel) {
+ sCompatiblityVersion = apiLevel;
+ nSetCompatibilityVersion(apiLevel);
+ }
private static native void nFreeCaches();
private static native void nFreeTextLayoutCaches();
diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java
index 97edf22..1eebd26 100644
--- a/graphics/java/android/graphics/SurfaceTexture.java
+++ b/graphics/java/android/graphics/SurfaceTexture.java
@@ -318,13 +318,17 @@
* Retrieve the timestamp associated with the texture image set by the most recent call to
* updateTexImage.
*
- * This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp
- * should be unaffected by time-of-day adjustments, and for a camera should be strictly
- * monotonic but for a MediaPlayer may be reset when the position is set. The
- * specific meaning and zero point of the timestamp depends on the source providing images to
- * the SurfaceTexture. Unless otherwise specified by the image source, timestamps cannot
- * generally be compared across SurfaceTexture instances, or across multiple program
- * invocations. It is mostly useful for determining time offsets between subsequent frames.
+ * <p>This timestamp is in nanoseconds, and is normally monotonically increasing. The timestamp
+ * should be unaffected by time-of-day adjustments. The specific meaning and zero point of the
+ * timestamp depends on the source providing images to the SurfaceTexture. Unless otherwise
+ * specified by the image source, timestamps cannot generally be compared across SurfaceTexture
+ * instances, or across multiple program invocations. It is mostly useful for determining time
+ * offsets between subsequent frames.</p>
+ *
+ * <p>For camera sources, timestamps should be strictly monotonic. Timestamps from MediaPlayer
+ * sources may be reset when the playback position is set. For EGL and Vulkan producers, the
+ * timestamp is the desired present time set with the EGL_ANDROID_presentation_time or
+ * VK_GOOGLE_display_timing extensions.</p>
*/
public long getTimestamp() {
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 457e4aa..898939e 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -52,8 +52,20 @@
/**
* {@link Drawable} for drawing animated images (like GIF).
*
+ * <p>The framework handles decoding subsequent frames in another thread and
+ * updating when necessary. The drawable will only animate while it is being
+ * displayed.</p>
+ *
* <p>Created by {@link ImageDecoder#decodeDrawable}. A user needs to call
* {@link #start} to start the animation.</p>
+ *
+ * <p>It can also be defined in XML using the <code><animated-image></code>
+ * element.</p>
+ *
+ * @attr ref android.R.styleable#AnimatedImageDrawable_src
+ * @attr ref android.R.styleable#AnimatedImageDrawable_autoStart
+ * @attr ref android.R.styleable#AnimatedImageDrawable_repeatCount
+ * @attr ref android.R.styleable#AnimatedImageDrawable_autoMirrored
*/
public class AnimatedImageDrawable extends Drawable implements Animatable2 {
private int mIntrinsicWidth;
@@ -456,8 +468,8 @@
* <p>Does nothing if the animation is already running. If the animation is stopped,
* this will reset it.</p>
*
- * <p>If the animation starts, this will call
- * {@link Animatable2.AnimationCallback#onAnimationStart}.</p>
+ * <p>When the drawable is drawn, starting the animation,
+ * {@link Animatable2.AnimationCallback#onAnimationStart} will be called.</p>
*/
@Override
public void start() {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 09b3b9b..419eb24 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -243,13 +243,7 @@
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
- KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
- spec.isUserAuthenticationRequired(),
- spec.getUserAuthenticationValidityDurationSeconds(),
- spec.isUserAuthenticationValidWhileOnBody(),
- spec.isInvalidatedByBiometricEnrollment(),
- GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
- spec.isUserConfirmationRequired());
+ KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), spec);
} catch (IllegalStateException | IllegalArgumentException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -285,16 +279,7 @@
args.addEnums(KeymasterDefs.KM_TAG_BLOCK_MODE, mKeymasterBlockModes);
args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterPaddings);
args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
- KeymasterUtils.addUserAuthArgs(args,
- spec.isUserAuthenticationRequired(),
- spec.getUserAuthenticationValidityDurationSeconds(),
- spec.isUserAuthenticationValidWhileOnBody(),
- spec.isInvalidatedByBiometricEnrollment(),
- GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
- spec.isUserConfirmationRequired());
- if (spec.isTrustedUserPresenceRequired()) {
- args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
- }
+ KeymasterUtils.addUserAuthArgs(args, spec);
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
mKeymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index e33e3cd..d68a33d 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -344,13 +344,7 @@
// Check that user authentication related parameters are acceptable. This method
// will throw an IllegalStateException if there are issues (e.g., secure lock screen
// not set up).
- KeymasterUtils.addUserAuthArgs(new KeymasterArguments(),
- mSpec.isUserAuthenticationRequired(),
- mSpec.getUserAuthenticationValidityDurationSeconds(),
- mSpec.isUserAuthenticationValidWhileOnBody(),
- mSpec.isInvalidatedByBiometricEnrollment(),
- GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
- mSpec.isUserConfirmationRequired());
+ KeymasterUtils.addUserAuthArgs(new KeymasterArguments(), mSpec);
} catch (IllegalArgumentException | IllegalStateException e) {
throw new InvalidAlgorithmParameterException(e);
}
@@ -541,13 +535,7 @@
args.addEnums(KeymasterDefs.KM_TAG_PADDING, mKeymasterSignaturePaddings);
args.addEnums(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigests);
- KeymasterUtils.addUserAuthArgs(args,
- mSpec.isUserAuthenticationRequired(),
- mSpec.getUserAuthenticationValidityDurationSeconds(),
- mSpec.isUserAuthenticationValidWhileOnBody(),
- mSpec.isInvalidatedByBiometricEnrollment(),
- GateKeeper.INVALID_SECURE_USER_ID /* boundToSpecificSecureUserId */,
- mSpec.isUserConfirmationRequired());
+ KeymasterUtils.addUserAuthArgs(args, mSpec);
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, mSpec.getKeyValidityStart());
args.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
mSpec.getKeyValidityForOriginationEnd());
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
index 05cc74a..fc86ca0 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreSpi.java
@@ -497,13 +497,7 @@
importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterEncryptionPaddings);
importArgs.addEnums(KeymasterDefs.KM_TAG_PADDING,
KeyProperties.SignaturePadding.allToKeymaster(spec.getSignaturePaddings()));
- KeymasterUtils.addUserAuthArgs(importArgs,
- spec.isUserAuthenticationRequired(),
- spec.getUserAuthenticationValidityDurationSeconds(),
- spec.isUserAuthenticationValidWhileOnBody(),
- spec.isInvalidatedByBiometricEnrollment(),
- spec.getBoundToSpecificSecureUserId(),
- spec.isUserConfirmationRequired());
+ KeymasterUtils.addUserAuthArgs(importArgs, spec);
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ACTIVE_DATETIME,
spec.getKeyValidityStart());
importArgs.addDateIfNotNull(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME,
@@ -700,13 +694,7 @@
int[] keymasterPaddings = KeyProperties.EncryptionPadding.allToKeymaster(
params.getEncryptionPaddings());
args.addEnums(KeymasterDefs.KM_TAG_PADDING, keymasterPaddings);
- KeymasterUtils.addUserAuthArgs(args,
- params.isUserAuthenticationRequired(),
- params.getUserAuthenticationValidityDurationSeconds(),
- params.isUserAuthenticationValidWhileOnBody(),
- params.isInvalidatedByBiometricEnrollment(),
- params.getBoundToSpecificSecureUserId(),
- params.isUserConfirmationRequired());
+ KeymasterUtils.addUserAuthArgs(args, params);
KeymasterUtils.addMinMacLengthAuthorizationIfNecessary(
args,
keymasterAlgorithm,
diff --git a/keystore/java/android/security/keystore/KeyGenParameterSpec.java b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
index da23c70..4b9f3c80 100644
--- a/keystore/java/android/security/keystore/KeyGenParameterSpec.java
+++ b/keystore/java/android/security/keystore/KeyGenParameterSpec.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
+import android.security.GateKeeper;
import android.security.KeyStore;
import android.text.TextUtils;
@@ -232,7 +233,7 @@
* key = (SecretKey) keyStore.getKey("key2", null);
* }</pre>
*/
-public final class KeyGenParameterSpec implements AlgorithmParameterSpec {
+public final class KeyGenParameterSpec implements AlgorithmParameterSpec, UserAuthArgs {
private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
@@ -669,6 +670,13 @@
}
/**
+ * @hide
+ */
+ public long getBoundToSpecificSecureUserId() {
+ return GateKeeper.INVALID_SECURE_USER_ID;
+ }
+
+ /**
* Builder of {@link KeyGenParameterSpec} instances.
*/
public final static class Builder {
diff --git a/keystore/java/android/security/keystore/KeyProtection.java b/keystore/java/android/security/keystore/KeyProtection.java
index b5b3281..95eeec7 100644
--- a/keystore/java/android/security/keystore/KeyProtection.java
+++ b/keystore/java/android/security/keystore/KeyProtection.java
@@ -212,7 +212,7 @@
* ...
* }</pre>
*/
-public final class KeyProtection implements ProtectionParameter {
+public final class KeyProtection implements ProtectionParameter, UserAuthArgs {
private final Date mKeyValidityStart;
private final Date mKeyValidityForOriginationEnd;
private final Date mKeyValidityForConsumptionEnd;
@@ -224,6 +224,7 @@
private final boolean mRandomizedEncryptionRequired;
private final boolean mUserAuthenticationRequired;
private final int mUserAuthenticationValidityDurationSeconds;
+ private final boolean mTrustedUserPresenceRequred;
private final boolean mUserAuthenticationValidWhileOnBody;
private final boolean mInvalidatedByBiometricEnrollment;
private final long mBoundToSecureUserId;
@@ -242,6 +243,7 @@
boolean randomizedEncryptionRequired,
boolean userAuthenticationRequired,
int userAuthenticationValidityDurationSeconds,
+ boolean trustedUserPresenceRequred,
boolean userAuthenticationValidWhileOnBody,
boolean invalidatedByBiometricEnrollment,
long boundToSecureUserId,
@@ -260,6 +262,7 @@
mRandomizedEncryptionRequired = randomizedEncryptionRequired;
mUserAuthenticationRequired = userAuthenticationRequired;
mUserAuthenticationValidityDurationSeconds = userAuthenticationValidityDurationSeconds;
+ mTrustedUserPresenceRequred = trustedUserPresenceRequred;
mUserAuthenticationValidWhileOnBody = userAuthenticationValidWhileOnBody;
mInvalidatedByBiometricEnrollment = invalidatedByBiometricEnrollment;
mBoundToSecureUserId = boundToSecureUserId;
@@ -437,6 +440,14 @@
}
/**
+ * Returns {@code true} if the key is authorized to be used only if a test of user presence has
+ * been performed between the {@code Signature.initSign()} and {@code Signature.sign()} calls.
+ */
+ public boolean isTrustedUserPresenceRequired() {
+ return mTrustedUserPresenceRequred;
+ }
+
+ /**
* Returns {@code true} if the key will be de-authorized when the device is removed from the
* user's body. This option has no effect on keys that don't have an authentication validity
* duration, and has no effect if the device lacks an on-body sensor.
@@ -509,6 +520,7 @@
private boolean mRandomizedEncryptionRequired = true;
private boolean mUserAuthenticationRequired;
private int mUserAuthenticationValidityDurationSeconds = -1;
+ private boolean mTrustedUserPresenceRequired = false;
private boolean mUserAuthenticationValidWhileOnBody;
private boolean mInvalidatedByBiometricEnrollment = true;
private boolean mUserConfirmationRequired;
@@ -811,6 +823,16 @@
}
/**
+ * Sets whether a test of user presence is required to be performed between the
+ * {@code Signature.initSign()} and {@code Signature.sign()} method calls.
+ */
+ @NonNull
+ public Builder setTrustedUserPresenceRequired(boolean required) {
+ mTrustedUserPresenceRequired = required;
+ return this;
+ }
+
+ /**
* Sets whether the key will remain authorized only until the device is removed from the
* user's body up to the limit of the authentication validity period (see
* {@link #setUserAuthenticationValidityDurationSeconds} and
@@ -910,6 +932,7 @@
mRandomizedEncryptionRequired,
mUserAuthenticationRequired,
mUserAuthenticationValidityDurationSeconds,
+ mTrustedUserPresenceRequired,
mUserAuthenticationValidWhileOnBody,
mInvalidatedByBiometricEnrollment,
mBoundToSecureUserId,
diff --git a/keystore/java/android/security/keystore/KeymasterUtils.java b/keystore/java/android/security/keystore/KeymasterUtils.java
index 4e28601..0ef08f2 100644
--- a/keystore/java/android/security/keystore/KeymasterUtils.java
+++ b/keystore/java/android/security/keystore/KeymasterUtils.java
@@ -18,6 +18,7 @@
import android.util.Log;
import android.hardware.fingerprint.FingerprintManager;
+import android.os.UserHandle;
import android.security.GateKeeper;
import android.security.KeyStore;
import android.security.keymaster.KeymasterArguments;
@@ -101,22 +102,21 @@
* require user authentication.
*/
public static void addUserAuthArgs(KeymasterArguments args,
- boolean userAuthenticationRequired,
- int userAuthenticationValidityDurationSeconds,
- boolean userAuthenticationValidWhileOnBody,
- boolean invalidatedByBiometricEnrollment,
- long boundToSpecificSecureUserId,
- boolean userConfirmationRequired) {
- if (userConfirmationRequired) {
+ UserAuthArgs spec) {
+ if (spec.isUserConfirmationRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_CONFIRMATION_REQUIRED);
}
- if (!userAuthenticationRequired) {
+ if (spec.isTrustedUserPresenceRequired()) {
+ args.addBoolean(KeymasterDefs.KM_TAG_TRUSTED_USER_PRESENCE_REQUIRED);
+ }
+
+ if (!spec.isUserAuthenticationRequired()) {
args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED);
return;
}
- if (userAuthenticationValidityDurationSeconds == -1) {
+ if (spec.getUserAuthenticationValidityDurationSeconds() == -1) {
// Every use of this key needs to be authorized by the user. This currently means
// fingerprint-only auth.
FingerprintManager fingerprintManager =
@@ -132,9 +132,9 @@
}
long sid;
- if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
- sid = boundToSpecificSecureUserId;
- } else if (invalidatedByBiometricEnrollment) {
+ if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
+ sid = spec.getBoundToSpecificSecureUserId();
+ } else if (spec.isInvalidatedByBiometricEnrollment()) {
// The fingerprint-only SID will change on fingerprint enrollment or removal of all,
// enrolled fingerprints, invalidating the key.
sid = fingerprintOnlySid;
@@ -147,14 +147,14 @@
args.addUnsignedLong(
KeymasterDefs.KM_TAG_USER_SECURE_ID, KeymasterArguments.toUint64(sid));
args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE, KeymasterDefs.HW_AUTH_FINGERPRINT);
- if (userAuthenticationValidWhileOnBody) {
+ if (spec.isUserAuthenticationValidWhileOnBody()) {
throw new ProviderException("Key validity extension while device is on-body is not "
+ "supported for keys requiring fingerprint authentication");
}
} else {
long sid;
- if (boundToSpecificSecureUserId != GateKeeper.INVALID_SECURE_USER_ID) {
- sid = boundToSpecificSecureUserId;
+ if (spec.getBoundToSpecificSecureUserId() != GateKeeper.INVALID_SECURE_USER_ID) {
+ sid = spec.getBoundToSpecificSecureUserId();
} else {
// The key is authorized for use for the specified amount of time after the user has
// authenticated. Whatever unlocks the secure lock screen should authorize this key.
@@ -165,8 +165,8 @@
args.addEnum(KeymasterDefs.KM_TAG_USER_AUTH_TYPE,
KeymasterDefs.HW_AUTH_PASSWORD | KeymasterDefs.HW_AUTH_FINGERPRINT);
args.addUnsignedInt(KeymasterDefs.KM_TAG_AUTH_TIMEOUT,
- userAuthenticationValidityDurationSeconds);
- if (userAuthenticationValidWhileOnBody) {
+ spec.getUserAuthenticationValidityDurationSeconds());
+ if (spec.isUserAuthenticationValidWhileOnBody()) {
args.addBoolean(KeymasterDefs.KM_TAG_ALLOW_WHILE_ON_BODY);
}
}
diff --git a/keystore/java/android/security/keystore/UserAuthArgs.java b/keystore/java/android/security/keystore/UserAuthArgs.java
new file mode 100644
index 0000000..1949592
--- /dev/null
+++ b/keystore/java/android/security/keystore/UserAuthArgs.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2017 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.security.keystore;
+
+/**
+ * @hide
+ *
+ * This is an interface to encapsulate the user authentication arguments that
+ * are passed to KeymasterUtils.addUserAuthArgs. Classes that represent
+ * authorization characteristics for new or imported keys can implement this
+ * interface to be passed to that method.
+ */
+public interface UserAuthArgs {
+
+ boolean isUserAuthenticationRequired();
+ int getUserAuthenticationValidityDurationSeconds();
+ boolean isUserAuthenticationValidWhileOnBody();
+ boolean isInvalidatedByBiometricEnrollment();
+ boolean isUserConfirmationRequired();
+ long getBoundToSpecificSecureUserId();
+ boolean isTrustedUserPresenceRequired();
+
+}
diff --git a/libs/hwui/PathParser.cpp b/libs/hwui/PathParser.cpp
index a48fdfc..47fcca9 100644
--- a/libs/hwui/PathParser.cpp
+++ b/libs/hwui/PathParser.cpp
@@ -156,10 +156,63 @@
return;
}
-bool PathParser::isVerbValid(char verb) {
- verb = tolower(verb);
- return verb == 'a' || verb == 'c' || verb == 'h' || verb == 'l' || verb == 'm' || verb == 'q' ||
- verb == 's' || verb == 't' || verb == 'v' || verb == 'z';
+void PathParser::validateVerbAndPoints(char verb, size_t points, PathParser::ParseResult* result) {
+ size_t numberOfPointsExpected = -1;
+ switch (verb) {
+ case 'z':
+ case 'Z':
+ numberOfPointsExpected = 0;
+ break;
+ case 'm':
+ case 'l':
+ case 't':
+ case 'M':
+ case 'L':
+ case 'T':
+ numberOfPointsExpected = 2;
+ break;
+ case 'h':
+ case 'v':
+ case 'H':
+ case 'V':
+ numberOfPointsExpected = 1;
+ break;
+ case 'c':
+ case 'C':
+ numberOfPointsExpected = 6;
+ break;
+ case 's':
+ case 'q':
+ case 'S':
+ case 'Q':
+ numberOfPointsExpected = 4;
+ break;
+ case 'a':
+ case 'A':
+ numberOfPointsExpected = 7;
+ break;
+ default:
+ result->failureOccurred = true;
+ result->failureMessage += verb;
+ result->failureMessage += " is not a valid verb. ";
+ return;
+ }
+ if (numberOfPointsExpected == 0 && points == 0) {
+ return;
+ }
+ if (numberOfPointsExpected > 0 && points % numberOfPointsExpected == 0) {
+ return;
+ }
+
+ result->failureOccurred = true;
+ result->failureMessage += verb;
+ result->failureMessage += " needs to be followed by ";
+ if (numberOfPointsExpected > 0) {
+ result->failureMessage += "a multiple of ";
+ }
+ result->failureMessage += std::to_string(numberOfPointsExpected)
+ + " floats. However, " + std::to_string(points)
+ + " float(s) are found. ";
}
void PathParser::getPathDataFromAsciiString(PathData* data, ParseResult* result,
@@ -186,13 +239,11 @@
end = nextStart(pathStr, strLen, end);
std::vector<float> points;
getFloats(&points, result, pathStr, start, end);
- if (!isVerbValid(pathStr[start])) {
- result->failureOccurred = true;
- result->failureMessage = "Invalid pathData. Failure occurred at position " +
- std::to_string(start) + " of path: " + pathStr;
- }
- // If either verb or points is not valid, return immediately.
+ validateVerbAndPoints(pathStr[start], points.size(), result);
if (result->failureOccurred) {
+ // If either verb or points is not valid, return immediately.
+ result->failureMessage += "Failure occurred at position " +
+ std::to_string(start) + " of path: " + pathStr;
return;
}
data->verbs.push_back(pathStr[start]);
@@ -203,9 +254,10 @@
}
if ((end - start) == 1 && start < strLen) {
- if (!isVerbValid(pathStr[start])) {
- result->failureOccurred = true;
- result->failureMessage = "Invalid pathData. Failure occurred at position " +
+ validateVerbAndPoints(pathStr[start], 0, result);
+ if (result->failureOccurred) {
+ // If either verb or points is not valid, return immediately.
+ result->failureMessage += "Failure occurred at position " +
std::to_string(start) + " of path: " + pathStr;
return;
}
diff --git a/libs/hwui/PathParser.h b/libs/hwui/PathParser.h
index e4ec7be..474eb97 100644
--- a/libs/hwui/PathParser.h
+++ b/libs/hwui/PathParser.h
@@ -43,7 +43,7 @@
ANDROID_API static void getPathDataFromAsciiString(PathData* outData, ParseResult* result,
const char* pathStr, size_t strLength);
static void dump(const PathData& data);
- static bool isVerbValid(char verb);
+ static void validateVerbAndPoints(char verb, size_t points, ParseResult* result);
};
}; // namespace uirenderer
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index e7496f7..02f740c 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -242,7 +242,8 @@
{"\n \t z", true}, // Valid path data with leading spaces
{"1-2e34567", false}, // Not starting with a verb and ill-formatted float
{"f 4 5", false}, // Invalid verb
- {"\r ", false} // Empty string
+ {"\r ", false}, // Empty string
+ {"L1,0 L1,1 L0,1 z M1000", false} // Not enough floats following verb M.
};
static bool hasSameVerbs(const PathData& from, const PathData& to) {
diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java
index 56edace..72d52d3 100644
--- a/media/java/android/media/ImageReader.java
+++ b/media/java/android/media/ImageReader.java
@@ -727,18 +727,7 @@
return false;
}
- if (format == ImageFormat.PRIVATE) {
- // Usage need to be either USAGE0_GPU_SAMPLED_IMAGE or USAGE0_VIDEO_ENCODE or combined.
- boolean isAllowed = (usage == HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE);
- isAllowed = isAllowed || (usage == HardwareBuffer.USAGE_VIDEO_ENCODE);
- isAllowed = isAllowed || (usage ==
- (HardwareBuffer.USAGE_VIDEO_ENCODE | HardwareBuffer.USAGE_GPU_SAMPLED_IMAGE));
- return isAllowed;
- } else {
- // Usage need to make the buffer CPU readable for explicit format.
- return ((usage == HardwareBuffer.USAGE_CPU_READ_RARELY) ||
- (usage == HardwareBuffer.USAGE_CPU_READ_OFTEN));
- }
+ return true;
}
/**
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 1244d7f..7976f67 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -314,7 +314,9 @@
public void addStorage(StorageVolume storage) {
MtpStorage mtpStorage = mManager.addMtpStorage(storage);
mStorageMap.put(storage.getPath(), mtpStorage);
- mServer.addStorage(mtpStorage);
+ if (mServer != null) {
+ mServer.addStorage(mtpStorage);
+ }
}
public void removeStorage(StorageVolume storage) {
@@ -322,7 +324,9 @@
if (mtpStorage == null) {
return;
}
- mServer.removeStorage(mtpStorage);
+ if (mServer != null) {
+ mServer.removeStorage(mtpStorage);
+ }
mManager.removeMtpStorage(mtpStorage);
mStorageMap.remove(storage.getPath());
}
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 4db0034..dbdf5e16 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -35,6 +35,7 @@
import android.os.Bundle;
import android.provider.Settings;
import android.support.v4.widget.SwipeRefreshLayout;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.TypedValue;
@@ -42,6 +43,7 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.webkit.CookieManager;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
@@ -147,6 +149,7 @@
final WebView webview = getWebview();
webview.clearCache(true);
+ CookieManager.getInstance().setAcceptThirdPartyCookies(webview, true);
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
@@ -529,7 +532,7 @@
private String getHeaderTitle() {
NetworkInfo info = mCm.getNetworkInfo(mNetwork);
- if (info == null) {
+ if (info == null || TextUtils.isEmpty(info.getExtraInfo())) {
return getString(R.string.action_bar_label);
}
NetworkCapabilities nc = mCm.getNetworkCapabilities(mNetwork);
diff --git a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java b/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
index 4ad4b24..de2659f 100644
--- a/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
+++ b/packages/ExtServices/src/android/ext/services/notification/ChannelImpressions.java
@@ -30,7 +30,7 @@
private static final String TAG = "ExtAssistant.CI";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- static final double DISMISS_TO_VIEW_RATIO_LIMIT = .8;
+ static final double DISMISS_TO_VIEW_RATIO_LIMIT = .4;
static final int STREAK_LIMIT = 2;
static final String ATT_DISMISSALS = "dismisses";
static final String ATT_VIEWS = "views";
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 24a6804..584fc34 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -97,6 +97,12 @@
<!-- Summary for Connected wifi network without internet -->
<string name="wifi_connected_no_internet">Connected, no internet</string>
+ <!-- Wi-Fi status indicating that the current network is connected, but has no internet access. -->
+ <string name="wifi_status_no_internet">No internet</string>
+
+ <!-- Wi-Fi status indicating that the current network is connected requires sign in to access the internet. -->
+ <string name="wifi_status_sign_in_required">Sign in required</string>
+
<!-- Summary for networks failing to connect due to association rejection status 17, AP full -->
<string name="wifi_ap_unable_to_handle_new_sta">Access point temporarily full</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
index 48b7c35..42b3156 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedSwitchPreference.java
@@ -16,20 +16,20 @@
package com.android.settingslib;
+import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.os.UserHandle;
+import android.support.v14.preference.SwitchPreference;
import android.support.v4.content.res.TypedArrayUtils;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceViewHolder;
-import android.support.v14.preference.SwitchPreference;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.TextView;
-import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
-
/**
* Version of SwitchPreference that can be disabled by a device admin
* using a user restriction.
@@ -37,7 +37,7 @@
public class RestrictedSwitchPreference extends SwitchPreference {
RestrictedPreferenceHelper mHelper;
boolean mUseAdditionalSummary = false;
- String mRestrictedSwitchSummary = null;
+ CharSequence mRestrictedSwitchSummary;
public RestrictedSwitchPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
@@ -57,19 +57,15 @@
final TypedValue restrictedSwitchSummary = attributes.peekValue(
R.styleable.RestrictedSwitchPreference_restrictedSwitchSummary);
- CharSequence data = null;
if (restrictedSwitchSummary != null
&& restrictedSwitchSummary.type == TypedValue.TYPE_STRING) {
if (restrictedSwitchSummary.resourceId != 0) {
- data = context.getString(restrictedSwitchSummary.resourceId);
+ mRestrictedSwitchSummary =
+ context.getText(restrictedSwitchSummary.resourceId);
} else {
- data = restrictedSwitchSummary.string;
+ mRestrictedSwitchSummary = restrictedSwitchSummary.string;
}
}
- mRestrictedSwitchSummary = data == null ? null : data.toString();
- }
- if (mRestrictedSwitchSummary == null) {
- mRestrictedSwitchSummary = context.getString(R.string.disabled_by_admin);
}
if (mUseAdditionalSummary) {
setLayoutResource(R.layout.restricted_switch_preference);
@@ -94,6 +90,15 @@
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
+
+ CharSequence switchSummary;
+ if (mRestrictedSwitchSummary == null) {
+ switchSummary = getContext().getText(isChecked()
+ ? R.string.enabled_by_admin : R.string.disabled_by_admin);
+ } else {
+ switchSummary = mRestrictedSwitchSummary;
+ }
+
final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
final View switchWidget = holder.findViewById(android.R.id.switch_widget);
if (restrictedIcon != null) {
@@ -102,12 +107,13 @@
if (switchWidget != null) {
switchWidget.setVisibility(isDisabledByAdmin() ? View.GONE : View.VISIBLE);
}
+
if (mUseAdditionalSummary) {
final TextView additionalSummaryView = (TextView) holder.findViewById(
R.id.additional_summary);
if (additionalSummaryView != null) {
if (isDisabledByAdmin()) {
- additionalSummaryView.setText(mRestrictedSwitchSummary);
+ additionalSummaryView.setText(switchSummary);
additionalSummaryView.setVisibility(View.VISIBLE);
} else {
additionalSummaryView.setVisibility(View.GONE);
@@ -117,7 +123,7 @@
final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary);
if (summaryView != null) {
if (isDisabledByAdmin()) {
- summaryView.setText(mRestrictedSwitchSummary);
+ summaryView.setText(switchSummary);
summaryView.setVisibility(View.VISIBLE);
}
// No need to change the visibility to GONE in the else case here since Preference
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index e2c7747..28833a3 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -20,7 +20,9 @@
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
+import android.provider.Settings.Global;
import android.provider.Settings.Secure;
+import android.support.annotation.VisibleForTesting;
import android.util.Log;
/**
@@ -34,10 +36,27 @@
private static final boolean DEBUG = false;
- // Broadcast action for SystemUI to show the battery saver confirmation dialog.
+ private static final String SYSUI_PACKAGE = "com.android.systemui";
+
+ /** Broadcast action for SystemUI to show the battery saver confirmation dialog. */
public static final String ACTION_SHOW_START_SAVER_CONFIRMATION = "PNW.startSaverConfirmation";
/**
+ * Broadcast action for SystemUI to show the notification that suggests turning on
+ * automatic battery saver.
+ */
+ public static final String ACTION_SHOW_AUTO_SAVER_SUGGESTION
+ = "PNW.autoSaverSuggestion";
+
+ /**
+ * We show the auto battery saver suggestion notification when the user manually enables
+ * battery saver for the START_NTH time through the END_NTH time.
+ * (We won't show it for END_NTH + 1 time and after.)
+ */
+ private static final int AUTO_SAVER_SUGGESTION_START_NTH = 4;
+ private static final int AUTO_SAVER_SUGGESTION_END_NTH = 8;
+
+ /**
* Enable / disable battery saver by user request.
* - If it's the first time and needFirstTimeWarning, show the first time dialog.
* - If it's 4th time through 8th time, show the schedule suggestion notification.
@@ -62,11 +81,17 @@
if (context.getSystemService(PowerManager.class).setPowerSaveMode(enable)) {
if (enable) {
- Secure.putInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT,
- Secure.getInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 0) + 1);
+ final int count =
+ Secure.getInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, 0) + 1;
+ Secure.putInt(cr, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, count);
- // TODO If enabling, and the count is between 4 and 8 (inclusive), then
- // show the "battery saver schedule suggestion" notification.
+ if ((count >= AUTO_SAVER_SUGGESTION_START_NTH)
+ && (count <= AUTO_SAVER_SUGGESTION_END_NTH)
+ && Global.getInt(cr, Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0) == 0
+ && Secure.getInt(cr,
+ Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 0) == 0) {
+ showAutoBatterySaverSuggestion(context);
+ }
}
return true;
@@ -79,13 +104,34 @@
Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 0) != 0) {
return false; // Already shown.
}
- final Intent i = new Intent(ACTION_SHOW_START_SAVER_CONFIRMATION);
- context.sendBroadcast(i);
-
+ context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_START_SAVER_CONFIRMATION));
return true;
}
+ private static void showAutoBatterySaverSuggestion(Context context) {
+ context.sendBroadcast(getSystemUiBroadcast(ACTION_SHOW_AUTO_SAVER_SUGGESTION));
+ }
+
+ private static Intent getSystemUiBroadcast(String action) {
+ final Intent i = new Intent(action);
+ i.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ i.setPackage(SYSUI_PACKAGE);
+ return i;
+ }
+
private static void setBatterySaverConfirmationAcknowledged(Context context) {
Secure.putInt(context.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
}
+
+ public static void suppressAutoBatterySaver(Context context) {
+ Secure.putInt(context.getContentResolver(),
+ Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 1);
+ }
+
+ public static void scheduleAutoBatterySaver(Context context, int level) {
+ if (Global.getInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)
+ == 0) {
+ Global.putInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, level);
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index c5c1169..78045f9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -1154,7 +1154,7 @@
@Nullable
@Speed
- private int roundToClosestSpeedEnum(int speed) {
+ private static int roundToClosestSpeedEnum(int speed) {
if (speed < Speed.SLOW) {
return Speed.NONE;
} else if (speed < (Speed.SLOW + Speed.MODERATE) / 2) {
@@ -1170,21 +1170,31 @@
@Nullable
String getSpeedLabel(@Speed int speed) {
+ return getSpeedLabel(mContext, speed);
+ }
+
+ private static String getSpeedLabel(Context context, int speed) {
switch (speed) {
case Speed.VERY_FAST:
- return mContext.getString(R.string.speed_label_very_fast);
+ return context.getString(R.string.speed_label_very_fast);
case Speed.FAST:
- return mContext.getString(R.string.speed_label_fast);
+ return context.getString(R.string.speed_label_fast);
case Speed.MODERATE:
- return mContext.getString(R.string.speed_label_okay);
+ return context.getString(R.string.speed_label_okay);
case Speed.SLOW:
- return mContext.getString(R.string.speed_label_slow);
+ return context.getString(R.string.speed_label_slow);
case Speed.NONE:
default:
return null;
}
}
+ /** Return the speed label for a {@link ScoredNetwork} at the specified {@code rssi} level. */
+ @Nullable
+ public static String getSpeedLabel(Context context, ScoredNetwork scoredNetwork, int rssi) {
+ return getSpeedLabel(context, roundToClosestSpeedEnum(scoredNetwork.calculateBadge(rssi)));
+ }
+
/** Return true if the current RSSI is reachable, and false otherwise. */
public boolean isReachable() {
return mRssi != UNREACHABLE_RSSI;
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
index 6e12e20..4cd23f9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiStatusTracker.java
@@ -10,28 +10,90 @@
package com.android.settingslib.wifi;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
+
+import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
+import android.net.NetworkKey;
+import android.net.NetworkRequest;
+import android.net.NetworkScoreManager;
+import android.net.ScoredNetwork;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
+import android.net.wifi.WifiNetworkScoreCache;
import android.net.wifi.WifiSsid;
+import android.os.Handler;
+import android.os.Looper;
+
+import com.android.settingslib.R;
import java.util.List;
-public class WifiStatusTracker {
-
+public class WifiStatusTracker extends ConnectivityManager.NetworkCallback {
+ private final Context mContext;
+ private final WifiNetworkScoreCache mWifiNetworkScoreCache;
private final WifiManager mWifiManager;
+ private final NetworkScoreManager mNetworkScoreManager;
+ private final ConnectivityManager mConnectivityManager;
+ private final WifiNetworkScoreCache.CacheListener mCacheListener =
+ new WifiNetworkScoreCache.CacheListener(new Handler(Looper.getMainLooper())) {
+ @Override
+ public void networkCacheUpdated(List<ScoredNetwork> updatedNetworks) {
+ updateStatusLabel();
+ mCallback.run();
+ }
+ };
+ private final NetworkRequest mNetworkRequest = new NetworkRequest.Builder()
+ .clearCapabilities().addTransportType(NetworkCapabilities.TRANSPORT_WIFI).build();
+ private final ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager
+ .NetworkCallback() {
+ @Override
+ public void onCapabilitiesChanged(
+ Network network, NetworkCapabilities networkCapabilities) {
+ updateStatusLabel();
+ mCallback.run();
+ }
+ };
+ private final Runnable mCallback;
+
+ private WifiInfo mWifiInfo;
public boolean enabled;
public int state;
public boolean connected;
- public boolean connecting;
public String ssid;
public int rssi;
public int level;
+ public String statusLabel;
- public WifiStatusTracker(WifiManager wifiManager) {
+ public WifiStatusTracker(Context context, WifiManager wifiManager,
+ NetworkScoreManager networkScoreManager, ConnectivityManager connectivityManager,
+ Runnable callback) {
+ mContext = context;
mWifiManager = wifiManager;
+ mWifiNetworkScoreCache = new WifiNetworkScoreCache(context);
+ mNetworkScoreManager = networkScoreManager;
+ mConnectivityManager = connectivityManager;
+ mCallback = callback;
+ }
+
+ public void setListening(boolean listening) {
+ if (listening) {
+ mNetworkScoreManager.registerNetworkScoreCache(NetworkKey.TYPE_WIFI,
+ mWifiNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK);
+ mWifiNetworkScoreCache.registerListener(mCacheListener);
+ mConnectivityManager.registerNetworkCallback(mNetworkRequest, mNetworkCallback);
+ } else {
+ mNetworkScoreManager.unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI,
+ mWifiNetworkScoreCache);
+ mWifiNetworkScoreCache.unregisterListener();
+ mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
+ }
}
public void handleBroadcast(Intent intent) {
@@ -40,34 +102,59 @@
state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN);
enabled = state == WifiManager.WIFI_STATE_ENABLED;
-
-
- enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
} else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final NetworkInfo networkInfo = (NetworkInfo)
+ final NetworkInfo networkInfo =
intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- connecting = networkInfo != null && !networkInfo.isConnected()
- && networkInfo.isConnectedOrConnecting();
connected = networkInfo != null && networkInfo.isConnected();
- // If Connected grab the signal strength and ssid.
+ mWifiInfo = null;
+ ssid = null;
if (connected) {
- WifiInfo info = mWifiManager.getConnectionInfo();
- if (info != null) {
- ssid = getValidSsid(info);
- } else {
- ssid = null;
+ mWifiInfo = mWifiManager.getConnectionInfo();
+ if (mWifiInfo != null) {
+ ssid = getValidSsid(mWifiInfo);
+ updateRssi(mWifiInfo.getRssi());
+ maybeRequestNetworkScore();
}
- } else if (!connected) {
- ssid = null;
}
+ updateStatusLabel();
} else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) {
// Default to -200 as its below WifiManager.MIN_RSSI.
- rssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
- level = WifiManager.calculateSignalLevel(rssi, 5);
+ updateRssi(intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200));
+ updateStatusLabel();
}
}
+ private void updateRssi(int newRssi) {
+ rssi = newRssi;
+ level = WifiManager.calculateSignalLevel(rssi, WifiManager.RSSI_LEVELS);
+ }
+
+ private void maybeRequestNetworkScore() {
+ NetworkKey networkKey = NetworkKey.createFromWifiInfo(mWifiInfo);
+ if (mWifiNetworkScoreCache.getScoredNetwork(networkKey) == null) {
+ mNetworkScoreManager.requestScores(new NetworkKey[]{ networkKey });
+ }
+ }
+
+ private void updateStatusLabel() {
+ final NetworkCapabilities networkCapabilities
+ = mConnectivityManager.getNetworkCapabilities(mWifiManager.getCurrentNetwork());
+ if (networkCapabilities != null) {
+ if (networkCapabilities.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL)) {
+ statusLabel = mContext.getString(R.string.wifi_status_sign_in_required);
+ return;
+ } else if (!networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) {
+ statusLabel = mContext.getString(R.string.wifi_status_no_internet);
+ return;
+ }
+ }
+
+ ScoredNetwork scoredNetwork =
+ mWifiNetworkScoreCache.getScoredNetwork(NetworkKey.createFromWifiInfo(mWifiInfo));
+ statusLabel = scoredNetwork == null
+ ? null : AccessPoint.getSpeedLabel(mContext, scoredNetwork, rssi);
+ }
+
private String getValidSsid(WifiInfo info) {
String ssid = info.getSSID();
if (ssid != null && !WifiSsid.NONE.equals(ssid)) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 6d9da9b..a444ac8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1512,105 +1512,357 @@
s.dumpHistoricalOperations(p, SecureSettingsProto.HISTORICAL_OPERATIONS);
- // This uses the same order as in Settings.Secure.
+ // This uses the same order as in SecureSettingsProto.
- // Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED intentionally excluded since it's deprecated.
- // Settings.Secure.BUGREPORT_IN_POWER_MENU intentionally excluded since it's deprecated.
- // Settings.Secure.ADB_ENABLED intentionally excluded since it's deprecated.
- // Settings.Secure.ALLOW_MOCK_LOCATION intentionally excluded since it's deprecated.
+ final long accessibilityToken = p.start(SecureSettingsProto.ACCESSIBILITY);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_ENABLED,
+ SecureSettingsProto.Accessibility.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
+ SecureSettingsProto.Accessibility.ENABLED_ACCESSIBILITY_SERVICES);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED,
+ SecureSettingsProto.Accessibility.AUTOCLICK_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
+ SecureSettingsProto.Accessibility.AUTOCLICK_DELAY);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
+ SecureSettingsProto.Accessibility.BUTTON_TARGET_COMPONENT);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
+ SecureSettingsProto.Accessibility.CAPTIONING_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE,
+ SecureSettingsProto.Accessibility.CAPTIONING_LOCALE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET,
+ SecureSettingsProto.Accessibility.CAPTIONING_PRESET);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
+ SecureSettingsProto.Accessibility.CAPTIONING_BACKGROUND_COLOR);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
+ SecureSettingsProto.Accessibility.CAPTIONING_FOREGROUND_COLOR);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
+ SecureSettingsProto.Accessibility.CAPTIONING_EDGE_TYPE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
+ SecureSettingsProto.Accessibility.CAPTIONING_EDGE_COLOR);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
+ SecureSettingsProto.Accessibility.CAPTIONING_WINDOW_COLOR);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
+ SecureSettingsProto.Accessibility.CAPTIONING_TYPEFACE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
+ SecureSettingsProto.Accessibility.CAPTIONING_FONT_SCALE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
+ SecureSettingsProto.Accessibility.DISPLAY_DALTONIZER_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
+ SecureSettingsProto.Accessibility.DISPLAY_DALTONIZER);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
+ SecureSettingsProto.Accessibility.DISPLAY_INVERSION_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
+ SecureSettingsProto.Accessibility.DISPLAY_MAGNIFICATION_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
+ SecureSettingsProto.Accessibility.DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
+ SecureSettingsProto.Accessibility.DISPLAY_MAGNIFICATION_SCALE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
+ SecureSettingsProto.Accessibility.HIGH_TEXT_CONTRAST_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
+ SecureSettingsProto.Accessibility.LARGE_POINTER_ICON);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED,
+ SecureSettingsProto.Accessibility.SHORTCUT_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
+ SecureSettingsProto.Accessibility.SHORTCUT_ON_LOCK_SCREEN);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
+ SecureSettingsProto.Accessibility.SHORTCUT_DIALOG_SHOWN);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
+ SecureSettingsProto.Accessibility.SHORTCUT_TARGET_SERVICE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
+ SecureSettingsProto.Accessibility.SOFT_KEYBOARD_MODE);
+ dumpSetting(s, p,
+ Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
+ SecureSettingsProto.Accessibility.SPEAK_PASSWORD);
+ dumpSetting(s, p,
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED,
+ SecureSettingsProto.Accessibility.TOUCH_EXPLORATION_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
+ SecureSettingsProto.Accessibility.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
+ p.end(accessibilityToken);
+
+ dumpSetting(s, p,
+ Settings.Secure.ALLOWED_GEOLOCATION_ORIGINS,
+ SecureSettingsProto.ALLOWED_GEOLOCATION_ORIGINS);
+
+ final long aovToken = p.start(SecureSettingsProto.ALWAYS_ON_VPN);
+ dumpSetting(s, p,
+ Settings.Secure.ALWAYS_ON_VPN_APP,
+ SecureSettingsProto.AlwaysOnVpn.APP);
+ dumpSetting(s, p,
+ Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN,
+ SecureSettingsProto.AlwaysOnVpn.LOCKDOWN);
+ p.end(aovToken);
+
dumpSetting(s, p,
Settings.Secure.ANDROID_ID,
SecureSettingsProto.ANDROID_ID);
- // Settings.Secure.BLUETOOTH_ON intentionally excluded since it's deprecated.
- // Settings.Secure.DATA_ROAMING intentionally excluded since it's deprecated.
dumpSetting(s, p,
- Settings.Secure.DEFAULT_INPUT_METHOD,
- SecureSettingsProto.DEFAULT_INPUT_METHOD);
+ Settings.Secure.ANR_SHOW_BACKGROUND,
+ SecureSettingsProto.ANR_SHOW_BACKGROUND);
+
+ final long assistToken = p.start(SecureSettingsProto.ASSIST);
dumpSetting(s, p,
- Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
- SecureSettingsProto.SELECTED_INPUT_METHOD_SUBTYPE);
+ Settings.Secure.ASSISTANT,
+ SecureSettingsProto.Assist.ASSISTANT);
dumpSetting(s, p,
- Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY,
- SecureSettingsProto.INPUT_METHODS_SUBTYPE_HISTORY);
+ Settings.Secure.ASSIST_STRUCTURE_ENABLED,
+ SecureSettingsProto.Assist.STRUCTURE_ENABLED);
dumpSetting(s, p,
- Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY,
- SecureSettingsProto.INPUT_METHOD_SELECTOR_VISIBILITY);
+ Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
+ SecureSettingsProto.Assist.SCREENSHOT_ENABLED);
dumpSetting(s, p,
- Settings.Secure.VOICE_INTERACTION_SERVICE,
- SecureSettingsProto.VOICE_INTERACTION_SERVICE);
+ Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
+ SecureSettingsProto.Assist.DISCLOSURE_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ASSIST_GESTURE_ENABLED,
+ SecureSettingsProto.Assist.GESTURE_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
+ SecureSettingsProto.Assist.GESTURE_SENSITIVITY);
+ dumpSetting(s, p,
+ Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
+ SecureSettingsProto.Assist.GESTURE_SILENCE_ALERTS_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
+ SecureSettingsProto.Assist.GESTURE_WAKE_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
+ SecureSettingsProto.Assist.GESTURE_SETUP_COMPLETE);
+ p.end(assistToken);
+
+ final long autofillToken = p.start(SecureSettingsProto.AUTOFILL);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_SERVICE,
- SecureSettingsProto.AUTOFILL_SERVICE);
+ SecureSettingsProto.Autofill.SERVICE);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_FEATURE_FIELD_CLASSIFICATION,
- SecureSettingsProto.AUTOFILL_FEATURE_FIELD_CLASSIFICATION);
+ SecureSettingsProto.Autofill.FEATURE_FIELD_CLASSIFICATION);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE,
- SecureSettingsProto.AUTOFILL_USER_DATA_MAX_USER_DATA_SIZE);
+ SecureSettingsProto.Autofill.USER_DATA_MAX_USER_DATA_SIZE);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE,
- SecureSettingsProto.AUTOFILL_USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE);
+ SecureSettingsProto.Autofill.USER_DATA_MAX_FIELD_CLASSIFICATION_IDS_SIZE);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT,
- SecureSettingsProto.AUTOFILL_USER_DATA_MAX_CATEGORY_COUNT);
+ SecureSettingsProto.Autofill.USER_DATA_MAX_CATEGORY_COUNT);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_USER_DATA_MAX_VALUE_LENGTH,
- SecureSettingsProto.AUTOFILL_USER_DATA_MAX_VALUE_LENGTH);
+ SecureSettingsProto.Autofill.USER_DATA_MAX_VALUE_LENGTH);
dumpSetting(s, p,
Settings.Secure.AUTOFILL_USER_DATA_MIN_VALUE_LENGTH,
- SecureSettingsProto.AUTOFILL_USER_DATA_MIN_VALUE_LENGTH);
- // Settings.Secure.DEVICE_PROVISIONED intentionally excluded since it's deprecated.
+ SecureSettingsProto.Autofill.USER_DATA_MIN_VALUE_LENGTH);
dumpSetting(s, p,
- Settings.Secure.USER_SETUP_COMPLETE,
- SecureSettingsProto.USER_SETUP_COMPLETE);
- // Whether the current user has been set up via setup wizard (0 = false, 1 = true). This
- // value differs from USER_SETUP_COMPLETE in that it can be reset back to 0 in case
- // SetupWizard has been re-enabled on TV devices.
+ Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
+ SecureSettingsProto.Autofill.SERVICE_SEARCH_URI);
+ p.end(autofillToken);
+
+ final long asmToken = p.start(SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER);
dumpSetting(s, p,
- Settings.Secure.TV_USER_SETUP_COMPLETE,
- SecureSettingsProto.TV_USER_SETUP_COMPLETE);
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
+ SecureSettingsProto.AutomaticStorageManager.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
+ SecureSettingsProto.AutomaticStorageManager.DAYS_TO_RETAIN);
+ dumpSetting(s, p,
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
+ SecureSettingsProto.AutomaticStorageManager.BYTES_CLEARED);
+ dumpSetting(s, p,
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
+ SecureSettingsProto.AutomaticStorageManager.LAST_RUN);
+ dumpSetting(s, p,
+ Settings.Secure.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY,
+ SecureSettingsProto.AutomaticStorageManager.TURNED_OFF_BY_POLICY);
+ p.end(asmToken);
+
+ final long backupToken = p.start(SecureSettingsProto.BACKUP);
+ dumpSetting(s, p,
+ Settings.Secure.BACKUP_ENABLED,
+ SecureSettingsProto.Backup.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.BACKUP_AUTO_RESTORE,
+ SecureSettingsProto.Backup.AUTO_RESTORE);
+ dumpSetting(s, p,
+ Settings.Secure.BACKUP_PROVISIONED,
+ SecureSettingsProto.Backup.PROVISIONED);
+ dumpSetting(s, p,
+ Settings.Secure.BACKUP_TRANSPORT,
+ SecureSettingsProto.Backup.TRANSPORT);
+ dumpSetting(s, p,
+ Settings.Secure.BACKUP_MANAGER_CONSTANTS,
+ SecureSettingsProto.Backup.MANAGER_CONSTANTS);
+ dumpSetting(s, p,
+ Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS,
+ SecureSettingsProto.Backup.LOCAL_TRANSPORT_PARAMETERS);
+ p.end(backupToken);
+
+ // Settings.Secure.BLUETOOTH_ON intentionally excluded since it's deprecated.
+ dumpSetting(s, p,
+ Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
+ SecureSettingsProto.BLUETOOTH_ON_WHILE_DRIVING);
+
+ final long cameraToken = p.start(SecureSettingsProto.CAMERA);
+ dumpSetting(s, p,
+ Settings.Secure.CAMERA_GESTURE_DISABLED,
+ SecureSettingsProto.Camera.GESTURE_DISABLED);
+ dumpSetting(s, p,
+ Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
+ SecureSettingsProto.Camera.DOUBLE_TAP_POWER_GESTURE_DISABLED);
+ dumpSetting(s, p,
+ Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+ SecureSettingsProto.Camera.DOUBLE_TWIST_TO_FLIP_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED,
+ SecureSettingsProto.Camera.LIFT_TRIGGER_ENABLED);
+ p.end(cameraToken);
+
+ dumpSetting(s, p,
+ Settings.Secure.CARRIER_APPS_HANDLED,
+ SecureSettingsProto.CARRIER_APPS_HANDLED);
+ dumpSetting(s, p,
+ Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
+ SecureSettingsProto.CMAS_ADDITIONAL_BROADCAST_PKG);
dumpRepeatedSetting(s, p,
Settings.Secure.COMPLETED_CATEGORY_PREFIX,
SecureSettingsProto.COMPLETED_CATEGORIES);
dumpSetting(s, p,
- Settings.Secure.ENABLED_INPUT_METHODS,
- SecureSettingsProto.ENABLED_INPUT_METHODS);
+ Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
+ SecureSettingsProto.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS);
+ dumpSetting(s, p,
+ Settings.Secure.DEVICE_PAIRED,
+ SecureSettingsProto.DEVICE_PAIRED);
+ dumpSetting(s, p,
+ Settings.Secure.DIALER_DEFAULT_APPLICATION,
+ SecureSettingsProto.DIALER_DEFAULT_APPLICATION);
+ dumpSetting(s, p,
+ Settings.Secure.DISPLAY_DENSITY_FORCED,
+ SecureSettingsProto.DISPLAY_DENSITY_FORCED);
+ dumpSetting(s, p,
+ Settings.Secure.DOUBLE_TAP_TO_WAKE,
+ SecureSettingsProto.DOUBLE_TAP_TO_WAKE);
+
+ final long dozeToken = p.start(SecureSettingsProto.DOZE);
+ dumpSetting(s, p,
+ Settings.Secure.DOZE_ENABLED,
+ SecureSettingsProto.Doze.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.DOZE_ALWAYS_ON,
+ SecureSettingsProto.Doze.ALWAYS_ON);
+ dumpSetting(s, p,
+ Settings.Secure.DOZE_PULSE_ON_PICK_UP,
+ SecureSettingsProto.Doze.PULSE_ON_PICK_UP);
+ dumpSetting(s, p,
+ Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
+ SecureSettingsProto.Doze.PULSE_ON_LONG_PRESS);
+ dumpSetting(s, p,
+ Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
+ SecureSettingsProto.Doze.PULSE_ON_DOUBLE_TAP);
+ p.end(dozeToken);
+
+ dumpSetting(s, p,
+ Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION,
+ SecureSettingsProto.EMERGENCY_ASSISTANCE_APPLICATION);
+ dumpSetting(s, p,
+ Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED,
+ SecureSettingsProto.ENHANCED_VOICE_PRIVACY_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
+ SecureSettingsProto.IMMERSIVE_MODE_CONFIRMATIONS);
+
+ final long incallToken = p.start(SecureSettingsProto.INCALL);
+ dumpSetting(s, p,
+ Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
+ SecureSettingsProto.Incall.POWER_BUTTON_BEHAVIOR);
+ dumpSetting(s, p,
+ Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR,
+ SecureSettingsProto.Incall.BACK_BUTTON_BEHAVIOR);
+ p.end(incallToken);
+
+ final long inputMethodsToken = p.start(SecureSettingsProto.INPUT_METHODS);
+ dumpSetting(s, p,
+ Settings.Secure.DEFAULT_INPUT_METHOD,
+ SecureSettingsProto.InputMethods.DEFAULT_INPUT_METHOD);
dumpSetting(s, p,
Settings.Secure.DISABLED_SYSTEM_INPUT_METHODS,
- SecureSettingsProto.DISABLED_SYSTEM_INPUT_METHODS);
+ SecureSettingsProto.InputMethods.DISABLED_SYSTEM_INPUT_METHODS);
+ dumpSetting(s, p,
+ Settings.Secure.ENABLED_INPUT_METHODS,
+ SecureSettingsProto.InputMethods.ENABLED_INPUT_METHODS);
+ dumpSetting(s, p,
+ Settings.Secure.INPUT_METHODS_SUBTYPE_HISTORY,
+ SecureSettingsProto.InputMethods.SUBTYPE_HISTORY);
+ dumpSetting(s, p,
+ Settings.Secure.INPUT_METHOD_SELECTOR_VISIBILITY,
+ SecureSettingsProto.InputMethods.METHOD_SELECTOR_VISIBILITY);
+ dumpSetting(s, p,
+ Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
+ SecureSettingsProto.InputMethods.SELECTED_INPUT_METHOD_SUBTYPE);
dumpSetting(s, p,
Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD,
- SecureSettingsProto.SHOW_IME_WITH_HARD_KEYBOARD);
- // Settings.Secure.HTTP_PROXY intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.Secure.ALWAYS_ON_VPN_APP,
- SecureSettingsProto.ALWAYS_ON_VPN_APP);
- dumpSetting(s, p,
- Settings.Secure.ALWAYS_ON_VPN_LOCKDOWN,
- SecureSettingsProto.ALWAYS_ON_VPN_LOCKDOWN);
+ SecureSettingsProto.InputMethods.SHOW_IME_WITH_HARD_KEYBOARD);
+ p.end(inputMethodsToken);
+
dumpSetting(s, p,
Settings.Secure.INSTALL_NON_MARKET_APPS,
SecureSettingsProto.INSTALL_NON_MARKET_APPS);
dumpSetting(s, p,
- Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED,
- SecureSettingsProto.UNKNOWN_SOURCES_DEFAULT_REVERSED);
+ Settings.Secure.INSTANT_APPS_ENABLED,
+ SecureSettingsProto.INSTANT_APPS_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.KEYGUARD_SLICE_URI,
+ SecureSettingsProto.KEYGUARD_SLICE_URI);
+ dumpSetting(s, p,
+ Settings.Secure.LAST_SETUP_SHOWN,
+ SecureSettingsProto.LAST_SETUP_SHOWN);
+
+ final long locationToken = p.start(SecureSettingsProto.LOCATION);
// Settings.Secure.LOCATION_PROVIDERS_ALLOWED intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Secure.LOCATION_MODE,
- SecureSettingsProto.LOCATION_MODE);
+ SecureSettingsProto.Location.MODE);
dumpSetting(s, p,
Settings.Secure.LOCATION_CHANGER,
- SecureSettingsProto.LOCATION_CHANGER);
+ SecureSettingsProto.Location.CHANGER);
+ p.end(locationToken);
+
+ final long lockScreenToken = p.start(SecureSettingsProto.LOCK_SCREEN);
// Settings.Secure.LOCK_BIOMETRIC_WEAK_FLAGS intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
- SecureSettingsProto.LOCK_TO_APP_EXIT_LOCKED);
// Settings.Secure.LOCK_PATTERN_ENABLED intentionally excluded since it's deprecated.
// Settings.Secure.LOCK_PATTERN_VISIBLE intentionally excluded since it's deprecated.
// Settings.Secure.LOCK_PATTERN_TACTICLE_FEEDBACK_ENABLED intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
- SecureSettingsProto.LOCK_SCREEN_LOCK_AFTER_TIMEOUT);
+ SecureSettingsProto.LockScreen.LOCK_AFTER_TIMEOUT);
// Settings.Secure.LOCK_SCREEN_OWNER_INFO intentionally excluded since it's deprecated.
// Settings.Secure.LOCK_SCREEN_APPWIDGET_IDS intentionally excluded since it's deprecated.
// Settings.Secure.LOCK_SCREEN_FALLBACK_APPWIDGET_ID intentionally excluded since it's deprecated.
@@ -1618,162 +1870,371 @@
// Settings.Secure.LOCK_SCREEN_OWNER_INFO_ENABLED intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS,
- SecureSettingsProto.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS);
+ SecureSettingsProto.LockScreen.ALLOW_PRIVATE_NOTIFICATIONS);
dumpSetting(s, p,
Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
- SecureSettingsProto.LOCK_SCREEN_ALLOW_REMOTE_INPUT);
+ SecureSettingsProto.LockScreen.ALLOW_REMOTE_INPUT);
dumpSetting(s, p,
- Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING,
- SecureSettingsProto.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING);
+ Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ SecureSettingsProto.LockScreen.SHOW_NOTIFICATIONS);
+ p.end(lockScreenToken);
+
dumpSetting(s, p,
- Settings.Secure.TRUST_AGENTS_INITIALIZED,
- SecureSettingsProto.TRUST_AGENTS_INITIALIZED);
- // Settings.Secure.LOGGING_ID intentionally excluded since it's deprecated.
- // Settings.Secure.NETWORK_PREFERENCE intentionally excluded since it's deprecated.
+ Settings.Secure.LOCK_TO_APP_EXIT_LOCKED,
+ SecureSettingsProto.LOCK_TO_APP_EXIT_LOCKED);
dumpSetting(s, p,
- Settings.Secure.PARENTAL_CONTROL_ENABLED,
- SecureSettingsProto.PARENTAL_CONTROL_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
- SecureSettingsProto.PARENTAL_CONTROL_LAST_UPDATE);
- dumpSetting(s, p,
- Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
- SecureSettingsProto.PARENTAL_CONTROL_REDIRECT_URL);
- dumpSetting(s, p,
- Settings.Secure.SETTINGS_CLASSNAME,
- SecureSettingsProto.SETTINGS_CLASSNAME);
- // Settings.Secure.USB_MASS_STORAGE_ENABLED intentionally excluded since it's deprecated.
- // Settings.Secure.USE_GOOGLE_MAIL intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_SHORTCUT_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_SHORTCUT_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN,
- SecureSettingsProto.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN,
- SecureSettingsProto.ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE,
- SecureSettingsProto.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_BUTTON_TARGET_COMPONENT,
- SecureSettingsProto.ACCESSIBILITY_BUTTON_TARGET_COMPONENT);
- dumpSetting(s, p,
- Settings.Secure.TOUCH_EXPLORATION_ENABLED,
- SecureSettingsProto.TOUCH_EXPLORATION_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES,
- SecureSettingsProto.ENABLED_ACCESSIBILITY_SERVICES);
- dumpSetting(s, p,
- Settings.Secure.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES,
- SecureSettingsProto.TOUCH_EXPLORATION_GRANTED_ACCESSIBILITY_SERVICES);
- dumpSetting(s, p,
- Settings.Secure.KEYGUARD_SLICE_URI,
- SecureSettingsProto.KEYGUARD_SLICE_URI);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_SPEAK_PASSWORD,
- SecureSettingsProto.ACCESSIBILITY_SPEAK_PASSWORD);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_HIGH_TEXT_CONTRAST_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_NAVBAR_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE,
- SecureSettingsProto.ACCESSIBILITY_DISPLAY_MAGNIFICATION_SCALE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE,
- SecureSettingsProto.ACCESSIBILITY_SOFT_KEYBOARD_MODE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_LOCALE,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_LOCALE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_PRESET,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_PRESET);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_BACKGROUND_COLOR);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_FOREGROUND_COLOR);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_TYPE,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_EDGE_TYPE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_EDGE_COLOR,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_EDGE_COLOR);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_WINDOW_COLOR);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_TYPEFACE,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_TYPEFACE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_CAPTIONING_FONT_SCALE,
- SecureSettingsProto.ACCESSIBILITY_CAPTIONING_FONT_SCALE);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER,
- SecureSettingsProto.ACCESSIBILITY_DISPLAY_DALTONIZER);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_AUTOCLICK_ENABLED,
- SecureSettingsProto.ACCESSIBILITY_AUTOCLICK_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_AUTOCLICK_DELAY,
- SecureSettingsProto.ACCESSIBILITY_AUTOCLICK_DELAY);
- dumpSetting(s, p,
- Settings.Secure.ACCESSIBILITY_LARGE_POINTER_ICON,
- SecureSettingsProto.ACCESSIBILITY_LARGE_POINTER_ICON);
+ Settings.Secure.LOCKDOWN_IN_POWER_MENU,
+ SecureSettingsProto.LOCKDOWN_IN_POWER_MENU);
dumpSetting(s, p,
Settings.Secure.LONG_PRESS_TIMEOUT,
SecureSettingsProto.LONG_PRESS_TIMEOUT);
+
+ final long managedProfileToken = p.start(SecureSettingsProto.MANAGED_PROFILE);
+ dumpSetting(s, p,
+ Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
+ SecureSettingsProto.ManagedProfile.CONTACT_REMOTE_SEARCH);
+ p.end(managedProfileToken);
+
+ final long mountToken = p.start(SecureSettingsProto.MOUNT);
+ dumpSetting(s, p,
+ Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
+ SecureSettingsProto.Mount.PLAY_NOTIFICATION_SND);
+ dumpSetting(s, p,
+ Settings.Secure.MOUNT_UMS_AUTOSTART,
+ SecureSettingsProto.Mount.UMS_AUTOSTART);
+ dumpSetting(s, p,
+ Settings.Secure.MOUNT_UMS_PROMPT,
+ SecureSettingsProto.Mount.UMS_PROMPT);
+ dumpSetting(s, p,
+ Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
+ SecureSettingsProto.Mount.UMS_NOTIFY_ENABLED);
+ p.end(mountToken);
+
dumpSetting(s, p,
Settings.Secure.MULTI_PRESS_TIMEOUT,
SecureSettingsProto.MULTI_PRESS_TIMEOUT);
+
+ final long nfcPaymentToken = p.start(SecureSettingsProto.NFC_PAYMENT);
+ dumpSetting(s, p,
+ Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
+ SecureSettingsProto.NfcPayment.DEFAULT_COMPONENT);
+ dumpSetting(s, p,
+ Settings.Secure.NFC_PAYMENT_FOREGROUND,
+ SecureSettingsProto.NfcPayment.FOREGROUND);
+ dumpSetting(s, p,
+ Settings.Secure.PAYMENT_SERVICE_SEARCH_URI,
+ SecureSettingsProto.NfcPayment.PAYMENT_SERVICE_SEARCH_URI);
+ p.end(nfcPaymentToken);
+
+ final long nightDisplayToken = p.start(SecureSettingsProto.NIGHT_DISPLAY);
+ dumpSetting(s, p,
+ Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
+ SecureSettingsProto.NightDisplay.ACTIVATED);
+ dumpSetting(s, p,
+ Settings.Secure.NIGHT_DISPLAY_AUTO_MODE,
+ SecureSettingsProto.NightDisplay.AUTO_MODE);
+ dumpSetting(s, p,
+ Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
+ SecureSettingsProto.NightDisplay.COLOR_TEMPERATURE);
+ dumpSetting(s, p,
+ Settings.Secure.NIGHT_DISPLAY_CUSTOM_START_TIME,
+ SecureSettingsProto.NightDisplay.CUSTOM_START_TIME);
+ dumpSetting(s, p,
+ Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
+ SecureSettingsProto.NightDisplay.CUSTOM_END_TIME);
+ dumpSetting(s, p,
+ Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
+ SecureSettingsProto.NightDisplay.LAST_ACTIVATED_TIME);
+ p.end(nightDisplayToken);
+
+ final long notificationToken = p.start(SecureSettingsProto.NOTIFICATION);
+ dumpSetting(s, p,
+ Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT,
+ SecureSettingsProto.Notification.ENABLED_ASSISTANT);
+ dumpSetting(s, p,
+ Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
+ SecureSettingsProto.Notification.ENABLED_LISTENERS);
+ dumpSetting(s, p,
+ Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
+ SecureSettingsProto.Notification.ENABLED_POLICY_ACCESS_PACKAGES);
+ dumpSetting(s, p,
+ Settings.Secure.NOTIFICATION_BADGING,
+ SecureSettingsProto.Notification.BADGING);
+ dumpSetting(s, p,
+ Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING,
+ SecureSettingsProto.Notification.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING);
+ p.end(notificationToken);
+
+ final long packageVerifierToken = p.start(SecureSettingsProto.PACKAGE_VERIFIER);
+ dumpSetting(s, p,
+ Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
+ SecureSettingsProto.PackageVerifier.USER_CONSENT);
+ dumpSetting(s, p,
+ Settings.Secure.PACKAGE_VERIFIER_STATE,
+ SecureSettingsProto.PackageVerifier.STATE);
+ p.end(packageVerifierToken);
+
+ final long parentalControlToken = p.start(SecureSettingsProto.PARENTAL_CONTROL);
+ dumpSetting(s, p,
+ Settings.Secure.PARENTAL_CONTROL_ENABLED,
+ SecureSettingsProto.ParentalControl.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.PARENTAL_CONTROL_LAST_UPDATE,
+ SecureSettingsProto.ParentalControl.LAST_UPDATE);
+ dumpSetting(s, p,
+ Settings.Secure.PARENTAL_CONTROL_REDIRECT_URL,
+ SecureSettingsProto.ParentalControl.REDIRECT_URL);
+ p.end(parentalControlToken);
+
+ final long printServiceToken = p.start(SecureSettingsProto.PRINT_SERVICE);
+ dumpSetting(s, p,
+ Settings.Secure.PRINT_SERVICE_SEARCH_URI,
+ SecureSettingsProto.PrintService.SEARCH_URI);
dumpSetting(s, p,
Settings.Secure.ENABLED_PRINT_SERVICES,
- SecureSettingsProto.ENABLED_PRINT_SERVICES);
+ SecureSettingsProto.PrintService.ENABLED_PRINT_SERVICES);
dumpSetting(s, p,
Settings.Secure.DISABLED_PRINT_SERVICES,
- SecureSettingsProto.DISABLED_PRINT_SERVICES);
+ SecureSettingsProto.PrintService.DISABLED_PRINT_SERVICES);
+ p.end(printServiceToken);
+
+ final long qsToken = p.start(SecureSettingsProto.QS);
dumpSetting(s, p,
- Settings.Secure.DISPLAY_DENSITY_FORCED,
- SecureSettingsProto.DISPLAY_DENSITY_FORCED);
+ Settings.Secure.QS_TILES,
+ SecureSettingsProto.QuickSettings.TILES);
+ dumpSetting(s, p,
+ Settings.Secure.QS_AUTO_ADDED_TILES,
+ SecureSettingsProto.QuickSettings.AUTO_ADDED_TILES);
+ p.end(qsToken);
+
+ final long rotationToken = p.start(SecureSettingsProto.ROTATION);
+ dumpSetting(s, p,
+ Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
+ SecureSettingsProto.Rotation.SHOW_ROTATION_SUGGESTIONS);
+ dumpSetting(s, p,
+ Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
+ SecureSettingsProto.Rotation.NUM_ROTATION_SUGGESTIONS_ACCEPTED);
+ p.end(rotationToken);
+
+ final long screensaverToken = p.start(SecureSettingsProto.SCREENSAVER);
+ dumpSetting(s, p,
+ Settings.Secure.SCREENSAVER_ENABLED,
+ SecureSettingsProto.Screensaver.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.SCREENSAVER_COMPONENTS,
+ SecureSettingsProto.Screensaver.COMPONENTS);
+ dumpSetting(s, p,
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
+ SecureSettingsProto.Screensaver.ACTIVATE_ON_DOCK);
+ dumpSetting(s, p,
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
+ SecureSettingsProto.Screensaver.ACTIVATE_ON_SLEEP);
+ dumpSetting(s, p,
+ Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
+ SecureSettingsProto.Screensaver.DEFAULT_COMPONENT);
+ p.end(screensaverToken);
+
+ final long searchToken = p.start(SecureSettingsProto.SEARCH);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY,
+ SecureSettingsProto.Search.GLOBAL_SEARCH_ACTIVITY);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_NUM_PROMOTED_SOURCES,
+ SecureSettingsProto.Search.NUM_PROMOTED_SOURCES);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MAX_RESULTS_TO_DISPLAY,
+ SecureSettingsProto.Search.MAX_RESULTS_TO_DISPLAY);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MAX_RESULTS_PER_SOURCE,
+ SecureSettingsProto.Search.MAX_RESULTS_PER_SOURCE);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_WEB_RESULTS_OVERRIDE_LIMIT,
+ SecureSettingsProto.Search.WEB_RESULTS_OVERRIDE_LIMIT);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS,
+ SecureSettingsProto.Search.PROMOTED_SOURCE_DEADLINE_MILLIS);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_SOURCE_TIMEOUT_MILLIS,
+ SecureSettingsProto.Search.SOURCE_TIMEOUT_MILLIS);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_PREFILL_MILLIS,
+ SecureSettingsProto.Search.PREFILL_MILLIS);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MAX_STAT_AGE_MILLIS,
+ SecureSettingsProto.Search.MAX_STAT_AGE_MILLIS);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS,
+ SecureSettingsProto.Search.MAX_SOURCE_EVENT_AGE_MILLIS);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING,
+ SecureSettingsProto.Search.MIN_IMPRESSIONS_FOR_SOURCE_RANKING);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING,
+ SecureSettingsProto.Search.MIN_CLICKS_FOR_SOURCE_RANKING);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_MAX_SHORTCUTS_RETURNED,
+ SecureSettingsProto.Search.MAX_SHORTCUTS_RETURNED);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_QUERY_THREAD_CORE_POOL_SIZE,
+ SecureSettingsProto.Search.QUERY_THREAD_CORE_POOL_SIZE);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_QUERY_THREAD_MAX_POOL_SIZE,
+ SecureSettingsProto.Search.QUERY_THREAD_MAX_POOL_SIZE);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE,
+ SecureSettingsProto.Search.SHORTCUT_REFRESH_CORE_POOL_SIZE);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE,
+ SecureSettingsProto.Search.SHORTCUT_REFRESH_MAX_POOL_SIZE);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_THREAD_KEEPALIVE_SECONDS,
+ SecureSettingsProto.Search.THREAD_KEEPALIVE_SECONDS);
+ dumpSetting(s, p,
+ Settings.Secure.SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT,
+ SecureSettingsProto.Search.PER_SOURCE_CONCURRENT_QUERY_LIMIT);
+ p.end(searchToken);
+
+ final long spellCheckerToken = p.start(SecureSettingsProto.SPELL_CHECKER);
+ dumpSetting(s, p,
+ Settings.Secure.SPELL_CHECKER_ENABLED,
+ SecureSettingsProto.SpellChecker.ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.SELECTED_SPELL_CHECKER,
+ SecureSettingsProto.SpellChecker.SELECTED);
+ dumpSetting(s, p,
+ Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE,
+ SecureSettingsProto.SpellChecker.SELECTED_SUBTYPE);
+ p.end(spellCheckerToken);
+
+ dumpSetting(s, p,
+ Settings.Secure.SETTINGS_CLASSNAME,
+ SecureSettingsProto.SETTINGS_CLASSNAME);
+ dumpSetting(s, p,
+ Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
+ SecureSettingsProto.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION);
+ dumpSetting(s, p,
+ Settings.Secure.SKIP_FIRST_USE_HINTS,
+ SecureSettingsProto.SKIP_FIRST_USE_HINTS);
+ dumpSetting(s, p,
+ Settings.Secure.SLEEP_TIMEOUT,
+ SecureSettingsProto.SLEEP_TIMEOUT);
+ dumpSetting(s, p,
+ Settings.Secure.SMS_DEFAULT_APPLICATION,
+ SecureSettingsProto.SMS_DEFAULT_APPLICATION);
+ dumpSetting(s, p,
+ Settings.Secure.SYNC_PARENT_SOUNDS,
+ SecureSettingsProto.SYNC_PARENT_SOUNDS);
+ dumpSetting(s, p,
+ Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
+ SecureSettingsProto.SYSTEM_NAVIGATION_KEYS_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.TRUST_AGENTS_INITIALIZED,
+ SecureSettingsProto.TRUST_AGENTS_INITIALIZED);
+
+ final long ttsToken = p.start(SecureSettingsProto.TTS);
// Settings.Secure.TTS_USE_DEFAULTS intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Secure.TTS_DEFAULT_RATE,
- SecureSettingsProto.TTS_DEFAULT_RATE);
+ SecureSettingsProto.Tts.DEFAULT_RATE);
dumpSetting(s, p,
Settings.Secure.TTS_DEFAULT_PITCH,
- SecureSettingsProto.TTS_DEFAULT_PITCH);
+ SecureSettingsProto.Tts.DEFAULT_PITCH);
dumpSetting(s, p,
Settings.Secure.TTS_DEFAULT_SYNTH,
- SecureSettingsProto.TTS_DEFAULT_SYNTH);
+ SecureSettingsProto.Tts.DEFAULT_SYNTH);
// Settings.Secure.TTS_DEFAULT_LANG intentionally excluded since it's deprecated.
// Settings.Secure.TTS_DEFAULT_COUNTRY intentionally excluded since it's deprecated.
// Settings.Secure.TTS_DEFAULT_VARIANT intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Secure.TTS_DEFAULT_LOCALE,
- SecureSettingsProto.TTS_DEFAULT_LOCALE);
+ SecureSettingsProto.Tts.DEFAULT_LOCALE);
dumpSetting(s, p,
Settings.Secure.TTS_ENABLED_PLUGINS,
- SecureSettingsProto.TTS_ENABLED_PLUGINS);
+ SecureSettingsProto.Tts.ENABLED_PLUGINS);
+ p.end(ttsToken);
+
+ final long ttyToken = p.start(SecureSettingsProto.TTY);
+ dumpSetting(s, p,
+ Settings.Secure.TTY_MODE_ENABLED,
+ SecureSettingsProto.Tty.TTY_MODE_ENABLED);
+ dumpSetting(s, p,
+ Settings.Secure.PREFERRED_TTY_MODE,
+ SecureSettingsProto.Tty.PREFERRED_TTY_MODE);
+ p.end(ttyToken);
+
+ final long tvToken = p.start(SecureSettingsProto.TV);
+ // Whether the current user has been set up via setup wizard (0 = false, 1 = true). This
+ // value differs from USER_SETUP_COMPLETE in that it can be reset back to 0 in case
+ // SetupWizard has been re-enabled on TV devices.
+ dumpSetting(s, p,
+ Settings.Secure.TV_USER_SETUP_COMPLETE,
+ SecureSettingsProto.Tv.USER_SETUP_COMPLETE);
+ dumpSetting(s, p,
+ Settings.Secure.TV_INPUT_HIDDEN_INPUTS,
+ SecureSettingsProto.Tv.INPUT_HIDDEN_INPUTS);
+ dumpSetting(s, p,
+ Settings.Secure.TV_INPUT_CUSTOM_LABELS,
+ SecureSettingsProto.Tv.INPUT_CUSTOM_LABELS);
+ p.end(tvToken);
+
+ dumpSetting(s, p,
+ Settings.Secure.UI_NIGHT_MODE,
+ SecureSettingsProto.UI_NIGHT_MODE);
+ dumpSetting(s, p,
+ Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED,
+ SecureSettingsProto.UNKNOWN_SOURCES_DEFAULT_REVERSED);
+ dumpSetting(s, p,
+ Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
+ SecureSettingsProto.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED);
+ dumpSetting(s, p,
+ Settings.Secure.USER_SETUP_COMPLETE,
+ SecureSettingsProto.USER_SETUP_COMPLETE);
+
+ final long voiceToken = p.start(SecureSettingsProto.VOICE);
+ dumpSetting(s, p,
+ Settings.Secure.VOICE_INTERACTION_SERVICE,
+ SecureSettingsProto.Voice.INTERACTION_SERVICE);
+ dumpSetting(s, p,
+ Settings.Secure.VOICE_RECOGNITION_SERVICE,
+ SecureSettingsProto.Voice.RECOGNITION_SERVICE);
+ p.end(voiceToken);
+
+ final long volumeToken = p.start(SecureSettingsProto.VOLUME);
+ dumpSetting(s, p,
+ Settings.Secure.VOLUME_HUSH_GESTURE,
+ SecureSettingsProto.Volume.HUSH_GESTURE);
+ dumpSetting(s, p,
+ Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS,
+ SecureSettingsProto.Volume.UNSAFE_VOLUME_MUSIC_ACTIVE_MS);
+ p.end(volumeToken);
+
+ final long vrToken = p.start(SecureSettingsProto.VR);
+ dumpSetting(s, p,
+ Settings.Secure.VR_DISPLAY_MODE,
+ SecureSettingsProto.Vr.DISPLAY_MODE);
+ dumpSetting(s, p,
+ Settings.Secure.ENABLED_VR_LISTENERS,
+ SecureSettingsProto.Vr.ENABLED_LISTENERS);
+ p.end(vrToken);
+
+ dumpSetting(s, p,
+ Settings.Secure.WAKE_GESTURE_ENABLED,
+ SecureSettingsProto.WAKE_GESTURE_ENABLED);
+
+ // Please insert new settings using the same order as in SecureSettingsProto.
+ p.end(token);
+
+ // Settings.Secure.DEVELOPMENT_SETTINGS_ENABLED intentionally excluded since it's deprecated.
+ // Settings.Secure.BUGREPORT_IN_POWER_MENU intentionally excluded since it's deprecated.
+ // Settings.Secure.ADB_ENABLED intentionally excluded since it's deprecated.
+ // Settings.Secure.ALLOW_MOCK_LOCATION intentionally excluded since it's deprecated.
+ // Settings.Secure.DATA_ROAMING intentionally excluded since it's deprecated.
+ // Settings.Secure.DEVICE_PROVISIONED intentionally excluded since it's deprecated.
+ // Settings.Secure.HTTP_PROXY intentionally excluded since it's deprecated.
+ // Settings.Secure.LOGGING_ID intentionally excluded since it's deprecated.
+ // Settings.Secure.NETWORK_PREFERENCE intentionally excluded since it's deprecated.
+ // Settings.Secure.USB_MASS_STORAGE_ENABLED intentionally excluded since it's deprecated.
+ // Settings.Secure.USE_GOOGLE_MAIL intentionally excluded since it's deprecated.
// Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON intentionally excluded since it's deprecated.
// Settings.Secure.WIFI_NETWORKS_AVAILABLE_REPEAT_DELAY intentionally excluded since it's deprecated.
// Settings.Secure.WIFI_NUM_OPEN_NETWORKS_KEPT intentionally excluded since it's deprecated.
@@ -1792,365 +2253,11 @@
// Settings.Secure.WIFI_WATCHDOG_PING_TIMEOUT_MS intentionally excluded since it's deprecated.
// Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT intentionally excluded since it's deprecated.
// Settings.Secure.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS,
- SecureSettingsProto.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS);
// Settings.Secure.BACKGROUND_DATA intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.Secure.ALLOWED_GEOLOCATION_ORIGINS,
- SecureSettingsProto.ALLOWED_GEOLOCATION_ORIGINS);
- dumpSetting(s, p,
- Settings.Secure.PREFERRED_TTY_MODE,
- SecureSettingsProto.PREFERRED_TTY_MODE);
- dumpSetting(s, p,
- Settings.Secure.ENHANCED_VOICE_PRIVACY_ENABLED,
- SecureSettingsProto.ENHANCED_VOICE_PRIVACY_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.TTY_MODE_ENABLED,
- SecureSettingsProto.TTY_MODE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.BACKUP_ENABLED,
- SecureSettingsProto.BACKUP_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.BACKUP_AUTO_RESTORE,
- SecureSettingsProto.BACKUP_AUTO_RESTORE);
- dumpSetting(s, p,
- Settings.Secure.BACKUP_PROVISIONED,
- SecureSettingsProto.BACKUP_PROVISIONED);
- dumpSetting(s, p,
- Settings.Secure.BACKUP_TRANSPORT,
- SecureSettingsProto.BACKUP_TRANSPORT);
- dumpSetting(s, p,
- Settings.Secure.LAST_SETUP_SHOWN,
- SecureSettingsProto.LAST_SETUP_SHOWN);
// Settings.Secure.WIFI_IDLE_MS intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY,
- SecureSettingsProto.SEARCH_GLOBAL_SEARCH_ACTIVITY);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_NUM_PROMOTED_SOURCES,
- SecureSettingsProto.SEARCH_NUM_PROMOTED_SOURCES);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MAX_RESULTS_TO_DISPLAY,
- SecureSettingsProto.SEARCH_MAX_RESULTS_TO_DISPLAY);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MAX_RESULTS_PER_SOURCE,
- SecureSettingsProto.SEARCH_MAX_RESULTS_PER_SOURCE);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_WEB_RESULTS_OVERRIDE_LIMIT,
- SecureSettingsProto.SEARCH_WEB_RESULTS_OVERRIDE_LIMIT);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS,
- SecureSettingsProto.SEARCH_PROMOTED_SOURCE_DEADLINE_MILLIS);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_SOURCE_TIMEOUT_MILLIS,
- SecureSettingsProto.SEARCH_SOURCE_TIMEOUT_MILLIS);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_PREFILL_MILLIS,
- SecureSettingsProto.SEARCH_PREFILL_MILLIS);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MAX_STAT_AGE_MILLIS,
- SecureSettingsProto.SEARCH_MAX_STAT_AGE_MILLIS);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS,
- SecureSettingsProto.SEARCH_MAX_SOURCE_EVENT_AGE_MILLIS);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING,
- SecureSettingsProto.SEARCH_MIN_IMPRESSIONS_FOR_SOURCE_RANKING);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING,
- SecureSettingsProto.SEARCH_MIN_CLICKS_FOR_SOURCE_RANKING);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_MAX_SHORTCUTS_RETURNED,
- SecureSettingsProto.SEARCH_MAX_SHORTCUTS_RETURNED);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_QUERY_THREAD_CORE_POOL_SIZE,
- SecureSettingsProto.SEARCH_QUERY_THREAD_CORE_POOL_SIZE);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_QUERY_THREAD_MAX_POOL_SIZE,
- SecureSettingsProto.SEARCH_QUERY_THREAD_MAX_POOL_SIZE);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE,
- SecureSettingsProto.SEARCH_SHORTCUT_REFRESH_CORE_POOL_SIZE);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE,
- SecureSettingsProto.SEARCH_SHORTCUT_REFRESH_MAX_POOL_SIZE);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_THREAD_KEEPALIVE_SECONDS,
- SecureSettingsProto.SEARCH_THREAD_KEEPALIVE_SECONDS);
- dumpSetting(s, p,
- Settings.Secure.SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT,
- SecureSettingsProto.SEARCH_PER_SOURCE_CONCURRENT_QUERY_LIMIT);
- dumpSetting(s, p,
- Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
- SecureSettingsProto.MOUNT_PLAY_NOTIFICATION_SND);
- dumpSetting(s, p,
- Settings.Secure.MOUNT_UMS_AUTOSTART,
- SecureSettingsProto.MOUNT_UMS_AUTOSTART);
- dumpSetting(s, p,
- Settings.Secure.MOUNT_UMS_PROMPT,
- SecureSettingsProto.MOUNT_UMS_PROMPT);
- dumpSetting(s, p,
- Settings.Secure.MOUNT_UMS_NOTIFY_ENABLED,
- SecureSettingsProto.MOUNT_UMS_NOTIFY_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ANR_SHOW_BACKGROUND,
- SecureSettingsProto.ANR_SHOW_BACKGROUND);
- dumpSetting(s, p,
- Settings.Secure.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION,
- SecureSettingsProto.SHOW_FIRST_CRASH_DIALOG_DEV_OPTION);
- dumpSetting(s, p,
- Settings.Secure.VOICE_RECOGNITION_SERVICE,
- SecureSettingsProto.VOICE_RECOGNITION_SERVICE);
- dumpSetting(s, p,
- Settings.Secure.PACKAGE_VERIFIER_USER_CONSENT,
- SecureSettingsProto.PACKAGE_VERIFIER_USER_CONSENT);
- dumpSetting(s, p,
- Settings.Secure.SELECTED_SPELL_CHECKER,
- SecureSettingsProto.SELECTED_SPELL_CHECKER);
- dumpSetting(s, p,
- Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE,
- SecureSettingsProto.SELECTED_SPELL_CHECKER_SUBTYPE);
- dumpSetting(s, p,
- Settings.Secure.SPELL_CHECKER_ENABLED,
- SecureSettingsProto.SPELL_CHECKER_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR,
- SecureSettingsProto.INCALL_POWER_BUTTON_BEHAVIOR);
- dumpSetting(s, p,
- Settings.Secure.INCALL_BACK_BUTTON_BEHAVIOR,
- SecureSettingsProto.INCALL_BACK_BUTTON_BEHAVIOR);
- dumpSetting(s, p,
- Settings.Secure.WAKE_GESTURE_ENABLED,
- SecureSettingsProto.WAKE_GESTURE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.DOZE_ENABLED,
- SecureSettingsProto.DOZE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.DOZE_ALWAYS_ON,
- SecureSettingsProto.DOZE_ALWAYS_ON);
- dumpSetting(s, p,
- Settings.Secure.DOZE_PULSE_ON_PICK_UP,
- SecureSettingsProto.DOZE_PULSE_ON_PICK_UP);
- dumpSetting(s, p,
- Settings.Secure.DOZE_PULSE_ON_LONG_PRESS,
- SecureSettingsProto.DOZE_PULSE_ON_LONG_PRESS);
- dumpSetting(s, p,
- Settings.Secure.DOZE_PULSE_ON_DOUBLE_TAP,
- SecureSettingsProto.DOZE_PULSE_ON_DOUBLE_TAP);
- dumpSetting(s, p,
- Settings.Secure.UI_NIGHT_MODE,
- SecureSettingsProto.UI_NIGHT_MODE);
- dumpSetting(s, p,
- Settings.Secure.SCREENSAVER_ENABLED,
- SecureSettingsProto.SCREENSAVER_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.SCREENSAVER_COMPONENTS,
- SecureSettingsProto.SCREENSAVER_COMPONENTS);
- dumpSetting(s, p,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
- SecureSettingsProto.SCREENSAVER_ACTIVATE_ON_DOCK);
- dumpSetting(s, p,
- Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
- SecureSettingsProto.SCREENSAVER_ACTIVATE_ON_SLEEP);
- dumpSetting(s, p,
- Settings.Secure.SCREENSAVER_DEFAULT_COMPONENT,
- SecureSettingsProto.SCREENSAVER_DEFAULT_COMPONENT);
- dumpSetting(s, p,
- Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT,
- SecureSettingsProto.NFC_PAYMENT_DEFAULT_COMPONENT);
- dumpSetting(s, p,
- Settings.Secure.NFC_PAYMENT_FOREGROUND,
- SecureSettingsProto.NFC_PAYMENT_FOREGROUND);
- dumpSetting(s, p,
- Settings.Secure.SMS_DEFAULT_APPLICATION,
- SecureSettingsProto.SMS_DEFAULT_APPLICATION);
- dumpSetting(s, p,
- Settings.Secure.DIALER_DEFAULT_APPLICATION,
- SecureSettingsProto.DIALER_DEFAULT_APPLICATION);
- dumpSetting(s, p,
- Settings.Secure.EMERGENCY_ASSISTANCE_APPLICATION,
- SecureSettingsProto.EMERGENCY_ASSISTANCE_APPLICATION);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_STRUCTURE_ENABLED,
- SecureSettingsProto.ASSIST_STRUCTURE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_SCREENSHOT_ENABLED,
- SecureSettingsProto.ASSIST_SCREENSHOT_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_DISCLOSURE_ENABLED,
- SecureSettingsProto.ASSIST_DISCLOSURE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
- SecureSettingsProto.SHOW_ROTATION_SUGGESTIONS);
- dumpSetting(s, p,
- Settings.Secure.NUM_ROTATION_SUGGESTIONS_ACCEPTED,
- SecureSettingsProto.NUM_ROTATION_SUGGESTIONS_ACCEPTED);
- dumpSetting(s, p,
- Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT,
- SecureSettingsProto.ENABLED_NOTIFICATION_ASSISTANT);
- dumpSetting(s, p,
- Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
- SecureSettingsProto.ENABLED_NOTIFICATION_LISTENERS);
- dumpSetting(s, p,
- Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES,
- SecureSettingsProto.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES);
- dumpSetting(s, p,
- Settings.Secure.SYNC_PARENT_SOUNDS,
- SecureSettingsProto.SYNC_PARENT_SOUNDS);
- dumpSetting(s, p,
- Settings.Secure.IMMERSIVE_MODE_CONFIRMATIONS,
- SecureSettingsProto.IMMERSIVE_MODE_CONFIRMATIONS);
- dumpSetting(s, p,
- Settings.Secure.PRINT_SERVICE_SEARCH_URI,
- SecureSettingsProto.PRINT_SERVICE_SEARCH_URI);
- dumpSetting(s, p,
- Settings.Secure.PAYMENT_SERVICE_SEARCH_URI,
- SecureSettingsProto.PAYMENT_SERVICE_SEARCH_URI);
- dumpSetting(s, p,
- Settings.Secure.AUTOFILL_SERVICE_SEARCH_URI,
- SecureSettingsProto.AUTOFILL_SERVICE_SEARCH_URI);
- dumpSetting(s, p,
- Settings.Secure.SKIP_FIRST_USE_HINTS,
- SecureSettingsProto.SKIP_FIRST_USE_HINTS);
- dumpSetting(s, p,
- Settings.Secure.UNSAFE_VOLUME_MUSIC_ACTIVE_MS,
- SecureSettingsProto.UNSAFE_VOLUME_MUSIC_ACTIVE_MS);
- dumpSetting(s, p,
- Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
- SecureSettingsProto.LOCK_SCREEN_SHOW_NOTIFICATIONS);
- dumpSetting(s, p,
- Settings.Secure.TV_INPUT_HIDDEN_INPUTS,
- SecureSettingsProto.TV_INPUT_HIDDEN_INPUTS);
- dumpSetting(s, p,
- Settings.Secure.TV_INPUT_CUSTOM_LABELS,
- SecureSettingsProto.TV_INPUT_CUSTOM_LABELS);
- dumpSetting(s, p,
- Settings.Secure.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED,
- SecureSettingsProto.USB_AUDIO_AUTOMATIC_ROUTING_DISABLED);
- dumpSetting(s, p,
- Settings.Secure.SLEEP_TIMEOUT,
- SecureSettingsProto.SLEEP_TIMEOUT);
- dumpSetting(s, p,
- Settings.Secure.DOUBLE_TAP_TO_WAKE,
- SecureSettingsProto.DOUBLE_TAP_TO_WAKE);
- dumpSetting(s, p,
- Settings.Secure.ASSISTANT,
- SecureSettingsProto.ASSISTANT);
- dumpSetting(s, p,
- Settings.Secure.CAMERA_GESTURE_DISABLED,
- SecureSettingsProto.CAMERA_GESTURE_DISABLED);
- dumpSetting(s, p,
- Settings.Secure.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
- SecureSettingsProto.CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED);
- dumpSetting(s, p,
- Settings.Secure.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
- SecureSettingsProto.CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.CAMERA_LIFT_TRIGGER_ENABLED,
- SecureSettingsProto.CAMERA_LIFT_TRIGGER_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_GESTURE_ENABLED,
- SecureSettingsProto.ASSIST_GESTURE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_GESTURE_SENSITIVITY,
- SecureSettingsProto.ASSIST_GESTURE_SENSITIVITY);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED,
- SecureSettingsProto.ASSIST_GESTURE_SILENCE_ALERTS_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
- SecureSettingsProto.ASSIST_GESTURE_WAKE_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.ASSIST_GESTURE_SETUP_COMPLETE,
- SecureSettingsProto.ASSIST_GESTURE_SETUP_COMPLETE);
- dumpSetting(s, p,
- Settings.Secure.NIGHT_DISPLAY_ACTIVATED,
- SecureSettingsProto.NIGHT_DISPLAY_ACTIVATED);
- dumpSetting(s, p,
- Settings.Secure.NIGHT_DISPLAY_AUTO_MODE,
- SecureSettingsProto.NIGHT_DISPLAY_AUTO_MODE);
- dumpSetting(s, p,
- Settings.Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE,
- SecureSettingsProto.NIGHT_DISPLAY_COLOR_TEMPERATURE);
- dumpSetting(s, p,
- Settings.Secure.NIGHT_DISPLAY_CUSTOM_START_TIME,
- SecureSettingsProto.NIGHT_DISPLAY_CUSTOM_START_TIME);
- dumpSetting(s, p,
- Settings.Secure.NIGHT_DISPLAY_CUSTOM_END_TIME,
- SecureSettingsProto.NIGHT_DISPLAY_CUSTOM_END_TIME);
- dumpSetting(s, p,
- Settings.Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
- SecureSettingsProto.NIGHT_DISPLAY_LAST_ACTIVATED_TIME);
- dumpSetting(s, p,
- Settings.Secure.ENABLED_VR_LISTENERS,
- SecureSettingsProto.ENABLED_VR_LISTENERS);
- dumpSetting(s, p,
- Settings.Secure.VR_DISPLAY_MODE,
- SecureSettingsProto.VR_DISPLAY_MODE);
- dumpSetting(s, p,
- Settings.Secure.CARRIER_APPS_HANDLED,
- SecureSettingsProto.CARRIER_APPS_HANDLED);
- dumpSetting(s, p,
- Settings.Secure.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH,
- SecureSettingsProto.MANAGED_PROFILE_CONTACT_REMOTE_SEARCH);
- dumpSetting(s, p,
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_ENABLED,
- SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
- SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN);
- dumpSetting(s, p,
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED,
- SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_BYTES_CLEARED);
- dumpSetting(s, p,
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_LAST_RUN,
- SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_LAST_RUN);
- dumpSetting(s, p,
- Settings.Secure.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY,
- SecureSettingsProto.AUTOMATIC_STORAGE_MANAGER_TURNED_OFF_BY_POLICY);
- dumpSetting(s, p,
- Settings.Secure.SYSTEM_NAVIGATION_KEYS_ENABLED,
- SecureSettingsProto.SYSTEM_NAVIGATION_KEYS_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.QS_TILES,
- SecureSettingsProto.QS_TILES);
- dumpSetting(s, p,
- Settings.Secure.INSTANT_APPS_ENABLED,
- SecureSettingsProto.INSTANT_APPS_ENABLED);
- dumpSetting(s, p,
- Settings.Secure.DEVICE_PAIRED,
- SecureSettingsProto.DEVICE_PAIRED);
- dumpSetting(s, p,
- Settings.Secure.PACKAGE_VERIFIER_STATE,
- SecureSettingsProto.PACKAGE_VERIFIER_STATE);
- dumpSetting(s, p,
- Settings.Secure.CMAS_ADDITIONAL_BROADCAST_PKG,
- SecureSettingsProto.CMAS_ADDITIONAL_BROADCAST_PKG);
- dumpSetting(s, p,
- Settings.Secure.NOTIFICATION_BADGING,
- SecureSettingsProto.NOTIFICATION_BADGING);
- dumpSetting(s, p,
- Settings.Secure.QS_AUTO_ADDED_TILES,
- SecureSettingsProto.QS_AUTO_ADDED_TILES);
- dumpSetting(s, p,
- Settings.Secure.LOCKDOWN_IN_POWER_MENU,
- SecureSettingsProto.LOCKDOWN_IN_POWER_MENU);
- dumpSetting(s, p,
- Settings.Secure.BACKUP_MANAGER_CONSTANTS,
- SecureSettingsProto.BACKUP_MANAGER_CONSTANTS);
- dumpSetting(s, p,
- Settings.Secure.BACKUP_LOCAL_TRANSPORT_PARAMETERS,
- SecureSettingsProto.BACKUP_LOCAL_TRANSPORT_PARAMETERS);
- dumpSetting(s, p,
- Settings.Secure.BLUETOOTH_ON_WHILE_DRIVING,
- SecureSettingsProto.BLUETOOTH_ON_WHILE_DRIVING);
- dumpSetting(s, p,
- Settings.Secure.VOLUME_HUSH_GESTURE,
- SecureSettingsProto.VOLUME_HUSH_GESTURE);
- // Please insert new settings using the same order as in Settings.Secure.
- p.end(token);
+
+ // Please insert new settings using the same order as in SecureSettingsProto.
}
private static void dumpProtoSystemSettingsLocked(
@@ -2159,15 +2266,293 @@
s.dumpHistoricalOperations(p, SystemSettingsProto.HISTORICAL_OPERATIONS);
- // This uses the same order as in Settings.System.
+ // This uses the same order as in SystemSettingsProto.
- // Settings.System.STAY_ON_WHILE_PLUGGED_IN intentionally excluded since it's deprecated.
+ dumpSetting(s, p,
+ Settings.System.ADVANCED_SETTINGS,
+ SystemSettingsProto.ADVANCED_SETTINGS);
+
+ final long alarmToken = p.start(SystemSettingsProto.ALARM);
+ dumpSetting(s, p,
+ Settings.System.ALARM_ALERT,
+ SystemSettingsProto.Alarm.DEFAULT_URI);
+ dumpSetting(s, p,
+ Settings.System.ALARM_ALERT_CACHE,
+ SystemSettingsProto.Alarm.ALERT_CACHE);
+ // Settings.System.NEXT_ALARM_FORMATTED intentionally excluded since it's deprecated.
+ p.end(alarmToken);
+
+ final long bluetoothToken = p.start(SystemSettingsProto.BLUETOOTH);
+ dumpSetting(s, p,
+ Settings.System.BLUETOOTH_DISCOVERABILITY,
+ SystemSettingsProto.Bluetooth.DISCOVERABILITY);
+ dumpSetting(s, p,
+ Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
+ SystemSettingsProto.Bluetooth.DISCOVERABILITY_TIMEOUT_SECS);
+ p.end(bluetoothToken);
+
+ dumpSetting(s, p,
+ Settings.System.DATE_FORMAT,
+ SystemSettingsProto.DATE_FORMAT);
+ dumpSetting(s, p,
+ Settings.System.DISPLAY_COLOR_MODE,
+ SystemSettingsProto.DISPLAY_COLOR_MODE);
+
+ final long devOptionsToken = p.start(SystemSettingsProto.DEVELOPER_OPTIONS);
+ dumpSetting(s, p,
+ Settings.System.SHOW_TOUCHES,
+ SystemSettingsProto.DevOptions.SHOW_TOUCHES);
+ dumpSetting(s, p,
+ Settings.System.POINTER_LOCATION,
+ SystemSettingsProto.DevOptions.POINTER_LOCATION);
+ dumpSetting(s, p,
+ Settings.System.WINDOW_ORIENTATION_LISTENER_LOG,
+ SystemSettingsProto.DevOptions.WINDOW_ORIENTATION_LISTENER_LOG);
+ p.end(devOptionsToken);
+
+ final long dtmfToneToken = p.start(SystemSettingsProto.DTMF_TONE);
+ dumpSetting(s, p,
+ Settings.System.DTMF_TONE_WHEN_DIALING,
+ SystemSettingsProto.DtmfTone.PLAY_WHEN_DIALING);
+ dumpSetting(s, p,
+ Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
+ SystemSettingsProto.DtmfTone.TYPE_PLAYED_WHEN_DIALING);
+ p.end(dtmfToneToken);
+
+ dumpSetting(s, p,
+ Settings.System.EGG_MODE,
+ SystemSettingsProto.EGG_MODE);
dumpSetting(s, p,
Settings.System.END_BUTTON_BEHAVIOR,
SystemSettingsProto.END_BUTTON_BEHAVIOR);
dumpSetting(s, p,
- Settings.System.ADVANCED_SETTINGS,
- SystemSettingsProto.ADVANCED_SETTINGS);
+ Settings.System.FONT_SCALE,
+ SystemSettingsProto.FONT_SCALE);
+
+ final long hapticFeedbackToken = p.start(SystemSettingsProto.HAPTIC_FEEDBACK);
+ dumpSetting(s, p,
+ Settings.System.HAPTIC_FEEDBACK_ENABLED,
+ SystemSettingsProto.HapticFeedback.ENABLED);
+ dumpSetting(s, p,
+ Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ SystemSettingsProto.HapticFeedback.INTENSITY);
+ p.end(hapticFeedbackToken);
+
+ dumpSetting(s, p,
+ Settings.System.HEARING_AID,
+ SystemSettingsProto.HEARING_AID);
+ dumpSetting(s, p,
+ Settings.System.LOCK_TO_APP_ENABLED,
+ SystemSettingsProto.LOCK_TO_APP_ENABLED);
+
+ final long lockscreenToken = p.start(SystemSettingsProto.LOCKSCREEN);
+ dumpSetting(s, p,
+ Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
+ SystemSettingsProto.Lockscreen.SOUNDS_ENABLED);
+ dumpSetting(s, p,
+ Settings.System.LOCKSCREEN_DISABLED,
+ SystemSettingsProto.Lockscreen.DISABLED);
+ p.end(lockscreenToken);
+
+ dumpSetting(s, p,
+ Settings.System.MEDIA_BUTTON_RECEIVER,
+ SystemSettingsProto.MEDIA_BUTTON_RECEIVER);
+
+ final long notificationToken = p.start(SystemSettingsProto.NOTIFICATION);
+ dumpSetting(s, p,
+ Settings.System.NOTIFICATION_SOUND,
+ SystemSettingsProto.Notification.SOUND);
+ dumpSetting(s, p,
+ Settings.System.NOTIFICATION_SOUND_CACHE,
+ SystemSettingsProto.Notification.SOUND_CACHE);
+ dumpSetting(s, p,
+ Settings.System.NOTIFICATION_LIGHT_PULSE,
+ SystemSettingsProto.Notification.LIGHT_PULSE);
+ dumpSetting(s, p,
+ Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ SystemSettingsProto.Notification.VIBRATION_INTENSITY);
+ // Settings.System.NOTIFICATIONS_USE_RING_VOLUME intentionally excluded since it's deprecated.
+ p.end(notificationToken);
+
+ dumpSetting(s, p,
+ Settings.System.POINTER_SPEED,
+ SystemSettingsProto.POINTER_SPEED);
+
+ final long ringtoneToken = p.start(SystemSettingsProto.RINGTONE);
+ dumpSetting(s, p,
+ Settings.System.RINGTONE,
+ SystemSettingsProto.Ringtone.DEFAULT_URI);
+ dumpSetting(s, p,
+ Settings.System.RINGTONE_CACHE,
+ SystemSettingsProto.Ringtone.CACHE);
+ p.end(ringtoneToken);
+
+ final long rotationToken = p.start(SystemSettingsProto.ROTATION);
+ dumpSetting(s, p,
+ Settings.System.ACCELEROMETER_ROTATION,
+ SystemSettingsProto.Rotation.ACCELEROMETER_ROTATION);
+ dumpSetting(s, p,
+ Settings.System.USER_ROTATION,
+ SystemSettingsProto.Rotation.USER_ROTATION);
+ dumpSetting(s, p,
+ Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
+ SystemSettingsProto.Rotation.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY);
+ p.end(rotationToken);
+
+ dumpSetting(s, p,
+ Settings.System.RTT_CALLING_MODE,
+ SystemSettingsProto.RTT_CALLING_MODE);
+
+ final long screenToken = p.start(SystemSettingsProto.SCREEN);
+ dumpSetting(s, p,
+ Settings.System.SCREEN_OFF_TIMEOUT,
+ SystemSettingsProto.Screen.OFF_TIMEOUT);
+ dumpSetting(s, p,
+ Settings.System.SCREEN_BRIGHTNESS,
+ SystemSettingsProto.Screen.BRIGHTNESS);
+ dumpSetting(s, p,
+ Settings.System.SCREEN_BRIGHTNESS_FOR_VR,
+ SystemSettingsProto.Screen.BRIGHTNESS_FOR_VR);
+ dumpSetting(s, p,
+ Settings.System.SCREEN_BRIGHTNESS_MODE,
+ SystemSettingsProto.Screen.BRIGHTNESS_MODE);
+ dumpSetting(s, p,
+ Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
+ SystemSettingsProto.Screen.AUTO_BRIGHTNESS_ADJ);
+ p.end(screenToken);
+
+ dumpSetting(s, p,
+ Settings.System.SETUP_WIZARD_HAS_RUN,
+ SystemSettingsProto.SETUP_WIZARD_HAS_RUN);
+ dumpSetting(s, p,
+ Settings.System.SHOW_BATTERY_PERCENT,
+ SystemSettingsProto.SHOW_BATTERY_PERCENT);
+ dumpSetting(s, p,
+ Settings.System.SHOW_GTALK_SERVICE_STATUS,
+ SystemSettingsProto.SHOW_GTALK_SERVICE_STATUS);
+ // Settings.System.SHOW_PROCESSES intentionally excluded since it's deprecated.
+ // Settings.System.SHOW_WEB_SUGGESTIONS intentionally excluded since it's deprecated.
+
+ final long sipToken = p.start(SystemSettingsProto.SIP);
+ dumpSetting(s, p,
+ Settings.System.SIP_RECEIVE_CALLS,
+ SystemSettingsProto.Sip.RECEIVE_CALLS);
+ dumpSetting(s, p,
+ Settings.System.SIP_CALL_OPTIONS,
+ SystemSettingsProto.Sip.CALL_OPTIONS);
+ dumpSetting(s, p,
+ Settings.System.SIP_ALWAYS,
+ SystemSettingsProto.Sip.ALWAYS);
+ dumpSetting(s, p,
+ Settings.System.SIP_ADDRESS_ONLY,
+ SystemSettingsProto.Sip.ADDRESS_ONLY);
+ // Settings.System.SIP_ASK_ME_EACH_TIME intentionally excluded since it's deprecated.
+ p.end(sipToken);
+
+ dumpSetting(s, p,
+ Settings.System.SOUND_EFFECTS_ENABLED,
+ SystemSettingsProto.SOUND_EFFECTS_ENABLED);
+ // Settings.System.POWER_SOUNDS_ENABLED intentionally excluded since it's deprecated.
+ // Settings.System.DOCK_SOUNDS_ENABLED intentionally excluded since it's deprecated.
+ // Settings.System.LOW_BATTERY_SOUND intentionally excluded since it's deprecated.
+ // Settings.System.DESK_DOCK_SOUND intentionally excluded since it's deprecated.
+ // Settings.System.DESK_UNDOCK_SOUND intentionally excluded since it's deprecated.
+ // Settings.System.CAR_DOCK_SOUND intentionally excluded since it's deprecated.
+ // Settings.System.CAR_UNDOCK_SOUND intentionally excluded since it's deprecated.
+ // Settings.System.LOCK_SOUND intentionally excluded since it's deprecated.
+ // Settings.System.UNLOCK_SOUND intentionally excluded since it's deprecated.
+ dumpSetting(s, p,
+ Settings.System.SYSTEM_LOCALES,
+ SystemSettingsProto.SYSTEM_LOCALES);
+
+ final long textToken = p.start(SystemSettingsProto.TEXT);
+ dumpSetting(s, p,
+ Settings.System.TEXT_AUTO_REPLACE,
+ SystemSettingsProto.Text.AUTO_REPLACE);
+ dumpSetting(s, p,
+ Settings.System.TEXT_AUTO_CAPS,
+ SystemSettingsProto.Text.AUTO_CAPS);
+ dumpSetting(s, p,
+ Settings.System.TEXT_AUTO_PUNCTUATE,
+ SystemSettingsProto.Text.AUTO_PUNCTUATE);
+ dumpSetting(s, p,
+ Settings.System.TEXT_SHOW_PASSWORD,
+ SystemSettingsProto.Text.SHOW_PASSWORD);
+ p.end(textToken);
+
+ // Settings.System.AUTO_TIME intentionally excluded since it's deprecated.
+ // Settings.System.AUTO_TIME_ZONE intentionally excluded since it's deprecated.
+ dumpSetting(s, p,
+ Settings.System.TIME_12_24,
+ SystemSettingsProto.TIME_12_24);
+ dumpSetting(s, p,
+ Settings.System.TTY_MODE,
+ SystemSettingsProto.TTY_MODE);
+
+ final long vibrateToken = p.start(SystemSettingsProto.VIBRATE);
+ dumpSetting(s, p,
+ Settings.System.VIBRATE_ON,
+ SystemSettingsProto.Vibrate.ON);
+ dumpSetting(s, p,
+ Settings.System.VIBRATE_INPUT_DEVICES,
+ SystemSettingsProto.Vibrate.INPUT_DEVICES);
+ dumpSetting(s, p,
+ Settings.System.VIBRATE_IN_SILENT,
+ SystemSettingsProto.Vibrate.IN_SILENT);
+ dumpSetting(s, p,
+ Settings.System.VIBRATE_WHEN_RINGING,
+ SystemSettingsProto.Vibrate.WHEN_RINGING);
+ p.end(vibrateToken);
+
+ final long volumeToken = p.start(SystemSettingsProto.VOLUME);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_RING,
+ SystemSettingsProto.Volume.RING);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_SYSTEM,
+ SystemSettingsProto.Volume.SYSTEM);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_VOICE,
+ SystemSettingsProto.Volume.VOICE);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_MUSIC,
+ SystemSettingsProto.Volume.MUSIC);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_ALARM,
+ SystemSettingsProto.Volume.ALARM);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_NOTIFICATION,
+ SystemSettingsProto.Volume.NOTIFICATION);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_BLUETOOTH_SCO,
+ SystemSettingsProto.Volume.BLUETOOTH_SCO);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_ACCESSIBILITY,
+ SystemSettingsProto.Volume.ACCESSIBILITY);
+ dumpSetting(s, p,
+ Settings.System.VOLUME_MASTER,
+ SystemSettingsProto.Volume.MASTER);
+ dumpSetting(s, p,
+ Settings.System.MASTER_MONO,
+ SystemSettingsProto.Volume.MASTER_MONO);
+ dumpSetting(s, p,
+ Settings.System.MODE_RINGER_STREAMS_AFFECTED,
+ SystemSettingsProto.Volume.MODE_RINGER_STREAMS_AFFECTED);
+ dumpSetting(s, p,
+ Settings.System.MUTE_STREAMS_AFFECTED,
+ SystemSettingsProto.Volume.MUTE_STREAMS_AFFECTED);
+ p.end(volumeToken);
+
+ dumpSetting(s, p,
+ Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
+ SystemSettingsProto.WHEN_TO_MAKE_WIFI_CALLS);
+
+ // Please insert new settings using the same order as in SecureSettingsProto.
+
+ // The rest of the settings were moved to Settings.Secure, and are thus excluded here since
+ // they're deprecated from Settings.System.
+
+ // Settings.System.STAY_ON_WHILE_PLUGGED_IN intentionally excluded since it's deprecated.
// Settings.System.AIRPLANE_MODE_ON intentionally excluded since it's deprecated.
// Settings.System.RADIO_BLUETOOTH intentionally excluded since it's just a constant.
// Settings.System.RADIO_WIFI intentionally excluded since it's just a constant.
@@ -2184,245 +2569,24 @@
// Settings.System.WIFI_STATIC_NETMASK intentionally excluded since it's deprecated.
// Settings.System.WIFI_STATIC_DNS1 intentionally excluded since it's deprecated.
// Settings.System.WIFI_STATIC_DNS2 intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.BLUETOOTH_DISCOVERABILITY,
- SystemSettingsProto.BLUETOOTH_DISCOVERABILITY);
- dumpSetting(s, p,
- Settings.System.BLUETOOTH_DISCOVERABILITY_TIMEOUT,
- SystemSettingsProto.BLUETOOTH_DISCOVERABILITY_TIMEOUT);
// Settings.System.LOCK_PATTERN_ENABLED intentionally excluded since it's deprecated.
// Settings.System.LOCK_PATTERN_VISIBLE intentionally excluded since it's deprecated.
// Settings.System.LOCK_PATTERN_TACTILE_FEEDBACK_ENABLED intentionally excluded since it's deprecated.
- // Settings.System.NEXT_ALARM_FORMATTED intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.FONT_SCALE,
- SystemSettingsProto.FONT_SCALE);
- dumpSetting(s, p,
- Settings.System.SYSTEM_LOCALES,
- SystemSettingsProto.SYSTEM_LOCALES);
// Settings.System.DEBUG_APP intentionally excluded since it's deprecated.
// Settings.System.WAIT_FOR_DEBUGGER intentionally excluded since it's deprecated.
// Settings.System.DIM_SCREEN intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.DISPLAY_COLOR_MODE,
- SystemSettingsProto.DISPLAY_COLOR_MODE);
- dumpSetting(s, p,
- Settings.System.SCREEN_OFF_TIMEOUT,
- SystemSettingsProto.SCREEN_OFF_TIMEOUT);
- dumpSetting(s, p,
- Settings.System.SCREEN_BRIGHTNESS,
- SystemSettingsProto.SCREEN_BRIGHTNESS);
- dumpSetting(s, p,
- Settings.System.SCREEN_BRIGHTNESS_FOR_VR,
- SystemSettingsProto.SCREEN_BRIGHTNESS_FOR_VR);
- dumpSetting(s, p,
- Settings.System.SCREEN_BRIGHTNESS_MODE,
- SystemSettingsProto.SCREEN_BRIGHTNESS_MODE);
- dumpSetting(s, p,
- Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
- SystemSettingsProto.SCREEN_AUTO_BRIGHTNESS_ADJ);
- // Settings.System.SHOW_PROCESSES intentionally excluded since it's deprecated.
// Settings.System.ALWAYS_FINISH_ACTIVITIES intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.MODE_RINGER_STREAMS_AFFECTED,
- SystemSettingsProto.MODE_RINGER_STREAMS_AFFECTED);
- dumpSetting(s, p,
- Settings.System.MUTE_STREAMS_AFFECTED,
- SystemSettingsProto.MUTE_STREAMS_AFFECTED);
- dumpSetting(s, p,
- Settings.System.VIBRATE_ON,
- SystemSettingsProto.VIBRATE_ON);
- dumpSetting(s, p,
- Settings.System.VIBRATE_INPUT_DEVICES,
- SystemSettingsProto.VIBRATE_INPUT_DEVICES);
- dumpSetting(s, p,
- Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
- SystemSettingsProto.NOTIFICATION_VIBRATION_INTENSITY);
- dumpSetting(s, p,
- Settings.System.HAPTIC_FEEDBACK_INTENSITY,
- SystemSettingsProto.HAPTIC_FEEDBACK_INTENSITY);
- dumpSetting(s, p,
- Settings.System.VOLUME_RING,
- SystemSettingsProto.VOLUME_RING);
- dumpSetting(s, p,
- Settings.System.VOLUME_SYSTEM,
- SystemSettingsProto.VOLUME_SYSTEM);
- dumpSetting(s, p,
- Settings.System.VOLUME_VOICE,
- SystemSettingsProto.VOLUME_VOICE);
- dumpSetting(s, p,
- Settings.System.VOLUME_MUSIC,
- SystemSettingsProto.VOLUME_MUSIC);
- dumpSetting(s, p,
- Settings.System.VOLUME_ALARM,
- SystemSettingsProto.VOLUME_ALARM);
- dumpSetting(s, p,
- Settings.System.VOLUME_NOTIFICATION,
- SystemSettingsProto.VOLUME_NOTIFICATION);
- dumpSetting(s, p,
- Settings.System.VOLUME_BLUETOOTH_SCO,
- SystemSettingsProto.VOLUME_BLUETOOTH_SCO);
- dumpSetting(s, p,
- Settings.System.VOLUME_ACCESSIBILITY,
- SystemSettingsProto.VOLUME_ACCESSIBILITY);
- dumpSetting(s, p,
- Settings.System.VOLUME_MASTER,
- SystemSettingsProto.VOLUME_MASTER);
- dumpSetting(s, p,
- Settings.System.MASTER_MONO,
- SystemSettingsProto.MASTER_MONO);
- // Settings.System.NOTIFICATIONS_USE_RING_VOLUME intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.VIBRATE_IN_SILENT,
- SystemSettingsProto.VIBRATE_IN_SILENT);
- dumpSetting(s, p,
- Settings.System.APPEND_FOR_LAST_AUDIBLE,
- SystemSettingsProto.APPEND_FOR_LAST_AUDIBLE);
- dumpSetting(s, p,
- Settings.System.RINGTONE,
- SystemSettingsProto.RINGTONE);
- dumpSetting(s, p,
- Settings.System.RINGTONE_CACHE,
- SystemSettingsProto.RINGTONE_CACHE);
- dumpSetting(s, p,
- Settings.System.NOTIFICATION_SOUND,
- SystemSettingsProto.NOTIFICATION_SOUND);
- dumpSetting(s, p,
- Settings.System.NOTIFICATION_SOUND_CACHE,
- SystemSettingsProto.NOTIFICATION_SOUND_CACHE);
- dumpSetting(s, p,
- Settings.System.ALARM_ALERT,
- SystemSettingsProto.ALARM_ALERT);
- dumpSetting(s, p,
- Settings.System.ALARM_ALERT_CACHE,
- SystemSettingsProto.ALARM_ALERT_CACHE);
- dumpSetting(s, p,
- Settings.System.MEDIA_BUTTON_RECEIVER,
- SystemSettingsProto.MEDIA_BUTTON_RECEIVER);
- dumpSetting(s, p,
- Settings.System.TEXT_AUTO_REPLACE,
- SystemSettingsProto.TEXT_AUTO_REPLACE);
- dumpSetting(s, p,
- Settings.System.TEXT_AUTO_CAPS,
- SystemSettingsProto.TEXT_AUTO_CAPS);
- dumpSetting(s, p,
- Settings.System.TEXT_AUTO_PUNCTUATE,
- SystemSettingsProto.TEXT_AUTO_PUNCTUATE);
- dumpSetting(s, p,
- Settings.System.TEXT_SHOW_PASSWORD,
- SystemSettingsProto.TEXT_SHOW_PASSWORD);
- dumpSetting(s, p,
- Settings.System.SHOW_GTALK_SERVICE_STATUS,
- SystemSettingsProto.SHOW_GTALK_SERVICE_STATUS);
+ // Settings.System.APPEND_FOR_LAST_AUDIBLE intentionally excluded since it hasn't been used since API 2.
// Settings.System.WALLPAPER_ACTIVITY intentionally excluded since it's deprecated.
- // Settings.System.AUTO_TIME intentionally excluded since it's deprecated.
- // Settings.System.AUTO_TIME_ZONE intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.TIME_12_24,
- SystemSettingsProto.TIME_12_24);
- dumpSetting(s, p,
- Settings.System.DATE_FORMAT,
- SystemSettingsProto.DATE_FORMAT);
- dumpSetting(s, p,
- Settings.System.SETUP_WIZARD_HAS_RUN,
- SystemSettingsProto.SETUP_WIZARD_HAS_RUN);
// Settings.System.WINDOW_ANIMATION_SCALE intentionally excluded since it's deprecated.
// Settings.System.TRANSITION_ANIMATION_SCALE intentionally excluded since it's deprecated.
// Settings.System.ANIMATOR_ANIMATION_SCALE intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.ACCELEROMETER_ROTATION,
- SystemSettingsProto.ACCELEROMETER_ROTATION);
- dumpSetting(s, p,
- Settings.System.USER_ROTATION,
- SystemSettingsProto.USER_ROTATION);
- dumpSetting(s, p,
- Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY,
- SystemSettingsProto.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY);
- dumpSetting(s, p,
- Settings.System.VIBRATE_WHEN_RINGING,
- SystemSettingsProto.VIBRATE_WHEN_RINGING);
- dumpSetting(s, p,
- Settings.System.DTMF_TONE_WHEN_DIALING,
- SystemSettingsProto.DTMF_TONE_WHEN_DIALING);
- dumpSetting(s, p,
- Settings.System.DTMF_TONE_TYPE_WHEN_DIALING,
- SystemSettingsProto.DTMF_TONE_TYPE_WHEN_DIALING);
- dumpSetting(s, p,
- Settings.System.HEARING_AID,
- SystemSettingsProto.HEARING_AID);
- dumpSetting(s, p,
- Settings.System.TTY_MODE,
- SystemSettingsProto.TTY_MODE);
- dumpSetting(s, p,
- Settings.System.RTT_CALLING_MODE,
- SystemSettingsProto.RTT_CALLING_MODE);
- dumpSetting(s, p,
- Settings.System.SOUND_EFFECTS_ENABLED,
- SystemSettingsProto.SOUND_EFFECTS_ENABLED);
- dumpSetting(s, p,
- Settings.System.HAPTIC_FEEDBACK_ENABLED,
- SystemSettingsProto.HAPTIC_FEEDBACK_ENABLED);
- // Settings.System.SHOW_WEB_SUGGESTIONS intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.NOTIFICATION_LIGHT_PULSE,
- SystemSettingsProto.NOTIFICATION_LIGHT_PULSE);
- dumpSetting(s, p,
- Settings.System.POINTER_LOCATION,
- SystemSettingsProto.POINTER_LOCATION);
- dumpSetting(s, p,
- Settings.System.SHOW_TOUCHES,
- SystemSettingsProto.SHOW_TOUCHES);
- dumpSetting(s, p,
- Settings.System.WINDOW_ORIENTATION_LISTENER_LOG,
- SystemSettingsProto.WINDOW_ORIENTATION_LISTENER_LOG);
- // Settings.System.POWER_SOUNDS_ENABLED intentionally excluded since it's deprecated.
- // Settings.System.DOCK_SOUNDS_ENABLED intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.LOCKSCREEN_SOUNDS_ENABLED,
- SystemSettingsProto.LOCKSCREEN_SOUNDS_ENABLED);
- dumpSetting(s, p,
- Settings.System.LOCKSCREEN_DISABLED,
- SystemSettingsProto.LOCKSCREEN_DISABLED);
- // Settings.System.LOW_BATTERY_SOUND intentionally excluded since it's deprecated.
- // Settings.System.DESK_DOCK_SOUND intentionally excluded since it's deprecated.
- // Settings.System.DESK_UNDOCK_SOUND intentionally excluded since it's deprecated.
- // Settings.System.CAR_DOCK_SOUND intentionally excluded since it's deprecated.
- // Settings.System.CAR_UNDOCK_SOUND intentionally excluded since it's deprecated.
- // Settings.System.LOCK_SOUND intentionally excluded since it's deprecated.
- // Settings.System.UNLOCK_SOUND intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.SIP_RECEIVE_CALLS,
- SystemSettingsProto.SIP_RECEIVE_CALLS);
- dumpSetting(s, p,
- Settings.System.SIP_CALL_OPTIONS,
- SystemSettingsProto.SIP_CALL_OPTIONS);
- dumpSetting(s, p,
- Settings.System.SIP_ALWAYS,
- SystemSettingsProto.SIP_ALWAYS);
- dumpSetting(s, p,
- Settings.System.SIP_ADDRESS_ONLY,
- SystemSettingsProto.SIP_ADDRESS_ONLY);
- // Settings.System.SIP_ASK_ME_EACH_TIME intentionally excluded since it's deprecated.
- dumpSetting(s, p,
- Settings.System.POINTER_SPEED,
- SystemSettingsProto.POINTER_SPEED);
- dumpSetting(s, p,
- Settings.System.LOCK_TO_APP_ENABLED,
- SystemSettingsProto.LOCK_TO_APP_ENABLED);
- dumpSetting(s, p,
- Settings.System.EGG_MODE,
- SystemSettingsProto.EGG_MODE);
- dumpSetting(s, p,
- Settings.System.SHOW_BATTERY_PERCENT,
- SystemSettingsProto.SHOW_BATTERY_PERCENT);
- dumpSetting(s, p,
- Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
- SystemSettingsProto.WHEN_TO_MAKE_WIFI_CALLS);
+
// The rest of the settings were moved to Settings.Secure, and are thus excluded here since
// they're deprecated from Settings.System.
- // Please insert new settings using the same order as in Settings.System.
-
+ // Please insert new settings using the same order as in SecureSettingsProto.
p.end(token);
+ // Please insert new settings using the same order as in SecureSettingsProto.
}
}
diff --git a/packages/SystemUI/res/layout/car_volume_dialog.xml b/packages/SystemUI/res/layout/car_volume_dialog.xml
index dca50a5..e45c0f9 100644
--- a/packages/SystemUI/res/layout/car_volume_dialog.xml
+++ b/packages/SystemUI/res/layout/car_volume_dialog.xml
@@ -24,7 +24,7 @@
android:clipChildren="false" >
<LinearLayout
android:id="@+id/volume_dialog"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top"
android:orientation="vertical"
@@ -53,14 +53,15 @@
android:layout_width="wrap_content"
android:layout_height="@dimen/car_single_line_list_item_height"
android:gravity="center"
- android:layout_marginEnd="@dimen/car_keyline_1">
- <ImageButton
+ android:layout_marginEnd="@dimen/car_keyline_1"
+ android:layout_gravity="end">
+ <com.android.keyguard.AlphaOptimizedImageButton
android:id="@+id/expand"
android:layout_gravity="center"
android:layout_width="@dimen/car_primary_icon_size"
android:layout_height="@dimen/car_primary_icon_size"
- android:layout_marginEnd="@dimen/car_keyline_1"
android:src="@drawable/car_ic_arrow_drop_up"
+ android:background="?android:attr/selectableItemBackground"
android:tint="@color/car_tint"
android:scaleType="fitCenter"
/>
diff --git a/packages/SystemUI/res/layout/car_volume_dialog_row.xml b/packages/SystemUI/res/layout/car_volume_dialog_row.xml
index 14baf49..33cecfa 100644
--- a/packages/SystemUI/res/layout/car_volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/car_volume_dialog_row.xml
@@ -33,13 +33,14 @@
android:layout_width="@dimen/car_primary_icon_size"
android:layout_height="@dimen/car_primary_icon_size"
android:layout_marginStart="@dimen/car_keyline_1"
+ android:background="?android:attr/selectableItemBackground"
android:tint="@color/car_tint"
android:scaleType="fitCenter"
android:soundEffectsEnabled="false" />
<SeekBar
android:id="@+id/volume_row_slider"
android:clickable="true"
- android:layout_marginStart="@dimen/car_keyline_3"
+ android:layout_marginStart="@dimen/car_keyline_1_keyline_3_diff"
android:layout_marginEnd="@dimen/car_keyline_3"
android:layout_width="match_parent"
android:layout_height="@dimen/car_single_line_list_item_height"/>
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index ea1ad2d1..ef18725 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -22,6 +22,7 @@
android:layout_width="match_parent"
android:layout_height="@dimen/qs_footer_height"
android:elevation="4dp"
+ android:background="@android:color/transparent"
android:baselineAligned="false"
android:clickable="false"
android:clipChildren="false"
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 1c9ce18..72ff653 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -56,9 +56,9 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/qs_footer_height"
android:elevation="4dp"
+ android:background="@android:color/transparent"
/>
-
<include layout="@layout/quick_status_bar_expanded_header" />
<include layout="@layout/qs_footer_impl" />
diff --git a/packages/SystemUI/res/layout/qs_tile_label.xml b/packages/SystemUI/res/layout/qs_tile_label.xml
index b138df0..74c22b0 100644
--- a/packages/SystemUI/res/layout/qs_tile_label.xml
+++ b/packages/SystemUI/res/layout/qs_tile_label.xml
@@ -44,7 +44,7 @@
android:maxLines="2"
android:padding="0dp"
android:gravity="center"
- android:ellipsize="end"
+ android:ellipsize="marquee"
android:textAppearance="@style/TextAppearance.QS.TileLabel"
android:textColor="?android:attr/textColorPrimary"/>
@@ -75,6 +75,7 @@
android:layout_alignEnd="@id/label_group"
android:layout_below="@id/label_group"
android:clickable="false"
+ android:ellipsize="marquee"
android:maxLines="1"
android:padding="0dp"
android:visibility="gone"
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index f38129f..388b633 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -31,25 +31,23 @@
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
- android:textAppearance="@style/TextAppearance.StatusBar.Clock"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:singleLine="true"
+ android:gravity="center_vertical|start"
android:paddingStart="@dimen/status_bar_left_clock_starting_padding"
android:paddingEnd="@dimen/status_bar_left_clock_end_padding"
- android:gravity="center_vertical|start"
- systemui:showDark="false"
- />
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.StatusBar.Clock"
+ systemui:showDark="false" />
<com.android.systemui.statusbar.policy.DateView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:padding="4dp"
+ android:gravity="center_vertical"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
android:textSize="@dimen/qs_time_collapsed_size"
- android:gravity="center_vertical"
systemui:datePattern="@string/abbrev_wday_month_day_no_year_alarm" />
<android.widget.Space
@@ -57,12 +55,11 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
- android:gravity="center_vertical|center_horizontal"
- />
+ android:gravity="center_vertical|center_horizontal" />
- <com.android.systemui.BatteryMeterView android:id="@+id/battery"
+ <com.android.systemui.BatteryMeterView
+ android:id="@+id/battery"
android:layout_height="match_parent"
android:layout_width="wrap_content"
- android:gravity="center_vertical|end"
- />
+ android:gravity="center_vertical|end" />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
similarity index 63%
rename from packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
rename to packages/SystemUI/res/layout/status_bar_notification_footer.xml
index 8dc4cb4..aa0d4a0 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_dismiss_all.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_footer.xml
@@ -15,13 +15,27 @@
-->
<!-- Extends Framelayout -->
-<com.android.systemui.statusbar.DismissView
+<com.android.systemui.statusbar.FooterView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="8dp"
android:visibility="gone">
- <com.android.systemui.statusbar.DismissViewButton
+ <FrameLayout
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <com.android.systemui.statusbar.FooterViewButton
+ style="@android:style/Widget.Material.Button.Borderless"
+ android:id="@+id/manage_text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="start"
+ android:focusable="true"
+ android:text="@string/manage_notifications_text"
+ android:textColor="?attr/wallpaperTextColor"
+ android:textAllCaps="false"/>
+ <com.android.systemui.statusbar.FooterViewButton
style="@android:style/Widget.Material.Button.Borderless"
android:id="@+id/dismiss_text"
android:layout_width="wrap_content"
@@ -32,4 +46,5 @@
android:text="@string/clear_all_notifications_text"
android:textColor="?attr/wallpaperTextColor"
android:textAllCaps="true"/>
-</com.android.systemui.statusbar.DismissView>
+ </FrameLayout>
+</com.android.systemui.statusbar.FooterView>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index e37ca1c..c59492f 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -24,6 +24,8 @@
<dimen name="brightness_mirror_height">96dp</dimen>
+ <!-- Width for the spacer, used between QS tiles. -->
+ <dimen name="qs_quick_tile_space_width">38dp</dimen>
<dimen name="qs_tile_margin_top">2dp</dimen>
<dimen name="qs_header_tooltip_height">24dp</dimen>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index f76603b..711d550 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -45,9 +45,6 @@
interface. This name is in the ComponentName flattened format (package/class) -->
<string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.StatusBar</string>
- <!-- Component name of launcher service for overview to connect to -->
- <string name="config_overviewServiceComponent" translatable="false">com.android.launcher3/com.android.quickstep.TouchInteractionService</string>
-
<!-- Whether or not we show the number in the bar. -->
<bool name="config_statusBarShowNumber">false</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index ff3f696..91c8724 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -317,6 +317,8 @@
<dimen name="qs_tile_margin_vertical">24dp</dimen>
<dimen name="qs_tile_margin_top">18dp</dimen>
<dimen name="qs_quick_tile_size">48dp</dimen>
+ <!-- Width for the spacer, used between QS tiles. -->
+ <dimen name="qs_quick_tile_space_width">0dp</dimen>
<dimen name="qs_quick_tile_padding">12dp</dimen>
<dimen name="qs_header_gear_translation">16dp</dimen>
<dimen name="qs_header_tile_margin_horizontal">0dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d3a55e8..8c00af6 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -191,16 +191,14 @@
<string name="screenshot_saving_ticker">Saving screenshot\u2026</string>
<!-- Notification title displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=50] -->
<string name="screenshot_saving_title">Saving screenshot\u2026</string>
- <!-- Notification text displayed when a screenshot is being saved to the Gallery. [CHAR LIMIT=100] -->
- <string name="screenshot_saving_text">Screenshot is being saved</string>
<!-- Notification title displayed when a screenshot is saved to the Gallery. [CHAR LIMIT=50] -->
<string name="screenshot_saved_title">Screenshot saved</string>
<!-- Notification text displayed when a screenshot is saved to the Gallery. [CHAR LIMIT=100] -->
<string name="screenshot_saved_text">Tap to view your screenshot</string>
<!-- Notification title displayed when we fail to take a screenshot. [CHAR LIMIT=50] -->
- <string name="screenshot_failed_title">Couldn\'t capture screenshot</string>
+ <string name="screenshot_failed_title">Couldn\'t save screenshot</string>
<!-- Notification text displayed when we fail to save a screenshot for unknown reasons. [CHAR LIMIT=100] -->
- <string name="screenshot_failed_to_save_unknown_text">Problem encountered while saving screenshot</string>
+ <string name="screenshot_failed_to_save_unknown_text">Try taking screenshot again</string>
<!-- Notification text displayed when we fail to save a screenshot. [CHAR LIMIT=100] -->
<string name="screenshot_failed_to_save_text">Can\'t save screenshot due to limited storage space</string>
<!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] -->
@@ -1055,6 +1053,9 @@
<!-- The text to clear all notifications. [CHAR LIMIT=60] -->
<string name="clear_all_notifications_text">Clear all</string>
+ <!-- The text for the manage notifications link. [CHAR LIMIT=40] -->
+ <string name="manage_notifications_text">Manage notifications</string>
+
<!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
<string name="dnd_suppressing_shade_text">Do Not disturb is hiding notifications</string>
@@ -2095,6 +2096,8 @@
<string name="notification_channel_general">General Messages</string>
<!-- Title for the notification channel for problems with storage (i.e. low disk). [CHAR LIMIT=NONE] -->
<string name="notification_channel_storage">Storage</string>
+ <!-- Title for the notification channel for hints and suggestions. [CHAR LIMIT=NONE] -->
+ <string name="notification_channel_hints">Hints</string>
<!-- App label of the instant apps notification [CHAR LIMIT=60] -->
<string name="instant_apps">Instant Apps</string>
@@ -2185,4 +2188,25 @@
<string-array name="recents_onboarding_blacklisted_packages" translatable="false">
</string-array>
+ <!-- The title of the notification to suggest enabling automatic battery saver. [CHAR LIMIT=NONE]-->
+ <string name="auto_saver_title">Tap to schedule Battery Saver</string>
+
+ <!-- The content of the notification to suggest enabling automatic battery saver. [CHAR LIMIT=NONE]-->
+ <string name="auto_saver_text">Turn on automatically when battery is at <xliff:g id="percentage">%d</xliff:g>%%</string>
+
+ <!-- An action on the notification to suggest enabling automatic battery saver: Do not turn on automatic battery saver. [CHAR LIMIT=NONE]-->
+ <string name="no_auto_saver_action">No thanks</string>
+
+ <!-- The title of the dialog that tells that scheduled (i.e. automatic) battery saver has been turned on. [CHAR LIMIT=NONE]-->
+ <string name="auto_saver_enabled_title">Battery Saver schedule turned on</string>
+
+ <!-- The content of the dialog that tells that scheduled (i.e. automatic) battery saver has been turned on. [CHAR LIMIT=NONE]-->
+ <string name="auto_saver_enabled_text">Battery Saver will turn on automatically once battery goes below <xliff:g id="percentage">%d</xliff:g>%%.</string>
+
+ <!-- An action on the dialog that tells that scheduled (i.e. automatic) battery saver: open the battery saver setting. [CHAR LIMIT=NONE]-->
+ <string name="open_saver_setting_action">Settings</string>
+
+ <!-- An action on the dialog that tells that scheduled (i.e. automatic) battery saver: user acknowledges and closes the dialog. [CHAR LIMIT=NONE]-->
+ <string name="auto_saver_okay_action">Got it</string>
+
</resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
index 14767f1..20d1418 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
@@ -106,11 +107,12 @@
return createDrawableFromBitmap(tdIcon, userId, desc);
}
if (desc.getIconResource() != 0) {
- // TODO: Use task context here
try {
- return createBadgedDrawable(
- mContext.getDrawable(desc.getIconResource()), userId, desc);
- } catch (Resources.NotFoundException e) {
+ Context packageContext = mContext.createPackageContextAsUser(
+ taskKey.getPackageName(), 0, UserHandle.of(userId));
+ return createBadgedDrawable(packageContext.getDrawable(desc.getIconResource()),
+ userId, desc);
+ } catch (Resources.NotFoundException|PackageManager.NameNotFoundException e) {
Log.e(TAG, "Could not find icon drawable from resource", e);
}
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
index 6bddbe0..6af89fc 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/Task.java
@@ -80,6 +80,13 @@
return this.baseIntent.getComponent();
}
+ public String getPackageName() {
+ if (this.baseIntent.getComponent() != null) {
+ return this.baseIntent.getComponent().getPackageName();
+ }
+ return this.baseIntent.getPackage();
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof TaskKey)) {
diff --git a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
index 1ae06d7..0683514 100644
--- a/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/BatteryMeterView.java
@@ -81,6 +81,14 @@
private float mDarkIntensity;
private int mUser;
+ /**
+ * Whether we should use colors that adapt based on wallpaper/the scrim behind quick settings.
+ */
+ private boolean mUseWallpaperTextColors;
+
+ private int mNonAdaptedForegroundColor;
+ private int mNonAdaptedBackgroundColor;
+
public BatteryMeterView(Context context) {
this(context, null, 0);
}
@@ -140,6 +148,29 @@
updateShowPercent();
}
+ /**
+ * Sets whether the battery meter view uses the wallpaperTextColor. If we're not using it, we'll
+ * revert back to dark-mode-based/tinted colors.
+ *
+ * @param shouldUseWallpaperTextColor whether we should use wallpaperTextColor for all
+ * components
+ */
+ public void useWallpaperTextColor(boolean shouldUseWallpaperTextColor) {
+ if (shouldUseWallpaperTextColor == mUseWallpaperTextColors) {
+ return;
+ }
+
+ mUseWallpaperTextColors = shouldUseWallpaperTextColor;
+
+ if (mUseWallpaperTextColors) {
+ updateColors(
+ Utils.getColorAttr(mContext, R.attr.wallpaperTextColor),
+ Utils.getColorAttr(mContext, R.attr.wallpaperTextColorSecondary));
+ } else {
+ updateColors(mNonAdaptedForegroundColor, mNonAdaptedBackgroundColor);
+ }
+ }
+
public void setColorsFromContext(Context context) {
if (context == null) {
return;
@@ -179,7 +210,8 @@
getContext().getContentResolver().registerContentObserver(
Settings.System.getUriFor(SHOW_BATTERY_PERCENT), false, mSettingObserver, mUser);
updateShowPercent();
- Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
+ Dependency.get(TunerService.class)
+ .addTunable(this, StatusBarIconController.ICON_BLACKLIST);
Dependency.get(ConfigurationController.class).addCallback(this);
mUserTracker.startTracking();
}
@@ -273,19 +305,23 @@
@Override
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
mDarkIntensity = darkIntensity;
+
float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0;
- int foreground = getColorForDarkIntensity(intensity, mLightModeFillColor,
- mDarkModeFillColor);
- int background = getColorForDarkIntensity(intensity, mLightModeBackgroundColor,
- mDarkModeBackgroundColor);
- mDrawable.setColors(foreground, background);
- setTextColor(foreground);
+ mNonAdaptedForegroundColor = getColorForDarkIntensity(
+ intensity, mLightModeFillColor, mDarkModeFillColor);
+ mNonAdaptedBackgroundColor = getColorForDarkIntensity(
+ intensity, mLightModeBackgroundColor,mDarkModeBackgroundColor);
+
+ if (!mUseWallpaperTextColors) {
+ updateColors(mNonAdaptedForegroundColor, mNonAdaptedBackgroundColor);
+ }
}
- public void setTextColor(int color) {
- mTextColor = color;
+ private void updateColors(int foregroundColor, int backgroundColor) {
+ mDrawable.setColors(foregroundColor, backgroundColor);
+ mTextColor = foregroundColor;
if (mBatteryPercentView != null) {
- mBatteryPercentView.setTextColor(color);
+ mBatteryPercentView.setTextColor(foregroundColor);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index a59c97e..a4f8d8c 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -24,11 +24,13 @@
import android.graphics.RectF;
import android.graphics.Region.Op;
import android.os.AsyncTask;
+import android.os.Handler;
import android.os.Trace;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.Display;
import android.view.DisplayInfo;
+import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.WindowManager;
@@ -45,6 +47,7 @@
private static final String GL_LOG_TAG = "ImageWallpaperGL";
private static final boolean DEBUG = false;
private static final String PROPERTY_KERNEL_QEMU = "ro.kernel.qemu";
+ private static final long DELAY_FORGET_WALLPAPER = 5000;
private WallpaperManager mWallpaperManager;
private DrawableEngine mEngine;
@@ -69,6 +72,10 @@
}
class DrawableEngine extends Engine {
+ private final Runnable mUnloadWallpaperCallback = () -> {
+ unloadWallpaper(false /* forgetSize */);
+ };
+
Bitmap mBackground;
int mBackgroundWidth = -1, mBackgroundHeight = -1;
int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1;
@@ -331,6 +338,7 @@
}
drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels);
+ scheduleUnloadWallpaper();
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIEW);
}
@@ -433,6 +441,9 @@
mBackgroundHeight = -1;
}
+ final Surface surface = getSurfaceHolder().getSurface();
+ surface.hwuiDestroy();
+
mLoader = new AsyncTask<Void, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(Void... params) {
@@ -442,6 +453,12 @@
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
+ private void scheduleUnloadWallpaper() {
+ Handler handler = getMainThreadHandler();
+ handler.removeCallbacks(mUnloadWallpaperCallback);
+ handler.postDelayed(mUnloadWallpaperCallback, DELAY_FORGET_WALLPAPER);
+ }
+
@Override
protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
super.dump(prefix, fd, out, args);
diff --git a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
index a4af6b2..2983df6 100644
--- a/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/OverviewProxyService.java
@@ -57,6 +57,8 @@
*/
public class OverviewProxyService implements CallbackController<OverviewProxyListener>, Dumpable {
+ private static final String ACTION_QUICKSTEP = "android.intent.action.QUICKSTEP_SERVICE";
+
public static final String TAG_OPS = "OverviewProxyService";
public static final boolean DEBUG_OVERVIEW_PROXY = false;
private static final long BACKOFF_MILLIS = 5000;
@@ -64,7 +66,7 @@
private final Context mContext;
private final Handler mHandler;
private final Runnable mConnectionRunnable = this::internalConnectToCurrentUser;
- private final ComponentName mLauncherComponentName;
+ private final ComponentName mRecentsComponentName;
private final DeviceProvisionedController mDeviceProvisionedController
= Dependency.get(DeviceProvisionedController.class);
private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
@@ -191,8 +193,8 @@
mContext = context;
mHandler = new Handler();
mConnectionBackoffAttempts = 0;
- mLauncherComponentName = ComponentName
- .unflattenFromString(context.getString(R.string.config_overviewServiceComponent));
+ mRecentsComponentName = ComponentName.unflattenFromString(context.getString(
+ com.android.internal.R.string.config_recentsComponentName));
// Listen for the package update changes.
if (SystemServicesProxy.getInstance(context)
@@ -200,7 +202,7 @@
mDeviceProvisionedController.addCallback(mDeviceProvisionedCallback);
IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
filter.addDataScheme("package");
- filter.addDataSchemeSpecificPart(mLauncherComponentName.getPackageName(),
+ filter.addDataSchemeSpecificPart(mRecentsComponentName.getPackageName(),
PatternMatcher.PATTERN_LITERAL);
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
mContext.registerReceiver(mLauncherAddedReceiver, filter);
@@ -223,8 +225,8 @@
return;
}
mHandler.removeCallbacks(mConnectionRunnable);
- Intent launcherServiceIntent = new Intent();
- launcherServiceIntent.setComponent(mLauncherComponentName);
+ Intent launcherServiceIntent = new Intent(ACTION_QUICKSTEP)
+ .setPackage(mRecentsComponentName.getPackageName());
boolean bound = mContext.bindServiceAsUser(launcherServiceIntent,
mOverviewServiceConnection, Context.BIND_AUTO_CREATE,
UserHandle.of(mDeviceProvisionedController.getCurrentUser()));
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 391843c..039e7b5 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -31,6 +31,7 @@
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.statusbar.KeyguardIndicationController;
+import com.android.systemui.statusbar.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.NotificationEntryManager;
import com.android.systemui.statusbar.NotificationGutsManager;
import com.android.systemui.statusbar.NotificationListener;
@@ -130,6 +131,8 @@
providers.put(NotificationGroupManager.class, NotificationGroupManager::new);
providers.put(NotificationMediaManager.class, () -> new NotificationMediaManager(context));
providers.put(NotificationGutsManager.class, () -> new NotificationGutsManager(context));
+ providers.put(NotificationBlockingHelperManager.class,
+ () -> new NotificationBlockingHelperManager(context));
providers.put(NotificationRemoteInputManager.class,
() -> new NotificationRemoteInputManager(context));
providers.put(SmartReplyConstants.class,
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
index 4b15fbc..f2eea26 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogImpl.java
@@ -147,6 +147,9 @@
private void handleFingerprintAuthenticated() {
if (DEBUG) Log.d(TAG, "handleFingerprintAuthenticated");
+ mDialogView.announceForAccessibility(
+ mContext.getResources().getText(
+ com.android.internal.R.string.fingerprint_authenticated));
handleHideDialog(false /* userCanceled */);
}
diff --git a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
index ebdc703..05906f7 100644
--- a/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/fingerprint/FingerprintDialogView.java
@@ -55,7 +55,8 @@
private static final String TAG = "FingerprintDialogView";
- private static final int ANIMATION_DURATION = 250; // ms
+ private static final int ANIMATION_DURATION_SHOW = 250; // ms
+ private static final int ANIMATION_DURATION_AWAY = 350; // ms
private static final int STATE_NONE = 0;
private static final int STATE_FINGERPRINT = 1;
@@ -164,8 +165,23 @@
title.setText(mBundle.getCharSequence(FingerprintDialog.KEY_TITLE));
title.setSelected(true);
- subtitle.setText(mBundle.getCharSequence(FingerprintDialog.KEY_SUBTITLE));
- description.setText(mBundle.getCharSequence(FingerprintDialog.KEY_DESCRIPTION));
+
+ final CharSequence subtitleText = mBundle.getCharSequence(FingerprintDialog.KEY_SUBTITLE);
+ if (subtitleText == null) {
+ subtitle.setVisibility(View.GONE);
+ } else {
+ subtitle.setVisibility(View.VISIBLE);
+ subtitle.setText(subtitleText);
+ }
+
+ final CharSequence descriptionText = mBundle.getCharSequence(FingerprintDialog.KEY_DESCRIPTION);
+ if (descriptionText == null) {
+ subtitle.setVisibility(View.VISIBLE);
+ description.setVisibility(View.GONE);
+ } else {
+ description.setText(mBundle.getCharSequence(FingerprintDialog.KEY_DESCRIPTION));
+ }
+
negative.setText(mBundle.getCharSequence(FingerprintDialog.KEY_NEGATIVE_TEXT));
final CharSequence positiveText =
@@ -185,13 +201,13 @@
public void run() {
mLayout.animate()
.alpha(1f)
- .setDuration(ANIMATION_DURATION)
+ .setDuration(ANIMATION_DURATION_SHOW)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.start();
mDialog.animate()
.translationY(0)
- .setDuration(ANIMATION_DURATION)
+ .setDuration(ANIMATION_DURATION_SHOW)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.start();
@@ -221,13 +237,13 @@
public void run() {
mLayout.animate()
.alpha(0f)
- .setDuration(ANIMATION_DURATION)
+ .setDuration(ANIMATION_DURATION_AWAY)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.start();
mDialog.animate()
.translationY(mAnimationTranslationOffset)
- .setDuration(ANIMATION_DURATION)
+ .setDuration(ANIMATION_DURATION_AWAY)
.setInterpolator(mLinearOutSlowIn)
.withLayer()
.withEndAction(endActionRunnable)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index a1b17e4..d6e59c7 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -27,7 +27,6 @@
import android.app.ActivityManager;
import android.app.AlarmManager;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.StatusBarManager;
import android.app.trust.TrustManager;
@@ -235,6 +234,9 @@
// answer whether the input should be restricted)
private boolean mShowing;
+ // AOD is enabled and status bar is in AOD state.
+ private boolean mAodShowing;
+
// display id of the secondary display on which we have put a keyguard window
private int mSecondaryDisplayShowing = INVALID_DISPLAY;
@@ -664,7 +666,7 @@
@Override
public void onSecondaryDisplayShowingChanged(int displayId) {
synchronized (KeyguardViewMediator.this) {
- setShowingLocked(mShowing, displayId, false);
+ setShowingLocked(mShowing, mAodShowing, displayId, false);
}
}
};
@@ -707,10 +709,10 @@
setShowingLocked(!shouldWaitForProvisioning()
&& !mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser()),
- mSecondaryDisplayShowing, true /* forceCallbacks */);
+ mAodShowing, mSecondaryDisplayShowing, true /* forceCallbacks */);
} else {
// The system's keyguard is disabled or missing.
- setShowingLocked(false, mSecondaryDisplayShowing, true);
+ setShowingLocked(false, mAodShowing, mSecondaryDisplayShowing, true);
}
mStatusBarKeyguardViewManager =
@@ -1311,7 +1313,7 @@
if (mLockPatternUtils.checkVoldPassword(KeyguardUpdateMonitor.getCurrentUser())) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
- setShowingLocked(false);
+ setShowingLocked(false, mAodShowing);
hideLocked();
return;
}
@@ -1713,10 +1715,12 @@
playSound(mTrustedSoundId);
}
- private void updateActivityLockScreenState(boolean showing, int secondaryDisplayShowing) {
+ private void updateActivityLockScreenState(boolean showing, boolean aodShowing,
+ int secondaryDisplayShowing) {
mUiOffloadThread.submit(() -> {
try {
- ActivityManager.getService().setLockScreenShown(showing, secondaryDisplayShowing);
+ ActivityManager.getService().setLockScreenShown(showing, aodShowing,
+ secondaryDisplayShowing);
} catch (RemoteException e) {
}
});
@@ -1740,7 +1744,7 @@
if (DEBUG) Log.d(TAG, "handleShow");
}
- setShowingLocked(true);
+ setShowingLocked(true, mAodShowing);
mStatusBarKeyguardViewManager.show(options);
mHiding = false;
mWakeAndUnlocking = false;
@@ -1849,7 +1853,7 @@
}
mWakeAndUnlocking = false;
- setShowingLocked(false);
+ setShowingLocked(false, mAodShowing);
mDismissCallbackRegistry.notifyDismissSucceeded();
mStatusBarKeyguardViewManager.hide(startTime, fadeoutDuration);
resetKeyguardDonePendingLocked();
@@ -1909,7 +1913,7 @@
Trace.beginSection("KeyguardViewMediator#handleVerifyUnlock");
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleVerifyUnlock");
- setShowingLocked(true);
+ setShowingLocked(true, mAodShowing);
mStatusBarKeyguardViewManager.dismissAndCollapse();
}
Trace.endSection();
@@ -2064,6 +2068,10 @@
pw.print(" mDrawnCallback: "); pw.println(mDrawnCallback);
}
+ public void setAodShowing(boolean aodShowing) {
+ setShowingLocked(mShowing, aodShowing);
+ }
+
private static class StartKeyguardExitAnimParams {
long startTime;
@@ -2075,20 +2083,23 @@
}
}
- private void setShowingLocked(boolean showing) {
- setShowingLocked(showing, mSecondaryDisplayShowing, false /* forceCallbacks */);
+ private void setShowingLocked(boolean showing, boolean aodShowing) {
+ setShowingLocked(showing, aodShowing, mSecondaryDisplayShowing,
+ false /* forceCallbacks */);
}
- private void setShowingLocked(
- boolean showing, int secondaryDisplayShowing, boolean forceCallbacks) {
- final boolean notifyDefaultDisplayCallbacks = showing != mShowing || forceCallbacks;
+ private void setShowingLocked(boolean showing, boolean aodShowing, int secondaryDisplayShowing,
+ boolean forceCallbacks) {
+ final boolean notifyDefaultDisplayCallbacks = showing != mShowing
+ || aodShowing != mAodShowing || forceCallbacks;
if (notifyDefaultDisplayCallbacks || secondaryDisplayShowing != mSecondaryDisplayShowing) {
mShowing = showing;
+ mAodShowing = aodShowing;
mSecondaryDisplayShowing = secondaryDisplayShowing;
if (notifyDefaultDisplayCallbacks) {
notifyDefaultDisplayCallbacks(showing);
}
- updateActivityLockScreenState(showing, secondaryDisplayShowing);
+ updateActivityLockScreenState(showing, aodShowing, secondaryDisplayShowing);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index 8d93157..49b00ce 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -21,9 +21,6 @@
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioAttributes;
@@ -52,15 +49,18 @@
private static final String TAG_BATTERY = "low_battery";
private static final String TAG_TEMPERATURE = "high_temp";
+ private static final String TAG_AUTO_SAVER = "auto_saver";
private static final int SHOWING_NOTHING = 0;
private static final int SHOWING_WARNING = 1;
private static final int SHOWING_INVALID_CHARGER = 3;
+ private static final int SHOWING_AUTO_SAVER_SUGGESTION = 4;
private static final String[] SHOWING_STRINGS = {
"SHOWING_NOTHING",
"SHOWING_WARNING",
"SHOWING_SAVER",
"SHOWING_INVALID_CHARGER",
+ "SHOWING_AUTO_SAVER_SUGGESTION",
};
private static final String ACTION_SHOW_BATTERY_SETTINGS = "PNW.batterySettings";
@@ -74,6 +74,18 @@
"PNW.dismissedThermalShutdownWarning";
private static final String ACTION_SHOW_START_SAVER_CONFIRMATION =
BatterySaverUtils.ACTION_SHOW_START_SAVER_CONFIRMATION;
+ private static final String ACTION_SHOW_AUTO_SAVER_SUGGESTION =
+ BatterySaverUtils.ACTION_SHOW_AUTO_SAVER_SUGGESTION;
+ private static final String ACTION_DISMISS_AUTO_SAVER_SUGGESTION =
+ "PNW.dismissAutoSaverSuggestion";
+
+ private static final String ACTION_ENABLE_AUTO_SAVER =
+ "PNW.enableAutoSaver";
+ private static final String ACTION_AUTO_SAVER_NO_THANKS =
+ "PNW.autoSaverNoThanks";
+
+ private static final String SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING =
+ "android.settings.BATTERY_SAVER_SETTINGS";
private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
@@ -98,9 +110,11 @@
private long mLowWarningThreshold;
private long mSevereWarningThreshold;
private boolean mWarning;
+ private boolean mShowAutoSaverSuggestion;
private boolean mPlaySound;
private boolean mInvalidCharger;
private SystemUIDialog mSaverConfirmation;
+ private SystemUIDialog mSaverEnabledConfirmation;
private boolean mHighTempWarning;
private SystemUIDialog mHighTempDialog;
private SystemUIDialog mThermalShutdownDialog;
@@ -119,12 +133,19 @@
pw.print("mInvalidCharger="); pw.println(mInvalidCharger);
pw.print("mShowing="); pw.println(SHOWING_STRINGS[mShowing]);
pw.print("mSaverConfirmation="); pw.println(mSaverConfirmation != null ? "not null" : null);
+ pw.print("mSaverEnabledConfirmation=");
+ pw.println(mSaverEnabledConfirmation != null ? "not null" : null);
pw.print("mHighTempWarning="); pw.println(mHighTempWarning);
pw.print("mHighTempDialog="); pw.println(mHighTempDialog != null ? "not null" : null);
pw.print("mThermalShutdownDialog=");
pw.println(mThermalShutdownDialog != null ? "not null" : null);
}
+ private int getLowBatteryAutoTriggerDefaultLevel() {
+ return mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryAutoTriggerDefaultLevel);
+ }
+
@Override
public void update(int batteryLevel, int bucket, long screenOffTime) {
mBatteryLevel = batteryLevel;
@@ -151,7 +172,6 @@
mSevereWarningThreshold = severeThreshold;
}
-
private void updateNotification() {
if (DEBUG) Slog.d(TAG, "updateNotification mWarning=" + mWarning + " mPlaySound="
+ mPlaySound + " mInvalidCharger=" + mInvalidCharger);
@@ -161,9 +181,14 @@
} else if (mWarning) {
showWarningNotification();
mShowing = SHOWING_WARNING;
+ } else if (mShowAutoSaverSuggestion) {
+ showAutoSaverSuggestionNotification();
+ mShowing = SHOWING_AUTO_SAVER_SUGGESTION;
} else {
mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_BAD_CHARGER, UserHandle.ALL);
mNoMan.cancelAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, UserHandle.ALL);
+ mNoMan.cancelAsUser(TAG_AUTO_SAVER,
+ SystemMessage.NOTE_AUTO_SAVER_SUGGESTION, UserHandle.ALL);
mShowing = SHOWING_NOTHING;
}
}
@@ -229,6 +254,28 @@
mNoMan.notifyAsUser(TAG_BATTERY, SystemMessage.NOTE_POWER_LOW, n, UserHandle.ALL);
}
+ private void showAutoSaverSuggestionNotification() {
+ final Notification.Builder nb =
+ new Notification.Builder(mContext, NotificationChannels.HINTS)
+ .setSmallIcon(R.drawable.ic_power_saver)
+ .setWhen(0)
+ .setShowWhen(false)
+ .setContentTitle(mContext.getString(R.string.auto_saver_title))
+ .setContentText(mContext.getString(R.string.auto_saver_text,
+ getLowBatteryAutoTriggerDefaultLevel()));
+ nb.setContentIntent(pendingBroadcast(ACTION_ENABLE_AUTO_SAVER));
+ nb.setDeleteIntent(pendingBroadcast(ACTION_DISMISS_AUTO_SAVER_SUGGESTION));
+ nb.addAction(0,
+ mContext.getString(R.string.no_auto_saver_action),
+ pendingBroadcast(ACTION_AUTO_SAVER_NO_THANKS));
+
+ SystemUI.overrideNotificationAppName(mContext, nb, false);
+
+ final Notification n = nb.build();
+ mNoMan.notifyAsUser(
+ TAG_AUTO_SAVER, SystemMessage.NOTE_AUTO_SAVER_SUGGESTION, n, UserHandle.ALL);
+ }
+
private String getHybridContentString(String percentage) {
return PowerUtil.getBatteryRemainingStringFormatted(
mContext,
@@ -238,8 +285,8 @@
}
private PendingIntent pendingBroadcast(String action) {
- return PendingIntent.getBroadcastAsUser(mContext,
- 0, new Intent(action), 0, UserHandle.CURRENT);
+ return PendingIntent.getBroadcastAsUser(mContext, 0,
+ new Intent(action).setPackage(mContext.getPackageName()), 0, UserHandle.CURRENT);
}
private static Intent settings(String action) {
@@ -394,6 +441,16 @@
updateNotification();
}
+ private void showAutoSaverSuggestion() {
+ mShowAutoSaverSuggestion = true;
+ updateNotification();
+ }
+
+ private void dismissAutoSaverSuggestion() {
+ mShowAutoSaverSuggestion = false;
+ updateNotification();
+ }
+
@Override
public void userSwitched() {
updateNotification();
@@ -405,22 +462,53 @@
d.setTitle(R.string.battery_saver_confirmation_title);
d.setMessage(com.android.internal.R.string.battery_saver_description);
d.setNegativeButton(android.R.string.cancel, null);
- d.setPositiveButton(R.string.battery_saver_confirmation_ok, mStartSaverModeNoConfirmation);
+ d.setPositiveButton(R.string.battery_saver_confirmation_ok,
+ (dialog, which) -> setSaverMode(true, false));
d.setShowForAllUsers(true);
- d.setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- mSaverConfirmation = null;
- }
- });
+ d.setOnDismissListener((dialog) -> mSaverConfirmation = null);
d.show();
mSaverConfirmation = d;
}
+ private void showAutoSaverEnabledConfirmation() {
+ if (mSaverEnabledConfirmation != null) return;
+
+ // Open the Battery Saver setting page.
+ final Intent actionBatterySaverSetting =
+ new Intent(SETTINGS_ACTION_OPEN_BATTERY_SAVER_SETTING)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+ final SystemUIDialog d = new SystemUIDialog(mContext);
+ d.setTitle(R.string.auto_saver_enabled_title);
+ d.setMessage(mContext.getString(R.string.auto_saver_enabled_text,
+ getLowBatteryAutoTriggerDefaultLevel()));
+
+ // Negative == "got it". Just close the dialog. Battery saver has already been enabled.
+ d.setNegativeButton(R.string.auto_saver_okay_action, null);
+ d.setPositiveButton(R.string.open_saver_setting_action, (dialog, which) ->
+ mContext.startActivity(actionBatterySaverSetting));
+ d.setShowForAllUsers(true);
+ d.setOnDismissListener((dialog) -> mSaverEnabledConfirmation = null);
+ d.show();
+ mSaverEnabledConfirmation = d;
+ }
+
+
private void setSaverMode(boolean mode, boolean needFirstTimeWarning) {
BatterySaverUtils.setPowerSaveMode(mContext, mode, needFirstTimeWarning);
}
+ private void scheduleAutoBatterySaver() {
+ int autoTriggerThreshold = mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryWarningLevel);
+ if (autoTriggerThreshold == 0) {
+ autoTriggerThreshold = 15;
+ }
+
+ BatterySaverUtils.scheduleAutoBatterySaver(mContext, autoTriggerThreshold);
+ showAutoSaverEnabledConfirmation();
+ }
+
private final class Receiver extends BroadcastReceiver {
public void init() {
@@ -433,6 +521,9 @@
filter.addAction(ACTION_CLICKED_THERMAL_SHUTDOWN_WARNING);
filter.addAction(ACTION_DISMISSED_THERMAL_SHUTDOWN_WARNING);
filter.addAction(ACTION_SHOW_START_SAVER_CONFIRMATION);
+ filter.addAction(ACTION_SHOW_AUTO_SAVER_SUGGESTION);
+ filter.addAction(ACTION_ENABLE_AUTO_SAVER);
+ filter.addAction(ACTION_AUTO_SAVER_NO_THANKS);
mContext.registerReceiverAsUser(this, UserHandle.ALL, filter,
android.Manifest.permission.DEVICE_POWER, mHandler);
}
@@ -462,10 +553,17 @@
showThermalShutdownDialog();
} else if (ACTION_DISMISSED_THERMAL_SHUTDOWN_WARNING.equals(action)) {
dismissThermalShutdownWarning();
+ } else if (ACTION_SHOW_AUTO_SAVER_SUGGESTION.equals(action)) {
+ showAutoSaverSuggestion();
+ } else if (ACTION_DISMISS_AUTO_SAVER_SUGGESTION.equals(action)) {
+ dismissAutoSaverSuggestion();
+ } else if (ACTION_ENABLE_AUTO_SAVER.equals(action)) {
+ dismissAutoSaverSuggestion();
+ scheduleAutoBatterySaver();
+ } else if (ACTION_AUTO_SAVER_NO_THANKS.equals(action)) {
+ dismissAutoSaverSuggestion();
+ BatterySaverUtils.suppressAutoBatterySaver(context);
}
}
}
-
- private final OnClickListener mStartSaverModeNoConfirmation =
- (dialog, which) -> setSaverMode(true, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index bfbfbf6..7161463 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -18,17 +18,15 @@
import android.content.Context;
import android.content.res.Configuration;
-import android.graphics.Canvas;
-import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.qs.customize.QSCustomizer;
-import com.android.systemui.statusbar.ExpandableOutlineView;
/**
* Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader}
@@ -44,7 +42,11 @@
protected float mQsExpansion;
private QSCustomizer mQSCustomizer;
private View mQSFooter;
+
private View mBackground;
+ private View mBackgroundGradient;
+ private View mStatusBarBackground;
+
private int mSideMargins;
public QSContainerImpl(Context context, AttributeSet attrs) {
@@ -60,6 +62,8 @@
mQSCustomizer = findViewById(R.id.qs_customize);
mQSFooter = findViewById(R.id.qs_footer);
mBackground = findViewById(R.id.quick_settings_background);
+ mStatusBarBackground = findViewById(R.id.quick_settings_status_bar_background);
+ mBackgroundGradient = findViewById(R.id.quick_settings_gradient_view);
mSideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
setClickable(true);
@@ -68,6 +72,22 @@
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ // Hide the backgrounds when in landscape mode.
+ if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ mBackgroundGradient.setVisibility(View.INVISIBLE);
+ mStatusBarBackground.setVisibility(View.INVISIBLE);
+ } else {
+ mBackgroundGradient.setVisibility(View.VISIBLE);
+ mStatusBarBackground.setVisibility(View.VISIBLE);
+ }
+
+ updateResources();
+ }
+
+ @Override
public boolean performClick() {
// Want to receive clicks so missing QQS tiles doesn't cause collapse, but
// don't want to do anything with them.
@@ -101,6 +121,14 @@
updateExpansion();
}
+ private void updateResources() {
+ LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams();
+ layoutParams.topMargin = mContext.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.quick_qs_offset_height);
+
+ mQSPanel.setLayoutParams(layoutParams);
+ }
+
/**
* Overrides the height of this view (post-layout), so that the content is clipped to that
* height and the background is set to that height.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 2270b60..c9c04d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -17,6 +17,7 @@
package com.android.systemui.qs;
import android.content.Context;
+import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -179,16 +180,56 @@
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
private boolean mListening;
+ /** Size of the QS tile (width & height). */
+ private int mTileDimensionSize;
public HeaderTileLayout(Context context) {
super(context);
setClipChildren(false);
setClipToPadding(false);
- setGravity(Gravity.CENTER_VERTICAL);
+
+ mTileDimensionSize = mContext.getResources().getDimensionPixelSize(
+ R.dimen.qs_quick_tile_size);
+
+ setGravity(Gravity.CENTER);
setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ setGravity(Gravity.CENTER);
+ LayoutParams staticSpaceLayoutParams = generateSpaceLayoutParams(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.qs_quick_tile_space_width));
+
+ // Update space params since they fill any open space in portrait orientation and have
+ // a static width in landscape orientation.
+ final int childViewCount = getChildCount();
+ for (int i = 0; i < childViewCount; i++) {
+ View childView = getChildAt(i);
+ if (childView instanceof Space) {
+ childView.setLayoutParams(staticSpaceLayoutParams);
+ }
+ }
+ }
+
+ /**
+ * Returns {@link LayoutParams} based on the given {@code spaceWidth}. If the width is 0,
+ * then we're going to have the space expand to take up as much space as possible. If the
+ * width is non-zero, we want the inter-tile spacers to be fixed.
+ */
+ private LayoutParams generateSpaceLayoutParams(int spaceWidth) {
+ LayoutParams lp = new LayoutParams(spaceWidth, mTileDimensionSize);
+ if (spaceWidth == 0) {
+ lp.weight = 1;
+ }
+ lp.gravity = Gravity.CENTER;
+ return lp;
+ }
+
+ @Override
public void setListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
@@ -200,25 +241,22 @@
@Override
public void addTile(TileRecord tile) {
if (getChildCount() != 0) {
- // Add a spacer.
- addView(new Space(mContext), getChildCount(), generateSpaceParams());
+ // Add a spacer between tiles. We want static-width spaces if we're in landscape to
+ // keep the tiles close. For portrait, we stick with spaces that fill up any
+ // available space.
+ LayoutParams spaceLayoutParams = generateSpaceLayoutParams(
+ mContext.getResources().getDimensionPixelSize(
+ R.dimen.qs_quick_tile_space_width));
+ addView(new Space(mContext), getChildCount(), spaceLayoutParams);
}
- addView(tile.tileView, getChildCount(), generateLayoutParams());
+
+ addView(tile.tileView, getChildCount(), generateTileLayoutParams());
mRecords.add(tile);
tile.tile.setListening(this, mListening);
}
- private LayoutParams generateSpaceParams() {
- int size = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
- LayoutParams lp = new LayoutParams(0, size);
- lp.weight = 1;
- lp.gravity = Gravity.CENTER;
- return lp;
- }
-
- private LayoutParams generateLayoutParams() {
- int size = mContext.getResources().getDimensionPixelSize(R.dimen.qs_quick_tile_size);
- LayoutParams lp = new LayoutParams(size, size);
+ private LayoutParams generateTileLayoutParams() {
+ LayoutParams lp = new LayoutParams(mTileDimensionSize, mTileDimensionSize);
lp.gravity = Gravity.CENTER;
return lp;
}
@@ -237,8 +275,8 @@
}
private int getChildIndex(QSTileView tileView) {
- final int N = getChildCount();
- for (int i = 0; i < N; i++) {
+ final int childViewCount = getChildCount();
+ for (int i = 0; i < childViewCount; i++) {
if (getChildAt(i) == tileView) {
return i;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 9792e41..eb779a5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -24,6 +24,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
import android.os.Handler;
@@ -52,8 +53,10 @@
import com.android.systemui.statusbar.phone.PhoneStatusBarView;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarIconController.TintedIconManager;
+import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.DarkIconDispatcher;
import com.android.systemui.statusbar.policy.DarkIconDispatcher.DarkReceiver;
+import com.android.systemui.statusbar.policy.DateView;
import com.android.systemui.statusbar.policy.NextAlarmController;
import java.util.Locale;
@@ -88,6 +91,7 @@
private TouchAnimator mStatusIconsAlphaAnimator;
private TouchAnimator mHeaderTextContainerAlphaAnimator;
+ private View mSystemIconsView;
private View mQuickQsStatusIcons;
private View mDate;
private View mHeaderTextContainerView;
@@ -97,6 +101,9 @@
private View mLongPressTooltipView;
/** {@link TextView} containing the actual text indicating when the next alarm will go off. */
private TextView mNextAlarmTextView;
+ private BatteryMeterView mBatteryMeterView;
+ private Clock mClockView;
+ private DateView mDateView;
private NextAlarmController mAlarmController;
private String mNextAlarmText;
@@ -122,6 +129,7 @@
mHeaderQsPanel = findViewById(R.id.quick_qs_panel);
mDate = findViewById(R.id.date);
mDate.setOnClickListener(this);
+ mSystemIconsView = findViewById(R.id.quick_status_bar_system_icons);
mQuickQsStatusIcons = findViewById(R.id.quick_qs_status_icons);
mIconManager = new TintedIconManager(findViewById(R.id.statusIcons));
@@ -145,8 +153,10 @@
// Set the correct tint for the status icons so they contrast
mIconManager.setTint(fillColor);
- BatteryMeterView battery = findViewById(R.id.battery);
- battery.setForceShowPercent(true);
+ mBatteryMeterView = findViewById(R.id.battery);
+ mBatteryMeterView.setForceShowPercent(true);
+ mClockView = findViewById(R.id.clock);
+ mDateView = findViewById(R.id.date);
}
private void applyDarkness(int id, Rect tintArea, float intensity, int color) {
@@ -167,6 +177,13 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateResources();
+
+ // Update color schemes in landscape to use wallpaperTextColor
+ boolean shouldUseWallpaperTextColor =
+ newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE;
+ mBatteryMeterView.useWallpaperTextColor(shouldUseWallpaperTextColor);
+ mClockView.useWallpaperTextColor(shouldUseWallpaperTextColor);
+ mDateView.useWallpaperTextColor(shouldUseWallpaperTextColor);
}
@Override
@@ -176,11 +193,21 @@
}
private void updateResources() {
- // Update height, especially due to landscape mode restricting space.
+ Resources resources = mContext.getResources();
+
+ // Update height for a few views, especially due to landscape mode restricting space.
mHeaderTextContainerView.getLayoutParams().height =
- mContext.getResources().getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
+ resources.getDimensionPixelSize(R.dimen.qs_header_tooltip_height);
mHeaderTextContainerView.setLayoutParams(mHeaderTextContainerView.getLayoutParams());
+ mSystemIconsView.getLayoutParams().height = resources.getDimensionPixelSize(
+ com.android.internal.R.dimen.quick_qs_offset_height);
+ mSystemIconsView.setLayoutParams(mSystemIconsView.getLayoutParams());
+
+ getLayoutParams().height =
+ resources.getDimensionPixelSize(com.android.internal.R.dimen.quick_qs_total_height);
+ setLayoutParams(getLayoutParams());
+
updateStatusIconAlphaAnimator();
updateHeaderTextContainerAlphaAnimator();
}
@@ -449,9 +476,8 @@
mHeaderQsPanel.setHost(host, null /* No customization in header */);
// Use SystemUI context to get battery meter colors, and let it use the default tint (white)
- BatteryMeterView battery = findViewById(R.id.battery);
- battery.setColorsFromContext(mHost.getContext());
- battery.onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
+ mBatteryMeterView.setColorsFromContext(mHost.getContext());
+ mBatteryMeterView.onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
}
public void setCallback(Callback qsPanelCallback) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
index c9c678c..a9defc8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileBaseView.java
@@ -15,7 +15,6 @@
import static com.android.systemui.qs.tileimpl.QSIconViewImpl.QS_ANIM_LENGTH;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
@@ -122,14 +121,14 @@
private void setRipple(RippleDrawable tileBackground) {
mRipple = tileBackground;
if (getWidth() != 0) {
- updateRippleSize(getWidth(), getHeight());
+ updateRippleSize();
}
}
- private void updateRippleSize(int width, int height) {
+ private void updateRippleSize() {
// center the touch feedback on the center of the icon, and dial it down a bit
- final int cx = width / 2;
- final int cy = mIconFrame.getMeasuredHeight() / 2;
+ final int cx = mIconFrame.getMeasuredWidth() / 2 + mIconFrame.getLeft();
+ final int cy = mIconFrame.getMeasuredHeight() / 2 + mIconFrame.getTop();
final int rad = (int) (mIcon.getHeight() * .85f);
mRipple.setHotspotBounds(cx - rad, cy - rad, cx + rad, cy + rad);
}
@@ -151,11 +150,8 @@
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- final int w = getMeasuredWidth();
- final int h = getMeasuredHeight();
-
if (mRipple != null) {
- updateRippleSize(w, h);
+ updateRippleSize();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
index 4774785..3cb4c71 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileView.java
@@ -32,11 +32,12 @@
import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile;
+
import java.util.Objects;
/** View that represents a standard quick settings tile. **/
public class QSTileView extends QSTileBaseView {
-
+ private static final int DEFAULT_MAX_LINES = 2;
private static final boolean DUAL_TARGET_ALLOWED = false;
private View mDivider;
protected TextView mLabel;
@@ -61,7 +62,7 @@
setId(View.generateViewId());
createLabel();
setOrientation(VERTICAL);
- setGravity(Gravity.CENTER);
+ setGravity(Gravity.CENTER_HORIZONTAL | Gravity.TOP);
}
TextView getLabel() {
@@ -72,6 +73,7 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
FontSizeUtils.updateFontSize(mLabel, R.dimen.qs_tile_text_size);
+ FontSizeUtils.updateFontSize(mSecondLine, R.dimen.qs_tile_text_size);
}
@Override
@@ -85,17 +87,33 @@
mLabelContainer.setClipChildren(false);
mLabelContainer.setClipToPadding(false);
mLabel = mLabelContainer.findViewById(R.id.tile_label);
+ mLabel.setSelected(true); // Allow marquee to work.
mPadLock = mLabelContainer.findViewById(R.id.restricted_padlock);
mDivider = mLabelContainer.findViewById(R.id.underline);
mExpandIndicator = mLabelContainer.findViewById(R.id.expand_indicator);
mExpandSpace = mLabelContainer.findViewById(R.id.expand_space);
mSecondLine = mLabelContainer.findViewById(R.id.app_label);
mSecondLine.setAlpha(.6f);
-
+ mSecondLine.setSelected(true); // Allow marquee to work.
addView(mLabelContainer);
}
@Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ if (mLabel.getMaxLines() != DEFAULT_MAX_LINES) {
+ mLabel.setMaxLines(DEFAULT_MAX_LINES);
+ }
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+ // Remeasure view if the secondary label text will be cut off.
+ if (!TextUtils.isEmpty(mSecondLine.getText())
+ && mSecondLine.getLineHeight() > mSecondLine.getHeight()) {
+ mLabel.setSingleLine();
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+ }
+
+ @Override
protected void handleStateChanged(QSTile.State state) {
super.handleStateChanged(state);
if (!Objects.equals(mLabel.getText(), state.label) || mState != state.state) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index 28fdc11..8a1e4da 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -150,8 +150,8 @@
cb = mSignalCallback.mInfo;
}
boolean transientEnabling = arg == ARG_SHOW_TRANSIENT_ENABLING;
- boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null);
- boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null);
+ boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.ssid != null);
+ boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.ssid == null);
boolean enabledChanging = state.value != cb.enabled;
if (enabledChanging) {
mDetailAdapter.setItemsVisible(cb.enabled);
@@ -163,7 +163,7 @@
}
state.slash.isSlashed = false;
boolean isTransient = transientEnabling || cb.isTransient;
- state.secondaryLabel = getSecondaryLabel(isTransient);
+ state.secondaryLabel = getSecondaryLabel(isTransient, cb.statusLabel);
state.state = Tile.STATE_ACTIVE;
state.dualTarget = true;
state.value = transientEnabling || cb.enabled;
@@ -181,7 +181,7 @@
state.label = r.getString(R.string.quick_settings_wifi_label);
} else if (wifiConnected) {
state.icon = ResourceIcon.get(cb.wifiSignalIconId);
- state.label = removeDoubleQuotes(cb.enabledDesc);
+ state.label = removeDoubleQuotes(cb.ssid);
} else if (wifiNotConnected) {
state.icon = ResourceIcon.get(R.drawable.ic_qs_wifi_disconnected);
state.label = r.getString(R.string.quick_settings_wifi_label);
@@ -194,7 +194,7 @@
if (state.value) {
if (wifiConnected) {
minimalContentDescription.append(cb.wifiSignalContentDescription).append(",");
- minimalContentDescription.append(removeDoubleQuotes(cb.enabledDesc));
+ minimalContentDescription.append(removeDoubleQuotes(cb.ssid));
}
}
state.contentDescription = minimalContentDescription.toString();
@@ -203,10 +203,10 @@
state.expandedAccessibilityClassName = Switch.class.getName();
}
- private CharSequence getSecondaryLabel(boolean isTransient) {
+ private CharSequence getSecondaryLabel(boolean isTransient, String statusLabel) {
return isTransient
? mContext.getString(R.string.quick_settings_wifi_secondary_label_transient)
- : null;
+ : statusLabel;
}
@Override
@@ -246,11 +246,12 @@
boolean enabled;
boolean connected;
int wifiSignalIconId;
- String enabledDesc;
+ String ssid;
boolean activityIn;
boolean activityOut;
String wifiSignalContentDescription;
boolean isTransient;
+ public String statusLabel;
@Override
public String toString() {
@@ -258,7 +259,7 @@
.append("enabled=").append(enabled)
.append(",connected=").append(connected)
.append(",wifiSignalIconId=").append(wifiSignalIconId)
- .append(",enabledDesc=").append(enabledDesc)
+ .append(",ssid=").append(ssid)
.append(",activityIn=").append(activityIn)
.append(",activityOut=").append(activityOut)
.append(",wifiSignalContentDescription=").append(wifiSignalContentDescription)
@@ -272,16 +273,18 @@
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description, boolean isTransient) {
+ boolean activityIn, boolean activityOut, String description, boolean isTransient,
+ String statusLabel) {
if (DEBUG) Log.d(TAG, "onWifiSignalChanged enabled=" + enabled);
mInfo.enabled = enabled;
mInfo.connected = qsIcon.visible;
mInfo.wifiSignalIconId = qsIcon.icon;
- mInfo.enabledDesc = description;
+ mInfo.ssid = description;
mInfo.activityIn = activityIn;
mInfo.activityOut = activityOut;
mInfo.wifiSignalContentDescription = qsIcon.contentDescription;
mInfo.isTransient = isTransient;
+ mInfo.statusLabel = statusLabel;
if (isShowingDetail()) {
mDetailAdapter.updateItems();
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 068fd3f..227f2d2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -189,7 +189,6 @@
mPublicNotificationBuilder =
new Notification.Builder(context, NotificationChannels.SCREENSHOTS_HEADSUP)
.setContentTitle(r.getString(R.string.screenshot_saving_title))
- .setContentText(r.getString(R.string.screenshot_saving_text))
.setSmallIcon(R.drawable.stat_notify_image)
.setCategory(Notification.CATEGORY_PROGRESS)
.setWhen(now)
@@ -203,7 +202,6 @@
.setTicker(r.getString(R.string.screenshot_saving_ticker)
+ (mTickerAddSpace ? " " : ""))
.setContentTitle(r.getString(R.string.screenshot_saving_title))
- .setContentText(r.getString(R.string.screenshot_saving_text))
.setSmallIcon(R.drawable.stat_notify_image)
.setWhen(now)
.setShowWhen(true)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index 3698c3a0..4388b41 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -48,6 +48,11 @@
return findViewById(R.id.no_notifications);
}
+ @Override
+ protected View findSecondaryView() {
+ return null;
+ }
+
public void setTextColor(@ColorInt int color) {
mEmptyText.setTextColor(color);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 24ebc83..05a5a8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
import static com.android.systemui.statusbar.notification.NotificationInflater.InflationCallback;
@@ -34,7 +35,6 @@
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
-import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -127,6 +127,8 @@
private boolean mHasUserChangedExpansion;
/** If {@link #mHasUserChangedExpansion}, has the user expanded this row */
private boolean mUserExpanded;
+ /** Whether the blocking helper is showing on this notification (even if dismissed) */
+ private boolean mIsBlockingHelperShowing;
/**
* Has this notification been expanded while it was pinned
@@ -400,8 +402,7 @@
updateIconVisibilities();
updateShelfIconColor();
- showBlockingHelper(mEntry.userSentiment ==
- NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
+ showBlockingHelperButton(mEntry.userSentiment == USER_SENTIMENT_NEGATIVE);
updateRippleAllowed();
}
@@ -594,6 +595,13 @@
return mNotificationParent != null;
}
+ /**
+ * @return whether this notification is the only child in the group summary
+ */
+ public boolean isOnlyChildInGroup() {
+ return mGroupManager.isOnlyChildInGroup(getStatusBarNotification());
+ }
+
public ExpandableNotificationRow getNotificationParent() {
return mNotificationParent;
}
@@ -1061,6 +1069,7 @@
}
public void setDismissed(boolean fromAccessibility) {
+ setLongPressListener(null);
mDismissed = true;
mGroupParentWhenDismissed = mNotificationParent;
mRefocusOnDismiss = fromAccessibility;
@@ -1149,11 +1158,31 @@
return mGroupParentWhenDismissed;
}
+ /**
+ * Dismisses the notification with the option of showing the blocking helper in-place if we have
+ * a negative user sentiment.
+ *
+ * @param fromAccessibility whether this dismiss is coming from an accessibility action
+ * @return whether a blocking helper is shown in this row
+ */
+ public boolean performDismissWithBlockingHelper(boolean fromAccessibility) {
+ NotificationBlockingHelperManager manager =
+ Dependency.get(NotificationBlockingHelperManager.class);
+ boolean isBlockingHelperShown = manager.perhapsShowBlockingHelper(this, mMenuRow);
+
+ // Continue with dismiss since we don't want the blocking helper to be directly associated
+ // with a certain notification.
+ performDismiss(fromAccessibility);
+ return isBlockingHelperShown;
+ }
+
public void performDismiss(boolean fromAccessibility) {
- if (mGroupManager.isOnlyChildInGroup(getStatusBarNotification())) {
+ if (isOnlyChildInGroup()) {
ExpandableNotificationRow groupSummary =
mGroupManager.getLogicalGroupSummary(getStatusBarNotification());
if (groupSummary.isClearable()) {
+ // If this is the only child in the group, dismiss the group, but don't try to show
+ // the blocking helper affordance!
groupSummary.performDismiss(fromAccessibility);
}
}
@@ -1165,6 +1194,14 @@
}
}
+ public void setBlockingHelperShowing(boolean isBlockingHelperShowing) {
+ mIsBlockingHelperShowing = isBlockingHelperShowing;
+ }
+
+ public boolean isBlockingHelperShowing() {
+ return mIsBlockingHelperShowing;
+ }
+
public void setOnDismissRunnable(Runnable onDismissRunnable) {
mOnDismissRunnable = onDismissRunnable;
}
@@ -1389,7 +1426,7 @@
requestLayout();
}
- public void showBlockingHelper(boolean show) {
+ public void showBlockingHelperButton(boolean show) {
mHelperButton.setVisibility(show ? View.VISIBLE : View.GONE);
}
@@ -1422,7 +1459,6 @@
mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);
mLayouts = new NotificationContentView[] {mPrivateLayout, mPublicLayout};
- final NotificationGutsManager gutsMan = Dependency.get(NotificationGutsManager.class);
mHelperButton = findViewById(R.id.helper);
mHelperButton.setOnClickListener(view -> {
doLongClickCallback();
@@ -2525,7 +2561,7 @@
}
switch (action) {
case AccessibilityNodeInfo.ACTION_DISMISS:
- performDismiss(true /* fromAccessibility */);
+ performDismissWithBlockingHelper(true /* fromAccessibility */);
return true;
case AccessibilityNodeInfo.ACTION_COLLAPSE:
case AccessibilityNodeInfo.ACTION_EXPAND:
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java b/packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java
similarity index 68%
rename from packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java
index d7c6443..0f4b621 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FooterView.java
@@ -26,11 +26,12 @@
import com.android.systemui.statusbar.stack.ExpandableViewState;
import com.android.systemui.statusbar.stack.StackScrollState;
-public class DismissView extends StackScrollerDecorView {
+public class FooterView extends StackScrollerDecorView {
private final int mClearAllTopPadding;
- private DismissViewButton mDismissButton;
+ private FooterViewButton mDismissButton;
+ private FooterViewButton mManageButton;
- public DismissView(Context context, AttributeSet attrs) {
+ public FooterView(Context context, AttributeSet attrs) {
super(context, attrs);
mClearAllTopPadding = context.getResources().getDimensionPixelSize(
R.dimen.clear_all_padding_top);
@@ -38,21 +39,31 @@
@Override
protected View findContentView() {
+ return findViewById(R.id.content);
+ }
+
+ protected View findSecondaryView() {
return findViewById(R.id.dismiss_text);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mDismissButton = (DismissViewButton) findContentView();
+ mDismissButton = (FooterViewButton) findSecondaryView();
+ mManageButton = findViewById(R.id.manage_text);
}
public void setTextColor(@ColorInt int color) {
+ mManageButton.setTextColor(color);
mDismissButton.setTextColor(color);
}
- public void setOnButtonClickListener(OnClickListener listener) {
- mContent.setOnClickListener(listener);
+ public void setManageButtonClickListener(OnClickListener listener) {
+ mManageButton.setOnClickListener(listener);
+ }
+
+ public void setDismissButtonClickListener(OnClickListener listener) {
+ mDismissButton.setOnClickListener(listener);
}
public boolean isOnEmptySpace(float touchX, float touchY) {
@@ -68,25 +79,26 @@
mDismissButton.setText(R.string.clear_all_notifications_text);
mDismissButton.setContentDescription(
mContext.getString(R.string.accessibility_clear_all));
+ mManageButton.setText(R.string.manage_notifications_text);
}
public boolean isButtonVisible() {
- return mDismissButton.getAlpha() != 0.0f;
+ return mManageButton.getAlpha() != 0.0f;
}
@Override
public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
- return new DismissViewState();
+ return new FooterViewState();
}
- public class DismissViewState extends ExpandableViewState {
+ public class FooterViewState extends ExpandableViewState {
@Override
public void applyToView(View view) {
super.applyToView(view);
- if (view instanceof DismissView) {
- DismissView dismissView = (DismissView) view;
+ if (view instanceof FooterView) {
+ FooterView footerView = (FooterView) view;
boolean visible = this.clipTopAmount < mClearAllTopPadding;
- dismissView.performVisibilityAnimation(visible && !dismissView.willBeGone());
+ footerView.performVisibilityAnimation(visible && !footerView.willBeGone());
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/FooterViewButton.java
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java
rename to packages/SystemUI/src/com/android/systemui/statusbar/FooterViewButton.java
index b608d67..16ca0f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DismissViewButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FooterViewButton.java
@@ -23,21 +23,21 @@
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
-public class DismissViewButton extends AlphaOptimizedButton {
+public class FooterViewButton extends AlphaOptimizedButton {
- public DismissViewButton(Context context) {
+ public FooterViewButton(Context context) {
this(context, null);
}
- public DismissViewButton(Context context, AttributeSet attrs) {
+ public FooterViewButton(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
- public DismissViewButton(Context context, AttributeSet attrs, int defStyleAttr) {
+ public FooterViewButton(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
- public DismissViewButton(Context context, AttributeSet attrs, int defStyleAttr,
+ public FooterViewButton(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java
new file mode 100644
index 0000000..c9c1bc6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBlockingHelperManager.java
@@ -0,0 +1,137 @@
+/*
+ * 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
+ */
+
+package com.android.systemui.statusbar;
+
+import android.content.Context;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+
+import com.android.systemui.Dependency;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
+
+/**
+ * Manager for the notification blocking helper - tracks and helps create the blocking helper
+ * affordance.
+ */
+public class NotificationBlockingHelperManager {
+ /** Enables debug logging and always makes the blocking helper show up after a dismiss. */
+ private static final boolean DEBUG = false;
+ private static final String TAG = "BlockingHelper";
+
+ private final Context mContext;
+ /** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */
+ private ExpandableNotificationRow mBlockingHelperRow;
+
+ /**
+ * Whether the notification shade/stack is expanded - used to determine blocking helper
+ * eligibility.
+ */
+ private boolean mIsShadeExpanded;
+
+ public NotificationBlockingHelperManager(Context context) {
+ mContext = context;
+ }
+
+ /**
+ * Potentially shows the blocking helper, represented via the {@link NotificationInfo} menu
+ * item, in the current row if user sentiment is negative.
+ *
+ * @param row row to render the blocking helper in
+ * @param menuRow menu used to generate the {@link NotificationInfo} view that houses the
+ * blocking helper UI
+ * @return whether we're showing a blocking helper in the given notification row
+ */
+ boolean perhapsShowBlockingHelper(
+ ExpandableNotificationRow row, NotificationMenuRowPlugin menuRow) {
+ int numChildren = row.getNumberOfNotificationChildren();
+
+ // We only show the blocking helper if:
+ // - The dismissed row is a valid group (>1 or 0 children) or the only child in the group
+ // - The notification shade is fully expanded (guarantees we're not touching a HUN).
+ // - User sentiment is negative
+ if (DEBUG
+ || row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE
+ && mIsShadeExpanded
+ && (!row.isChildInGroup() || row.isOnlyChildInGroup())) {
+ // Dismiss any current blocking helper before continuing forward (only one can be shown
+ // at a given time).
+ dismissCurrentBlockingHelper();
+
+ if (DEBUG) {
+ Log.d(TAG, "Manager.perhapsShowBlockingHelper: Showing new blocking helper");
+ }
+ NotificationGutsManager manager = Dependency.get(NotificationGutsManager.class);
+
+ // Enable blocking helper on the row before moving forward so everything in the guts is
+ // correctly prepped.
+ mBlockingHelperRow = row;
+ mBlockingHelperRow.setBlockingHelperShowing(true);
+
+ // We don't care about the touch origin (x, y) since we're opening guts without any
+ // explicit user interaction.
+ manager.openGuts(mBlockingHelperRow, 0, 0, menuRow.getLongpressMenuItem(mContext));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Dismiss the currently showing blocking helper, if any, through a notification update.
+ *
+ * @return whether the blocking helper was dismissed
+ */
+ boolean dismissCurrentBlockingHelper() {
+ if (!isBlockingHelperRowNull()) {
+ if (DEBUG) {
+ Log.d(TAG, "Manager.dismissCurrentBlockingHelper: Dismissing current helper");
+ }
+ if (!mBlockingHelperRow.isBlockingHelperShowing()) {
+ Log.e(TAG, "Manager.dismissCurrentBlockingHelper: "
+ + "Non-null row is not showing a blocking helper");
+ }
+
+ mBlockingHelperRow.setBlockingHelperShowing(false);
+ if (mBlockingHelperRow.isAttachedToWindow()) {
+ Dependency.get(NotificationEntryManager.class).updateNotifications();
+ }
+ mBlockingHelperRow = null;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Update the expansion status of the notification shade/stack.
+ *
+ * @param expandedHeight how much the shade is expanded ({code 0} indicating it's collapsed)
+ */
+ public void setNotificationShadeExpanded(float expandedHeight) {
+ mIsShadeExpanded = expandedHeight > 0.0f;
+ }
+
+ @VisibleForTesting
+ boolean isBlockingHelperRowNull() {
+ return mBlockingHelperRow == null;
+ }
+
+ @VisibleForTesting
+ void setBlockingHelperRowForTest(ExpandableNotificationRow blockingHelperRowForTest) {
+ mBlockingHelperRow = blockingHelperRowForTest;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
index 52776d7..bc572a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java
@@ -30,6 +30,7 @@
import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.stack.StackStateAnimator;
@@ -189,8 +190,12 @@
}
public void openControls(
- int x, int y, boolean needsFalsingProtection, @Nullable Runnable onAnimationEnd) {
- animateOpen(x, y, onAnimationEnd);
+ boolean shouldDoCircularReveal,
+ int x,
+ int y,
+ boolean needsFalsingProtection,
+ @Nullable Runnable onAnimationEnd) {
+ animateOpen(shouldDoCircularReveal, x, y, onAnimationEnd);
setExposed(true /* exposed */, needsFalsingProtection);
}
@@ -204,7 +209,20 @@
}
}
+ /**
+ * Closes any exposed guts/views.
+ *
+ * @param x x coordinate to animate the close circular reveal with
+ * @param y y coordinate to animate the close circular reveal with
+ * @param save whether the state should be saved
+ * @param force whether the guts should be force-closed regardless of state.
+ */
public void closeControls(int x, int y, boolean save, boolean force) {
+ // First try to dismiss any blocking helper.
+ boolean wasBlockingHelperDismissed =
+ Dependency.get(NotificationBlockingHelperManager.class)
+ .dismissCurrentBlockingHelper();
+
if (getWindowToken() == null) {
if (mClosedListener != null) {
mClosedListener.onGutsClosed(this);
@@ -212,8 +230,12 @@
return;
}
- if (mGutsContent == null || !mGutsContent.handleCloseControls(save, force)) {
- animateClose(x, y);
+ if (mGutsContent == null
+ || !mGutsContent.handleCloseControls(save, force)
+ || wasBlockingHelperDismissed) {
+ // We only want to do a circular reveal if we're not showing the blocking helper.
+ animateClose(x, y, !wasBlockingHelperDismissed /* shouldDoCircularReveal */);
+
setExposed(false, mNeedsFalsingProtection);
if (mClosedListener != null) {
mClosedListener.onGutsClosed(this);
@@ -221,47 +243,58 @@
}
}
- private void animateOpen(int x, int y, @Nullable Runnable onAnimationEnd) {
- final double horz = Math.max(getWidth() - x, x);
- final double vert = Math.max(getHeight() - y, y);
- final float r = (float) Math.hypot(horz, vert);
-
- final Animator a
- = ViewAnimationUtils.createCircularReveal(this, x, y, 0, r);
- a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
- a.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- if (onAnimationEnd != null) {
- onAnimationEnd.run();
- }
- }
- });
- a.start();
+ /** Animates in the guts view via either a fade or a circular reveal. */
+ private void animateOpen(
+ boolean shouldDoCircularReveal, int x, int y, @Nullable Runnable onAnimationEnd) {
+ if (shouldDoCircularReveal) {
+ double horz = Math.max(getWidth() - x, x);
+ double vert = Math.max(getHeight() - y, y);
+ float r = (float) Math.hypot(horz, vert);
+ // Circular reveal originating at (x, y)
+ Animator a = ViewAnimationUtils.createCircularReveal(this, x, y, 0, r);
+ a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ a.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
+ a.addListener(new AnimateOpenListener(onAnimationEnd));
+ a.start();
+ } else {
+ // Fade in content
+ this.setAlpha(0f);
+ this.animate()
+ .alpha(1f)
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
+ .setInterpolator(Interpolators.ALPHA_IN)
+ .setListener(new AnimateOpenListener(onAnimationEnd))
+ .start();
+ }
}
- private void animateClose(int x, int y) {
- if (x == -1 || y == -1) {
- x = (getLeft() + getRight()) / 2;
- y = (getTop() + getHeight() / 2);
- }
- final double horz = Math.max(getWidth() - x, x);
- final double vert = Math.max(getHeight() - y, y);
- final float r = (float) Math.hypot(horz, vert);
- final Animator a = ViewAnimationUtils.createCircularReveal(this,
- x, y, r, 0);
- a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
- a.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- super.onAnimationEnd(animation);
- setVisibility(View.GONE);
+
+ /** Animates out the guts view via either a fade or a circular reveal. */
+ private void animateClose(int x, int y, boolean shouldDoCircularReveal) {
+ if (shouldDoCircularReveal) {
+ // Circular reveal originating at (x, y)
+ if (x == -1 || y == -1) {
+ x = (getLeft() + getRight()) / 2;
+ y = (getTop() + getHeight() / 2);
}
- });
- a.start();
+ double horz = Math.max(getWidth() - x, x);
+ double vert = Math.max(getHeight() - y, y);
+ float r = (float) Math.hypot(horz, vert);
+ Animator a = ViewAnimationUtils.createCircularReveal(this,
+ x, y, r, 0);
+ a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
+ a.addListener(new AnimateCloseListener(this /* view */));
+ a.start();
+ } else {
+ // Fade in the blocking helper.
+ this.animate()
+ .alpha(0f)
+ .setDuration(StackStateAnimator.ANIMATION_DURATION_BLOCKING_HELPER_FADE)
+ .setInterpolator(Interpolators.ALPHA_OUT)
+ .setListener(new AnimateCloseListener(this /* view */))
+ .start();
+ }
}
public void setActualHeight(int actualHeight) {
@@ -336,4 +369,36 @@
public boolean isLeavebehind() {
return mGutsContent != null && mGutsContent.isLeavebehind();
}
+
+ /** Listener for animations executed in {@link #animateOpen(boolean, int, int, Runnable)}. */
+ private static class AnimateOpenListener extends AnimatorListenerAdapter {
+ final Runnable mOnAnimationEnd;
+
+ private AnimateOpenListener(Runnable onAnimationEnd) {
+ mOnAnimationEnd = onAnimationEnd;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ if (mOnAnimationEnd != null) {
+ mOnAnimationEnd.run();
+ }
+ }
+ }
+
+ /** Listener for animations executed in {@link #animateClose(int, int, boolean)}. */
+ private static class AnimateCloseListener extends AnimatorListenerAdapter {
+ final View mView;
+
+ private AnimateCloseListener(View view) {
+ mView = view;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ mView.setVisibility(View.GONE);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
index 9b2f939..75204d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
@@ -21,7 +21,6 @@
import static android.service.notification.NotificationListenerService.Ranking
.USER_SENTIMENT_NEGATIVE;
-import android.app.AppOpsManager;
import android.app.INotificationManager;
import android.app.NotificationChannel;
import android.content.Context;
@@ -34,6 +33,7 @@
import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
+import android.support.annotation.VisibleForTesting;
import android.util.ArraySet;
import android.util.Log;
import android.view.HapticFeedbackConstants;
@@ -119,22 +119,6 @@
bindGuts(row);
}
- private void saveAndCloseNotificationMenu(
- ExpandableNotificationRow row, NotificationGuts guts, View done) {
- guts.resetFalsingCheck();
- int[] rowLocation = new int[2];
- int[] doneLocation = new int[2];
- row.getLocationOnScreen(rowLocation);
- done.getLocationOnScreen(doneLocation);
-
- final int centerX = done.getWidth() / 2;
- final int centerY = done.getHeight() / 2;
- final int x = doneLocation[0] - rowLocation[0] + centerX;
- final int y = doneLocation[1] - rowLocation[1] + centerY;
- closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
- true /* removeControls */, x, y, true /* resetMenu */);
- }
-
/**
* Sends an intent to open the app settings for a particular package and optional
* channel.
@@ -174,12 +158,12 @@
private void bindGuts(final ExpandableNotificationRow row,
NotificationMenuRowPlugin.MenuItem item) {
+ StatusBarNotification sbn = row.getStatusBarNotification();
+
row.inflateGuts();
row.setGutsView(item);
- final StatusBarNotification sbn = row.getStatusBarNotification();
row.setTag(sbn.getPackageName());
- final NotificationGuts guts = row.getGuts();
- guts.setClosedListener((NotificationGuts g) -> {
+ row.getGuts().setClosedListener((NotificationGuts g) -> {
if (!g.willBeRemoved() && !row.isRemoved()) {
mListContainer.onHeightChanged(
row, !mPresenter.isPresenterFullyCollapsed() /* needsAnimation */);
@@ -197,87 +181,143 @@
View gutsView = item.getGutsView();
if (gutsView instanceof NotificationSnooze) {
- NotificationSnooze snoozeGuts = (NotificationSnooze) gutsView;
- snoozeGuts.setSnoozeListener(mListContainer.getSwipeActionHelper());
- snoozeGuts.setStatusBarNotification(sbn);
- snoozeGuts.setSnoozeOptions(row.getEntry().snoozeCriteria);
- guts.setHeightChangedListener((NotificationGuts g) -> {
- mListContainer.onHeightChanged(row, row.isShown() /* needsAnimation */);
- });
+ initializeSnoozeView(row, (NotificationSnooze) gutsView);
+ } else if (gutsView instanceof AppOpsInfo) {
+ initializeAppOpsInfo(row, (AppOpsInfo) gutsView);
+ } else if (gutsView instanceof NotificationInfo) {
+ initializeNotificationInfo(row, (NotificationInfo) gutsView);
}
+ }
- if (gutsView instanceof AppOpsInfo) {
- AppOpsInfo info = (AppOpsInfo) gutsView;
- final UserHandle userHandle = sbn.getUser();
- PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
- userHandle.getIdentifier());
- final AppOpsInfo.OnSettingsClickListener onSettingsClick = (View v,
- String pkg, int uid, ArraySet<Integer> ops) -> {
- mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
- guts.resetFalsingCheck();
- startAppOpsSettingsActivity(pkg, uid, ops, row);
- };
- if (!row.getEntry().mActiveAppOps.isEmpty()) {
- info.bindGuts(pmUser, onSettingsClick, sbn, row.getEntry().mActiveAppOps);
- }
+ /**
+ * Sets up the {@link NotificationSnooze} inside the notification row's guts.
+ *
+ * @param row view to set up the guts for
+ * @param notificationSnoozeView view to set up/bind within {@code row}
+ */
+ private void initializeSnoozeView(
+ final ExpandableNotificationRow row,
+ NotificationSnooze notificationSnoozeView) {
+ NotificationGuts guts = row.getGuts();
+ StatusBarNotification sbn = row.getStatusBarNotification();
+
+ notificationSnoozeView.setSnoozeListener(mListContainer.getSwipeActionHelper());
+ notificationSnoozeView.setStatusBarNotification(sbn);
+ notificationSnoozeView.setSnoozeOptions(row.getEntry().snoozeCriteria);
+ guts.setHeightChangedListener((NotificationGuts g) -> {
+ mListContainer.onHeightChanged(row, row.isShown() /* needsAnimation */);
+ });
+ }
+
+ /**
+ * Sets up the {@link AppOpsInfo} inside the notification row's guts.
+ *
+ * @param row view to set up the guts for
+ * @param appOpsInfoView view to set up/bind within {@code row}
+ */
+ private void initializeAppOpsInfo(
+ final ExpandableNotificationRow row,
+ AppOpsInfo appOpsInfoView) {
+ NotificationGuts guts = row.getGuts();
+ StatusBarNotification sbn = row.getStatusBarNotification();
+ UserHandle userHandle = sbn.getUser();
+ PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
+ userHandle.getIdentifier());
+
+ AppOpsInfo.OnSettingsClickListener onSettingsClick =
+ (View v, String pkg, int uid, ArraySet<Integer> ops) -> {
+ mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_OPS_GUTS_SETTINGS);
+ guts.resetFalsingCheck();
+ startAppOpsSettingsActivity(pkg, uid, ops, row);
+ };
+ if (!row.getEntry().mActiveAppOps.isEmpty()) {
+ appOpsInfoView.bindGuts(pmUser, onSettingsClick, sbn, row.getEntry().mActiveAppOps);
}
+ }
- if (gutsView instanceof NotificationInfo) {
- final UserHandle userHandle = sbn.getUser();
- PackageManager pmUser = StatusBar.getPackageManagerForUser(mContext,
- userHandle.getIdentifier());
- final INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- final String pkg = sbn.getPackageName();
- NotificationInfo info = (NotificationInfo) gutsView;
- // Settings link is only valid for notifications that specify a user, unless this is the
- // system user.
- NotificationInfo.OnSettingsClickListener onSettingsClick = null;
- if (!userHandle.equals(UserHandle.ALL)
- || mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
- onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
- mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO);
+ /**
+ * Sets up the {@link NotificationInfo} inside the notification row's guts.
+ *
+ * @param row view to set up the guts for
+ * @param notificationInfoView view to set up/bind within {@code row}
+ */
+ @VisibleForTesting
+ void initializeNotificationInfo(
+ final ExpandableNotificationRow row,
+ NotificationInfo notificationInfoView) {
+ NotificationGuts guts = row.getGuts();
+ StatusBarNotification sbn = row.getStatusBarNotification();
+ String packageName = sbn.getPackageName();
+ // Settings link is only valid for notifications that specify a non-system user
+ NotificationInfo.OnSettingsClickListener onSettingsClick = null;
+ UserHandle userHandle = sbn.getUser();
+ PackageManager pmUser = StatusBar.getPackageManagerForUser(
+ mContext, userHandle.getIdentifier());
+ INotificationManager iNotificationManager = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick =
+ (View v, Intent intent) -> {
+ mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
guts.resetFalsingCheck();
- mOnSettingsClickListener.onClick(sbn.getKey());
- startAppNotificationSettingsActivity(pkg, appUid, channel, row);
+ mPresenter.startNotificationGutsIntent(intent, sbn.getUid(), row);
};
- }
- final NotificationInfo.OnAppSettingsClickListener onAppSettingsClick = (View v,
- Intent intent) -> {
- mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_APP_NOTE_SETTINGS);
- guts.resetFalsingCheck();
- mPresenter.startNotificationGutsIntent(intent, sbn.getUid(), row);
- };
- final View.OnClickListener onDoneClick = (View v) -> {
- saveAndCloseNotificationMenu(row, guts, v);
- };
+ boolean isForBlockingHelper = row.isBlockingHelperShowing();
- ArraySet<NotificationChannel> channels = new ArraySet<>();
- channels.add(row.getEntry().channel);
- if (row.isSummaryWithChildren()) {
- // If this is a summary, then add in the children notification channels for the
- // same user and pkg.
- final List<ExpandableNotificationRow> childrenRows = row.getNotificationChildren();
- final int numChildren = childrenRows.size();
- for (int i = 0; i < numChildren; i++) {
- final ExpandableNotificationRow childRow = childrenRows.get(i);
- final NotificationChannel childChannel = childRow.getEntry().channel;
- final StatusBarNotification childSbn = childRow.getStatusBarNotification();
- if (childSbn.getUser().equals(userHandle) &&
- childSbn.getPackageName().equals(pkg)) {
- channels.add(childChannel);
- }
+ if (!userHandle.equals(UserHandle.ALL)
+ || mLockscreenUserManager.getCurrentUserId() == UserHandle.USER_SYSTEM) {
+ onSettingsClick = (View v, NotificationChannel channel, int appUid) -> {
+ mMetricsLogger.action(MetricsProto.MetricsEvent.ACTION_NOTE_INFO);
+ guts.resetFalsingCheck();
+ mOnSettingsClickListener.onClick(sbn.getKey());
+ startAppNotificationSettingsActivity(packageName, appUid, channel, row);
+ };
+ }
+
+ try {
+ notificationInfoView.bindNotification(
+ pmUser,
+ iNotificationManager,
+ packageName,
+ row.getEntry().channel,
+ getNumNotificationChannels(row, packageName, userHandle),
+ sbn,
+ mCheckSaveListener,
+ onSettingsClick,
+ onAppSettingsClick,
+ mNonBlockablePkgs,
+ isForBlockingHelper,
+ row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ }
+
+ /**
+ * @return the number of channels covered by the notification row (including its children if
+ * it's a summary notification).
+ */
+ private int getNumNotificationChannels(
+ ExpandableNotificationRow row, String packageName, UserHandle userHandle) {
+ ArraySet<NotificationChannel> channels = new ArraySet<>();
+
+ channels.add(row.getEntry().channel);
+
+ // If this is a summary, then add in the children notification channels for the
+ // same user and pkg.
+ if (row.isSummaryWithChildren()) {
+ final List<ExpandableNotificationRow> childrenRows = row.getNotificationChildren();
+ final int numChildren = childrenRows.size();
+ for (int i = 0; i < numChildren; i++) {
+ final ExpandableNotificationRow childRow = childrenRows.get(i);
+ final NotificationChannel childChannel = childRow.getEntry().channel;
+ final StatusBarNotification childSbn = childRow.getStatusBarNotification();
+ if (childSbn.getUser().equals(userHandle) &&
+ childSbn.getPackageName().equals(packageName)) {
+ channels.add(childChannel);
}
}
- try {
- info.bindNotification(pmUser, iNotificationManager, pkg, row.getEntry().channel,
- channels.size(), sbn, mCheckSaveListener, onSettingsClick,
- onAppSettingsClick, mNonBlockablePkgs,
- row.getEntry().userSentiment == USER_SENTIMENT_NEGATIVE);
- } catch (RemoteException e) {
- Log.e(TAG, e.toString());
- }
}
+ return channels.size();
}
/**
@@ -312,37 +352,42 @@
}
/**
- * Opens guts on the given ExpandableNotificationRow |v|.
+ * Opens guts on the given ExpandableNotificationRow {@code view}. This handles opening guts for
+ * the normal half-swipe and long-press use cases via a circular reveal. When the blocking
+ * helper needs to be shown on the row, this will skip the circular reveal.
*
- * @param v ExpandableNotificationRow to open guts on
+ * @param view ExpandableNotificationRow to open guts on
* @param x x coordinate of origin of circular reveal
* @param y y coordinate of origin of circular reveal
- * @param item MenuItem the guts should display
+ * @param menuItem MenuItem the guts should display
* @return true if guts was opened
*/
- public boolean openGuts(View v, int x, int y,
- NotificationMenuRowPlugin.MenuItem item) {
- if (!(v instanceof ExpandableNotificationRow)) {
+ boolean openGuts(
+ View view,
+ int x,
+ int y,
+ NotificationMenuRowPlugin.MenuItem menuItem) {
+ if (!(view instanceof ExpandableNotificationRow)) {
return false;
}
- if (v.getWindowToken() == null) {
+ if (view.getWindowToken() == null) {
Log.e(TAG, "Trying to show notification guts, but not attached to window");
return false;
}
- final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+ final ExpandableNotificationRow row = (ExpandableNotificationRow) view;
if (row.isDark()) {
return false;
}
- v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+ view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
if (row.areGutsExposed()) {
closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
true /* removeControls */, -1 /* x */, -1 /* y */,
true /* resetMenu */);
return false;
}
- bindGuts(row, item);
+ bindGuts(row, menuItem);
NotificationGuts guts = row.getGuts();
// Assume we are a status_bar_notification_row
@@ -372,15 +417,18 @@
final boolean needsFalsingProtection =
(mPresenter.isPresenterLocked() &&
!mAccessibilityManager.isTouchExplorationEnabled());
- guts.openControls(x, y, needsFalsingProtection, () -> {
- // Move the notification view back over the menu
- row.resetTranslation();
- });
+
+ guts.openControls(
+ !row.isBlockingHelperShowing(),
+ x,
+ y,
+ needsFalsingProtection,
+ row::resetTranslation);
row.closeRemoteInput();
mListContainer.onHeightChanged(row, true /* needsAnimation */);
mNotificationGutsExposed = guts;
- mGutsMenuItem = item;
+ mGutsMenuItem = menuItem;
}
});
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index b1ad30c..a2f336e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -46,9 +46,11 @@
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -81,11 +83,12 @@
private OnSettingsClickListener mOnSettingsClickListener;
private OnAppSettingsClickListener mAppSettingsClickListener;
private NotificationGuts mGutsContainer;
+
+ /** Whether this view is being shown as part of the blocking helper */
+ private boolean mIsForBlockingHelper;
private boolean mNegativeUserSentiment;
- private OnClickListener mOnKeepShowing = v -> {
- closeControls(v);
- };
+ private OnClickListener mOnKeepShowing = this::closeControls;
private OnClickListener mOnStopMinNotifications = v -> {
swapContent(false);
@@ -114,7 +117,9 @@
void onClick(View v, Intent intent);
}
- public void bindNotification(final PackageManager pm,
+ @VisibleForTesting
+ void bindNotification(
+ final PackageManager pm,
final INotificationManager iNotificationManager,
final String pkg,
final NotificationChannel notificationChannel,
@@ -127,20 +132,24 @@
throws RemoteException {
bindNotification(pm, iNotificationManager, pkg, notificationChannel, numChannels, sbn,
checkSaveListener, onSettingsClick, onAppSettingsClick, nonBlockablePkgs,
- false /* negative sentiment */);
+ false /* isBlockingHelper */,
+ false /* isUserSentimentNegative */);
}
- public void bindNotification(final PackageManager pm,
- final INotificationManager iNotificationManager,
- final String pkg,
- final NotificationChannel notificationChannel,
- final int numChannels,
- final StatusBarNotification sbn,
- final CheckSaveListener checkSaveListener,
- final OnSettingsClickListener onSettingsClick,
- final OnAppSettingsClickListener onAppSettingsClick,
- final Set<String> nonBlockablePkgs,
- boolean negativeUserSentiment) throws RemoteException {
+ public void bindNotification(
+ PackageManager pm,
+ INotificationManager iNotificationManager,
+ String pkg,
+ NotificationChannel notificationChannel,
+ int numChannels,
+ StatusBarNotification sbn,
+ CheckSaveListener checkSaveListener,
+ OnSettingsClickListener onSettingsClick,
+ OnAppSettingsClickListener onAppSettingsClick,
+ Set<String> nonBlockablePkgs,
+ boolean isForBlockingHelper,
+ boolean isUserSentimentNegative)
+ throws RemoteException {
mINotificationManager = iNotificationManager;
mPkg = pkg;
mNumNotificationChannels = numChannels;
@@ -152,9 +161,10 @@
mOnSettingsClickListener = onSettingsClick;
mSingleNotificationChannel = notificationChannel;
mStartingUserImportance = mChosenImportance = mSingleNotificationChannel.getImportance();
- mNegativeUserSentiment = negativeUserSentiment;
+ mNegativeUserSentiment = isUserSentimentNegative;
mIsForeground =
(mSbn.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE) != 0;
+ mIsForBlockingHelper = isForBlockingHelper;
int numTotalChannels = mINotificationManager.getNumNotificationChannelsForPackage(
pkg, mAppUid, false /* includeDeleted */);
@@ -294,12 +304,14 @@
}
private void bindButtons() {
+ // Set up stay-in-notification actions
View block = findViewById(R.id.block);
- block.setOnClickListener(mOnStopMinNotifications);
TextView keep = findViewById(R.id.keep);
- keep.setOnClickListener(mOnKeepShowing);
- findViewById(R.id.undo).setOnClickListener(mOnUndo);
View minimize = findViewById(R.id.minimize);
+
+ findViewById(R.id.undo).setOnClickListener(mOnUndo);
+ block.setOnClickListener(mOnStopMinNotifications);
+ keep.setOnClickListener(mOnKeepShowing);
minimize.setOnClickListener(mOnStopMinNotifications);
if (mNonblockable) {
@@ -314,7 +326,7 @@
minimize.setVisibility(GONE);
}
- // app settings link
+ // Set up app settings link
TextView settingsLinkView = findViewById(R.id.app_settings);
Intent settingsIntent = getAppSettingsIntent(mPm, mPkg, mSingleNotificationChannel,
mSbn.getId(), mSbn.getTag());
@@ -421,16 +433,23 @@
return intent;
}
- private void closeControls(View v) {
- int[] parentLoc = new int[2];
- int[] targetLoc = new int[2];
- mGutsContainer.getLocationOnScreen(parentLoc);
- v.getLocationOnScreen(targetLoc);
- final int centerX = v.getWidth() / 2;
- final int centerY = v.getHeight() / 2;
- final int x = targetLoc[0] - parentLoc[0] + centerX;
- final int y = targetLoc[1] - parentLoc[1] + centerY;
- mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
+ @VisibleForTesting
+ void closeControls(View v) {
+ if (mIsForBlockingHelper) {
+ NotificationBlockingHelperManager manager =
+ Dependency.get(NotificationBlockingHelperManager.class);
+ manager.dismissCurrentBlockingHelper();
+ } else {
+ int[] parentLoc = new int[2];
+ int[] targetLoc = new int[2];
+ mGutsContainer.getLocationOnScreen(parentLoc);
+ v.getLocationOnScreen(targetLoc);
+ final int centerX = v.getWidth() / 2;
+ final int centerY = v.getHeight() / 2;
+ final int x = targetLoc[0] - parentLoc[0] + centerX;
+ final int y = targetLoc[1] - parentLoc[1] + centerY;
+ mGutsContainer.closeControls(x, y, true /* save */, false /* force */);
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index a4aa598..0112661 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -227,7 +227,6 @@
expandAmount = Math.min(1.0f, expandAmount);
}
// find the first view that doesn't overlap with the shelf
- int notificationIndex = 0;
int notGoneIndex = 0;
int colorOfViewBeforeLast = NO_COLOR;
boolean backgroundForceHidden = false;
@@ -247,13 +246,15 @@
int baseZHeight = mAmbientState.getBaseZHeight();
int backgroundTop = 0;
float firstElementRoundness = 0.0f;
- while (notificationIndex < mHostLayout.getChildCount()) {
- ExpandableView child = (ExpandableView) mHostLayout.getChildAt(notificationIndex);
- notificationIndex++;
+
+ for (int i = 0; i < mHostLayout.getChildCount(); i++) {
+ ExpandableView child = (ExpandableView) mHostLayout.getChildAt(i);
+
if (!(child instanceof ExpandableNotificationRow)
|| child.getVisibility() == GONE) {
continue;
}
+
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
float notificationClipEnd;
boolean aboveShelf = ViewState.getFinalTranslationZ(row) > baseZHeight
@@ -315,6 +316,9 @@
notGoneIndex++;
previousColor = ownColorUntinted;
}
+
+ clipTransientViews();
+
setBackgroundTop(backgroundTop);
setFirstElementRoundness(firstElementRoundness);
mShelfIcons.setSpeedBumpIndex(mAmbientState.getSpeedBumpIndex());
@@ -337,6 +341,25 @@
}
}
+ /**
+ * Clips transient views to the top of the shelf - Transient views are only used for
+ * disappearing views/animations and need to be clipped correctly by the shelf to ensure they
+ * don't show underneath the notification stack when something is animating and the user
+ * swipes quickly.
+ */
+ private void clipTransientViews() {
+ for (int i = 0; i < mHostLayout.getTransientViewCount(); i++) {
+ View transientView = mHostLayout.getTransientView(i);
+ if (transientView instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow transientRow = (ExpandableNotificationRow) transientView;
+ updateNotificationClipHeight(transientRow, getTranslationY());
+ } else {
+ Log.e(TAG, "NotificationShelf.clipTransientViews(): "
+ + "Trying to clip non-row transient view");
+ }
+ }
+ }
+
private void setFirstElementRoundness(float firstElementRoundness) {
if (mFirstElementRoundness != firstElementRoundness) {
mFirstElementRoundness = firstElementRoundness;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 75b8b37..b1e08b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -125,24 +125,30 @@
}
- ArrayList<ExpandableNotificationRow> toRemove = new ArrayList<>();
+ ArrayList<ExpandableNotificationRow> viewsToRemove = new ArrayList<>();
for (int i=0; i< mListContainer.getContainerChildCount(); i++) {
View child = mListContainer.getContainerChildAt(i);
if (!toShow.contains(child) && child instanceof ExpandableNotificationRow) {
- toRemove.add((ExpandableNotificationRow) child);
+ ExpandableNotificationRow row = (ExpandableNotificationRow) child;
+
+ // Blocking helper is effectively a detached view. Don't bother removing it from the
+ // layout.
+ if (!row.isBlockingHelperShowing()) {
+ viewsToRemove.add((ExpandableNotificationRow) child);
+ }
}
}
- for (ExpandableNotificationRow remove : toRemove) {
- if (mGroupManager.isChildInGroupWithSummary(remove.getStatusBarNotification())) {
+ for (ExpandableNotificationRow viewToRemove : viewsToRemove) {
+ if (mGroupManager.isChildInGroupWithSummary(viewToRemove.getStatusBarNotification())) {
// we are only transferring this notification to its parent, don't generate an
// animation
mListContainer.setChildTransferInProgress(true);
}
- if (remove.isSummaryWithChildren()) {
- remove.removeAllChildren();
+ if (viewToRemove.isSummaryWithChildren()) {
+ viewToRemove.removeAllChildren();
}
- mListContainer.removeContainerView(remove);
+ mListContainer.removeContainerView(viewToRemove);
mListContainer.setChildTransferInProgress(false);
}
@@ -168,6 +174,10 @@
// We don't care about non-notification views.
continue;
}
+ if (((ExpandableNotificationRow) child).isBlockingHelperShowing()) {
+ // Don't count/reorder notifications that are showing the blocking helper!
+ continue;
+ }
ExpandableNotificationRow targetChild = toShow.get(j);
if (child != targetChild) {
@@ -340,7 +350,7 @@
}
}
- row.showBlockingHelper(entry.userSentiment ==
+ row.showBlockingHelperButton(entry.userSentiment ==
NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE);
row.showAppOpsIcons(entry.mActiveAppOps);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
index 3cf7741..e7b768f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java
@@ -55,7 +55,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
// Intimately tied to the design of res/layout/signal_cluster_view.xml
public class SignalClusterView extends LinearLayout implements NetworkControllerImpl.SignalCallback,
@@ -277,7 +276,8 @@
@Override
public void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description, boolean isTransient) {
+ boolean activityIn, boolean activityOut, String description, boolean isTransient,
+ String secondaryLabel) {
mWifiVisible = statusIcon.visible && !mBlockWifi;
mWifiStrengthId = statusIcon.icon;
mWifiDescription = statusIcon.contentDescription;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
index badc40d..14a6c42 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StackScrollerDecorView.java
@@ -31,8 +31,11 @@
public abstract class StackScrollerDecorView extends ExpandableView {
protected View mContent;
+ protected View mSecondaryView;
private boolean mIsVisible;
+ private boolean mIsSecondaryVisible;
private boolean mAnimating;
+ private int mDuration = 260;
public StackScrollerDecorView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -42,6 +45,7 @@
protected void onFinishInflate() {
super.onFinishInflate();
mContent = findContentView();
+ mSecondaryView = findSecondaryView();
setInvisible();
}
@@ -57,17 +61,37 @@
}
public void performVisibilityAnimation(boolean nowVisible) {
- animateText(nowVisible, null /* onFinishedRunnable */);
+ animateText(mContent, nowVisible, null /* onFinishedRunnable */);
+ mIsVisible = nowVisible;
}
public void performVisibilityAnimation(boolean nowVisible, Runnable onFinishedRunnable) {
- animateText(nowVisible, onFinishedRunnable);
+ animateText(mContent, nowVisible, onFinishedRunnable);
+ mIsVisible = nowVisible;
+ }
+
+ public void performSecondaryVisibilityAnimation(boolean nowVisible) {
+ performSecondaryVisibilityAnimation(nowVisible, null /* onFinishedRunnable */);
+ }
+
+ public void performSecondaryVisibilityAnimation(boolean nowVisible,
+ Runnable onFinishedRunnable) {
+ animateText(mSecondaryView, nowVisible, onFinishedRunnable);
+ mIsSecondaryVisible = nowVisible;
+ }
+
+ public boolean isSecondaryVisible() {
+ return mSecondaryView != null && (mIsSecondaryVisible || mAnimating);
}
public boolean isVisible() {
return mIsVisible || mAnimating;
}
+ void setDuration(int duration) {
+ mDuration = duration;
+ }
+
/**
* Animate the text to a new visibility.
*
@@ -75,7 +99,10 @@
* @param onFinishedRunnable A runnable which should be run when the animation is
* finished.
*/
- private void animateText(boolean nowVisible, final Runnable onFinishedRunnable) {
+ private void animateText(View view, boolean nowVisible, final Runnable onFinishedRunnable) {
+ if (view == null) {
+ return;
+ }
if (nowVisible != mIsVisible) {
// Animate text
float endValue = nowVisible ? 1.0f : 0.0f;
@@ -86,10 +113,10 @@
interpolator = Interpolators.ALPHA_OUT;
}
mAnimating = true;
- mContent.animate()
+ view.animate()
.alpha(endValue)
.setInterpolator(interpolator)
- .setDuration(260)
+ .setDuration(mDuration)
.withEndAction(new Runnable() {
@Override
public void run() {
@@ -99,7 +126,6 @@
}
}
});
- mIsVisible = nowVisible;
} else {
if (onFinishedRunnable != null) {
onFinishedRunnable.run();
@@ -109,7 +135,11 @@
public void setInvisible() {
mContent.setAlpha(0.0f);
+ if (mSecondaryView != null) {
+ mSecondaryView.setAlpha(0.0f);
+ }
mIsVisible = false;
+ mIsSecondaryVisible = false;
}
@Override
@@ -134,7 +164,15 @@
public void cancelAnimation() {
mContent.animate().cancel();
+ if (mSecondaryView != null) {
+ mSecondaryView.animate().cancel();
+ }
}
protected abstract View findContentView();
+
+ /**
+ * Returns a view that might not always appear while the main content view is still visible.
+ */
+ protected abstract View findSecondaryView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
index a2b1013..6576eb7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
@@ -399,4 +399,11 @@
pw.print(" mMode="); pw.println(mMode);
pw.print(" mWakeLock="); pw.println(mWakeLock);
}
+
+ public boolean isWakeAndUnlock() {
+ return mMode == MODE_UNLOCK
+ || mMode == MODE_WAKE_AND_UNLOCK
+ || mMode == MODE_WAKE_AND_UNLOCK_PULSING
+ || mMode == MODE_WAKE_AND_UNLOCK_FROM_DREAM;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index a39800d..58f8baa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -171,7 +171,7 @@
private final OverviewProxyListener mOverviewProxyListener = new OverviewProxyListener() {
@Override
public void onConnectionChanged(boolean isConnected) {
- mNavigationBarView.onOverviewProxyConnectionChanged(isConnected);
+ mNavigationBarView.updateStates();
updateScreenPinningGestures();
WindowManagerWrapper.getInstance()
.setNavBarVirtualKeyHapticFeedbackEnabled(!isConnected);
@@ -188,6 +188,7 @@
@Override
public void onInteractionFlagsChanged(@InteractionType int flags) {
mNavigationBarView.updateStates();
+ updateScreenPinningGestures();
}
};
@@ -925,7 +926,9 @@
private boolean onLongPressRecents() {
if (mRecents == null || !ActivityManager.supportsMultiWindow(getContext())
|| !mDivider.getView().getSnapAlgorithm().isSplitScreenFeasible()
- || Recents.getConfiguration().isLowRamDevice) {
+ || Recents.getConfiguration().isLowRamDevice
+ // If we are connected to the overview service, then disable the recents button
+ || mOverviewProxyService.getProxy() != null) {
return false;
}
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 88bc6ea..b4cb088 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -681,6 +681,7 @@
updateSlippery();
reloadNavIcons();
updateNavButtonIcons();
+ setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
}
private void updateSlippery() {
@@ -816,11 +817,6 @@
}
}
- public void onOverviewProxyConnectionChanged(boolean isConnected) {
- updateStates();
- setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
- }
-
@Override
protected void onDraw(Canvas canvas) {
mGestureHelper.onDraw(canvas);
@@ -1045,7 +1041,7 @@
onPluginDisconnected(null); // Create default gesture helper
Dependency.get(PluginManager.class).addPluginListener(this,
NavGesture.class, false /* Only one */);
- setUpSwipeUpOnboarding(mOverviewProxyService.getProxy() != null);
+ setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index b75c7e0..ca65965 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -169,7 +169,7 @@
if (group.suppressed) {
handleSuppressedSummaryHeadsUpped(group.summary);
}
- if (!mIsUpdatingUnchangedGroup) {
+ if (!mIsUpdatingUnchangedGroup && mListener != null) {
mListener.onGroupsChanged();
}
}
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 64e205d..cccda90 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2165,18 +2165,18 @@
@Override
protected boolean fullyExpandedClearAllVisible() {
- return mNotificationStackScroller.isDismissViewNotGone()
+ return mNotificationStackScroller.isFooterViewNotGone()
&& mNotificationStackScroller.isScrolledToBottom() && !mQsExpandImmediate;
}
@Override
protected boolean isClearAllVisible() {
- return mNotificationStackScroller.isDismissViewVisible();
+ return mNotificationStackScroller.isFooterViewVisible();
}
@Override
protected int getClearAllHeight() {
- return mNotificationStackScroller.getDismissViewHeight();
+ return mNotificationStackScroller.getFooterViewHeight();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 7a6e98d..4e12936 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -85,7 +85,7 @@
/**
* Default alpha value for most scrims.
*/
- public static final float GRADIENT_SCRIM_ALPHA = 0.45f;
+ public static final float GRADIENT_SCRIM_ALPHA = 0.70f;
/**
* A scrim varies its opacity based on a busyness factor, for example
* how many notifications are currently visible.
@@ -347,7 +347,9 @@
if (mExpansionFraction != fraction) {
mExpansionFraction = fraction;
- if (!(mState == ScrimState.UNLOCKED || mState == ScrimState.KEYGUARD)) {
+ final boolean keyguardOrUnlocked = mState == ScrimState.UNLOCKED
+ || mState == ScrimState.KEYGUARD;
+ if (!keyguardOrUnlocked || !mExpansionAffectsAlpha) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 5b734eb..f4b6c38 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -156,7 +156,6 @@
mCurrentBehindTint = Color.BLACK;
mBlankScreen = true;
} else {
- // Scrims should still be black at the end of the transition.
mCurrentInFrontTint = Color.TRANSPARENT;
mCurrentBehindTint = Color.TRANSPARENT;
mBlankScreen = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 8246974..c03ecb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -130,7 +130,6 @@
import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.widget.LockPatternUtils;
@@ -185,12 +184,11 @@
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CrossFadeHelper;
-import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.FooterView;
import com.android.systemui.statusbar.GestureRecorder;
-import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.KeyboardShortcuts;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationData;
@@ -237,7 +235,6 @@
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
-import com.android.systemui.util.NotificationChannels;
import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
@@ -411,6 +408,7 @@
protected NotificationEntryManager mEntryManager;
protected NotificationViewHierarchyManager mViewHierarchyManager;
protected AppOpsListener mAppOpsListener;
+ protected KeyguardViewMediator mKeyguardViewMediator;
private ZenModeController mZenController;
/**
@@ -577,7 +575,7 @@
private final LockscreenGestureLogger mLockscreenGestureLogger = new LockscreenGestureLogger();
protected NotificationIconAreaController mNotificationIconAreaController;
private boolean mReinflateNotificationsOnUserSwitched;
- private boolean mClearAllEnabled;
+ protected boolean mClearAllEnabled;
@Nullable private View mAmbientIndicationContainer;
private SysuiColorExtractor mColorExtractor;
private ScreenLifecycle mScreenLifecycle;
@@ -635,6 +633,7 @@
mAppOpsListener = Dependency.get(AppOpsListener.class);
mAppOpsListener.setUpWithPresenter(this, mEntryManager);
mZenController = Dependency.get(ZenModeController.class);
+ mKeyguardViewMediator = getComponent(KeyguardViewMediator.class);
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mColorExtractor.addOnColorsChangedListener(this);
@@ -868,7 +867,7 @@
mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
inflateEmptyShadeView();
- inflateDismissView();
+ inflateFooterView();
mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
mBackdropFront = mBackdrop.findViewById(R.id.backdrop_front);
@@ -1133,8 +1132,8 @@
protected void reevaluateStyles() {
inflateSignalClusters();
- inflateDismissView();
- updateClearAll();
+ inflateFooterView();
+ updateFooter();
inflateEmptyShadeView();
updateEmptyShadeView();
}
@@ -1186,18 +1185,21 @@
mStackScroller.setEmptyShadeView(mEmptyShadeView);
}
- private void inflateDismissView() {
- if (!mClearAllEnabled || mStackScroller == null) {
+ private void inflateFooterView() {
+ if (mStackScroller == null) {
return;
}
- mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
- R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
- mDismissView.setOnButtonClickListener(v -> {
+ mFooterView = (FooterView) LayoutInflater.from(mContext).inflate(
+ R.layout.status_bar_notification_footer, mStackScroller, false);
+ mFooterView.setDismissButtonClickListener(v -> {
mMetricsLogger.action(MetricsEvent.ACTION_DISMISS_ALL_NOTES);
clearAllNotifications();
});
- mStackScroller.setDismissView(mDismissView);
+ mFooterView.setManageButtonClickListener(v -> {
+ manageNotifications();
+ });
+ mStackScroller.setFooterView(mFooterView);
}
protected void createUserSwitcher() {
@@ -1211,6 +1213,12 @@
R.layout.super_status_bar, null);
}
+ public void manageNotifications() {
+ Intent intent = new Intent(Settings.ACTION_ALL_APPS_NOTIFICATION_SETTINGS);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent, true, true);
+ }
+
public void clearAllNotifications() {
// animate-swipe all dismissable notifications, then animate the shade closed
@@ -1393,7 +1401,7 @@
mViewHierarchyManager.updateNotificationViews();
updateSpeedBumpIndex();
- updateClearAll();
+ updateFooter();
updateEmptyShadeView();
updateQsExpansionEnabled();
@@ -1457,13 +1465,14 @@
mQSPanel.clickTile(tile);
}
- private void updateClearAll() {
- if (!mClearAllEnabled) {
- return;
- }
- boolean showDismissView = mState != StatusBarState.KEYGUARD
+ @VisibleForTesting
+ protected void updateFooter() {
+ boolean showFooterView = mState != StatusBarState.KEYGUARD
+ && mEntryManager.getNotificationData().getActiveNotifications().size() != 0;
+ boolean showDismissView = mClearAllEnabled && mState != StatusBarState.KEYGUARD
&& hasActiveClearableNotifications();
- mStackScroller.updateDismissView(showDismissView);
+
+ mStackScroller.updateFooterView(showFooterView, showDismissView);
}
/**
@@ -4621,6 +4630,7 @@
boolean dozing = mDozingRequested && mState == StatusBarState.KEYGUARD
|| mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
+ final boolean alwaysOn = DozeParameters.getInstance(mContext).getAlwaysOn();
// When in wake-and-unlock we may not have received a change to mState
// but we still should not be dozing, manually set to false.
if (mFingerprintUnlockController.getMode() ==
@@ -4628,6 +4638,7 @@
dozing = false;
}
mDozing = dozing;
+ mKeyguardViewMediator.setAodShowing(mDozing && alwaysOn);
mStatusBarWindowManager.setDozing(mDozing);
mStatusBarKeyguardViewManager.setDozing(mDozing);
if (mAmbientIndicationContainer instanceof DozeReceiver) {
@@ -4648,9 +4659,8 @@
final boolean wakeAndUnlocking = mFingerprintUnlockController.getMode()
== FingerprintUnlockController.MODE_WAKE_AND_UNLOCK;
- // Do not animate the scrim expansion when it's triggered by the fingerprint sensor.
- mScrimController.setExpansionAffectsAlpha(mFingerprintUnlockController.getMode()
- != FingerprintUnlockController.MODE_UNLOCK);
+ // Do not animate the scrim expansion when triggered by the fingerprint sensor.
+ mScrimController.setExpansionAffectsAlpha(!mFingerprintUnlockController.isWakeAndUnlock());
if (mBouncerShowing) {
// Bouncer needs the front scrim when it's on top of an activity,
@@ -4938,7 +4948,7 @@
protected RecentsComponent mRecents;
protected NotificationShelf mNotificationShelf;
- protected DismissView mDismissView;
+ protected FooterView mFooterView;
protected EmptyShadeView mEmptyShadeView;
protected AssistManager mAssistManager;
@@ -5411,8 +5421,8 @@
// incremented in the following "changeViewPosition" calls so that its value is correct for
// subsequent calls.
int offsetFromEnd = 1;
- if (mDismissView != null) {
- mStackScroller.changeViewPosition(mDismissView,
+ if (mFooterView != null) {
+ mStackScroller.changeViewPosition(mFooterView,
mStackScroller.getChildCount() - offsetFromEnd++);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 1a64b00..5975608 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -154,7 +154,7 @@
if (expansion == 1) {
mBouncer.onFullyHidden();
} else if (!mBouncer.isShowing() && !mBouncer.isAnimatingAway()) {
- mBouncer.show(true /* resetSecuritySelection */, false /* notifyFalsing */);
+ mBouncer.show(false /* resetSecuritySelection */, false /* notifyFalsing */);
} else if (noLongerTracking) {
// Notify that falsing manager should stop its session when user stops touching,
// even before the animation ends, to guarantee that we're not recording sensitive
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 309a1a7..2437c51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -143,7 +143,9 @@
final boolean scrimsOccludingWallpaper =
state.scrimsVisibility == ScrimController.VISIBILITY_FULLY_OPAQUE;
- if (state.keyguardShowing && !state.backdropShowing && !scrimsOccludingWallpaper) {
+ final boolean keyguardOrAod = state.keyguardShowing
+ || (state.dozing && mDozeParameters.getAlwaysOn());
+ if (keyguardOrAod && !state.backdropShowing && !scrimsOccludingWallpaper) {
mLpChanged.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
} else {
mLpChanged.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
index 5159e8d..b76d536 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/CallbackHandler.java
@@ -109,13 +109,13 @@
@Override
public void setWifiIndicators(final boolean enabled, final IconState statusIcon,
final IconState qsIcon, final boolean activityIn, final boolean activityOut,
- final String description, boolean isTransient) {
+ final String description, boolean isTransient, String secondaryLabel) {
post(new Runnable() {
@Override
public void run() {
for (SignalCallback callback : mSignalCallbacks) {
callback.setWifiIndicators(enabled, statusIcon, qsIcon, activityIn, activityOut,
- description, isTransient);
+ description, isTransient, secondaryLabel);
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 4c92d01..baeaaad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -40,6 +40,7 @@
import android.view.View;
import android.widget.TextView;
+import com.android.settingslib.Utils;
import com.android.systemui.DemoMode;
import com.android.systemui.Dependency;
import com.android.systemui.FontSizeUtils;
@@ -84,6 +85,17 @@
private boolean mShowSeconds;
private Handler mSecondsHandler;
+ /**
+ * Whether we should use colors that adapt based on wallpaper/the scrim behind quick settings
+ * for text.
+ */
+ private boolean mUseWallpaperTextColor;
+
+ /**
+ * Color to be set on this {@link TextView}, when wallpaperTextColor is <b>not</b> utilized.
+ */
+ private int mNonAdaptedColor;
+
public Clock(Context context) {
this(context, null);
}
@@ -101,6 +113,7 @@
try {
mAmPmStyle = a.getInt(R.styleable.Clock_amPmStyle, AM_PM_STYLE_GONE);
mShowDark = a.getBoolean(R.styleable.Clock_showDark, true);
+ mNonAdaptedColor = getCurrentTextColor();
} finally {
a.recycle();
}
@@ -227,7 +240,10 @@
@Override
public void onDarkChanged(Rect area, float darkIntensity, int tint) {
- setTextColor(DarkIconDispatcher.getTint(area, this, tint));
+ mNonAdaptedColor = DarkIconDispatcher.getTint(area, this, tint);
+ if (!mUseWallpaperTextColor) {
+ setTextColor(mNonAdaptedColor);
+ }
}
@Override
@@ -242,6 +258,25 @@
0);
}
+ /**
+ * Sets whether the clock uses the wallpaperTextColor. If we're not using it, we'll revert back
+ * to dark-mode-based/tinted colors.
+ *
+ * @param shouldUseWallpaperTextColor whether we should use wallpaperTextColor for text color
+ */
+ public void useWallpaperTextColor(boolean shouldUseWallpaperTextColor) {
+ if (shouldUseWallpaperTextColor == mUseWallpaperTextColor) {
+ return;
+ }
+ mUseWallpaperTextColor = shouldUseWallpaperTextColor;
+
+ if (mUseWallpaperTextColor) {
+ setTextColor(Utils.getColorAttr(mContext, R.attr.wallpaperTextColor));
+ } else {
+ setTextColor(mNonAdaptedColor);
+ }
+ }
+
private void updateShowSeconds() {
if (mShowSeconds) {
// Wait until we have a display to start trying to show seconds.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
index 74a30fa..ef630c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DateView.java
@@ -27,6 +27,7 @@
import android.util.AttributeSet;
import android.widget.TextView;
+import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
@@ -42,6 +43,17 @@
private String mLastText;
private String mDatePattern;
+ /**
+ * Whether we should use colors that adapt based on wallpaper/the scrim behind quick settings
+ * for text.
+ */
+ private boolean mUseWallpaperTextColor;
+
+ /**
+ * Color to be set on this {@link TextView}, when wallpaperTextColor is <b>not</b> utilized.
+ */
+ private int mNonAdaptedTextColor;
+
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -62,6 +74,7 @@
public DateView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mNonAdaptedTextColor = getCurrentTextColor();
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.DateView,
@@ -117,6 +130,25 @@
}
}
+ /**
+ * Sets whether the date view uses the wallpaperTextColor. If we're not using it, we'll revert
+ * back to dark-mode-based/tinted colors.
+ *
+ * @param shouldUseWallpaperTextColor whether we should use wallpaperTextColor for text color
+ */
+ public void useWallpaperTextColor(boolean shouldUseWallpaperTextColor) {
+ if (shouldUseWallpaperTextColor == mUseWallpaperTextColor) {
+ return;
+ }
+ mUseWallpaperTextColor = shouldUseWallpaperTextColor;
+
+ if (mUseWallpaperTextColor) {
+ setTextColor(Utils.getColorAttr(mContext, R.attr.wallpaperTextColor));
+ } else {
+ setTextColor(mNonAdaptedTextColor);
+ }
+ }
+
public void setDatePattern(String pattern) {
if (TextUtils.equals(pattern, mDatePattern)) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 76e3ad7..51fef7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -47,7 +47,8 @@
public interface SignalCallback {
default void setWifiIndicators(boolean enabled, IconState statusIcon, IconState qsIcon,
- boolean activityIn, boolean activityOut, String description, boolean isTransient) {}
+ boolean activityIn, boolean activityOut, String description, boolean isTransient,
+ String statusLabel) {}
default void setMobileDataIndicators(IconState statusIcon, IconState qsIcon, int statusType,
int qsType, boolean activityIn, boolean activityOut, String typeContentDescription,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 0f65421..e5e576d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -17,12 +17,15 @@
import android.content.Context;
import android.content.Intent;
+import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
+import android.net.NetworkScoreManager;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
+import android.text.TextUtils;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -37,7 +40,6 @@
public class WifiSignalController extends
SignalController<WifiSignalController.WifiState, SignalController.IconGroup> {
- private final WifiManager mWifiManager;
private final AsyncChannel mWifiChannel;
private final boolean mHasMobileData;
private final WifiStatusTracker mWifiTracker;
@@ -47,12 +49,17 @@
WifiManager wifiManager) {
super("WifiSignalController", context, NetworkCapabilities.TRANSPORT_WIFI,
callbackHandler, networkController);
- mWifiManager = wifiManager;
- mWifiTracker = new WifiStatusTracker(mWifiManager);
+ NetworkScoreManager networkScoreManager =
+ context.getSystemService(NetworkScoreManager.class);
+ ConnectivityManager connectivityManager =
+ context.getSystemService(ConnectivityManager.class);
+ mWifiTracker = new WifiStatusTracker(mContext, wifiManager, networkScoreManager,
+ connectivityManager, this::handleStatusUpdated);
+ mWifiTracker.setListening(true);
mHasMobileData = hasMobileData;
Handler handler = new WifiHandler(Looper.getMainLooper());
mWifiChannel = new AsyncChannel();
- Messenger wifiMessenger = mWifiManager.getWifiServiceMessenger();
+ Messenger wifiMessenger = wifiManager.getWifiServiceMessenger();
if (wifiMessenger != null) {
mWifiChannel.connect(context, handler, wifiMessenger);
}
@@ -68,7 +75,6 @@
WifiIcons.QS_WIFI_NO_NETWORK,
AccessibilityContentDescriptions.WIFI_NO_CONNECTION
);
-
}
@Override
@@ -87,13 +93,12 @@
if (mCurrentState.inetCondition == 0) {
contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
}
-
IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
IconState qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconId(),
contentDescription);
callback.setWifiIndicators(mCurrentState.enabled, statusIcon, qsIcon,
ssidPresent && mCurrentState.activityIn, ssidPresent && mCurrentState.activityOut,
- wifiDesc, mCurrentState.isTransient);
+ wifiDesc, mCurrentState.isTransient, mCurrentState.statusLabel);
}
/**
@@ -106,6 +111,12 @@
mCurrentState.ssid = mWifiTracker.ssid;
mCurrentState.rssi = mWifiTracker.rssi;
mCurrentState.level = mWifiTracker.level;
+ mCurrentState.statusLabel = mWifiTracker.statusLabel;
+ notifyListenersIfNecessary();
+ }
+
+ private void handleStatusUpdated() {
+ mCurrentState.statusLabel = mWifiTracker.statusLabel;
notifyListenersIfNecessary();
}
@@ -150,6 +161,7 @@
static class WifiState extends SignalController.State {
String ssid;
boolean isTransient;
+ String statusLabel;
@Override
public void copyFrom(State s) {
@@ -157,20 +169,26 @@
WifiState state = (WifiState) s;
ssid = state.ssid;
isTransient = state.isTransient;
+ statusLabel = state.statusLabel;
}
@Override
protected void toString(StringBuilder builder) {
super.toString(builder);
- builder.append(',').append("ssid=").append(ssid);
- builder.append(',').append("isTransient=").append(isTransient);
+ builder.append(",ssid=").append(ssid)
+ .append(",isTransient=").append(isTransient)
+ .append(",statusLabel=").append(statusLabel);
}
@Override
public boolean equals(Object o) {
- return super.equals(o)
- && Objects.equals(((WifiState) o).ssid, ssid)
- && (((WifiState) o).isTransient == isTransient);
+ if (!super.equals(o)) {
+ return false;
+ }
+ WifiState other = (WifiState) o;
+ return Objects.equals(other.ssid, ssid)
+ && other.isTransient == isTransient
+ && TextUtils.equals(other.statusLabel, statusLabel);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index dc94203..375e860 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -16,7 +16,8 @@
package com.android.systemui.statusbar.stack;
-import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
+import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator
+ .ExpandAnimationParameters;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -43,6 +44,7 @@
import android.service.notification.StatusBarNotification;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
+import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
@@ -68,6 +70,7 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.Utils;
+import com.android.systemui.Dependency;
import com.android.systemui.ExpandHelper;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
@@ -77,10 +80,11 @@
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.ActivatableNotificationView;
-import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.FooterView;
+import com.android.systemui.statusbar.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationGuts;
import com.android.systemui.statusbar.NotificationListContainer;
@@ -99,8 +103,6 @@
import com.android.systemui.statusbar.policy.HeadsUpUtil;
import com.android.systemui.statusbar.policy.ScrollAdapter;
-import android.support.v4.graphics.ColorUtils;
-
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -109,7 +111,6 @@
import java.util.HashSet;
import java.util.List;
import java.util.function.BiConsumer;
-import java.util.function.Consumer;
/**
* A layout which handles a dynamic amount of notifications and presents them in a scrollable stack.
@@ -226,7 +227,7 @@
private boolean mExpandingNotification;
private boolean mExpandedInThisMotion;
protected boolean mScrollingEnabled;
- protected DismissView mDismissView;
+ protected FooterView mFooterView;
protected EmptyShadeView mEmptyShadeView;
private boolean mDismissAllInProgress;
private boolean mFadeNotificationsOnDismiss;
@@ -449,6 +450,13 @@
mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
addOnExpandedHeightListener(mRoundnessManager::setExpanded);
+ // Blocking helper manager wants to know the expanded state, update as well.
+ NotificationBlockingHelperManager blockingHelperManager =
+ Dependency.get(NotificationBlockingHelperManager.class);
+ addOnExpandedHeightListener((height, unused) -> {
+ blockingHelperManager.setNotificationShadeExpanded(height);
+ });
+
updateWillNotDraw();
mBackgroundPaint.setAntiAlias(true);
if (DEBUG) {
@@ -1039,45 +1047,63 @@
mQsContainer = qsContainer;
}
+ /**
+ * Handles cleanup after the given {@code view} has been fully swiped out (including
+ * re-invoking dismiss logic in case the notification has not made its way out yet).
+ */
@Override
- public void onChildDismissed(View v) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+ public void onChildDismissed(View view) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) view;
if (!row.isDismissed()) {
- handleChildDismissed(v);
+ handleChildViewDismissed(view);
}
ViewGroup transientContainer = row.getTransientContainer();
if (transientContainer != null) {
- transientContainer.removeTransientView(v);
+ transientContainer.removeTransientView(view);
}
}
- private void handleChildDismissed(View v) {
+ /**
+ * Starts up notification dismiss and tells the notification, if any, to remove itself from
+ * layout.
+ *
+ * @param view view (e.g. notification) to dismiss from the layout
+ */
+ private void handleChildViewDismissed(View view) {
if (mDismissAllInProgress) {
return;
}
+
+ boolean isBlockingHelperShown = false;
+
setSwipingInProgress(false);
- if (mDragAnimPendingChildren.contains(v)) {
- // We start the swipe and finish it in the same frame, we don't want any animation
- // for the drag
- mDragAnimPendingChildren.remove(v);
+ if (mDragAnimPendingChildren.contains(view)) {
+ // We start the swipe and finish it in the same frame; we don't want a drag animation.
+ mDragAnimPendingChildren.remove(view);
}
- mSwipedOutViews.add(v);
- mAmbientState.onDragFinished(v);
+ mAmbientState.onDragFinished(view);
updateContinuousShadowDrawing();
- if (v instanceof ExpandableNotificationRow) {
- ExpandableNotificationRow row = (ExpandableNotificationRow) v;
+
+ if (view instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) view;
if (row.isHeadsUp()) {
mHeadsUpManager.addSwipedOutNotification(row.getStatusBarNotification().getKey());
}
- }
- if (v instanceof ExpandableNotificationRow) {
- ((ExpandableNotificationRow) v).performDismiss(false /* fromAccessibility */);
+ isBlockingHelperShown =
+ row.performDismissWithBlockingHelper(false /* fromAccessibility */);
}
+ if (!isBlockingHelperShown) {
+ mSwipedOutViews.add(view);
+ }
mFalsingManager.onNotificationDismissed();
if (mFalsingManager.shouldEnforceBouncer()) {
- mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
- false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
+ mStatusBar.executeRunnableDismissingKeyguard(
+ null,
+ null /* cancelAction */,
+ false /* dismissShade */,
+ true /* afterKeyguardGone */,
+ false /* deferred */);
}
}
@@ -2730,9 +2756,8 @@
updateScrollStateForRemovedChild(expandableView);
boolean animationGenerated = generateRemoveAnimation(child);
if (animationGenerated) {
- if (!mSwipedOutViews.contains(child)) {
- container.getOverlay().add(child);
- } else if (Math.abs(expandableView.getTranslation()) != expandableView.getWidth()) {
+ if (!mSwipedOutViews.contains(child)
+ || Math.abs(expandableView.getTranslation()) != expandableView.getWidth()) {
container.addTransientView(child, 0);
expandableView.setTransientContainer(container);
}
@@ -3838,13 +3863,13 @@
Context context = new ContextThemeWrapper(mContext,
lightTheme ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI);
final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
- mDismissView.setTextColor(textColor);
+ mFooterView.setTextColor(textColor);
mEmptyShadeView.setTextColor(textColor);
}
public void goToFullShade(long delay) {
- if (mDismissView != null) {
- mDismissView.setInvisible();
+ if (mFooterView != null) {
+ mFooterView.setInvisible();
}
mEmptyShadeView.setInvisible();
mGoToFullShadeNeedsAnimation = true;
@@ -3967,14 +3992,14 @@
return -1;
}
- public void setDismissView(@NonNull DismissView dismissView) {
+ public void setFooterView(@NonNull FooterView footerView) {
int index = -1;
- if (mDismissView != null) {
- index = indexOfChild(mDismissView);
- removeView(mDismissView);
+ if (mFooterView != null) {
+ index = indexOfChild(mFooterView);
+ removeView(mFooterView);
}
- mDismissView = dismissView;
- addView(mDismissView, index);
+ mFooterView = footerView;
+ addView(mFooterView, index);
}
public void setEmptyShadeView(EmptyShadeView emptyShadeView) {
@@ -3992,77 +4017,64 @@
int newVisibility = visible ? VISIBLE : GONE;
if (oldVisibility != newVisibility) {
if (newVisibility != GONE) {
- if (mEmptyShadeView.willBeGone()) {
- mEmptyShadeView.cancelAnimation();
- } else {
- mEmptyShadeView.setInvisible();
- }
if (mStatusBar.areNotificationsHidden()) {
mEmptyShadeView.setText(R.string.dnd_suppressing_shade_text);
} else {
mEmptyShadeView.setText(R.string.empty_shade_text);
}
- mEmptyShadeView.setVisibility(newVisibility);
- mEmptyShadeView.setWillBeGone(false);
- updateContentHeight();
- notifyHeightChangeListener(mEmptyShadeView);
+ showFooterView(mEmptyShadeView);
} else {
- Runnable onFinishedRunnable = new Runnable() {
- @Override
- public void run() {
- mEmptyShadeView.setVisibility(GONE);
- mEmptyShadeView.setWillBeGone(false);
- updateContentHeight();
- notifyHeightChangeListener(mEmptyShadeView);
- }
- };
- if (mAnimationsEnabled && mIsExpanded) {
- mEmptyShadeView.setWillBeGone(true);
- mEmptyShadeView.performVisibilityAnimation(false, onFinishedRunnable);
- } else {
- mEmptyShadeView.setInvisible();
- onFinishedRunnable.run();
- }
+ hideFooterView(mEmptyShadeView, true);
}
}
}
- public void updateDismissView(boolean visible) {
- if (mDismissView == null) {
+ public void updateFooterView(boolean visible, boolean showDismissView) {
+ if (mFooterView == null) {
return;
}
-
- int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility();
+ int oldVisibility = mFooterView.willBeGone() ? GONE : mFooterView.getVisibility();
int newVisibility = visible ? VISIBLE : GONE;
if (oldVisibility != newVisibility) {
if (newVisibility != GONE) {
- if (mDismissView.willBeGone()) {
- mDismissView.cancelAnimation();
- } else {
- mDismissView.setInvisible();
- }
- mDismissView.setVisibility(newVisibility);
- mDismissView.setWillBeGone(false);
- updateContentHeight();
- notifyHeightChangeListener(mDismissView);
+ showFooterView(mFooterView);
} else {
- Runnable dimissHideFinishRunnable = new Runnable() {
- @Override
- public void run() {
- mDismissView.setVisibility(GONE);
- mDismissView.setWillBeGone(false);
- updateContentHeight();
- notifyHeightChangeListener(mDismissView);
- }
- };
- if (mDismissView.isButtonVisible() && mIsExpanded && mAnimationsEnabled) {
- mDismissView.setWillBeGone(true);
- mDismissView.performVisibilityAnimation(false, dimissHideFinishRunnable);
- } else {
- dimissHideFinishRunnable.run();
- }
+ hideFooterView(mFooterView, mFooterView.isButtonVisible());
}
}
+ if (mFooterView.isSecondaryVisible() != showDismissView) {
+ mFooterView.performSecondaryVisibilityAnimation(showDismissView);
+ }
+ }
+
+ private void showFooterView(StackScrollerDecorView footerView) {
+ if (footerView.willBeGone()) {
+ footerView.cancelAnimation();
+ } else {
+ footerView.setInvisible();
+ }
+ footerView.setVisibility(VISIBLE);
+ footerView.setWillBeGone(false);
+ updateContentHeight();
+ notifyHeightChangeListener(footerView);
+ }
+
+ private void hideFooterView(StackScrollerDecorView footerView, boolean isButtonVisible) {
+ Runnable onHideFinishRunnable = new Runnable() {
+ @Override
+ public void run() {
+ footerView.setVisibility(GONE);
+ footerView.setWillBeGone(false);
+ updateContentHeight();
+ notifyHeightChangeListener(footerView);
+ }
+ };
+ if (isButtonVisible && mIsExpanded && mAnimationsEnabled) {
+ footerView.setWillBeGone(true);
+ footerView.performVisibilityAnimation(false, onHideFinishRunnable);
+ } else {
+ onHideFinishRunnable.run();
+ }
}
public void setDismissAllInProgress(boolean dismissAllInProgress) {
@@ -4088,18 +4100,18 @@
}
}
- public boolean isDismissViewNotGone() {
- return mDismissView != null
- && mDismissView.getVisibility() != View.GONE
- && !mDismissView.willBeGone();
+ public boolean isFooterViewNotGone() {
+ return mFooterView != null
+ && mFooterView.getVisibility() != View.GONE
+ && !mFooterView.willBeGone();
}
- public boolean isDismissViewVisible() {
- return mDismissView != null && mDismissView.isVisible();
+ public boolean isFooterViewVisible() {
+ return mFooterView != null && mFooterView.isVisible();
}
- public int getDismissViewHeight() {
- return mDismissView == null ? 0 : mDismissView.getHeight() + mPaddingBetweenElements;
+ public int getFooterViewHeight() {
+ return mFooterView == null ? 0 : mFooterView.getHeight() + mPaddingBetweenElements;
}
public int getEmptyShadeViewHeight() {
@@ -4155,8 +4167,8 @@
}
boolean belowChild = touchY > childTop + child.getActualHeight()
- child.getClipBottomAmount();
- if (child == mDismissView) {
- if(!belowChild && !mDismissView.isOnEmptySpace(touchX - mDismissView.getX(),
+ if (child == mFooterView) {
+ if(!belowChild && !mFooterView.isOnEmptySpace(touchX - mFooterView.getX(),
touchY - childTop)) {
// We clicked on the dismiss button
return false;
@@ -4632,7 +4644,7 @@
if (mIsExpanded) {
// We don't want to quick-dismiss when it's a heads up as this might lead to closing
// of the panel early.
- handleChildDismissed(view);
+ handleChildViewDismissed(view);
}
mStatusBar.getGutsManager().closeAndSaveGuts(true /* removeLeavebehind */,
false /* force */, false /* removeControls */, -1 /* x */, -1 /* y */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index 7c8e0fc..a8d2d98 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -22,10 +22,10 @@
import android.view.View;
import android.view.ViewGroup;
import com.android.systemui.R;
-import com.android.systemui.statusbar.DismissView;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;
+import com.android.systemui.statusbar.FooterView;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.NotificationUtils;
@@ -390,7 +390,7 @@
int paddingAfterChild = getPaddingAfterChild(algorithmState, child);
int childHeight = getMaxAllowedChildHeight(child);
childViewState.yTranslation = currentYPosition;
- boolean isDismissView = child instanceof DismissView;
+ boolean isFooterView = child instanceof FooterView;
boolean isEmptyShadeView = child instanceof EmptyShadeView;
childViewState.location = ExpandableViewState.LOCATION_MAIN_AREA;
@@ -404,7 +404,7 @@
float end = childViewState.yTranslation + childViewState.height + inset;
childViewState.headsUpIsVisible = end < ambientState.getMaxHeadsUpTranslation();
}
- if (isDismissView) {
+ if (isFooterView) {
childViewState.yTranslation = Math.min(childViewState.yTranslation,
ambientState.getInnerHeight() - childHeight);
} else if (isEmptyShadeView) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index d48ae76..c80bdc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -51,6 +51,7 @@
= (int) (ANIMATION_DURATION_HEADS_UP_APPEAR
* HeadsUpAppearInterpolator.getFractionUntilOvershoot());
public static final int ANIMATION_DURATION_HEADS_UP_DISAPPEAR = 300;
+ public static final int ANIMATION_DURATION_BLOCKING_HELPER_FADE = 240;
public static final int ANIMATION_DELAY_PER_ELEMENT_INTERRUPTING = 80;
public static final int ANIMATION_DELAY_PER_ELEMENT_MANUAL = 32;
public static final int ANIMATION_DELAY_PER_ELEMENT_GO_TO_FULL_SHADE = 48;
@@ -79,6 +80,7 @@
private ValueAnimator mBottomOverScrollAnimator;
private int mHeadsUpAppearHeightBottom;
private boolean mShadeExpanded;
+ private ArrayList<ExpandableView> mTransientViewsToRemove = new ArrayList<>();
private NotificationShelf mShelf;
private float mStatusBarIconLocation;
private int[] mTmpLocation = new int[2];
@@ -333,6 +335,12 @@
private void onAnimationFinished() {
mHostLayout.onChildAnimationFinished();
+
+ for (ExpandableView transientViewsToRemove : mTransientViewsToRemove) {
+ transientViewsToRemove.getTransientContainer()
+ .removeTransientView(transientViewsToRemove);
+ }
+ mTransientViewsToRemove.clear();
}
/**
@@ -362,7 +370,7 @@
} else if (event.animationType ==
NotificationStackScrollLayout.AnimationEvent.ANIMATION_TYPE_REMOVE) {
if (changingView.getVisibility() != View.VISIBLE) {
- removeFromOverlay(changingView);
+ removeTransientView(changingView);
continue;
}
@@ -402,8 +410,7 @@
0, new Runnable() {
@Override
public void run() {
- // remove the temporary overlay
- removeFromOverlay(changingView);
+ removeTransientView(changingView);
}
}, null);
} else if (event.animationType ==
@@ -494,6 +501,12 @@
}
}
+ private static void removeTransientView(ExpandableView viewToRemove) {
+ if (viewToRemove.getTransientContainer() != null) {
+ viewToRemove.getTransientContainer().removeTransientView(viewToRemove);
+ }
+ }
+
public static void removeFromOverlay(View changingView) {
ViewGroup parent = (ViewGroup) changingView.getParent();
if (parent != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
index fc932c3..1cbdfe8 100644
--- a/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
+++ b/packages/SystemUI/src/com/android/systemui/util/NotificationChannels.java
@@ -37,6 +37,7 @@
public static String STORAGE = "DSK";
public static String TVPIP = "TPP";
public static String BATTERY = "BAT";
+ public static String HINTS = "HNT";
@VisibleForTesting
static void createAll(Context context) {
@@ -73,6 +74,12 @@
: NotificationManager.IMPORTANCE_LOW);
storage.setBypassDnd(true);
+ final NotificationChannel hint = new NotificationChannel(
+ HINTS,
+ context.getString(R.string.notification_channel_hints),
+ NotificationManager.IMPORTANCE_DEFAULT);
+ // No need to bypass DND.
+
nm.createNotificationChannels(Arrays.asList(
alerts,
general,
@@ -80,7 +87,8 @@
createScreenshotChannel(
context.getString(R.string.notification_channel_screenshot),
nm.getNotificationChannel(SCREENSHOTS_LEGACY)),
- batteryChannel
+ batteryChannel,
+ hint
));
// Delete older SS channel if present.
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 1c8a26c..d9cad0e 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -18,7 +18,6 @@
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
import static android.accessibilityservice.AccessibilityServiceInfo.FEEDBACK_GENERIC;
-import static android.media.AudioManager.RINGER_MODE_MAX;
import static android.media.AudioManager.RINGER_MODE_NORMAL;
import static android.media.AudioManager.RINGER_MODE_SILENT;
import static android.media.AudioManager.RINGER_MODE_VIBRATE;
@@ -570,7 +569,11 @@
return;
}
- enableRingerViewsH(mState.zenMode == Global.ZEN_MODE_OFF || !mState.disallowRinger);
+ boolean isZenMuted = mState.zenMode == Global.ZEN_MODE_ALARMS
+ || mState.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS
+ || (mState.zenMode == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
+ && mState.disallowRinger);
+ enableRingerViewsH(!isZenMuted);
switch (mState.ringerModeInternal) {
case AudioManager.RINGER_MODE_VIBRATE:
mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
@@ -586,7 +589,7 @@
case AudioManager.RINGER_MODE_NORMAL:
default:
boolean muted = (mAutomute && ss.level == 0) || ss.muted;
- if (muted) {
+ if (!isZenMuted && muted) {
mRingerIcon.setImageResource(R.drawable.ic_volume_ringer_mute);
mRingerIcon.setContentDescription(mContext.getString(
R.string.volume_stream_content_description_unmute,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
index 231a1866..23a3405 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/ExpandableNotificationRowTest.java
@@ -16,9 +16,13 @@
package com.android.systemui.statusbar;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -32,13 +36,19 @@
import android.view.View;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.stack.NotificationChildrenContainer;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.function.Consumer;
@@ -46,52 +56,59 @@
@RunWith(AndroidJUnit4.class)
public class ExpandableNotificationRowTest extends SysuiTestCase {
- private ExpandableNotificationRow mGroup;
+ private ExpandableNotificationRow mGroupRow;
+
private NotificationTestHelper mNotificationTestHelper;
boolean mHeadsUpAnimatingAway = false;
+ @Rule public MockitoRule mockito = MockitoJUnit.rule();
+ @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
+
@Before
public void setUp() throws Exception {
mNotificationTestHelper = new NotificationTestHelper(mContext);
- mGroup = mNotificationTestHelper.createGroup();
- mGroup.setHeadsUpAnimatingAwayListener(
+ mGroupRow = mNotificationTestHelper.createGroup();
+ mGroupRow.setHeadsUpAnimatingAwayListener(
animatingAway -> mHeadsUpAnimatingAway = animatingAway);
+ mDependency.injectTestDependency(
+ NotificationBlockingHelperManager.class,
+ mBlockingHelperManager);
}
@Test
public void testGroupSummaryNotShowingIconWhenPublic() {
- mGroup.setSensitive(true, true);
- mGroup.setHideSensitiveForIntrinsicHeight(true);
- Assert.assertTrue(mGroup.isSummaryWithChildren());
- Assert.assertFalse(mGroup.isShowingIcon());
+ mGroupRow.setSensitive(true, true);
+ mGroupRow.setHideSensitiveForIntrinsicHeight(true);
+ assertTrue(mGroupRow.isSummaryWithChildren());
+ assertFalse(mGroupRow.isShowingIcon());
}
@Test
public void testNotificationHeaderVisibleWhenAnimating() {
- mGroup.setSensitive(true, true);
- mGroup.setHideSensitive(true, false, 0, 0);
- mGroup.setHideSensitive(false, true, 0, 0);
- Assert.assertTrue(mGroup.getChildrenContainer().getVisibleHeader().getVisibility()
+ mGroupRow.setSensitive(true, true);
+ mGroupRow.setHideSensitive(true, false, 0, 0);
+ mGroupRow.setHideSensitive(false, true, 0, 0);
+ assertTrue(mGroupRow.getChildrenContainer().getVisibleHeader().getVisibility()
== View.VISIBLE);
}
@Test
public void testUserLockedResetEvenWhenNoChildren() {
- mGroup.setUserLocked(true);
- mGroup.removeAllChildren();
- mGroup.setUserLocked(false);
- Assert.assertFalse("The childrencontainer should not be userlocked but is, the state "
- + "seems out of sync.", mGroup.getChildrenContainer().isUserLocked());
+ mGroupRow.setUserLocked(true);
+ mGroupRow.removeAllChildren();
+ mGroupRow.setUserLocked(false);
+ assertFalse("The childrencontainer should not be userlocked but is, the state "
+ + "seems out of sync.", mGroupRow.getChildrenContainer().isUserLocked());
}
@Test
public void testReinflatedOnDensityChange() {
- mGroup.setUserLocked(true);
- mGroup.removeAllChildren();
- mGroup.setUserLocked(false);
+ mGroupRow.setUserLocked(true);
+ mGroupRow.removeAllChildren();
+ mGroupRow.setUserLocked(false);
NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
- mGroup.setChildrenContainer(mockContainer);
- mGroup.onDensityOrFontScaleChanged();
+ mGroupRow.setChildrenContainer(mockContainer);
+ mGroupRow.onDensityOrFontScaleChanged();
verify(mockContainer).reInflateViews(any(), any());
}
@@ -148,22 +165,38 @@
@Test
public void testClickSound() throws Exception {
- Assert.assertTrue("Should play sounds by default.", mGroup.isSoundEffectsEnabled());
- mGroup.setDark(true /* dark */, false /* fade */, 0 /* delay */);
- mGroup.setSecureStateProvider(()-> false);
- Assert.assertFalse("Shouldn't play sounds when dark and trusted.",
- mGroup.isSoundEffectsEnabled());
- mGroup.setSecureStateProvider(()-> true);
- Assert.assertTrue("Should always play sounds when not trusted.",
- mGroup.isSoundEffectsEnabled());
+ assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled());
+ mGroupRow.setDark(true /* dark */, false /* fade */, 0 /* delay */);
+ mGroupRow.setSecureStateProvider(()-> false);
+ assertFalse("Shouldn't play sounds when dark and trusted.",
+ mGroupRow.isSoundEffectsEnabled());
+ mGroupRow.setSecureStateProvider(()-> true);
+ assertTrue("Should always play sounds when not trusted.",
+ mGroupRow.isSoundEffectsEnabled());
+ }
+
+ @Test
+ public void testSetDismissed_longPressListenerRemoved() {
+ ExpandableNotificationRow.LongPressListener listener =
+ mock(ExpandableNotificationRow.LongPressListener.class);
+ mGroupRow.setLongPressListener(listener);
+ mGroupRow.doLongClickCallback(0,0);
+ verify(listener, times(1)).onLongPress(eq(mGroupRow), eq(0), eq(0),
+ any(NotificationMenuRowPlugin.MenuItem.class));
+ reset(listener);
+
+ mGroupRow.setDismissed(true);
+ mGroupRow.doLongClickCallback(0,0);
+ verify(listener, times(0)).onLongPress(eq(mGroupRow), eq(0), eq(0),
+ any(NotificationMenuRowPlugin.MenuItem.class));
}
@Test
public void testShowAppOps_noHeader() {
// public notification is custom layout - no header
- mGroup.setSensitive(true, true);
- mGroup.setAppOpsOnClickListener(null);
- mGroup.showAppOpsIcons(null);
+ mGroupRow.setSensitive(true, true);
+ mGroupRow.setAppOpsOnClickListener(null);
+ mGroupRow.showAppOpsIcons(null);
}
@Test
@@ -171,17 +204,17 @@
NotificationHeaderView mockHeader = mock(NotificationHeaderView.class);
NotificationContentView publicLayout = mock(NotificationContentView.class);
- mGroup.setPublicLayout(publicLayout);
+ mGroupRow.setPublicLayout(publicLayout);
NotificationContentView privateLayout = mock(NotificationContentView.class);
- mGroup.setPrivateLayout(privateLayout);
+ mGroupRow.setPrivateLayout(privateLayout);
NotificationChildrenContainer mockContainer = mock(NotificationChildrenContainer.class);
when(mockContainer.getNotificationChildCount()).thenReturn(1);
when(mockContainer.getHeaderView()).thenReturn(mockHeader);
- mGroup.setChildrenContainer(mockContainer);
+ mGroupRow.setChildrenContainer(mockContainer);
ArraySet<Integer> ops = new ArraySet<>();
ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
- mGroup.showAppOpsIcons(ops);
+ mGroupRow.showAppOpsIcons(ops);
verify(mockHeader, times(1)).showAppOpsIcons(ops);
verify(privateLayout, times(1)).showAppOpsIcons(ops);
@@ -195,17 +228,50 @@
ExpandableNotificationRow.OnAppOpsClickListener.class);
View view = mock(View.class);
- mGroup.setAppOpsOnClickListener(l);
+ mGroupRow.setAppOpsOnClickListener(l);
- mGroup.getAppOpsOnClickListener().onClick(view);
+ mGroupRow.getAppOpsOnClickListener().onClick(view);
verify(l, times(1)).onClick(any(), anyInt(), anyInt(), any());
}
@Test
public void testHeadsUpAnimatingAwayListener() {
- mGroup.setHeadsUpAnimatingAway(true);
+ mGroupRow.setHeadsUpAnimatingAway(true);
Assert.assertEquals(true, mHeadsUpAnimatingAway);
- mGroup.setHeadsUpAnimatingAway(false);
+ mGroupRow.setHeadsUpAnimatingAway(false);
Assert.assertEquals(false, mHeadsUpAnimatingAway);
}
+
+ @Test
+ public void testPerformDismissWithBlockingHelper_falseWhenBlockingHelperIsntShown() {
+ when(mBlockingHelperManager.perhapsShowBlockingHelper(
+ eq(mGroupRow), any(NotificationMenuRowPlugin.class))).thenReturn(false);
+
+ assertFalse(
+ mGroupRow.performDismissWithBlockingHelper(false /* fromAccessibility */));
+ }
+
+ @Test
+ public void testPerformDismissWithBlockingHelper_doesntPerformOnGroupSummary() {
+ ExpandableNotificationRow childRow = mGroupRow.getChildrenContainer().getViewAtPosition(0);
+ when(mBlockingHelperManager.perhapsShowBlockingHelper(eq(childRow), any(NotificationMenuRowPlugin.class)))
+ .thenReturn(true);
+
+ assertTrue(
+ childRow.performDismissWithBlockingHelper(false /* fromAccessibility */));
+
+ verify(mBlockingHelperManager, times(1))
+ .perhapsShowBlockingHelper(eq(childRow), any(NotificationMenuRowPlugin.class));
+ verify(mBlockingHelperManager, times(0))
+ .perhapsShowBlockingHelper(eq(mGroupRow), any(NotificationMenuRowPlugin.class));
+ }
+
+ @Test
+ public void testIsBlockingHelperShowing_isCorrectlyUpdated() {
+ mGroupRow.setBlockingHelperShowing(true);
+ assertTrue(mGroupRow.isBlockingHelperShowing());
+
+ mGroupRow.setBlockingHelperShowing(false);
+ assertFalse(mGroupRow.isBlockingHelperShowing());
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java
new file mode 100644
index 0000000..96b0255
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/FooterViewTest.java
@@ -0,0 +1,123 @@
+/*
+ * 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
+ */
+
+package com.android.systemui.statusbar;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertNull;
+import static junit.framework.Assert.assertTrue;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.os.UserHandle;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.util.NotificationColorUtil;
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentMatcher;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class FooterViewTest extends SysuiTestCase {
+
+ FooterView mView;
+
+ @Before
+ public void setUp() {
+ mView = (FooterView) LayoutInflater.from(mContext).inflate(
+ R.layout.status_bar_notification_footer, null, false);
+ mView.setDuration(0);
+ }
+
+ @Test
+ public void testViewsNotNull() {
+ assertNotNull(mView.findContentView());
+ assertNotNull(mView.findSecondaryView());
+ }
+
+ @Test
+ public void setDismissOnClick() {
+ mView.setDismissButtonClickListener(mock(View.OnClickListener.class));
+ assertTrue(mView.findSecondaryView().hasOnClickListeners());
+ }
+
+ @Test
+ public void setManageOnClick() {
+ mView.setManageButtonClickListener(mock(View.OnClickListener.class));
+ assertTrue(mView.findViewById(R.id.manage_text).hasOnClickListeners());
+ }
+
+ @Test
+ public void testPerformVisibilityAnimation() {
+ mView.setInvisible();
+ assertFalse(mView.isVisible());
+
+ Runnable test = new Runnable() {
+ @Override
+ public void run() {
+ assertEquals(1.0f, mView.findContentView().getAlpha());
+ assertEquals(0.0f, mView.findSecondaryView().getAlpha());
+ assertTrue(mView.isVisible());
+ }
+ };
+ mView.performVisibilityAnimation(true, test);
+ }
+
+ @Test
+ public void testPerformSecondaryVisibilityAnimation() {
+ mView.setInvisible();
+ assertFalse(mView.isSecondaryVisible());
+
+ Runnable test = new Runnable() {
+ @Override
+ public void run() {
+ assertEquals(0.0f, mView.findContentView().getAlpha());
+ assertEquals(1.0f, mView.findSecondaryView().getAlpha());
+ assertTrue(mView.isSecondaryVisible());
+ }
+ };
+ mView.performSecondaryVisibilityAnimation(true, test);
+ }
+}
+
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java
new file mode 100644
index 0000000..64f34e0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationBlockingHelperManagerTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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
+ */
+
+package com.android.systemui.statusbar;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+
+import android.content.Context;
+import android.support.test.filters.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.View;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+/**
+ * Tests for {@link NotificationBlockingHelperManager}.
+ */
+@SmallTest
+@org.junit.runner.RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
+
+ private NotificationBlockingHelperManager mBlockingHelperManager;
+
+ private NotificationTestHelper mHelper;
+
+ @Rule public MockitoRule mockito = MockitoJUnit.rule();
+ @Mock private NotificationGutsManager mGutsManager;
+ @Mock private NotificationEntryManager mEntryManager;
+ @Mock private NotificationMenuRow mMenuRow;
+ @Mock private NotificationMenuRowPlugin.MenuItem mMenuItem;
+
+ @Before
+ public void setUp() {
+ mBlockingHelperManager = new NotificationBlockingHelperManager(mContext);
+
+ mHelper = new NotificationTestHelper(mContext);
+ when(mGutsManager.openGuts(
+ any(View.class),
+ anyInt(),
+ anyInt(),
+ any(NotificationMenuRowPlugin.MenuItem.class)))
+ .thenReturn(true);
+ mDependency.injectTestDependency(NotificationGutsManager.class, mGutsManager);
+ mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
+ when(mMenuRow.getLongpressMenuItem(any(Context.class))).thenReturn(mMenuItem);
+ }
+
+ @Test
+ public void testDismissCurrentBlockingHelper_nullBlockingHelperRow() {
+ // By default, this shouldn't dismiss (no pointers/vars set up!)
+ assertFalse(mBlockingHelperManager.dismissCurrentBlockingHelper());
+ assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
+ }
+
+ @Test
+ public void testDismissCurrentBlockingHelper_withDetachedBlockingHelperRow() throws Exception {
+ ExpandableNotificationRow row = spy(mHelper.createRow());
+ row.setBlockingHelperShowing(true);
+ when(row.isAttachedToWindow()).thenReturn(false);
+ mBlockingHelperManager.setBlockingHelperRowForTest(row);
+
+ assertTrue(mBlockingHelperManager.dismissCurrentBlockingHelper());
+ assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
+
+ verify(mEntryManager, times(0)).updateNotifications();
+ }
+
+ @Test
+ public void testDismissCurrentBlockingHelper_withAttachedBlockingHelperRow() throws Exception {
+ ExpandableNotificationRow row = spy(mHelper.createRow());
+ row.setBlockingHelperShowing(true);
+ when(row.isAttachedToWindow()).thenReturn(true);
+ mBlockingHelperManager.setBlockingHelperRowForTest(row);
+
+ assertTrue(mBlockingHelperManager.dismissCurrentBlockingHelper());
+ assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
+
+ verify(mEntryManager).updateNotifications();
+ }
+
+ @Test
+ public void testPerhapsShowBlockingHelper_shown() throws Exception {
+ ExpandableNotificationRow row = mHelper.createRow();
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
+
+ verify(mGutsManager).openGuts(row, 0, 0, mMenuItem);
+ }
+
+
+ @Test
+ public void testPerhapsShowBlockingHelper_shownForLargeGroup() throws Exception {
+ ExpandableNotificationRow groupRow = mHelper.createGroup(10);
+ groupRow.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(groupRow, mMenuRow));
+
+ verify(mGutsManager).openGuts(groupRow, 0, 0, mMenuItem);
+ }
+
+ @Test
+ public void testPerhapsShowBlockingHelper_shownForOnlyChildNotification()
+ throws Exception {
+ ExpandableNotificationRow groupRow = mHelper.createGroup(1);
+ // Explicitly get the children container & call getViewAtPosition on it instead of the row
+ // as other factors such as view expansion may cause us to get the parent row back instead
+ // of the child row.
+ ExpandableNotificationRow childRow = groupRow.getChildrenContainer().getViewAtPosition(0);
+ childRow.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(childRow, mMenuRow));
+
+ verify(mGutsManager).openGuts(childRow, 0, 0, mMenuItem);
+ }
+
+ @Test
+ public void testPerhapsShowBlockingHelper_notShownDueToNeutralUserSentiment() throws Exception {
+ ExpandableNotificationRow row = mHelper.createRow();
+ row.getEntry().userSentiment = USER_SENTIMENT_NEUTRAL;
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
+ }
+
+ @Test
+ public void testPerhapsShowBlockingHelper_notShownDueToPositiveUserSentiment()
+ throws Exception {
+ ExpandableNotificationRow row = mHelper.createRow();
+ row.getEntry().userSentiment = USER_SENTIMENT_POSITIVE;
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
+ }
+
+ @Test
+ public void testPerhapsShowBlockingHelper_notShownDueToShadeVisibility() throws Exception {
+ ExpandableNotificationRow row = mHelper.createRow();
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ // Hide the shade
+ mBlockingHelperManager.setNotificationShadeExpanded(0f);
+
+ assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
+ }
+
+ @Test
+ public void testPerhapsShowBlockingHelper_notShownAsNotificationIsInMultipleChildGroup()
+ throws Exception {
+ ExpandableNotificationRow groupRow = mHelper.createGroup(2);
+ // Explicitly get the children container & call getViewAtPosition on it instead of the row
+ // as other factors such as view expansion may cause us to get the parent row back instead
+ // of the child row.
+ ExpandableNotificationRow childRow = groupRow.getChildrenContainer().getViewAtPosition(0);
+ childRow.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(childRow, mMenuRow));
+ }
+
+ @Test
+ public void testBlockingHelperShowAndDismiss() throws Exception{
+ ExpandableNotificationRow row = spy(mHelper.createRow());
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ when(row.isAttachedToWindow()).thenReturn(true);
+ mBlockingHelperManager.setNotificationShadeExpanded(1f);
+
+ // Show check
+ assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
+
+ verify(mGutsManager).openGuts(row, 0, 0, mMenuItem);
+
+ // Dismiss check
+ assertTrue(mBlockingHelperManager.dismissCurrentBlockingHelper());
+ assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
+
+ verify(mEntryManager).updateNotifications();
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java
index 6209d59..21f6750 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationGutsManagerTest.java
@@ -20,6 +20,7 @@
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
+import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
import static junit.framework.Assert.assertNotNull;
import static org.junit.Assert.assertEquals;
@@ -27,6 +28,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -34,31 +37,24 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
+import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
-import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.Handler;
-import android.os.Looper;
-import android.os.UserHandle;
import android.provider.Settings;
import android.service.notification.StatusBarNotification;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.ArraySet;
-import android.view.LayoutInflater;
import android.view.View;
-import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.statusbar.NotificationData;
-import com.android.systemui.statusbar.NotificationGuts;
-import com.android.systemui.statusbar.NotificationTestHelper;
-import com.android.systemui.statusbar.notification.NotificationInflater;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import org.junit.Before;
@@ -70,15 +66,18 @@
import org.mockito.junit.MockitoRule;
import org.mockito.junit.MockitoJUnit;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests for {@link NotificationGutsManager}.
+ */
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class NotificationGutsManagerTest extends SysuiTestCase {
private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
- private final String mPackageName = mContext.getPackageName();
- private final int mUid = Binder.getCallingUid();
-
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
private TestableLooper mTestableLooper;
@@ -87,7 +86,6 @@
private NotificationGutsManager mGutsManager;
@Rule public MockitoRule mockito = MockitoJUnit.rule();
- @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
@Mock private NotificationPresenter mPresenter;
@Mock private NotificationEntryManager mEntryManager;
@Mock private NotificationStackScrollLayout mStackScroller;
@@ -118,7 +116,12 @@
});
// Test doesn't support animation since the guts view is not attached.
- doNothing().when(guts).openControls(anyInt(), anyInt(), anyBoolean(), any(Runnable.class));
+ doNothing().when(guts).openControls(
+ eq(true) /* shouldDoCircularReveal */,
+ anyInt(),
+ anyInt(),
+ anyBoolean(),
+ any(Runnable.class));
ExpandableNotificationRow realRow = createTestNotificationRow();
NotificationMenuRowPlugin.MenuItem menuItem = createTestMenuItem(realRow);
@@ -130,7 +133,12 @@
mGutsManager.openGuts(row, 0, 0, menuItem);
assertEquals(View.INVISIBLE, guts.getVisibility());
mTestableLooper.processAllMessages();
- verify(guts).openControls(anyInt(), anyInt(), anyBoolean(), any(Runnable.class));
+ verify(guts).openControls(
+ eq(true),
+ anyInt(),
+ anyInt(),
+ anyBoolean(),
+ any(Runnable.class));
assertEquals(View.VISIBLE, guts.getVisibility());
mGutsManager.closeAndSaveGuts(false, false, false, 0, 0, false);
@@ -148,7 +156,12 @@
});
// Test doesn't support animation since the guts view is not attached.
- doNothing().when(guts).openControls(anyInt(), anyInt(), anyBoolean(), any(Runnable.class));
+ doNothing().when(guts).openControls(
+ eq(true) /* shouldDoCircularReveal */,
+ anyInt(),
+ anyInt(),
+ anyBoolean(),
+ any(Runnable.class));
ExpandableNotificationRow realRow = createTestNotificationRow();
NotificationMenuRowPlugin.MenuItem menuItem = createTestMenuItem(realRow);
@@ -160,7 +173,12 @@
mGutsManager.openGuts(row, 0, 0, menuItem);
mTestableLooper.processAllMessages();
- verify(guts).openControls(anyInt(), anyInt(), anyBoolean(), any(Runnable.class));
+ verify(guts).openControls(
+ eq(true),
+ anyInt(),
+ anyInt(),
+ anyBoolean(),
+ any(Runnable.class));
row.onDensityOrFontScaleChanged();
mGutsManager.onDensityOrFontScaleChanged(row);
@@ -247,6 +265,56 @@
assertEquals(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, captor.getValue().getAction());
}
+ @Test
+ public void testInitializeNotificationInfoView_showBlockingHelper() throws Exception {
+ NotificationInfo notificationInfoView = mock(NotificationInfo.class);
+ ExpandableNotificationRow row = mHelper.createRow();
+ row.setBlockingHelperShowing(true);
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+
+ mGutsManager.initializeNotificationInfo(row, notificationInfoView);
+
+ verify(notificationInfoView).bindNotification(
+ any(PackageManager.class),
+ any(INotificationManager.class),
+ eq(statusBarNotification.getPackageName()),
+ isNull(),
+ anyInt(),
+ eq(statusBarNotification),
+ any(NotificationInfo.CheckSaveListener.class),
+ any(NotificationInfo.OnSettingsClickListener.class),
+ any(NotificationInfo.OnAppSettingsClickListener.class),
+ any(),
+ eq(true) /* isForBlockingHelper */,
+ eq(true) /* isUserSentimentNegative */);
+ }
+
+ @Test
+ public void testInitializeNotificationInfoView_dontShowBlockingHelper() throws Exception {
+ NotificationInfo notificationInfoView = mock(NotificationInfo.class);
+ ExpandableNotificationRow row = mHelper.createRow();
+ row.setBlockingHelperShowing(false);
+ row.getEntry().userSentiment = USER_SENTIMENT_NEGATIVE;
+ StatusBarNotification statusBarNotification = row.getStatusBarNotification();
+
+ mGutsManager.initializeNotificationInfo(row, notificationInfoView);
+
+ verify(notificationInfoView).bindNotification(
+ any(PackageManager.class),
+ any(INotificationManager.class),
+ eq(statusBarNotification.getPackageName()),
+ isNull(),
+ anyInt(),
+ eq(statusBarNotification),
+ any(NotificationInfo.CheckSaveListener.class),
+ any(NotificationInfo.OnSettingsClickListener.class),
+ any(NotificationInfo.OnAppSettingsClickListener.class),
+ any(),
+ eq(false) /* isForBlockingHelper */,
+ eq(true) /* isUserSentimentNegative */);
+ }
+
////////////////////////////////////////////////////////////////////////////////////////////////
// Utility methods:
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 01664b2..7dda8b2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -67,9 +67,13 @@
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.Collections;
@@ -87,14 +91,21 @@
private static final String TEST_CHANNEL_NAME = "TEST CHANNEL NAME";
private NotificationInfo mNotificationInfo;
- private final INotificationManager mMockINotificationManager = mock(INotificationManager.class);
- private final PackageManager mMockPackageManager = mock(PackageManager.class);
private NotificationChannel mNotificationChannel;
private NotificationChannel mDefaultNotificationChannel;
private StatusBarNotification mSbn;
+ @Rule public MockitoRule mockito = MockitoJUnit.rule();
+ @Mock private INotificationManager mMockINotificationManager;
+ @Mock private PackageManager mMockPackageManager;
+ @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
+
@Before
public void setUp() throws Exception {
+ mDependency.injectTestDependency(
+ NotificationBlockingHelperManager.class,
+ mBlockingHelperManager);
+
// Inflate the layout
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
mNotificationInfo = (NotificationInfo) layoutInflater.inflate(R.layout.notification_info,
@@ -311,7 +322,7 @@
public void testbindNotification_BlockingHelper() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, mNotificationChannel, 1, mSbn, null, null,
- null, null, true);
+ null, null, false, true);
final TextView view = mNotificationInfo.findViewById(R.id.block_prompt);
assertEquals(View.VISIBLE, view.getVisibility());
assertEquals(mContext.getString(R.string.inline_blocking_helper), view.getText());
@@ -386,6 +397,27 @@
}
@Test
+ public void testCloseControls_blockingHelperDismissedIfShown() throws Exception {
+ mNotificationInfo.bindNotification(
+ mMockPackageManager,
+ mMockINotificationManager,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ 1 /* numChannels */,
+ mSbn,
+ null /* checkSaveListener */,
+ null /* onSettingsClick */,
+ null /* onAppSettingsClick */,
+ null /* nonBlockablePkgs */,
+ true /* isForBlockingHelper */,
+ false /* isUserSentimentNegative */);
+
+ mNotificationInfo.closeControls(mNotificationInfo);
+
+ verify(mBlockingHelperManager).dismissCurrentBlockingHelper();
+ }
+
+ @Test
public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
mNotificationChannel.setImportance(IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
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 2764254..de2e6bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.Notification;
@@ -23,33 +24,32 @@
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.support.test.InstrumentationRegistry;
+import android.text.TextUtils;
import android.view.LayoutInflater;
-import android.widget.FrameLayout;
import android.widget.RemoteViews;
import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
-import com.android.systemui.statusbar.notification.AboveShelfObserver;
-import com.android.systemui.statusbar.notification.InflationException;
import com.android.systemui.statusbar.notification.NotificationInflaterTest;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
/**
- * A helper class to create {@link ExpandableNotificationRow}
+ * A helper class to create {@link ExpandableNotificationRow} (for both individual and group
+ * notifications).
*/
public class NotificationTestHelper {
+ static final String PKG = "com.android.systemui";
+ static final int UID = 1000;
+ private static final String GROUP_KEY = "gruKey";
+
private final Context mContext;
private final Instrumentation mInstrumentation;
private int mId;
private final NotificationGroupManager mGroupManager = new NotificationGroupManager();
private ExpandableNotificationRow mRow;
- private InflationException mException;
private HeadsUpManager mHeadsUpManager;
- protected static final String PKG = "com.android.systemui";
- protected static final int UID = 1000;
public NotificationTestHelper(Context context) {
mContext = context;
@@ -57,57 +57,125 @@
mHeadsUpManager = new HeadsUpManagerPhone(mContext, null, mGroupManager, null, null);
}
+ public ExpandableNotificationRow createRow() throws Exception {
+ return createRow(PKG, UID);
+ }
+
public ExpandableNotificationRow createRow(String pkg, int uid) throws Exception {
+ return createRow(pkg, uid, false /* isGroupSummary */, null /* groupKey */);
+ }
+
+ public ExpandableNotificationRow createRow(Notification notification) throws Exception {
+ return generateRow(notification, PKG, UID, false /* isGroupRow */);
+ }
+
+ /**
+ * Returns an {@link ExpandableNotificationRow} group with the given number of child
+ * notifications.
+ */
+ public ExpandableNotificationRow createGroup(int numChildren) throws Exception {
+ ExpandableNotificationRow row = createGroupSummary(GROUP_KEY);
+ for (int i = 0; i < numChildren; i++) {
+ ExpandableNotificationRow childRow = createGroupChild(GROUP_KEY);
+ row.addChildNotification(childRow);
+ }
+ return row;
+ }
+
+ /** Returns a group notification with 2 child notifications. */
+ public ExpandableNotificationRow createGroup() throws Exception {
+ return createGroup(2);
+ }
+
+ private ExpandableNotificationRow createGroupSummary(String groupkey) throws Exception {
+ return createRow(PKG, UID, true /* isGroupSummary */, groupkey);
+ }
+
+ private ExpandableNotificationRow createGroupChild(String groupkey) throws Exception {
+ return createRow(PKG, UID, false /* isGroupSummary */, groupkey);
+ }
+
+ /**
+ * Creates a notification row with the given details.
+ *
+ * @param pkg package used for creating a {@link StatusBarNotification}
+ * @param uid uid used for creating a {@link StatusBarNotification}
+ * @param isGroupSummary whether the notification row is a group summary
+ * @param groupKey the group key for the notification group used across notifications
+ * @return a row with that's either a standalone notification or a group notification if the
+ * groupKey is non-null
+ * @throws Exception
+ */
+ private ExpandableNotificationRow createRow(
+ String pkg,
+ int uid,
+ boolean isGroupSummary,
+ @Nullable String groupKey)
+ throws Exception {
Notification publicVersion = new Notification.Builder(mContext).setSmallIcon(
R.drawable.ic_person)
.setCustomContentView(new RemoteViews(mContext.getPackageName(),
R.layout.custom_view_dark))
.build();
- Notification notification = new Notification.Builder(mContext).setSmallIcon(
- R.drawable.ic_person)
- .setContentTitle("Title")
- .setContentText("Text")
- .setPublicVersion(publicVersion)
- .build();
- return createRow(notification, pkg, uid);
+ Notification.Builder notificationBuilder =
+ new Notification.Builder(mContext)
+ .setSmallIcon(R.drawable.ic_person)
+ .setContentTitle("Title")
+ .setContentText("Text")
+ .setPublicVersion(publicVersion);
+
+ // Group notification setup
+ if (isGroupSummary) {
+ notificationBuilder.setGroupSummary(true);
+ }
+ if (!TextUtils.isEmpty(groupKey)) {
+ notificationBuilder.setGroup(groupKey);
+ }
+
+ return generateRow(notificationBuilder.build(), pkg, uid, !TextUtils.isEmpty(groupKey));
}
- public ExpandableNotificationRow createRow() throws Exception {
- return createRow(PKG, UID);
- }
-
- public ExpandableNotificationRow createRow(Notification notification) throws Exception {
- return createRow(notification, PKG, UID);
- }
-
- public ExpandableNotificationRow createRow(Notification notification, String pkg, int uid)
+ private ExpandableNotificationRow generateRow(
+ Notification notification,
+ String pkg,
+ int uid,
+ boolean isGroupRow)
throws Exception {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
mContext.LAYOUT_INFLATER_SERVICE);
- mInstrumentation.runOnMainSync(() -> {
- mRow = (ExpandableNotificationRow) inflater.inflate(
- R.layout.status_bar_notification_row,
- null, false);
- });
+ mInstrumentation.runOnMainSync(() ->
+ mRow = (ExpandableNotificationRow) inflater.inflate(
+ R.layout.status_bar_notification_row,
+ null /* root */,
+ false /* attachToRoot */)
+ );
ExpandableNotificationRow row = mRow;
row.setGroupManager(mGroupManager);
row.setHeadsUpManager(mHeadsUpManager);
row.setAboveShelfChangedListener(aboveShelf -> {});
UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
- StatusBarNotification sbn = new StatusBarNotification(pkg, pkg, mId++, null, uid,
- 2000, notification, mUser, null, System.currentTimeMillis());
+ StatusBarNotification sbn = new StatusBarNotification(
+ pkg,
+ pkg,
+ mId++,
+ null /* tag */,
+ uid,
+ 2000 /* initialPid */,
+ notification,
+ mUser,
+ null /* overrideGroupKey */,
+ System.currentTimeMillis());
NotificationData.Entry entry = new NotificationData.Entry(sbn);
entry.row = row;
entry.createIcons(mContext, sbn);
- NotificationInflaterTest.runThenWaitForInflation(() -> row.updateNotification(entry),
+ NotificationInflaterTest.runThenWaitForInflation(
+ () -> row.updateNotification(entry),
row.getNotificationInflater());
- return row;
- }
- public ExpandableNotificationRow createGroup() throws Exception {
- ExpandableNotificationRow row = createRow();
- row.addChildNotification(createRow());
- row.addChildNotification(createRow());
+ // This would be done as part of onAsyncInflationFinished, but we skip large amounts of
+ // the callback chain, so we need to make up for not adding it to the group manager
+ // here.
+ mGroupManager.onEntryAdded(entry);
return row;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 7743c6b..a88f31a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -26,6 +26,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;
@@ -73,7 +74,7 @@
@Before
public void setup() {
mLightBarController = mock(LightBarController.class);
- mScrimBehind = new ScrimView(getContext());
+ mScrimBehind = spy(new ScrimView(getContext()));
mScrimInFront = new ScrimView(getContext());
mWakeLock = mock(WakeLock.class);
mAlarmManager = mock(AlarmManager.class);
@@ -210,8 +211,10 @@
mScrimController.finishAnimationsImmediately();
final float scrimAlpha = mScrimBehind.getViewAlpha();
+ reset(mScrimBehind);
mScrimController.setExpansionAffectsAlpha(false);
mScrimController.setPanelExpansion(0.8f);
+ verifyZeroInteractions(mScrimBehind);
Assert.assertEquals("Scrim opacity shouldn't change when setExpansionAffectsAlpha "
+ "is false", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index f13fa4e..4a66bb7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -18,7 +18,9 @@
import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static junit.framework.TestCase.fail;
@@ -55,6 +57,8 @@
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.SparseArray;
+import android.view.Gravity;
+import android.view.View;
import android.view.ViewGroup.LayoutParams;
import com.android.internal.logging.MetricsLogger;
@@ -65,13 +69,16 @@
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.UiOffloadThread;
import com.android.systemui.assist.AssistManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.statusbar.ActivatableNotificationView;
import com.android.systemui.statusbar.AppOpsListener;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.FooterView;
+import com.android.systemui.statusbar.FooterViewButton;
import com.android.systemui.statusbar.KeyguardIndicationController;
import com.android.systemui.statusbar.NotificationData;
import com.android.systemui.statusbar.NotificationData.Entry;
@@ -88,7 +95,6 @@
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
@@ -97,12 +103,14 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.function.Predicate;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -125,6 +133,7 @@
@Mock private NotificationViewHierarchyManager mViewHierarchyManager;
@Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private NotificationListener mNotificationListener;
+ @Mock private KeyguardViewMediator mKeyguardViewMediator;
private TestableStatusBar mStatusBar;
private FakeMetricsLogger mMetricsLogger;
@@ -193,7 +202,7 @@
mPowerManager, mNotificationPanelView, mBarService, mNotificationListener,
mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager,
mEntryManager, mScrimController, mFingerprintUnlockController,
- mock(ActivityLaunchAnimator.class));
+ mock(ActivityLaunchAnimator.class), mKeyguardViewMediator);
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mContext.getComponents();
mEntryManager.setUpForTest(mStatusBar, mStackScroller, mStatusBar, mHeadsUpManager,
@@ -558,6 +567,68 @@
verify(mScrimController).setKeyguardOccluded(eq(false));
}
+ @Test
+ public void testInflateFooterView() {
+ mStatusBar.reevaluateStyles();
+ ArgumentCaptor<FooterView> captor = ArgumentCaptor.forClass(FooterView.class);
+ verify(mStackScroller).setFooterView(captor.capture());
+
+ assertNotNull(captor.getValue().findViewById(R.id.manage_text).hasOnClickListeners());
+ assertNotNull(captor.getValue().findViewById(R.id.dismiss_text).hasOnClickListeners());
+ }
+
+ @Test
+ public void testUpdateFooter_noNotifications() {
+ mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+ assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
+
+ mStatusBar.updateFooter();
+ verify(mStackScroller).updateFooterView(false, false);
+ }
+
+ @Test
+ public void testUpdateFooter_oneClearableNotification() {
+ mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+ ArrayList<Entry> entries = new ArrayList<>();
+ entries.add(mock(Entry.class));
+ when(mNotificationData.getActiveNotifications()).thenReturn(entries);
+
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+ when(row.canViewBeDismissed()).thenReturn(true);
+ when(mStackScroller.getChildCount()).thenReturn(1);
+ when(mStackScroller.getChildAt(anyInt())).thenReturn(row);
+
+ mStatusBar.updateFooter();
+ verify(mStackScroller).updateFooterView(true, true);
+ }
+
+ @Test
+ public void testUpdateFooter_oneNonClearableNotification() {
+ mStatusBar.setBarStateForTest(StatusBarState.SHADE);
+ ArrayList<Entry> entries = new ArrayList<>();
+ entries.add(mock(Entry.class));
+ when(mNotificationData.getActiveNotifications()).thenReturn(entries);
+
+ mStatusBar.updateFooter();
+ verify(mStackScroller).updateFooterView(true, false);
+ }
+
+ @Test
+ public void testUpdateFooter_atEnd() {
+ // add footer
+ mStatusBar.reevaluateStyles();
+
+ // add notification
+ ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+ when(row.isClearable()).thenReturn(true);
+ mStackScroller.addContainerView(row);
+
+ mStatusBar.onUpdateRowStates();
+
+ // move footer to end
+ verify(mStackScroller).changeViewPosition(any(FooterView.class), eq(-1 /* end */));
+ }
+
static class TestableStatusBar extends StatusBar {
public TestableStatusBar(StatusBarKeyguardViewManager man,
UnlockMethodCache unlock, KeyguardIndicationController key,
@@ -569,7 +640,7 @@
NotificationViewHierarchyManager viewHierarchyManager,
TestableNotificationEntryManager entryManager, ScrimController scrimController,
FingerprintUnlockController fingerprintUnlockController,
- ActivityLaunchAnimator launchAnimator) {
+ ActivityLaunchAnimator launchAnimator, KeyguardViewMediator keyguardViewMediator) {
mStatusBarKeyguardViewManager = man;
mUnlockMethodCache = unlock;
mKeyguardIndicationController = key;
@@ -587,6 +658,8 @@
mScrimController = scrimController;
mFingerprintUnlockController = fingerprintUnlockController;
mActivityLaunchAnimator = launchAnimator;
+ mKeyguardViewMediator = keyguardViewMediator;
+ mClearAllEnabled = true;
}
private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
index 2afb48c..ed0f9ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/CallbackHandlerTest.java
@@ -18,7 +18,6 @@
import android.os.HandlerThread;
import android.support.test.runner.AndroidJUnit4;
import android.telephony.SubscriptionInfo;
-import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
@@ -81,7 +80,8 @@
boolean in = true;
boolean out = true;
String description = "Test";
- mHandler.setWifiIndicators(enabled, status, qs, in, out, description, true);
+ String secondaryLabel = "Secondary label";
+ mHandler.setWifiIndicators(enabled, status, qs, in, out, description, true, secondaryLabel);
waitForCallbacks();
ArgumentCaptor<Boolean> enableArg = ArgumentCaptor.forClass(Boolean.class);
@@ -91,9 +91,10 @@
ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
ArgumentCaptor<String> descArg = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Boolean> isTransient = ArgumentCaptor.forClass(Boolean.class);
+ ArgumentCaptor<String> secondary = ArgumentCaptor.forClass(String.class);
Mockito.verify(mSignalCallback).setWifiIndicators(enableArg.capture(),
statusArg.capture(), qsArg.capture(), inArg.capture(), outArg.capture(),
- descArg.capture(), isTransient.capture());
+ descArg.capture(), isTransient.capture(), secondary.capture());
assertEquals(enabled, (boolean) enableArg.getValue());
assertEquals(status, statusArg.getValue());
assertEquals(qs, qsArg.getValue());
@@ -101,6 +102,7 @@
assertEquals(out, (boolean) outArg.getValue());
assertEquals(description, descArg.getValue());
assertTrue(isTransient.getValue());
+ assertEquals(secondaryLabel, secondary.getValue());
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index fc3de84..d30e777 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -5,8 +5,6 @@
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
-import android.net.wifi.WifiSsid;
-import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -20,6 +18,7 @@
import static junit.framework.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.when;
@@ -39,6 +38,7 @@
verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
setWifiState(true, testSsid);
+ setWifiLevel(0);
verifyLastWifiIcon(true, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
@@ -160,7 +160,8 @@
ArgumentCaptor<Boolean> outArg = ArgumentCaptor.forClass(Boolean.class);
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
- anyBoolean(), any(), any(), inArg.capture(), outArg.capture(), any(), anyBoolean());
+ anyBoolean(), any(), any(), inArg.capture(), outArg.capture(), any(), anyBoolean(),
+ any());
assertEquals("WiFi data in, in quick settings", in, (boolean) inArg.getValue());
assertEquals("WiFi data out, in quick settings", out, (boolean) outArg.getValue());
}
@@ -173,7 +174,7 @@
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
enabledArg.capture(), any(), iconArg.capture(), anyBoolean(),
- anyBoolean(), descArg.capture(), anyBoolean());
+ anyBoolean(), descArg.capture(), anyBoolean(), any());
IconState iconState = iconArg.getValue();
assertEquals("WiFi enabled, in quick settings", enabled, (boolean) enabledArg.getValue());
assertEquals("WiFi connected, in quick settings", connected, iconState.visible);
@@ -186,7 +187,7 @@
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setWifiIndicators(
anyBoolean(), iconArg.capture(), any(), anyBoolean(), anyBoolean(),
- any(), anyBoolean());
+ any(), anyBoolean(), any());
IconState iconState = iconArg.getValue();
assertEquals("WiFi visible, in status bar", visible, iconState.visible);
assertEquals("WiFi signal, in status bar", icon, iconState.icon);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
index 6fa91ff..cd3031b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
@@ -16,40 +16,87 @@
package com.android.systemui.statusbar.stack;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import android.view.View;
+import com.android.systemui.ExpandHelper;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.TestableDependency;
import com.android.systemui.statusbar.EmptyShadeView;
+import com.android.systemui.statusbar.FooterView;
+import com.android.systemui.statusbar.NotificationBlockingHelperManager;
+import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+/**
+ * Tests for {@link NotificationStackScrollLayout}.
+ */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class NotificationStackScrollLayoutTest extends SysuiTestCase {
private NotificationStackScrollLayout mStackScroller;
- private StatusBar mBar;
+
+ @Rule public MockitoRule mockito = MockitoJUnit.rule();
+ @Mock private StatusBar mBar;
+ @Mock private HeadsUpManagerPhone mHeadsUpManager;
+ @Mock private NotificationBlockingHelperManager mBlockingHelperManager;
+ @Mock private NotificationGroupManager mGroupManager;
+ @Mock private ExpandHelper mExpandHelper;
+ @Mock private EmptyShadeView mEmptyShadeView;
@Before
@UiThreadTest
public void setUp() throws Exception {
+ // Inject dependencies before initializing the layout
+ mDependency.injectTestDependency(
+ NotificationBlockingHelperManager.class,
+ mBlockingHelperManager);
+
+ NotificationShelf notificationShelf = spy(new NotificationShelf(getContext(), null));
mStackScroller = new NotificationStackScrollLayout(getContext());
- mBar = mock(StatusBar.class);
+ mStackScroller.setShelf(notificationShelf);
mStackScroller.setStatusBar(mBar);
mStackScroller.setScrimController(mock(ScrimController.class));
+ mStackScroller.setHeadsUpManager(mHeadsUpManager);
+ mStackScroller.setGroupManager(mGroupManager);
+ mStackScroller.setEmptyShadeView(mEmptyShadeView);
+
+ // Stub out functionality that isn't necessary to test.
+ doNothing().when(mBar)
+ .executeRunnableDismissingKeyguard(any(Runnable.class),
+ any(Runnable.class),
+ anyBoolean(),
+ anyBoolean(),
+ anyBoolean());
+ doNothing().when(mGroupManager).collapseAllGroups();
+ doNothing().when(mExpandHelper).cancelImmediately();
+ doNothing().when(notificationShelf).setAnimationsEnabled(anyBoolean());
}
@Test
@@ -73,25 +120,59 @@
@Test
public void updateEmptyView_dndSuppressing() {
- EmptyShadeView view = mock(EmptyShadeView.class);
- mStackScroller.setEmptyShadeView(view);
- when(view.willBeGone()).thenReturn(true);
+ when(mEmptyShadeView.willBeGone()).thenReturn(true);
when(mBar.areNotificationsHidden()).thenReturn(true);
mStackScroller.updateEmptyShadeView(true);
- verify(view).setText(R.string.dnd_suppressing_shade_text);
+ verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
}
@Test
public void updateEmptyView_dndNotSuppressing() {
- EmptyShadeView view = mock(EmptyShadeView.class);
- mStackScroller.setEmptyShadeView(view);
- when(view.willBeGone()).thenReturn(true);
+ mStackScroller.setEmptyShadeView(mEmptyShadeView);
+ when(mEmptyShadeView.willBeGone()).thenReturn(true);
when(mBar.areNotificationsHidden()).thenReturn(false);
mStackScroller.updateEmptyShadeView(true);
- verify(view).setText(R.string.empty_shade_text);
+ verify(mEmptyShadeView).setText(R.string.empty_shade_text);
+ }
+
+ @Test
+ @UiThreadTest
+ public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() {
+ mStackScroller.setExpandedHeight(0f);
+ verify(mBlockingHelperManager).setNotificationShadeExpanded(0f);
+ reset(mBlockingHelperManager);
+
+ mStackScroller.setExpandedHeight(100f);
+ verify(mBlockingHelperManager).setNotificationShadeExpanded(100f);
+ }
+
+ @Test
+ public void manageNotifications_visible() {
+ FooterView view = mock(FooterView.class);
+ mStackScroller.setFooterView(view);
+ when(view.willBeGone()).thenReturn(true);
+ when(view.isSecondaryVisible()).thenReturn(true);
+
+ mStackScroller.updateFooterView(true, false);
+
+ verify(view).setVisibility(View.VISIBLE);
+ verify(view).performSecondaryVisibilityAnimation(false);
+ }
+
+ @Test
+ public void clearAll_visible() {
+ FooterView view = mock(FooterView.class);
+ mStackScroller.setFooterView(view);
+ when(view.willBeGone()).thenReturn(true);
+ when(view.isSecondaryVisible()).thenReturn(false);
+
+ mStackScroller.updateFooterView(true, true);
+
+ verify(view).setVisibility(View.VISIBLE);
+ verify(view).performSecondaryVisibilityAnimation(true);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
index 80dc2c9..50b4f3f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/ChannelsTest.java
@@ -60,7 +60,8 @@
NotificationChannels.SCREENSHOTS_HEADSUP,
NotificationChannels.STORAGE,
NotificationChannels.GENERAL,
- NotificationChannels.BATTERY
+ NotificationChannels.BATTERY,
+ NotificationChannels.HINTS
));
NotificationChannels.createAll(mContext);
ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-land/config.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-land/config.xml
new file mode 100644
index 0000000..1aa1af3
--- /dev/null
+++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values-land/config.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ 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>
+ <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
+ <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
+ <dimen name="quick_qs_total_height">156dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-land/config.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-land/config.xml
new file mode 100644
index 0000000..1aa1af3
--- /dev/null
+++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values-land/config.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ 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>
+ <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
+ <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
+ <dimen name="quick_qs_total_height">156dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-land/config.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-land/config.xml
new file mode 100644
index 0000000..1aa1af3
--- /dev/null
+++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values-land/config.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ 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>
+ <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
+ <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
+ <dimen name="quick_qs_total_height">156dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-land/config.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-land/config.xml
new file mode 100644
index 0000000..1aa1af3
--- /dev/null
+++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values-land/config.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ 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>
+ <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
+ <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
+ <dimen name="quick_qs_total_height">156dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-land/config.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-land/config.xml
new file mode 100644
index 0000000..1aa1af3
--- /dev/null
+++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values-land/config.xml
@@ -0,0 +1,21 @@
+<!--
+ ~ 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>
+ <dimen name="quick_qs_offset_height">@dimen/status_bar_height_landscape</dimen>
+ <!-- Total height of QQS in landscape, this is effectively status_bar_height_landscape + 128 -->
+ <dimen name="quick_qs_total_height">156dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index cfb5c6d..c6878d7 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5557,6 +5557,10 @@
// OS: P
SETTINGS_CONDITION_DEVICE_VIBRATE = 1369;
+ // OPEN: Settings > Connected devices > previously connected devices
+ // CATEGORY: SETTINGS
+ // OS: P
+ PREVIOUSLY_CONNECTED_DEVICES = 1370;
// ---- End P Constants, all P constants go above this line ----
// Add new aosp constants above this line.
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 608970f..f9af31c 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -208,6 +208,10 @@
// Package: android
NOTE_ZEN_UPGRADE = 48;
+ // Notification to suggest automatic battery saver.
+ // Package: android
+ NOTE_AUTO_SAVER_SUGGESTION = 49;
+
// ADD_NEW_IDS_ABOVE_THIS_LINE
// Legacy IDs with arbitrary values appear below
// Legacy IDs existed as stable non-conflicting constants prior to the O release
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 39d0070..9c74188 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -382,6 +382,9 @@
// WifiWake statistics
optional WifiWakeStats wifi_wake_stats = 94;
+
+ // Histogram counting instances of scans with N many 802.11mc (RTT) supporting APs
+ repeated NumConnectableNetworksBucket observed_80211mc_supporting_aps_in_scan_histogram = 95;
}
// Information that gets logged for every WiFi connection.
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 009e723..5114308 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -1036,6 +1036,18 @@
}
@Override
+ public void setAutofillFailure(int sessionId, @NonNull List<AutofillId> ids, int userId) {
+ synchronized (mLock) {
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.setAutofillFailureLocked(sessionId, getCallingUid(), ids);
+ } else if (sVerbose) {
+ Slog.v(TAG, "setAutofillFailure(): no service for " + userId);
+ }
+ }
+ }
+
+ @Override
public void finishSession(int sessionId, int userId) {
synchronized (mLock) {
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index ef0d7e6..0bb29a7 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -404,6 +404,19 @@
}
@GuardedBy("mLock")
+ void setAutofillFailureLocked(int sessionId, int uid, @NonNull List<AutofillId> ids) {
+ if (!isEnabledLocked()) {
+ return;
+ }
+ final Session session = mSessions.get(sessionId);
+ if (session == null || uid != session.uid) {
+ Slog.v(TAG, "setAutofillFailure(): no session for " + sessionId + "(" + uid + ")");
+ return;
+ }
+ session.setAutofillFailureLocked(ids);
+ }
+
+ @GuardedBy("mLock")
void finishSessionLocked(int sessionId, int uid) {
if (!isEnabledLocked()) {
return;
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index bcb0bc4..706fb1a 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -1827,6 +1827,11 @@
}
viewState.setState(ViewState.STATE_STARTED_PARTITION);
requestNewFillResponseLocked(flags);
+ } else {
+ if (sVerbose) {
+ Slog.v(TAG, "Not starting new partition for view " + id + ": "
+ + viewState.getStateAsString());
+ }
}
}
@@ -2194,6 +2199,27 @@
}
}
+ /**
+ * Sets the state of views that failed to autofill.
+ */
+ @GuardedBy("mLock")
+ void setAutofillFailureLocked(@NonNull List<AutofillId> ids) {
+ for (int i = 0; i < ids.size(); i++) {
+ final AutofillId id = ids.get(i);
+ final ViewState viewState = mViewStates.get(id);
+ if (viewState == null) {
+ Slog.w(TAG, "setAutofillFailure(): no view for id " + id);
+ continue;
+ }
+ viewState.resetState(ViewState.STATE_AUTOFILLED);
+ final int state = viewState.getState();
+ viewState.setState(state | ViewState.STATE_AUTOFILL_FAILED);
+ if (sVerbose) {
+ Slog.v(TAG, "Changed state of " + id + " to " + viewState.getStateAsString());
+ }
+ }
+ }
+
@GuardedBy("mLock")
private void replaceResponseLocked(@NonNull FillResponse oldResponse,
@NonNull FillResponse newResponse, @Nullable Bundle newClientState) {
diff --git a/services/autofill/java/com/android/server/autofill/ViewState.java b/services/autofill/java/com/android/server/autofill/ViewState.java
index 97ab97b..9210de2 100644
--- a/services/autofill/java/com/android/server/autofill/ViewState.java
+++ b/services/autofill/java/com/android/server/autofill/ViewState.java
@@ -69,6 +69,8 @@
public static final int STATE_RESTARTED_SESSION = 0x100;
/** View is the URL bar of a package on compat mode. */
public static final int STATE_URL_BAR = 0x200;
+ /** View was asked to autofil but failed to do so. */
+ public static final int STATE_AUTOFILL_FAILED = 0x400;
public final AutofillId id;
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 539c001..83fe976 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1753,7 +1753,8 @@
long token = Binder.clearCallingIdentity();
try {
return LocationAccessPolicy.canAccessCellLocation(mContext,
- r.callingPackage, r.callerUid, r.callerPid);
+ r.callingPackage, r.callerUid, r.callerPid,
+ /*throwOnDeniedPermission*/ false);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5131a93..e3584e6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -820,7 +820,7 @@
public boolean canShowErrorDialogs() {
return mShowDialogs && !mSleeping && !mShuttingDown
- && !mKeyguardController.isKeyguardShowing(DEFAULT_DISPLAY)
+ && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
&& !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
mUserController.getCurrentUserId())
&& !(UserManager.isDeviceInDemoMode(mContext)
@@ -1262,8 +1262,12 @@
}
public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
- return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
- ContentProvider.getUriWithoutUserId(uri), false);
+ if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
+ return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
+ ContentProvider.getUriWithoutUserId(uri), false);
+ } else {
+ return new GrantUri(defaultSourceUserHandle, uri, false);
+ }
}
}
@@ -10601,8 +10605,8 @@
intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
}
}
- final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp, 0,
- UserHandle.getUserId(callingUid));
+ final ActivityInfo ainfo = AppGlobals.getPackageManager().getActivityInfo(comp,
+ STOCK_PM_FLAGS, UserHandle.getUserId(callingUid));
if (ainfo.applicationInfo.uid != callingUid) {
throw new SecurityException(
"Can't add task for another application: target uid="
@@ -13046,6 +13050,22 @@
return mSleeping;
}
+ void reportGlobalUsageEventLocked(int event) {
+ mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
+ int[] profiles = mUserController.getCurrentProfileIds();
+ if (profiles != null) {
+ for (int i = profiles.length - 1; i >= 0; i--) {
+ mUsageStatsService.reportEvent((String)null, profiles[i], event);
+ }
+ }
+ }
+
+ void reportCurWakefulnessUsageEventLocked() {
+ reportGlobalUsageEventLocked(mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE
+ ? UsageEvents.Event.SCREEN_INTERACTIVE
+ : UsageEvents.Event.SCREEN_NON_INTERACTIVE);
+ }
+
void onWakefulnessChanged(int wakefulness) {
synchronized(this) {
boolean wasAwake = mWakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -13055,6 +13075,7 @@
if (wasAwake != isAwake) {
// Also update state in a special way for running foreground services UI.
mServices.updateScreenStateLocked(isAwake);
+ reportCurWakefulnessUsageEventLocked();
mHandler.obtainMessage(DISPATCH_SCREEN_AWAKE_MSG, isAwake ? 1 : 0, 0)
.sendToTarget();
}
@@ -13202,7 +13223,8 @@
}
@Override
- public void setLockScreenShown(boolean showing, int secondaryDisplayShowing) {
+ public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
+ int secondaryDisplayShowing) {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
@@ -13212,13 +13234,14 @@
synchronized(this) {
long ident = Binder.clearCallingIdentity();
try {
- mKeyguardController.setKeyguardShown(showing, secondaryDisplayShowing);
+ mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
+ secondaryDisplayShowing);
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, showing ? 1 : 0, 0)
+ mHandler.obtainMessage(DISPATCH_SCREEN_KEYGUARD_MSG, keyguardShowing ? 1 : 0, 0)
.sendToTarget();
}
@@ -14029,6 +14052,18 @@
}
@Override
+ public boolean isUidActive(int uid, String callingPackage) {
+ if (!hasUsageStatsPermission(callingPackage)) {
+ enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
+ "getPackageProcessState");
+ }
+ synchronized (this) {
+ final UidRecord uidRecord = mActiveUids.get(uid);
+ return uidRecord != null && !uidRecord.setIdle;
+ }
+ }
+
+ @Override
public boolean convertFromTranslucent(IBinder token) {
final long origId = Binder.clearCallingIdentity();
try {
@@ -21190,7 +21225,7 @@
ApplicationInfo aInfo = null;
try {
aInfo = AppGlobals.getPackageManager()
- .getApplicationInfo(ssp, 0 /*flags*/, userId);
+ .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
} catch (RemoteException ignore) {}
if (aInfo == null) {
Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
@@ -21215,7 +21250,7 @@
try {
ApplicationInfo ai = AppGlobals.getPackageManager().
- getApplicationInfo(ssp, 0, 0);
+ getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
mBatteryStatsService.notePackageInstalled(ssp,
ai != null ? ai.versionCode : 0);
} catch (RemoteException e) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index ccc17a3..1af4114 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -236,7 +236,8 @@
final IApplicationToken.Stub appToken; // window manager token
AppWindowContainerController mWindowContainerController;
final ActivityInfo info; // all about me
- final ApplicationInfo appInfo; // information about activity's app
+ // TODO: This is duplicated state already contained in info.applicationInfo - remove
+ ApplicationInfo appInfo; // information about activity's app
final int launchedFromPid; // always the pid who started the activity.
final int launchedFromUid; // always the uid who started the activity.
final String launchedFromPackage; // always the package who started the activity.
@@ -605,6 +606,11 @@
}
}
+ void updateApplicationInfo(ApplicationInfo aInfo) {
+ appInfo = aInfo;
+ info.applicationInfo = aInfo;
+ }
+
private boolean crossesHorizontalSizeThreshold(int firstDp, int secondDp) {
return crossesSizeThreshold(mHorizontalSizeConfigurations, firstDp, secondDp);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index aa462ec..00ebcbd 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1324,7 +1324,7 @@
final ActivityRecord ar = activities.get(activityNdx);
if ((userId == ar.userId) && packageName.equals(ar.packageName)) {
- ar.info.applicationInfo = aInfo;
+ ar.updateApplicationInfo(aInfo);
}
}
}
@@ -2019,8 +2019,9 @@
* @return true if {@param r} is visible taken Keyguard state into account, false otherwise
*/
boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible, boolean isTop) {
- final boolean keyguardShowing = mStackSupervisor.getKeyguardController().isKeyguardShowing(
- mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY);
+ final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
+ final boolean keyguardOrAodShowing = mStackSupervisor.getKeyguardController()
+ .isKeyguardOrAodShowing(displayId);
final boolean keyguardLocked = mStackSupervisor.getKeyguardController().isKeyguardLocked();
final boolean showWhenLocked = r.canShowWhenLocked();
final boolean dismissKeyguard = r.hasDismissKeyguardWindows();
@@ -2041,10 +2042,9 @@
return true;
}
}
- if (keyguardShowing) {
-
+ if (keyguardOrAodShowing) {
// If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard
- // right away.
+ // right away and AOD isn't visible.
return shouldBeVisible && mStackSupervisor.getKeyguardController()
.canShowActivityWhileKeyguardShowing(r, dismissKeyguard);
} else if (keyguardLocked) {
@@ -3987,7 +3987,8 @@
} else {
try {
ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
- destIntent.getComponent(), 0, srec.userId);
+ destIntent.getComponent(), ActivityManagerService.STOCK_PM_FLAGS,
+ srec.userId);
// TODO(b/64750076): Check if calling pid should really be -1.
final int res = mService.getActivityStartController()
.obtainStarter(destIntent, "navigateUpTo")
@@ -5139,8 +5140,9 @@
mService, taskId, info, intent, voiceSession, voiceInteractor);
// add the task to stack first, mTaskPositioner might need the stack association
addTask(task, toTop, "createTaskRecord");
+ final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
final boolean isLockscreenShown = mService.mStackSupervisor.getKeyguardController()
- .isKeyguardShowing(mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY);
+ .isKeyguardOrAodShowing(displayId);
if (!mStackSupervisor.getLaunchParamsController()
.layoutTask(task, info.windowLayout, activity, source, options)
&& !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 265e4fa..d5dfdcf 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3382,8 +3382,8 @@
stack.goToSleepIfPossible(false /* shuttingDown */);
} else {
stack.awakeFromSleepingLocked();
- if (isFocusedStack(stack)
- && !getKeyguardController().isKeyguardShowing(display.mDisplayId)) {
+ if (isFocusedStack(stack) && !getKeyguardController().isKeyguardOrAodShowing(
+ display.mDisplayId)) {
// If the keyguard is unlocked - resume immediately.
// It is possible that the display will not be awake at the time we
// process the keyguard going away, which can happen before the sleep token
diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java
index 868f90d..fb78838 100644
--- a/services/core/java/com/android/server/am/ActivityStartController.java
+++ b/services/core/java/com/android/server/am/ActivityStartController.java
@@ -198,9 +198,10 @@
// See if we should be showing the platform update setup UI.
final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
- final List<ResolveInfo> ris = mService.mContext.getPackageManager()
- .queryIntentActivities(intent,
- PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
+ final List<ResolveInfo> ris =
+ mService.mContext.getPackageManager().queryIntentActivities(intent,
+ PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA
+ | ActivityManagerService.STOCK_PM_FLAGS);
if (!ris.isEmpty()) {
final ResolveInfo ri = ris.get(0);
String vers = ri.activityInfo.metaData != null
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 3c49ece..b338029 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -17,10 +17,15 @@
package com.android.server.am;
import android.app.ActivityManager;
+import android.app.job.JobProtoEnums;
import android.bluetooth.BluetoothActivityEnergyInfo;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.hardware.usb.UsbManager;
import android.net.wifi.WifiActivityEnergyInfo;
import android.os.PowerManager.ServiceType;
import android.os.PowerSaveState;
@@ -34,6 +39,7 @@
import android.os.ParcelFormatException;
import android.os.PowerManagerInternal;
import android.os.Process;
+import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -70,7 +76,6 @@
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
@@ -438,6 +443,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteSyncStartLocked(name, uid);
+ StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name,
+ StatsLog.SYNC_STATE_CHANGED__STATE__ON);
}
}
@@ -445,6 +452,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteSyncFinishLocked(name, uid);
+ StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name,
+ StatsLog.SYNC_STATE_CHANGED__STATE__OFF);
}
}
@@ -452,6 +461,9 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteJobStartLocked(name, uid);
+ StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null,
+ name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
+ JobProtoEnums.STOP_REASON_UNKNOWN);
}
}
@@ -459,6 +471,9 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteJobFinishLocked(name, uid, stopReason);
+ StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null,
+ name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
+ stopReason);
}
}
@@ -573,6 +588,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStartSensorLocked(uid, sensor);
+ StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null, sensor,
+ StatsLog.SENSOR_STATE_CHANGED__STATE__ON);
}
}
@@ -580,6 +597,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStopSensorLocked(uid, sensor);
+ StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null,
+ sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
}
}
@@ -684,6 +703,13 @@
}
}
+ public void noteUsbConnectionState(boolean connected) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteUsbConnectionStateLocked(connected);
+ }
+ }
+
public void notePhoneSignalStrength(SignalStrength signalStrength) {
enforceCallingPermission();
synchronized (mStats) {
@@ -724,6 +750,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteAudioOnLocked(uid);
+ StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__ON);
}
}
@@ -731,6 +759,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteAudioOffLocked(uid);
+ StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
}
}
@@ -738,6 +768,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteVideoOnLocked(uid);
+ StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, uid, null,
+ StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__ON);
}
}
@@ -745,6 +777,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteVideoOffLocked(uid);
+ StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, uid,
+ null, StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__OFF);
}
}
@@ -752,6 +786,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteResetAudioLocked();
+ StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, -1, null,
+ StatsLog.AUDIO_STATE_CHANGED__STATE__RESET);
}
}
@@ -759,6 +795,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteResetVideoLocked();
+ StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, -1, null,
+ StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED__STATE__RESET);
}
}
@@ -766,6 +804,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFlashlightOnLocked(uid);
+ StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null,
+ StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
}
}
@@ -773,6 +813,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFlashlightOffLocked(uid);
+ StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null,
+ StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
}
}
@@ -781,6 +823,8 @@
if (DBG) Slog.d(TAG, "begin noteStartCamera");
synchronized (mStats) {
mStats.noteCameraOnLocked(uid);
+ StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null,
+ StatsLog.CAMERA_STATE_CHANGED__STATE__ON);
}
if (DBG) Slog.d(TAG, "end noteStartCamera");
}
@@ -789,6 +833,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteCameraOffLocked(uid);
+ StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null,
+ StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
}
}
@@ -796,6 +842,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteResetCameraLocked();
+ StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, -1, null,
+ StatsLog.CAMERA_STATE_CHANGED__STATE__RESET);
}
}
@@ -803,6 +851,8 @@
enforceCallingPermission();
synchronized (mStats) {
mStats.noteResetFlashlightLocked();
+ StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, -1, null,
+ StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET);
}
}
@@ -1116,6 +1166,35 @@
Binder.getCallingPid(), Binder.getCallingUid(), null);
}
+ public final static class UsbConnectionReceiver extends BroadcastReceiver {
+ private static final String TAG = UsbConnectionReceiver.class.getSimpleName();
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final String action = intent.getAction();
+ if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
+ final Intent usbState = context.registerReceiver(null, new IntentFilter(UsbManager.ACTION_USB_STATE));
+ if (usbState != null) {
+ handleUsbState(usbState);
+ }
+ } else if (UsbManager.ACTION_USB_STATE.equals(action)) {
+ handleUsbState(intent);
+ }
+ }
+ private void handleUsbState(Intent intent) {
+ IBatteryStats bs = getService();
+ if (bs == null) {
+ Slog.w(TAG, "Could not access batterystats");
+ return;
+ }
+ boolean connected = intent.getExtras().getBoolean(UsbManager.USB_CONNECTED);
+ try {
+ bs.noteUsbConnectionState(connected);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not access batterystats: ", e);
+ }
+ }
+ }
+
final class WakeupReasonThread extends Thread {
private static final int MAX_REASON_SIZE = 512;
private CharsetDecoder mDecoder;
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index b67dd0d..1b7f75b 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -62,6 +62,7 @@
private final ActivityStackSupervisor mStackSupervisor;
private WindowManagerService mWindowManager;
private boolean mKeyguardShowing;
+ private boolean mAodShowing;
private boolean mKeyguardGoingAway;
private boolean mOccluded;
private boolean mDismissalRequested;
@@ -82,6 +83,15 @@
}
/**
+ * @return true if either Keyguard or AOD are showing, not going away, and not being occluded
+ * on the given display, false otherwise
+ */
+ boolean isKeyguardOrAodShowing(int displayId) {
+ return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway &&
+ (displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
+ }
+
+ /**
* @return true if Keyguard is showing, not going away, and not being occluded on the given
* display, false otherwise
*/
@@ -108,17 +118,19 @@
/**
* Update the Keyguard showing state.
*/
- void setKeyguardShown(boolean showing, int secondaryDisplayShowing) {
- boolean showingChanged = showing != mKeyguardShowing;
+ void setKeyguardShown(boolean keyguardShowing, boolean aodShowing,
+ int secondaryDisplayShowing) {
+ boolean showingChanged = keyguardShowing != mKeyguardShowing || aodShowing != mAodShowing;
if (!showingChanged && secondaryDisplayShowing == mSecondaryDisplayShowing) {
return;
}
- mKeyguardShowing = showing;
+ mKeyguardShowing = keyguardShowing;
+ mAodShowing = aodShowing;
mSecondaryDisplayShowing = secondaryDisplayShowing;
if (showingChanged) {
dismissDockedStackIfNeeded();
setKeyguardGoingAway(false);
- if (showing) {
+ if (keyguardShowing) {
mDismissalRequested = false;
}
}
@@ -230,8 +242,8 @@
// Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is
// already the dismissing activity, in which case we don't allow it to repeatedly dismiss
// Keyguard.
- return dismissKeyguard && canDismissKeyguard() &&
- (mDismissalRequested || r != mDismissingKeyguardActivity);
+ return dismissKeyguard && canDismissKeyguard() && !mAodShowing
+ && (mDismissalRequested || r != mDismissingKeyguardActivity);
}
/**
@@ -369,9 +381,9 @@
}
private void updateKeyguardSleepToken() {
- if (mSleepToken == null && isKeyguardShowing(DEFAULT_DISPLAY)) {
+ if (mSleepToken == null && isKeyguardOrAodShowing(DEFAULT_DISPLAY)) {
mSleepToken = mService.acquireSleepToken("Keyguard", DEFAULT_DISPLAY);
- } else if (mSleepToken != null && !isKeyguardShowing(DEFAULT_DISPLAY)) {
+ } else if (mSleepToken != null && !isKeyguardOrAodShowing(DEFAULT_DISPLAY)) {
mSleepToken.release();
mSleepToken = null;
}
@@ -380,6 +392,7 @@
void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "KeyguardController:");
pw.println(prefix + " mKeyguardShowing=" + mKeyguardShowing);
+ pw.println(prefix + " mAodShowing=" + mAodShowing);
pw.println(prefix + " mKeyguardGoingAway=" + mKeyguardGoingAway);
pw.println(prefix + " mOccluded=" + mOccluded);
pw.println(prefix + " mDismissingKeyguardActivity=" + mDismissingKeyguardActivity);
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index efd8153..fcf00ce 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -600,7 +600,8 @@
// activities that are fully runnable based on
// current system state.
ai = pm.getActivityInfo(task.realActivity,
- PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
+ PackageManager.MATCH_DEBUG_TRIAGED_MISSING
+ | ActivityManagerService.STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
// Will never happen.
continue;
diff --git a/services/core/java/com/android/server/am/RecentsAnimation.java b/services/core/java/com/android/server/am/RecentsAnimation.java
index da56ffd..73a7c3eb 100644
--- a/services/core/java/com/android/server/am/RecentsAnimation.java
+++ b/services/core/java/com/android/server/am/RecentsAnimation.java
@@ -168,7 +168,7 @@
"RecentsAnimation#onAnimationFinished_inSurfaceTransaction");
mWindowManager.deferSurfaceLayout();
try {
- mWindowManager.cleanupRecentsAnimation();
+ mWindowManager.cleanupRecentsAnimation(moveHomeToTop);
// Move the home stack to the front
final ActivityRecord homeActivity = mStackSupervisor.getHomeActivity();
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 0d125e0..f710690 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -47,6 +47,7 @@
import android.app.IStopUserCallback;
import android.app.IUserSwitchObserver;
import android.app.KeyguardManager;
+import android.app.usage.UsageEvents;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
@@ -959,6 +960,8 @@
mInjector.getUserManagerInternal().setUserState(userId, uss.state);
}
if (foreground) {
+ // Make sure the old user is no longer considering the display to be on.
+ mInjector.reportGlobalUsageEventLocked(UsageEvents.Event.SCREEN_NON_INTERACTIVE);
synchronized (mLock) {
mCurrentUserId = userId;
mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
@@ -966,6 +969,7 @@
mInjector.updateUserConfiguration();
updateCurrentProfileIds();
mInjector.getWindowManager().setCurrentUser(userId, getCurrentProfileIds());
+ mInjector.reportCurWakefulnessUsageEvent();
// Once the internal notion of the active user has switched, we lock the device
// with the option to show the user switcher on the keyguard.
if (mUserSwitchUiEnabled) {
@@ -2183,6 +2187,18 @@
d.show();
}
+ void reportGlobalUsageEventLocked(int event) {
+ synchronized (mService) {
+ mService.reportGlobalUsageEventLocked(event);
+ }
+ }
+
+ void reportCurWakefulnessUsageEvent() {
+ synchronized (mService) {
+ mService.reportCurWakefulnessUsageEventLocked();
+ }
+ }
+
void stackSupervisorRemoveUser(int userId) {
synchronized (mService) {
mService.mStackSupervisor.removeUserLocked(userId);
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 041764f..c8b6b50 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1422,21 +1422,24 @@
direction/*val1*/, flags/*val2*/, new StringBuilder(callingPackage)
.append("/").append(caller).append(" uid:").append(uid).toString()));
final int streamType;
- if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
- streamType = mVolumeControlStream;
- } else {
- final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
- final boolean activeForReal;
- if (maybeActiveStreamType == AudioSystem.STREAM_RING
- || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
- activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
- } else {
- activeForReal = AudioSystem.isStreamActive(maybeActiveStreamType, 0);
- }
- if (activeForReal || mVolumeControlStream == -1) {
- streamType = maybeActiveStreamType;
- } else {
+ synchronized (mForceControlStreamLock) {
+ // Request lock in case mVolumeControlStream is changed by other thread.
+ if (mUserSelectedVolumeControlStream) { // implies mVolumeControlStream != -1
streamType = mVolumeControlStream;
+ } else {
+ final int maybeActiveStreamType = getActiveStreamType(suggestedStreamType);
+ final boolean activeForReal;
+ if (maybeActiveStreamType == AudioSystem.STREAM_RING
+ || maybeActiveStreamType == AudioSystem.STREAM_NOTIFICATION) {
+ activeForReal = wasStreamActiveRecently(maybeActiveStreamType, 0);
+ } else {
+ activeForReal = AudioSystem.isStreamActive(maybeActiveStreamType, 0);
+ }
+ if (activeForReal || mVolumeControlStream == -1) {
+ streamType = maybeActiveStreamType;
+ } else {
+ streamType = mVolumeControlStream;
+ }
}
}
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index ff8b88b..1784ef1 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -500,7 +500,7 @@
}
public void onSwitchUser(@UserIdInt int newUserId) {
- handleSettingsChange();
+ handleSettingsChange(true /* userSwitch */);
mBrightnessTracker.onSwitchUser(newUserId);
}
@@ -1420,8 +1420,12 @@
mHandler.post(mOnStateChangedRunnable);
}
- private void handleSettingsChange() {
+ private void handleSettingsChange(boolean userSwitch) {
mPendingScreenBrightnessSetting = getScreenBrightnessSetting();
+ if (userSwitch) {
+ // Don't treat user switches as user initiated change.
+ mCurrentScreenBrightnessSetting = mPendingScreenBrightnessSetting;
+ }
mPendingAutoBrightnessAdjustment = getAutoBrightnessAdjustmentSetting();
// We don't bother with a pending variable for VR screen brightness since we just
// immediately adapt to it.
@@ -1735,7 +1739,7 @@
@Override
public void onChange(boolean selfChange, Uri uri) {
- handleSettingsChange();
+ handleSettingsChange(false /* userSwitch */);
}
}
diff --git a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
index a52dd0b..644e0a8 100644
--- a/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
+++ b/services/core/java/com/android/server/fingerprint/AuthenticationClient.java
@@ -54,7 +54,7 @@
private final FingerprintManager mFingerprintManager;
protected boolean mDialogDismissed;
- // Receives events from SystemUI
+ // Receives events from SystemUI and handles them before forwarding them to FingerprintDialog
protected IFingerprintDialogReceiver mDialogReceiver = new IFingerprintDialogReceiver.Stub() {
@Override // binder call
public void onDialogDismissed(int reason) {
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index abe55bb..8365fd2 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -160,7 +160,7 @@
private static boolean isRelaxedSatisfied(JobStatus jobStatus, Network network,
NetworkCapabilities capabilities, Constants constants) {
// Only consider doing this for prefetching jobs
- if ((jobStatus.getJob().getFlags() & JobInfo.FLAG_IS_PREFETCH) == 0) {
+ if (!jobStatus.getJob().isPrefetch()) {
return false;
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
index e0487ea..6d2bec8 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManager.java
@@ -217,12 +217,17 @@
ERROR_INVALID_CERTIFICATE, "Failed to validate certificate.");
}
+ boolean wasInitialized = mDatabase.getRecoveryServiceCertPath(userId, uid) != null;
+
// Save the chosen and validated certificate into database
try {
Log.d(TAG, "Saving the randomly chosen endpoint certificate to database");
if (mDatabase.setRecoveryServiceCertPath(userId, uid, certPath) > 0) {
mDatabase.setRecoveryServiceCertSerial(userId, uid, newSerial);
- mDatabase.setShouldCreateSnapshot(userId, uid, true);
+ if (wasInitialized) {
+ Log.i(TAG, "This is a certificate change. Snapshot pending.");
+ mDatabase.setShouldCreateSnapshot(userId, uid, true);
+ }
mDatabase.setCounterId(userId, uid, new SecureRandom().nextLong());
}
} catch (CertificateEncodingException e) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 01f0d74..0eb906d 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -101,6 +101,7 @@
*/
public class MediaSessionService extends SystemService implements Monitor {
private static final String TAG = "MediaSessionService";
+ static final boolean USE_MEDIA2_APIS = false; // TODO: Change this to true when we're ready.
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
// Leave log for key event always.
private static final boolean DEBUG_KEY_EVENT = true;
@@ -508,6 +509,9 @@
}
private void buildMediaSessionService2List() {
+ if (!USE_MEDIA2_APIS) {
+ return;
+ }
if (DEBUG) {
Log.d(TAG, "buildMediaSessionService2List");
}
@@ -1531,6 +1535,9 @@
*/
@Override
public boolean createSession2(Bundle sessionToken) {
+ if (!USE_MEDIA2_APIS) {
+ return false;
+ }
final int uid = Binder.getCallingUid();
final SessionToken2 token = SessionToken2.fromBundle(sessionToken);
if (token == null || token.getUid() != uid) {
@@ -1570,6 +1577,9 @@
*/
@Override
public void destroySession2(Bundle sessionToken) {
+ if (!USE_MEDIA2_APIS) {
+ return;
+ }
final int uid = Binder.getCallingUid();
final SessionToken2 token = SessionToken2.fromBundle(sessionToken);
if (token == null || token.getUid() != uid) {
@@ -1586,6 +1596,9 @@
@Override
public List<Bundle> getSessionTokens(boolean activeSessionOnly,
boolean sessionServiceOnly, String packageName) throws RemoteException {
+ if (!USE_MEDIA2_APIS) {
+ return null;
+ }
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
@@ -1614,6 +1627,9 @@
@Override
public void addSessionTokensListener(ISessionTokensListener listener, int userId,
String packageName) throws RemoteException {
+ if (!USE_MEDIA2_APIS) {
+ return;
+ }
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
@@ -1637,6 +1653,9 @@
@Override
public void removeSessionTokensListener(ISessionTokensListener listener,
String packageName) throws RemoteException {
+ if (!USE_MEDIA2_APIS) {
+ return;
+ }
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index a5f8dc7..2ef754e 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -16,9 +16,9 @@
package com.android.server.net;
-import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.DEFAULT_NETWORK_NO;
import static android.net.NetworkStats.DEFAULT_NETWORK_YES;
+import static android.net.NetworkStats.IFACE_ALL;
import static android.net.NetworkStats.METERED_NO;
import static android.net.NetworkStats.METERED_YES;
import static android.net.NetworkStats.ROAMING_NO;
@@ -42,9 +42,11 @@
import android.service.NetworkStatsCollectionProto;
import android.service.NetworkStatsCollectionStatsProto;
import android.telephony.SubscriptionPlan;
+import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.IntArray;
+import android.util.MathUtils;
import android.util.Pair;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -245,7 +247,10 @@
+ " is forbidden for caller " + callerUid);
}
- final int bucketEstimate = (int) ((end - start) / mBucketDuration);
+ // 180 days of history should be enough for anyone; if we end up needing
+ // more, we'll dynamically grow the history object.
+ final int bucketEstimate = (int) MathUtils.constrain(((end - start) / mBucketDuration), 0,
+ (180 * DateUtils.DAY_IN_MILLIS) / mBucketDuration);
final NetworkStatsHistory combined = new NetworkStatsHistory(
mBucketDuration, bucketEstimate, fields);
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java b/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java
index 2714d5e..d793842 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistConfig.java
@@ -107,6 +107,10 @@
* Reload watchlist by reading config file.
*/
public void reloadConfig() {
+ if (!mXmlFile.exists()) {
+ // No config file
+ return;
+ }
try (FileInputStream stream = new FileInputStream(mXmlFile)){
final List<byte[]> crc32DomainList = new ArrayList<>();
final List<byte[]> sha256DomainList = new ArrayList<>();
diff --git a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
index f5ba889..e20a510 100644
--- a/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
+++ b/services/core/java/com/android/server/net/watchlist/WatchlistSettings.java
@@ -87,6 +87,10 @@
}
public void reloadSettings() {
+ if (!mXmlFile.exists()) {
+ // No settings config
+ return;
+ }
try (FileInputStream stream = mXmlFile.openRead()){
XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, StandardCharsets.UTF_8.name());
@@ -97,7 +101,7 @@
mPrivacySecretKey = parseSecretKey(parser);
}
}
- Log.i(TAG, "Reload watchlist settings done");
+ Slog.i(TAG, "Reload watchlist settings done");
} catch (IllegalStateException | NullPointerException | NumberFormatException |
XmlPullParserException | IOException | IndexOutOfBoundsException e) {
Slog.e(TAG, "Failed parsing xml", e);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 59cd561..210857e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -5969,6 +5969,7 @@
}
private boolean isPackageSuspendedForUser(String pkg, int uid) {
+ final long identity = Binder.clearCallingIdentity();
int userId = UserHandle.getUserId(uid);
try {
return mPackageManager.isPackageSuspendedForUser(pkg, userId);
@@ -5977,6 +5978,8 @@
} catch (IllegalArgumentException ex) {
// Package not found.
return false;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 5c82343..586abc1 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -933,11 +933,7 @@
}
break;
case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
- if (ZenModeConfig.areAllPriorityOnlyNotificationZenSoundsMuted(mConfig)
- && ringerModeInternal != AudioManager.RINGER_MODE_SILENT) {
- setPreviousRingerModeSetting(ringerModeInternal);
- newRingerModeInternal = AudioManager.RINGER_MODE_SILENT;
- }
+ // do not apply zen to ringer, streams zen muted in AudioService
break;
case Global.ZEN_MODE_OFF:
if (ringerModeInternal == AudioManager.RINGER_MODE_SILENT) {
diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
index e315bc5..0774672 100644
--- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java
+++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java
@@ -472,10 +472,17 @@
if (params.getJobId() == JOB_POST_BOOT_UPDATE) {
mAbortPostBootUpdate.set(true);
+
+ // Do not reschedule.
+ // TODO: We should reschedule if we didn't process all apps, yet.
+ return false;
} else {
mAbortIdleOptimization.set(true);
+
+ // Reschedule the run.
+ // TODO: Should this be dependent on the stop reason?
+ return true;
}
- return false;
}
private void notifyPinService(ArraySet<String> updatedPackages) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 950d8df..2ae337d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -92,6 +92,7 @@
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
+import static com.android.internal.util.ArrayUtils.appendElement;
import static com.android.internal.util.ArrayUtils.appendInt;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
@@ -778,8 +779,14 @@
return PackageManagerService.this.hasSystemFeature(feature, 0);
}
- final List<PackageParser.Package> getStaticOverlayPackagesLocked(
+ final List<PackageParser.Package> getStaticOverlayPackages(
Collection<PackageParser.Package> allPackages, String targetPackageName) {
+ if ("android".equals(targetPackageName)) {
+ // Static RROs targeting to "android", ie framework-res.apk, are already applied by
+ // native AssetManager.
+ return null;
+ }
+
List<PackageParser.Package> overlayPackages = null;
for (PackageParser.Package p : allPackages) {
if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
@@ -800,16 +807,8 @@
return overlayPackages;
}
- @GuardedBy("mInstallLock")
- final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
- String targetPackageName, String targetPath) {
- if ("android".equals(targetPackageName)) {
- // Static RROs targeting to "android", ie framework-res.apk, are already applied by
- // native AssetManager.
- return null;
- }
- List<PackageParser.Package> overlayPackages =
- getStaticOverlayPackagesLocked(allPackages, targetPackageName);
+ final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
+ String targetPath) {
if (overlayPackages == null || overlayPackages.isEmpty()) {
return null;
}
@@ -829,9 +828,11 @@
//
// OverlayManagerService will update each of them with a correct gid from its
// target package app id.
- mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
- UserHandle.getSharedAppGid(
- UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
+ synchronized (mInstallLock) {
+ mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
+ UserHandle.getSharedAppGid(
+ UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
+ }
if (overlayPathList == null) {
overlayPathList = new ArrayList<String>();
}
@@ -845,10 +846,14 @@
}
String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
+ List<PackageParser.Package> overlayPackages;
synchronized (mPackages) {
- return getStaticOverlayPathsLocked(
- mPackages.values(), targetPackageName, targetPath);
+ overlayPackages = getStaticOverlayPackages(
+ mPackages.values(), targetPackageName);
}
+ // It is safe to keep overlayPackages without holding mPackages because static overlay
+ // packages can't be uninstalled or disabled.
+ return getStaticOverlayPaths(overlayPackages, targetPath);
}
@Override public final String[] getOverlayApks(String targetPackageName) {
@@ -883,7 +888,9 @@
// can't happen while running parallel parsing.
// Moreover holding mPackages on each parsing thread causes dead-lock.
return mOverlayPackages == null ? null :
- getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
+ getStaticOverlayPaths(
+ getStaticOverlayPackages(mOverlayPackages, targetPackageName),
+ targetPath);
}
}
@@ -10355,7 +10362,7 @@
if (Build.IS_DEBUGGABLE &&
pkg.isPrivileged() &&
- !SystemProperties.getBoolean(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB, true)) {
+ SystemProperties.getBoolean(PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB, false)) {
PackageManagerServiceUtils.logPackageHasUncompressedCode(pkg);
}
@@ -13987,18 +13994,15 @@
return packageNames;
}
- // List of package names for whom the suspended state has changed.
- final List<String> changedPackages = new ArrayList<>(packageNames.length);
- // List of package names for whom the suspended state is not set as requested in this
- // method.
+ final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
final long callingId = Binder.clearCallingIdentity();
try {
synchronized (mPackages) {
for (int i = 0; i < packageNames.length; i++) {
final String packageName = packageNames[i];
- if (packageName == callingPackage) {
- Slog.w(TAG, "Calling package: " + callingPackage + "trying to "
+ if (callingPackage.equals(packageName)) {
+ Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
+ (suspended ? "" : "un") + "suspend itself. Ignoring");
unactionedPackages.add(packageName);
continue;
@@ -14018,17 +14022,18 @@
}
pkgSetting.setSuspended(suspended, callingPackage, appExtras,
launcherExtras, userId);
- changedPackages.add(packageName);
+ changedPackagesList.add(packageName);
}
}
}
} finally {
Binder.restoreCallingIdentity(callingId);
}
- // TODO (b/75036698): Also send each package a broadcast when suspended state changed
- if (!changedPackages.isEmpty()) {
- sendPackagesSuspendedForUser(changedPackages.toArray(
- new String[changedPackages.size()]), userId, suspended);
+ if (!changedPackagesList.isEmpty()) {
+ final String[] changedPackages = changedPackagesList.toArray(
+ new String[changedPackagesList.size()]);
+ sendPackagesSuspendedForUser(changedPackages, userId, suspended);
+ sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, appExtras, userId);
synchronized (mPackages) {
scheduleWritePackageRestrictionsLocked(userId);
}
@@ -14038,7 +14043,7 @@
}
@Override
- public PersistableBundle getPackageSuspendedAppExtras(String packageName, int userId) {
+ public PersistableBundle getSuspendedPackageAppExtras(String packageName, int userId) {
final int callingUid = Binder.getCallingUid();
if (getPackageUid(packageName, 0, userId) != callingUid) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS, null);
@@ -14049,7 +14054,10 @@
throw new IllegalArgumentException("Unknown target package: " + packageName);
}
final PackageUserState packageUserState = ps.readUserState(userId);
- return packageUserState.suspended ? packageUserState.suspendedAppExtras : null;
+ if (packageUserState.suspended) {
+ return packageUserState.suspendedAppExtras;
+ }
+ return null;
}
}
@@ -14065,12 +14073,49 @@
}
final PackageUserState packageUserState = ps.readUserState(userId);
if (packageUserState.suspended) {
- // TODO (b/75036698): Also send this package a broadcast with the new app extras
packageUserState.suspendedAppExtras = appExtras;
+ sendMyPackageSuspendedOrUnsuspended(new String[] {packageName}, true, appExtras,
+ userId);
}
}
}
+ private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
+ PersistableBundle appExtras, int userId) {
+ final String action;
+ final Bundle intentExtras = new Bundle();
+ if (suspended) {
+ action = Intent.ACTION_MY_PACKAGE_SUSPENDED;
+ if (appExtras != null) {
+ final Bundle bundledAppExtras = new Bundle(appExtras.deepCopy());
+ intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, bundledAppExtras);
+ }
+ } else {
+ action = Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
+ }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ final IActivityManager am = ActivityManager.getService();
+ if (am == null) {
+ Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
+ + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
+ return;
+ }
+ final int[] targetUserIds = new int[] {userId};
+ for (String packageName : affectedPackages) {
+ doSendBroadcast(am, action, null, intentExtras,
+ Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
+ targetUserIds, false);
+ }
+ } catch (RemoteException ex) {
+ // Shouldn't happen as AMS is in the same process.
+ }
+ }
+ });
+ }
+
@Override
public boolean isPackageSuspendedForUser(String packageName, int userId) {
final int callingUid = Binder.getCallingUid();
@@ -18890,7 +18935,7 @@
return true;
}
- private static final class ClearStorageConnection implements ServiceConnection {
+ private final class ClearStorageConnection implements ServiceConnection {
IMediaContainerService mContainerService;
@Override
@@ -21611,37 +21656,35 @@
// the given package is involved with.
if (dumpState.onTitlePrinted()) pw.println();
- try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120)) {
- ipw.println();
- ipw.println("Frozen packages:");
- ipw.increaseIndent();
- if (mFrozenPackages.size() == 0) {
- ipw.println("(none)");
- } else {
- for (int i = 0; i < mFrozenPackages.size(); i++) {
- ipw.println(mFrozenPackages.valueAt(i));
- }
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
+ ipw.println();
+ ipw.println("Frozen packages:");
+ ipw.increaseIndent();
+ if (mFrozenPackages.size() == 0) {
+ ipw.println("(none)");
+ } else {
+ for (int i = 0; i < mFrozenPackages.size(); i++) {
+ ipw.println(mFrozenPackages.valueAt(i));
}
- ipw.decreaseIndent();
}
+ ipw.decreaseIndent();
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
if (dumpState.onTitlePrinted()) pw.println();
- try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120)) {
- ipw.println();
- ipw.println("Loaded volumes:");
- ipw.increaseIndent();
- if (mLoadedVolumes.size() == 0) {
- ipw.println("(none)");
- } else {
- for (int i = 0; i < mLoadedVolumes.size(); i++) {
- ipw.println(mLoadedVolumes.valueAt(i));
- }
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ", 120);
+ ipw.println();
+ ipw.println("Loaded volumes:");
+ ipw.increaseIndent();
+ if (mLoadedVolumes.size() == 0) {
+ ipw.println("(none)");
+ } else {
+ for (int i = 0; i < mLoadedVolumes.size(); i++) {
+ ipw.println(mLoadedVolumes.valueAt(i));
}
- ipw.decreaseIndent();
}
+ ipw.decreaseIndent();
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
@@ -21770,63 +21813,61 @@
}
private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
- try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) {
- ipw.println();
- ipw.println("Dexopt state:");
- ipw.increaseIndent();
- Collection<PackageParser.Package> packages = null;
- if (packageName != null) {
- PackageParser.Package targetPackage = mPackages.get(packageName);
- if (targetPackage != null) {
- packages = Collections.singletonList(targetPackage);
- } else {
- ipw.println("Unable to find package: " + packageName);
- return;
- }
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ ipw.println();
+ ipw.println("Dexopt state:");
+ ipw.increaseIndent();
+ Collection<PackageParser.Package> packages = null;
+ if (packageName != null) {
+ PackageParser.Package targetPackage = mPackages.get(packageName);
+ if (targetPackage != null) {
+ packages = Collections.singletonList(targetPackage);
} else {
- packages = mPackages.values();
+ ipw.println("Unable to find package: " + packageName);
+ return;
}
+ } else {
+ packages = mPackages.values();
+ }
- for (PackageParser.Package pkg : packages) {
- ipw.println("[" + pkg.packageName + "]");
- ipw.increaseIndent();
- mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
- mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
- ipw.decreaseIndent();
- }
+ for (PackageParser.Package pkg : packages) {
+ ipw.println("[" + pkg.packageName + "]");
+ ipw.increaseIndent();
+ mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
+ mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
+ ipw.decreaseIndent();
}
}
private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
- try (final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) {
- ipw.println();
- ipw.println("Compiler stats:");
- ipw.increaseIndent();
- Collection<PackageParser.Package> packages = null;
- if (packageName != null) {
- PackageParser.Package targetPackage = mPackages.get(packageName);
- if (targetPackage != null) {
- packages = Collections.singletonList(targetPackage);
- } else {
- ipw.println("Unable to find package: " + packageName);
- return;
- }
+ final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
+ ipw.println();
+ ipw.println("Compiler stats:");
+ ipw.increaseIndent();
+ Collection<PackageParser.Package> packages = null;
+ if (packageName != null) {
+ PackageParser.Package targetPackage = mPackages.get(packageName);
+ if (targetPackage != null) {
+ packages = Collections.singletonList(targetPackage);
} else {
- packages = mPackages.values();
+ ipw.println("Unable to find package: " + packageName);
+ return;
}
+ } else {
+ packages = mPackages.values();
+ }
- for (PackageParser.Package pkg : packages) {
- ipw.println("[" + pkg.packageName + "]");
- ipw.increaseIndent();
+ for (PackageParser.Package pkg : packages) {
+ ipw.println("[" + pkg.packageName + "]");
+ ipw.increaseIndent();
- CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
- if (stats == null) {
- ipw.println("(No recorded stats)");
- } else {
- stats.dump(ipw);
- }
- ipw.decreaseIndent();
+ CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
+ if (stats == null) {
+ ipw.println("(No recorded stats)");
+ } else {
+ stats.dump(ipw);
}
+ ipw.decreaseIndent();
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index 5060c4d..853081a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -331,18 +331,18 @@
ZipEntry entry = it.next();
if (entry.getName().endsWith(".dex")) {
if (entry.getMethod() != ZipEntry.STORED) {
- Slog.wtf(TAG, "APK " + fileName + " has compressed dex code " +
+ Slog.w(TAG, "APK " + fileName + " has compressed dex code " +
entry.getName());
} else if ((entry.getDataOffset() & 0x3) != 0) {
- Slog.wtf(TAG, "APK " + fileName + " has unaligned dex code " +
+ Slog.w(TAG, "APK " + fileName + " has unaligned dex code " +
entry.getName());
}
} else if (entry.getName().endsWith(".so")) {
if (entry.getMethod() != ZipEntry.STORED) {
- Slog.wtf(TAG, "APK " + fileName + " has compressed native code " +
+ Slog.w(TAG, "APK " + fileName + " has compressed native code " +
entry.getName());
} else if ((entry.getDataOffset() & (0x1000 - 1)) != 0) {
- Slog.wtf(TAG, "APK " + fileName + " has unaligned native code " +
+ Slog.w(TAG, "APK " + fileName + " has unaligned native code " +
entry.getName());
}
}
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 062b154..81a8c55 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -213,7 +213,8 @@
// There are no longer any keyguard windows on secondary displays, so pass
// INVALID_DISPLAY. All that means is that showWhenLocked activities on
// secondary displays now get to show.
- ActivityManager.getService().setLockScreenShown(true, INVALID_DISPLAY);
+ ActivityManager.getService().setLockScreenShown(true /* keyguardShowing */,
+ false /* aodShowing */, INVALID_DISPLAY);
} catch (RemoteException e) {
// Local call.
}
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index 8901b04..d123099c 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -1428,7 +1428,7 @@
void clearWallpaperLocked(boolean defaultFailed, int which, int userId, IRemoteCallback reply) {
if (which != FLAG_SYSTEM && which != FLAG_LOCK) {
- throw new IllegalArgumentException("Must specify exactly one kind of wallpaper to read");
+ throw new IllegalArgumentException("Must specify exactly one kind of wallpaper to clear");
}
WallpaperData wallpaper = null;
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index d000bb6..1f95868 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -110,6 +110,11 @@
SurfaceAnimator mSurfaceAnimator;
/**
+ * Determines whether the dim layer should animate before destroying.
+ */
+ boolean mAnimateExit = true;
+
+ /**
* Used for Dims not associated with a WindowContainer. See {@link Dimmer#dimAbove} for
* details on Dim lifecycle.
*/
@@ -260,6 +265,12 @@
}
}
+ void dontAnimateExit() {
+ if (mDimState != null) {
+ mDimState.mAnimateExit = false;
+ }
+ }
+
/**
* Call after invoking {@link WindowContainer#prepareSurfaces} on children as
* described in {@link #resetDimStates}.
@@ -274,7 +285,11 @@
}
if (!mDimState.mDimming) {
- startDimExit(mLastRequestedDimContainer, mDimState.mSurfaceAnimator, t);
+ if (!mDimState.mAnimateExit) {
+ t.destroy(mDimState.mDimLayer);
+ } else {
+ startDimExit(mLastRequestedDimContainer, mDimState.mSurfaceAnimator, t);
+ }
mDimState = null;
return false;
} else {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 3e47ea6..a7eac55 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -385,6 +385,11 @@
*/
private int mSurfaceSize;
+ /**
+ * Sequence number for the current layout pass.
+ */
+ int mLayoutSeq = 0;
+
/** Temporary float array to retrieve 3x3 matrix values. */
private final float[] mTmpFloats = new float[9];
@@ -554,7 +559,7 @@
w.prelayout();
final boolean firstLayout = !w.isLaidOut();
mService.mPolicy.layoutWindowLw(w, null, mDisplayFrames);
- w.mLayoutSeq = mService.mLayoutSeq;
+ w.mLayoutSeq = mLayoutSeq;
// If this is the first layout, we need to initialize the last inset values as
// otherwise we'd immediately cause an unnecessary resize.
@@ -593,7 +598,7 @@
w.mLayoutNeeded = false;
w.prelayout();
mService.mPolicy.layoutWindowLw(w, w.getParentWindow(), mDisplayFrames);
- w.mLayoutSeq = mService.mLayoutSeq;
+ w.mLayoutSeq = mLayoutSeq;
if (DEBUG_LAYOUT) Slog.v(TAG, " LAYOUT: mFrame=" + w.mFrame
+ " mContainingFrame=" + w.mContainingFrame
+ " mDisplayFrame=" + w.mDisplayFrame);
@@ -2219,6 +2224,9 @@
pw.println(" mTouchExcludeRegion=" + mTouchExcludeRegion);
pw.println();
+ pw.print(prefix); pw.print("mLayoutSeq="); pw.println(mLayoutSeq);
+
+ pw.println();
pw.println(prefix + "Application tokens in top down Z order:");
for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
final TaskStack stack = mTaskStackContainers.getChildAt(stackNdx);
@@ -2927,9 +2935,9 @@
mService.mScreenRect.set(0, 0, dw, dh);
}
- int seq = mService.mLayoutSeq + 1;
+ int seq = mLayoutSeq + 1;
if (seq < 0) seq = 0;
- mService.mLayoutSeq = seq;
+ mLayoutSeq = seq;
// Used to indicate that we have processed the dream window and all additional windows are
// behind it.
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 87a7a74..1018848 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -41,7 +41,6 @@
import android.util.Slog;import android.util.proto.ProtoOutputStream;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
-import android.util.proto.ProtoOutputStream;
import android.view.IRecentsAnimationController;
import android.view.IRecentsAnimationRunner;
import android.view.RemoteAnimationTarget;
@@ -309,12 +308,15 @@
mCallbacks.onAnimationFinished(false /* moveHomeToTop */);
}
- void cleanupAnimation() {
+ void cleanupAnimation(boolean moveHomeToTop) {
if (DEBUG) Log.d(TAG, "cleanupAnimation(): mPendingAnimations="
+ mPendingAnimations.size());
for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
adapter.mTask.setCanAffectSystemUiFlags(true);
+ if (moveHomeToTop) {
+ adapter.mTask.dontAnimateDimExit();
+ }
adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
}
mPendingAnimations.clear();
diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java
index 541a6f6..379a1a1 100644
--- a/services/core/java/com/android/server/wm/RemoteAnimationController.java
+++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java
@@ -16,14 +16,15 @@
package com.android.server.wm;
+import static com.android.server.wm.AnimationAdapterProto.REMOTE;
+import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-import static com.android.server.wm.AnimationAdapterProto.REMOTE;
-import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET;
import android.graphics.Point;
import android.graphics.Rect;
+import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
import android.os.SystemClock;
@@ -202,12 +203,17 @@
@Override
public void onAnimationFinished() throws RemoteException {
- if (mOuter != null) {
- mOuter.onAnimationFinished();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ if (mOuter != null) {
+ mOuter.onAnimationFinished();
- // In case the client holds on to the finish callback, make sure we don't leak
- // RemoteAnimationController which in turn would leak the runner on the client.
- mOuter = null;
+ // In case the client holds on to the finish callback, make sure we don't leak
+ // RemoteAnimationController which in turn would leak the runner on the client.
+ mOuter = null;
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
}
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index e4722f9..e8d3210 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -645,6 +645,10 @@
return mCanAffectSystemUiFlags;
}
+ void dontAnimateDimExit() {
+ mDimmer.dontAnimateExit();
+ }
+
@Override
public String toString() {
return "{taskId=" + mTaskId + " appTokens=" + mChildren + " mdr=" + mDeferRemoval + "}";
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 56b314f..0b5c006 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -596,8 +596,6 @@
boolean mClientFreezingScreen = false;
int mAppsFreezingScreen = 0;
- int mLayoutSeq = 0;
-
// Last systemUiVisibility we received from status bar.
int mLastStatusBarVisibility = 0;
// Last systemUiVisibility we dispatched to windows.
@@ -2702,10 +2700,10 @@
}
}
- public void cleanupRecentsAnimation() {
+ public void cleanupRecentsAnimation(boolean moveHomeToTop) {
synchronized (mWindowMap) {
if (mRecentsAnimationController != null) {
- mRecentsAnimationController.cleanupAnimation();
+ mRecentsAnimationController.cleanupAnimation(moveHomeToTop);
mRecentsAnimationController = null;
mAppTransition.updateBooster();
}
@@ -6344,8 +6342,7 @@
if (mInputMethodTarget != null) {
pw.print(" mInputMethodTarget="); pw.println(mInputMethodTarget);
}
- pw.print(" mInTouchMode="); pw.print(mInTouchMode);
- pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
+ pw.print(" mInTouchMode="); pw.println(mInTouchMode);
pw.print(" mLastDisplayFreezeDuration=");
TimeUtils.formatDuration(mLastDisplayFreezeDuration, pw);
if ( mLastFinishedFreezeSource != null) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 993556f..30bbfe0 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -1236,7 +1236,7 @@
*/
void updateResizingWindowIfNeeded() {
final WindowStateAnimator winAnimator = mWinAnimator;
- if (!mHasSurface || mService.mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) {
+ if (!mHasSurface || getDisplayContent().mLayoutSeq != mLayoutSeq || isGoneForLayoutLw()) {
return;
}
@@ -1360,6 +1360,15 @@
return mToken.getDisplayContent();
}
+ @Override
+ void onDisplayChanged(DisplayContent dc) {
+ super.onDisplayChanged(dc);
+ // Window was not laid out for this display yet, so make sure mLayoutSeq does not match.
+ if (dc != null) {
+ mLayoutSeq = dc.mLayoutSeq - 1;
+ }
+ }
+
DisplayInfo getDisplayInfo() {
final DisplayContent displayContent = getDisplayContent();
return displayContent != null ? displayContent.getDisplayInfo() : null;
diff --git a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp
index e9d4482..ccb4f59 100644
--- a/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp
+++ b/services/core/jni/com_android_server_UsbAlsaJackDetector.cpp
@@ -19,6 +19,7 @@
#include "jni.h"
#include <nativehelper/JNIHelp.h>
+#include "android-base/strings.h"
#include "android_runtime/AndroidRuntime.h"
#include "android_runtime/Log.h"
@@ -33,24 +34,36 @@
#define DRIVER_NAME "/dev/usb_accessory"
-#define USB_IN_JACK_NAME "USB in Jack"
-#define USB_OUT_JACK_NAME "USB out Jack"
+#define USB_IN_JACK_SUFFIX "Input Jack"
+#define USB_OUT_JACK_SUFFIX "Output Jack"
namespace android
{
-static jboolean is_jack_connected(jint card, const char* control) {
+static struct mixer_ctl* find_mixer_with_suffix(struct mixer* card_mixer, const char* suffix) {
+ int id = 0;
+ struct mixer_ctl* ctl;
+ while ((ctl = mixer_get_ctl(card_mixer, id++)) != NULL) {
+ const char* name = mixer_ctl_get_name(ctl);
+ if (android::base::EndsWith(name, suffix)) {
+ return ctl;
+ }
+ }
+ return NULL;
+}
+
+static jboolean is_jack_connected(jint card, const char* suffix) {
struct mixer* card_mixer = mixer_open(card);
if (card_mixer == NULL) {
return true;
}
- struct mixer_ctl* ctl = mixer_get_ctl_by_name(card_mixer, control);
+ struct mixer_ctl* ctl = find_mixer_with_suffix(card_mixer, suffix);
if (!ctl) {
return true;
}
mixer_ctl_update(ctl);
int val = mixer_ctl_get_value(ctl, 0);
- ALOGI("JACK %s - value %d\n", control, val);
+ ALOGI("%s - value %d\n", mixer_ctl_get_name(ctl), val);
mixer_close(card_mixer);
return val != 0;
@@ -66,33 +79,31 @@
}
jboolean has_jack = false;
- if ((mixer_get_ctl_by_name(card_mixer, USB_IN_JACK_NAME) != NULL) ||
- (mixer_get_ctl_by_name(card_mixer, USB_OUT_JACK_NAME) != NULL)) {
+ if ((find_mixer_with_suffix(card_mixer, USB_IN_JACK_SUFFIX) != NULL) ||
+ (find_mixer_with_suffix(card_mixer, USB_OUT_JACK_SUFFIX) != NULL)) {
has_jack = true;
}
mixer_close(card_mixer);
return has_jack;
}
-
static jboolean android_server_UsbAlsaJackDetector_inputJackConnected(JNIEnv* /* env */,
jobject /* thiz */,
jint card)
{
- return is_jack_connected(card, USB_IN_JACK_NAME);
+ return is_jack_connected(card, USB_IN_JACK_SUFFIX);
}
-
static jboolean android_server_UsbAlsaJackDetector_outputJackConnected(JNIEnv* /* env */,
jobject /* thiz */,
jint card)
{
- return is_jack_connected(card, USB_OUT_JACK_NAME);
+ return is_jack_connected(card, USB_OUT_JACK_SUFFIX);
}
static void android_server_UsbAlsaJackDetector_jackDetect(JNIEnv* env,
- jobject thiz,
- jint card) {
+ jobject thiz,
+ jint card) {
jclass jdclass = env->GetObjectClass(thiz);
jmethodID method_jackDetectCallback = env->GetMethodID(jdclass, "jackDetectCallback", "()Z");
if (method_jackDetectCallback == NULL) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 44634ab..1e216a3 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11843,6 +11843,7 @@
@Override
public boolean isDeviceProvisioned() {
+ enforceManageUsers();
synchronized (this) {
return getUserDataUnchecked(UserHandle.USER_SYSTEM).mUserSetupComplete;
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
index b452ea5..cda968a7 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -240,7 +240,7 @@
doReturn(displayShouldSleep).when(display).shouldSleep();
doReturn(displaySleeping).when(display).isSleeping();
- doReturn(keyguardShowing).when(keyguard).isKeyguardShowing(anyInt());
+ doReturn(keyguardShowing).when(keyguard).isKeyguardOrAodShowing(anyInt());
mSupervisor.mFocusedStack = isFocusedStack ? stack : null;
mSupervisor.applySleepTokensLocked(true);
diff --git a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
index 6fdb029..3c10b03 100644
--- a/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/UserControllerTest.java
@@ -389,6 +389,14 @@
sentIntents.add(intent);
return 0;
}
+
+ @Override
+ void reportGlobalUsageEventLocked(int event) {
+ }
+
+ @Override
+ void reportCurWakefulnessUsageEvent() {
+ }
}
private static class TestHandler extends Handler {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
index 06b94cb..8db2537 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/RecoverableKeyStoreManagerTest.java
@@ -298,7 +298,7 @@
mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
TestData.getCertXmlWithSerial(certSerial));
- assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
+ assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid)).isEqualTo(
TestData.CERT_PATH_1);
assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid)).isEqualTo(
@@ -348,6 +348,7 @@
assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid))
.isEqualTo(certSerial + 1);
+ assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
}
@Test
@@ -363,6 +364,7 @@
assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertSerial(userId, uid))
.isEqualTo(certSerial);
+ assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
}
@Test
@@ -373,7 +375,6 @@
mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
TestData.getCertXmlWithSerial(certSerial));
- mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, false);
mRecoverableKeyStoreManager.initRecoveryService(ROOT_CERTIFICATE_ALIAS,
TestData.getCertXmlWithSerial(certSerial));
@@ -404,7 +405,7 @@
mRecoverableKeyStoreManager.initRecoveryServiceWithSigFile(
ROOT_CERTIFICATE_ALIAS, TestData.getCertXml(), TestData.getSigXml());
- assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
+ assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isFalse();
assertThat(mRecoverableKeyStoreDb.getRecoveryServiceCertPath(userId, uid)).isEqualTo(
TestData.CERT_PATH_1);
assertThat(mRecoverableKeyStoreDb.getRecoveryServicePublicKey(userId, uid)).isNull();
@@ -946,12 +947,12 @@
public void setRecoverySecretTypes_updatesShouldCreateSnapshot() throws Exception {
int uid = Binder.getCallingUid();
int userId = UserHandle.getCallingUserId();
- int[] types = new int[]{1, 2, 3};
+ mRecoverableKeyStoreManager.setRecoverySecretTypes(new int[] { 1 });
mRecoverableKeyStoreManager.generateAndStoreKey(TEST_ALIAS);
// Pretend that key was synced
mRecoverableKeyStoreDb.setShouldCreateSnapshot(userId, uid, false);
- mRecoverableKeyStoreManager.setRecoverySecretTypes(types);
+ mRecoverableKeyStoreManager.setRecoverySecretTypes(new int[] { 2 });
assertThat(mRecoverableKeyStoreDb.getShouldCreateSnapshot(userId, uid)).isTrue();
}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverySnapshotStorageTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverySnapshotStorageTest.java
index ead817a..c772956 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverySnapshotStorageTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/storage/RecoverySnapshotStorageTest.java
@@ -7,23 +7,19 @@
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
+import com.android.server.locksettings.recoverablekeystore.TestData;
+
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.security.cert.CertificateException;
import java.util.ArrayList;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class RecoverySnapshotStorageTest {
- private static final KeyChainSnapshot MINIMAL_KEYCHAIN_SNAPSHOT = new KeyChainSnapshot.Builder()
- .setCounterId(1)
- .setSnapshotVersion(1)
- .setServerParams(new byte[0])
- .setMaxAttempts(10)
- .setEncryptedRecoveryKeyBlob(new byte[0])
- .setKeyChainProtectionParams(new ArrayList<>())
- .setWrappedApplicationKeys(new ArrayList<>())
- .build();
+ private static final KeyChainSnapshot MINIMAL_KEYCHAIN_SNAPSHOT =
+ createMinimalKeyChainSnapshot();
private final RecoverySnapshotStorage mRecoverySnapshotStorage = new RecoverySnapshotStorage();
@@ -50,4 +46,21 @@
assertNull(mRecoverySnapshotStorage.get(1000));
}
+
+ private static KeyChainSnapshot createMinimalKeyChainSnapshot() {
+ try {
+ return new KeyChainSnapshot.Builder()
+ .setCounterId(1)
+ .setSnapshotVersion(1)
+ .setServerParams(new byte[0])
+ .setMaxAttempts(10)
+ .setEncryptedRecoveryKeyBlob(new byte[0])
+ .setKeyChainProtectionParams(new ArrayList<>())
+ .setWrappedApplicationKeys(new ArrayList<>())
+ .setTrustedHardwareCertPath(TestData.CERT_PATH_1)
+ .build();
+ } catch (CertificateException e) {
+ throw new RuntimeException(e);
+ }
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
index d702318..ee0ad39 100644
--- a/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/SuspendPackagesTest.java
@@ -16,55 +16,129 @@
package com.android.server.pm;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
+import android.app.AppGlobals;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.os.BaseBundle;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.PersistableBundle;
+import android.os.RemoteException;
import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.MediumTest;
+import android.support.test.filters.LargeTest;
import android.support.test.runner.AndroidJUnit4;
import com.android.servicestests.apps.suspendtestapp.SuspendTestReceiver;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@RunWith(AndroidJUnit4.class)
-@MediumTest
+@LargeTest
public class SuspendPackagesTest {
private static final String TEST_APP_PACKAGE_NAME = SuspendTestReceiver.PACKAGE_NAME;
private static final String[] PACKAGES_TO_SUSPEND = new String[]{TEST_APP_PACKAGE_NAME};
+ public static final String INSTRUMENTATION_PACKAGE = "com.android.frameworks.servicestests";
+ public static final String ACTION_REPORT_MY_PACKAGE_SUSPENDED =
+ INSTRUMENTATION_PACKAGE + ".action.REPORT_MY_PACKAGE_SUSPENDED";
+ public static final String ACTION_REPORT_MY_PACKAGE_UNSUSPENDED =
+ INSTRUMENTATION_PACKAGE + ".action.REPORT_MY_PACKAGE_UNSUSPENDED";
+
private Context mContext;
private PackageManager mPackageManager;
private Handler mReceiverHandler;
private ComponentName mTestReceiverComponent;
+ private AppCommunicationReceiver mAppCommsReceiver;
+
+ private static final class AppCommunicationReceiver extends BroadcastReceiver {
+ private Context context;
+ private boolean registered;
+ private SynchronousQueue<Intent> intentQueue = new SynchronousQueue<>();
+
+ AppCommunicationReceiver(Context context) {
+ this.context = context;
+ }
+
+ void register(Handler handler) {
+ registered = true;
+ final IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_REPORT_MY_PACKAGE_SUSPENDED);
+ intentFilter.addAction(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED);
+ context.registerReceiver(this, intentFilter, null, handler);
+ }
+
+ void unregister() {
+ if (registered) {
+ context.unregisterReceiver(this);
+ }
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ try {
+ intentQueue.offer(intent, 5, TimeUnit.SECONDS);
+ } catch (InterruptedException ie) {
+ throw new RuntimeException("Receiver thread interrupted", ie);
+ }
+ }
+
+ Intent receiveIntentFromApp() {
+ if (!registered) {
+ throw new IllegalStateException("Receiver not registered");
+ }
+ final Intent intent;
+ try {
+ intent = intentQueue.poll(5, TimeUnit.SECONDS);
+ } catch (InterruptedException ie) {
+ throw new RuntimeException("Interrupted while waiting for app broadcast", ie);
+ }
+ assertNotNull("No intent received from app within 5 seconds", intent);
+ return intent;
+ }
+ }
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
mPackageManager = mContext.getPackageManager();
- mPackageManager.setPackagesSuspended(PACKAGES_TO_SUSPEND, false, null, null, null);
mReceiverHandler = new Handler(Looper.getMainLooper());
mTestReceiverComponent = new ComponentName(TEST_APP_PACKAGE_NAME,
SuspendTestReceiver.class.getCanonicalName());
+ IPackageManager ipm = AppGlobals.getPackageManager();
+ try {
+ // Otherwise implicit broadcasts will not be delivered.
+ ipm.setPackageStoppedState(TEST_APP_PACKAGE_NAME, false, mContext.getUserId());
+ } catch (RemoteException e) {
+ e.rethrowAsRuntimeException();
+ }
+ unsuspendTestPackage();
+ mAppCommsReceiver = new AppCommunicationReceiver(mContext);
}
+ /**
+ * Care should be taken when used with {@link #mAppCommsReceiver} in the same test as both use
+ * the same handler.
+ */
private Bundle requestAppAction(String action) throws InterruptedException {
final AtomicReference<Bundle> result = new AtomicReference<>();
final CountDownLatch receiverLatch = new CountDownLatch(1);
@@ -98,6 +172,24 @@
assertTrue("setPackagesSuspended returned non-empty list", unchangedPackages.length == 0);
}
+ private void unsuspendTestPackage() {
+ final String[] unchangedPackages = mPackageManager.setPackagesSuspended(
+ PACKAGES_TO_SUSPEND, false, null, null, null);
+ assertTrue("setPackagesSuspended returned non-empty list", unchangedPackages.length == 0);
+ }
+
+
+ private static void assertSameExtras(String message, BaseBundle expected, BaseBundle received) {
+ if (expected != null) {
+ expected.get(""); // hack to unparcel the bundles.
+ }
+ if (received != null) {
+ received.get("");
+ }
+ assertTrue(message + ": [expected: " + expected + "; received: " + received + "]",
+ BaseBundle.kindofEquals(expected, received));
+ }
+
@Test
public void testIsPackageSuspended() {
suspendTestPackage(null, null);
@@ -109,19 +201,73 @@
public void testSuspendedStateFromApp() throws Exception {
Bundle resultFromApp = requestAppAction(SuspendTestReceiver.ACTION_GET_SUSPENDED_STATE);
assertFalse(resultFromApp.getBoolean(SuspendTestReceiver.EXTRA_SUSPENDED, true));
- assertNull(resultFromApp.getParcelable(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
+ assertNull(resultFromApp.getBundle(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
- final PersistableBundle appExtras = getExtras("appExtras", 20, "20", 0.2);
+ final PersistableBundle appExtras = getExtras("testSuspendedStateFromApp", 20, "20", 0.2);
suspendTestPackage(appExtras, null);
resultFromApp = requestAppAction(SuspendTestReceiver.ACTION_GET_SUSPENDED_STATE);
assertTrue("resultFromApp:suspended is false",
resultFromApp.getBoolean(SuspendTestReceiver.EXTRA_SUSPENDED));
- final PersistableBundle receivedAppExtras =
- resultFromApp.getParcelable(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS);
- receivedAppExtras.get(""); // hack to unparcel the bundles
- appExtras.get("");
- assertTrue("Received app extras " + receivedAppExtras + " different to the ones supplied",
- BaseBundle.kindofEquals(appExtras, receivedAppExtras));
+ final Bundle receivedAppExtras =
+ resultFromApp.getBundle(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS);
+ assertSameExtras("Received app extras different to the ones supplied",
+ appExtras, receivedAppExtras);
+ }
+
+ @Test
+ public void testMyPackageSuspendedUnsuspended() {
+ mAppCommsReceiver.register(mReceiverHandler);
+ final PersistableBundle appExtras = getExtras("testMyPackageSuspendBroadcasts", 1, "1", .1);
+ suspendTestPackage(appExtras, null);
+ Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertTrue("MY_PACKAGE_SUSPENDED delivery not reported",
+ ACTION_REPORT_MY_PACKAGE_SUSPENDED.equals(intentFromApp.getAction()));
+ assertSameExtras("Received app extras different to the ones supplied", appExtras,
+ intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
+ unsuspendTestPackage();
+ intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertTrue("MY_PACKAGE_UNSUSPENDED delivery not reported",
+ ACTION_REPORT_MY_PACKAGE_UNSUSPENDED.equals(intentFromApp.getAction()));
+ }
+
+ @Test
+ public void testUpdatingAppExtras() {
+ mAppCommsReceiver.register(mReceiverHandler);
+ final PersistableBundle extras1 = getExtras("testMyPackageSuspendedOnChangingExtras", 1,
+ "1", 0.1);
+ suspendTestPackage(extras1, null);
+ Intent intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertTrue("MY_PACKAGE_SUSPENDED delivery not reported",
+ ACTION_REPORT_MY_PACKAGE_SUSPENDED.equals(intentFromApp.getAction()));
+ assertSameExtras("Received app extras different to the ones supplied", extras1,
+ intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
+ final PersistableBundle extras2 = getExtras("testMyPackageSuspendedOnChangingExtras", 2,
+ "2", 0.2);
+ mPackageManager.setSuspendedPackageAppExtras(TEST_APP_PACKAGE_NAME, extras2);
+ intentFromApp = mAppCommsReceiver.receiveIntentFromApp();
+ assertTrue("MY_PACKAGE_SUSPENDED delivery not reported",
+ ACTION_REPORT_MY_PACKAGE_SUSPENDED.equals(intentFromApp.getAction()));
+ assertSameExtras("Received app extras different to the updated extras", extras2,
+ intentFromApp.getBundleExtra(SuspendTestReceiver.EXTRA_SUSPENDED_APP_EXTRAS));
+ }
+
+ @Test
+ public void testCannotSuspendSelf() {
+ final String[] unchangedPkgs = mPackageManager.setPackagesSuspended(
+ new String[]{mContext.getOpPackageName()}, true, null, null, null);
+ assertTrue(unchangedPkgs.length == 1);
+ assertEquals(mContext.getOpPackageName(), unchangedPkgs[0]);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mAppCommsReceiver.unregister();
+ Thread.sleep(250); // To prevent any race with the next registerReceiver
+ }
+
+ @FunctionalInterface
+ interface Condition {
+ boolean isTrue();
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
index 57dd808..6769e40 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
@@ -18,8 +18,12 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -99,16 +103,23 @@
private MockSurfaceBuildingContainer mHost;
private Dimmer mDimmer;
private SurfaceControl.Transaction mTransaction;
+ private Dimmer.SurfaceAnimatorStarter mSurfaceAnimatorStarter;
+
+ private static class SurfaceAnimatorStarterImpl implements Dimmer.SurfaceAnimatorStarter {
+ @Override
+ public void startAnimation(SurfaceAnimator surfaceAnimator, SurfaceControl.Transaction t,
+ AnimationAdapter anim, boolean hidden) {
+ surfaceAnimator.mAnimationFinishedCallback.run();
+ }
+ }
@Before
public void setUp() throws Exception {
super.setUp();
mHost = new MockSurfaceBuildingContainer();
-
+ mSurfaceAnimatorStarter = spy(new SurfaceAnimatorStarterImpl());
mTransaction = mock(SurfaceControl.Transaction.class);
- mDimmer = new Dimmer(mHost,
- (surfaceAnimator, t, anim, hidden) -> surfaceAnimator.mAnimationFinishedCallback
- .run());
+ mDimmer = new Dimmer(mHost, mSurfaceAnimatorStarter);
}
@Test
@@ -202,6 +213,8 @@
mDimmer.resetDimStates();
mDimmer.updateDims(mTransaction, new Rect());
+ verify(mSurfaceAnimatorStarter).startAnimation(any(SurfaceAnimator.class), any(
+ SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean());
verify(dimLayer).destroy();
}
@@ -243,6 +256,25 @@
verify(mTransaction).setPosition(dimLayer, 10, 10);
}
+ @Test
+ public void testRemoveDimImmediately() throws Exception {
+ TestWindowContainer child = new TestWindowContainer();
+ mHost.addChild(child, 0);
+
+ mDimmer.dimAbove(mTransaction, child, 1);
+ SurfaceControl dimLayer = getDimLayer();
+ mDimmer.updateDims(mTransaction, new Rect());
+ verify(mTransaction, times(1)).show(dimLayer);
+
+ reset(mSurfaceAnimatorStarter);
+ mDimmer.dontAnimateExit();
+ mDimmer.resetDimStates();
+ mDimmer.updateDims(mTransaction, new Rect());
+ verify(mSurfaceAnimatorStarter, never()).startAnimation(any(SurfaceAnimator.class), any(
+ SurfaceControl.Transaction.class), any(AnimationAdapter.class), anyBoolean());
+ verify(mTransaction).destroy(dimLayer);
+ }
+
private SurfaceControl getDimLayer() {
return mDimmer.mDimState.mDimLayer;
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index b645700..7f1bcac 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -30,8 +30,10 @@
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -436,6 +438,20 @@
}
@Test
+ public void testLayoutSeq_assignedDuringLayout() throws Exception {
+ synchronized (sWm.getWindowManagerLock()) {
+
+ final DisplayContent dc = createNewDisplay();
+ final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
+
+ dc.setLayoutNeeded();
+ dc.performLayout(true /* initial */, false /* updateImeWindows */);
+
+ assertThat(win.mLayoutSeq, is(dc.mLayoutSeq));
+ }
+ }
+
+ @Test
@SuppressLint("InlinedApi")
public void testOrientationDefinedByKeyguard() {
final DisplayContent dc = createNewDisplay();
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 56b7d9f..1248eae 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -40,9 +40,12 @@
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -312,6 +315,17 @@
assertTrue(child2.isSelfOrAncestorWindowAnimatingExit());
}
+ @Test
+ public void testLayoutSeqResetOnReparent() throws Exception {
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+ app.mLayoutSeq = 1;
+ mDisplayContent.mLayoutSeq = 1;
+
+ app.onDisplayChanged(mDisplayContent);
+
+ assertThat(app.mLayoutSeq, not(is(mDisplayContent.mLayoutSeq)));
+ }
+
private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
reset(mPowerManagerWrapper);
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
diff --git a/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk b/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
index 40a34b9..afdde72 100644
--- a/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
+++ b/services/tests/servicestests/test-apps/SuspendTestApp/Android.mk
@@ -17,14 +17,18 @@
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
-LOCAL_SDK_VERSION := current
LOCAL_COMPATIBILITY_SUITE := device-tests
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_SRC_FILES += ../../src/com/android/server/pm/SuspendPackagesTest.java
LOCAL_PACKAGE_NAME := SuspendTestApp
LOCAL_DEX_PREOPT := false
LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/services/tests/servicestests/test-apps/SuspendTestApp/AndroidManifest.xml b/services/tests/servicestests/test-apps/SuspendTestApp/AndroidManifest.xml
index 70a1fd0..ce6a27a 100644
--- a/services/tests/servicestests/test-apps/SuspendTestApp/AndroidManifest.xml
+++ b/services/tests/servicestests/test-apps/SuspendTestApp/AndroidManifest.xml
@@ -21,7 +21,12 @@
<activity android:name=".SuspendTestActivity"
android:exported="true" />
<receiver android:name=".SuspendTestReceiver"
- android:exported="true" />
+ android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MY_PACKAGE_SUSPENDED" />
+ <action android:name="android.intent.action.MY_PACKAGE_UNSUSPENDED" />
+ </intent-filter>
+ </receiver>
</application>
</manifest>
\ No newline at end of file
diff --git a/services/tests/servicestests/test-apps/SuspendTestApp/src/com/android/servicestests/apps/suspendtestapp/SuspendTestReceiver.java b/services/tests/servicestests/test-apps/SuspendTestApp/src/com/android/servicestests/apps/suspendtestapp/SuspendTestReceiver.java
index 6f353a0..90a9f01 100644
--- a/services/tests/servicestests/test-apps/SuspendTestApp/src/com/android/servicestests/apps/suspendtestapp/SuspendTestReceiver.java
+++ b/services/tests/servicestests/test-apps/SuspendTestApp/src/com/android/servicestests/apps/suspendtestapp/SuspendTestReceiver.java
@@ -16,12 +16,15 @@
package com.android.servicestests.apps.suspendtestapp;
+import static com.android.server.pm.SuspendPackagesTest.ACTION_REPORT_MY_PACKAGE_SUSPENDED;
+import static com.android.server.pm.SuspendPackagesTest.ACTION_REPORT_MY_PACKAGE_UNSUSPENDED;
+import static com.android.server.pm.SuspendPackagesTest.INSTRUMENTATION_PACKAGE;
+
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.os.PersistableBundle;
import android.util.Log;
public class SuspendTestReceiver extends BroadcastReceiver {
@@ -34,21 +37,33 @@
public static final String EXTRA_SUSPENDED_APP_EXTRAS =
PACKAGE_NAME + ".extra.SUSPENDED_APP_EXTRAS";
- private PackageManager mPm;
-
@Override
public void onReceive(Context context, Intent intent) {
- mPm = context.getPackageManager();
- Log.d(TAG, "Received request action " + intent.getAction());
+ final PackageManager packageManager = context.getPackageManager();
+ Log.d(TAG, "Received action " + intent.getAction());
+ final Bundle appExtras;
switch (intent.getAction()) {
case ACTION_GET_SUSPENDED_STATE:
final Bundle result = new Bundle();
- final boolean suspended = mPm.isPackageSuspended();
- final PersistableBundle appExtras = mPm.getSuspendedPackageAppExtras();
+ final boolean suspended = packageManager.isPackageSuspended();
+ appExtras = packageManager.getSuspendedPackageAppExtras();
result.putBoolean(EXTRA_SUSPENDED, suspended);
- result.putParcelable(EXTRA_SUSPENDED_APP_EXTRAS, appExtras);
+ result.putBundle(EXTRA_SUSPENDED_APP_EXTRAS, appExtras);
setResult(0, null, result);
break;
+ case Intent.ACTION_MY_PACKAGE_SUSPENDED:
+ appExtras = intent.getBundleExtra(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS);
+ final Intent reportSuspendIntent = new Intent(ACTION_REPORT_MY_PACKAGE_SUSPENDED)
+ .putExtra(EXTRA_SUSPENDED_APP_EXTRAS, appExtras)
+ .setPackage(INSTRUMENTATION_PACKAGE);
+ context.sendBroadcast(reportSuspendIntent);
+ break;
+ case Intent.ACTION_MY_PACKAGE_UNSUSPENDED:
+ final Intent reportUnsuspendIntent =
+ new Intent(ACTION_REPORT_MY_PACKAGE_UNSUSPENDED)
+ .setPackage(INSTRUMENTATION_PACKAGE);
+ context.sendBroadcast(reportUnsuspendIntent);
+ break;
default:
Log.e(TAG, "Unknown action: " + intent.getAction());
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 381e04c..3acc277 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -329,12 +329,12 @@
mZenModeHelperSpy.mConfig.allowEvents = false;
mZenModeHelperSpy.mConfig.allowRepeatCallers= false;
- // 2. apply priority only zen - verify ringer is set to silent
+ // 2. apply priority only zen - verify ringer is unchanged
mZenModeHelperSpy.applyZenToRingerMode();
- verify(mAudioManager, atLeastOnce()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
+ verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_SILENT,
mZenModeHelperSpy.TAG);
- // 3. apply zen off - verify zen is set to prevoius ringer (normal)
+ // 3. apply zen off - verify zen is set to previous ringer (normal)
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT);
mZenModeHelperSpy.mZenMode = Global.ZEN_MODE_OFF;
mZenModeHelperSpy.applyZenToRingerMode();
diff --git a/services/usage/java/com/android/server/usage/IntervalStats.java b/services/usage/java/com/android/server/usage/IntervalStats.java
index 00826e0..b070e03 100644
--- a/services/usage/java/com/android/server/usage/IntervalStats.java
+++ b/services/usage/java/com/android/server/usage/IntervalStats.java
@@ -16,6 +16,7 @@
package com.android.server.usage;
import android.app.usage.ConfigurationStats;
+import android.app.usage.EventStats;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
@@ -23,10 +24,18 @@
import android.util.ArrayMap;
import android.util.ArraySet;
+import java.util.List;
+
class IntervalStats {
public long beginTime;
public long endTime;
public long lastTimeSaved;
+ public long lastInteractiveTime;
+ public long lastNonInteractiveTime;
+ public long interactiveDuration;
+ public int interactiveCount;
+ public long nonInteractiveDuration;
+ public int nonInteractiveCount;
public final ArrayMap<String, UsageStats> packageStats = new ArrayMap<>();
public final ArrayMap<Configuration, ConfigurationStats> configurations = new ArrayMap<>();
public Configuration activeConfiguration;
@@ -171,6 +180,60 @@
usageStats.mAppLaunchCount += 1;
}
+ private void commitInteractiveTime(long timeStamp) {
+ if (lastInteractiveTime != 0) {
+ interactiveDuration += timeStamp - lastInteractiveTime;
+ lastInteractiveTime = 0;
+ }
+ if (lastNonInteractiveTime != 0) {
+ nonInteractiveDuration += timeStamp - lastNonInteractiveTime;
+ lastNonInteractiveTime = 0;
+ }
+ }
+
+ void commitTime(long timeStamp) {
+ commitInteractiveTime(timeStamp);
+ }
+
+ void updateScreenInteractive(long timeStamp) {
+ if (lastInteractiveTime != 0) {
+ // Already interactive, just keep running.
+ return;
+ }
+ commitInteractiveTime(timeStamp);
+ lastInteractiveTime = timeStamp;
+ interactiveCount++;
+ }
+
+ void updateScreenNonInteractive(long timeStamp) {
+ if (lastNonInteractiveTime != 0) {
+ // Already non-interactive, just keep running.
+ return;
+ }
+ commitInteractiveTime(timeStamp);
+ lastNonInteractiveTime = timeStamp;
+ nonInteractiveCount++;
+ }
+
+ private void addOneEventStats(List<EventStats> out, int event, int count, long duration) {
+ if (count != 0 || duration != 0) {
+ EventStats ev = new EventStats();
+ ev.mEventType = event;
+ ev.mCount = count;
+ ev.mTotalTime = duration;
+ ev.mBeginTimeStamp = beginTime;
+ ev.mEndTimeStamp = endTime;
+ out.add(ev);
+ }
+ }
+
+ void addEventStatsTo(List<EventStats> out) {
+ addOneEventStats(out, UsageEvents.Event.SCREEN_INTERACTIVE, interactiveCount,
+ interactiveDuration);
+ addOneEventStats(out, UsageEvents.Event.SCREEN_NON_INTERACTIVE, nonInteractiveCount,
+ nonInteractiveDuration);
+ }
+
private String getCachedStringRef(String str) {
final int index = mStringCache.indexOf(str);
if (index < 0) {
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index b8317b4..2258b24 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -25,6 +25,7 @@
import android.app.admin.DevicePolicyManagerInternal;
import android.app.usage.AppStandbyInfo;
import android.app.usage.ConfigurationStats;
+import android.app.usage.EventStats;
import android.app.usage.IUsageStatsManager;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManager;
@@ -486,6 +487,23 @@
/**
* Called by the Binder stub.
*/
+ List<EventStats> queryEventStats(int userId, int bucketType, long beginTime,
+ long endTime) {
+ synchronized (mLock) {
+ final long timeNow = checkAndGetTimeLocked();
+ if (!validRange(timeNow, beginTime, endTime)) {
+ return null;
+ }
+
+ final UserUsageStatsService service =
+ getUserDataAndInitializeIfNeededLocked(userId, timeNow);
+ return service.queryEventStats(bucketType, beginTime, endTime);
+ }
+ }
+
+ /**
+ * Called by the Binder stub.
+ */
UsageEvents queryEvents(int userId, long beginTime, long endTime,
boolean shouldObfuscateInstantApps) {
synchronized (mLock) {
@@ -713,6 +731,28 @@
}
@Override
+ public ParceledListSlice<EventStats> queryEventStats(int bucketType,
+ long beginTime, long endTime, String callingPackage) throws RemoteException {
+ if (!hasPermission(callingPackage)) {
+ return null;
+ }
+
+ final int userId = UserHandle.getCallingUserId();
+ final long token = Binder.clearCallingIdentity();
+ try {
+ final List<EventStats> results =
+ UsageStatsService.this.queryEventStats(userId, bucketType,
+ beginTime, endTime);
+ if (results != null) {
+ return new ParceledListSlice<>(results);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return null;
+ }
+
+ @Override
public UsageEvents queryEvents(long beginTime, long endTime, String callingPackage) {
if (!hasPermission(callingPackage)) {
return null;
diff --git a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
index bcfc421..2287b27 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsXmlV1.java
@@ -27,6 +27,7 @@
import android.app.usage.UsageStats;
import android.content.res.Configuration;
import android.util.ArrayMap;
+import android.util.Pair;
import java.io.IOException;
import java.net.ProtocolException;
@@ -37,6 +38,9 @@
final class UsageStatsXmlV1 {
private static final String TAG = "UsageStatsXmlV1";
+ private static final String INTERACTIVE_TAG = "interactive";
+ private static final String NON_INTERACTIVE_TAG = "non-interactive";
+
private static final String PACKAGES_TAG = "packages";
private static final String PACKAGE_TAG = "package";
@@ -99,6 +103,14 @@
}
}
+ private static Pair<Integer, Long> loadCountAndTime(XmlPullParser parser)
+ throws IOException, XmlPullParserException {
+ int count = XmlUtils.readIntAttribute(parser, COUNT_ATTR, 0);
+ long time = XmlUtils.readLongAttribute(parser, TIME_ATTR, 0);
+ XmlUtils.skipCurrentTag(parser);
+ return new Pair<>(count, time);
+ }
+
private static void loadChooserCounts(
XmlPullParser parser, UsageStats usageStats, String action)
throws XmlPullParserException, IOException {
@@ -202,6 +214,14 @@
xml.endTag(null, PACKAGE_TAG);
}
+ private static void writeCountAndTime(XmlSerializer xml, String tag, int count, long time)
+ throws IOException {
+ xml.startTag(null, tag);
+ XmlUtils.writeIntAttribute(xml, COUNT_ATTR, count);
+ XmlUtils.writeLongAttribute(xml, TIME_ATTR, time);
+ xml.endTag(null, tag);
+ }
+
private static void writeChooserCounts(XmlSerializer xml, final UsageStats usageStats)
throws IOException {
if (usageStats == null || usageStats.mChooserCounts == null ||
@@ -320,6 +340,18 @@
final String tag = parser.getName();
switch (tag) {
+ case INTERACTIVE_TAG: {
+ Pair<Integer, Long> result = loadCountAndTime(parser);
+ statsOut.interactiveCount = result.first;
+ statsOut.interactiveDuration = result.second;
+ } break;
+
+ case NON_INTERACTIVE_TAG: {
+ Pair<Integer, Long> result = loadCountAndTime(parser);
+ statsOut.nonInteractiveCount = result.first;
+ statsOut.nonInteractiveDuration = result.second;
+ } break;
+
case PACKAGE_TAG:
loadUsageStats(parser, statsOut);
break;
@@ -346,6 +378,11 @@
public static void write(XmlSerializer xml, IntervalStats stats) throws IOException {
XmlUtils.writeLongAttribute(xml, END_TIME_ATTR, stats.endTime - stats.beginTime);
+ writeCountAndTime(xml, INTERACTIVE_TAG, stats.interactiveCount, stats.interactiveDuration);
+
+ writeCountAndTime(xml, NON_INTERACTIVE_TAG, stats.nonInteractiveCount,
+ stats.nonInteractiveDuration);
+
xml.startTag(null, PACKAGES_TAG);
final int statsCount = stats.packageStats.size();
for (int i = 0; i < statsCount; i++) {
diff --git a/services/usage/java/com/android/server/usage/UserUsageStatsService.java b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
index afc3d59..6ad374b 100644
--- a/services/usage/java/com/android/server/usage/UserUsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UserUsageStatsService.java
@@ -17,6 +17,7 @@
package com.android.server.usage;
import android.app.usage.ConfigurationStats;
+import android.app.usage.EventStats;
import android.app.usage.TimeSparseArray;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
@@ -191,21 +192,31 @@
}
for (IntervalStats stats : mCurrentStats) {
- if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE) {
- stats.updateConfigurationStats(newFullConfig, event.mTimeStamp);
- } else if (event.mEventType == UsageEvents.Event.CHOOSER_ACTION) {
- stats.updateChooserCounts(event.mPackage, event.mContentType, event.mAction);
- String[] annotations = event.mContentAnnotations;
- if (annotations != null) {
- for (String annotation : annotations) {
- stats.updateChooserCounts(event.mPackage, annotation, event.mAction);
+ switch (event.mEventType) {
+ case UsageEvents.Event.CONFIGURATION_CHANGE: {
+ stats.updateConfigurationStats(newFullConfig, event.mTimeStamp);
+ } break;
+ case UsageEvents.Event.CHOOSER_ACTION: {
+ stats.updateChooserCounts(event.mPackage, event.mContentType, event.mAction);
+ String[] annotations = event.mContentAnnotations;
+ if (annotations != null) {
+ for (String annotation : annotations) {
+ stats.updateChooserCounts(event.mPackage, annotation, event.mAction);
+ }
}
- }
- } else {
- stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
- if (incrementAppLaunch) {
- stats.incrementAppLaunchCount(event.mPackage);
- }
+ } break;
+ case UsageEvents.Event.SCREEN_INTERACTIVE: {
+ stats.updateScreenInteractive(event.mTimeStamp);
+ } break;
+ case UsageEvents.Event.SCREEN_NON_INTERACTIVE: {
+ stats.updateScreenNonInteractive(event.mTimeStamp);
+ } break;
+ default: {
+ stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
+ if (incrementAppLaunch) {
+ stats.incrementAppLaunchCount(event.mPackage);
+ }
+ } break;
}
}
@@ -246,6 +257,15 @@
}
};
+ private static final StatCombiner<EventStats> sEventStatsCombiner =
+ new StatCombiner<EventStats>() {
+ @Override
+ public void combine(IntervalStats stats, boolean mutable,
+ List<EventStats> accResult) {
+ stats.addEventStatsTo(accResult);
+ }
+ };
+
/**
* Generic query method that selects the appropriate IntervalStats for the specified time range
* and bucket, then calls the {@link com.android.server.usage.UsageStatsDatabase.StatCombiner}
@@ -325,6 +345,10 @@
return queryStats(bucketType, beginTime, endTime, sConfigStatsCombiner);
}
+ List<EventStats> queryEventStats(int bucketType, long beginTime, long endTime) {
+ return queryStats(bucketType, beginTime, endTime, sEventStatsCombiner);
+ }
+
UsageEvents queryEvents(final long beginTime, final long endTime,
boolean obfuscateInstantApps) {
final ArraySet<String> names = new ArraySet<>();
@@ -448,6 +472,7 @@
}
stat.updateConfigurationStats(null, mDailyExpiryDate.getTimeInMillis() - 1);
+ stat.commitTime(mDailyExpiryDate.getTimeInMillis() - 1);
}
persistActiveStats();
@@ -640,6 +665,18 @@
}
}
+ void printEventAggregation(IndentingPrintWriter pw, String label, int count, long duration,
+ boolean prettyDates) {
+ if (count != 0 || duration != 0) {
+ pw.print(label);
+ pw.print(": ");
+ pw.print(count);
+ pw.print("x for ");
+ pw.print(formatElapsedTime(duration, prettyDates));
+ pw.println();
+ }
+ }
+
void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats,
boolean prettyDates, boolean skipEvents, String pkg) {
if (prettyDates) {
@@ -713,6 +750,13 @@
pw.println();
}
pw.decreaseIndent();
+ pw.println("event aggregations");
+ pw.increaseIndent();
+ printEventAggregation(pw, "screen-interactive", stats.interactiveCount,
+ stats.interactiveDuration, prettyDates);
+ printEventAggregation(pw, "screen-non-interactive", stats.nonInteractiveCount,
+ stats.nonInteractiveDuration, prettyDates);
+ pw.decreaseIndent();
}
// The last 24 hours of events is already printed in the non checkin dump
@@ -781,6 +825,10 @@
return "SLICE_PINNED";
case UsageEvents.Event.SLICE_PINNED_PRIV:
return "SLICE_PINNED_PRIV";
+ case UsageEvents.Event.SCREEN_INTERACTIVE:
+ return "SCREEN_INTERACTIVE";
+ case UsageEvents.Event.SCREEN_NON_INTERACTIVE:
+ return "SCREEN_NON_INTERACTIVE";
default:
return "UNKNOWN";
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index c79eec0..4683161 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -397,6 +397,15 @@
public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
/**
+ * Where there is no preloaded voicemail number on a SIM card, specifies the carrier's default
+ * voicemail number for roaming network.
+ * When empty string, no default voicemail number is specified for roaming network.
+ * @hide
+ */
+ public static final String KEY_DEFAULT_VM_NUMBER_ROAMING_STRING =
+ "default_vm_number_roaming_string";
+
+ /**
* Flag that specifies to use the user's own phone number as the voicemail number when there is
* no pre-loaded voicemail number on the SIM card.
* <p>
@@ -951,6 +960,8 @@
* If user has explicitly disabled some packages in the list, won't re-enable.
* Other carrier specific apps which are not in this list may be disabled for current carrier,
* and only be re-enabled when this config for another carrier includes it.
+ *
+ * @hide
*/
public static final String KEY_ENABLE_APPS_STRING_ARRAY = "enable_apps_string_array";
@@ -1929,6 +1940,7 @@
sDefaults.putBoolean(KEY_NOTIFY_HANDOVER_VIDEO_FROM_LTE_TO_WIFI_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL, true);
sDefaults.putString(KEY_DEFAULT_VM_NUMBER_STRING, "");
+ sDefaults.putString(KEY_DEFAULT_VM_NUMBER_ROAMING_STRING, "");
sDefaults.putBoolean(KEY_CONFIG_TELEPHONY_USE_OWN_NUMBER_FOR_VOICEMAIL_BOOL, false);
sDefaults.putBoolean(KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, true);
sDefaults.putBoolean(KEY_VILTE_DATA_IS_METERED_BOOL, true);
diff --git a/telephony/java/android/telephony/LocationAccessPolicy.java b/telephony/java/android/telephony/LocationAccessPolicy.java
index 6480aab..6db8e82 100644
--- a/telephony/java/android/telephony/LocationAccessPolicy.java
+++ b/telephony/java/android/telephony/LocationAccessPolicy.java
@@ -40,17 +40,19 @@
*/
public final class LocationAccessPolicy {
private static final String LOG_TAG = LocationAccessPolicy.class.getSimpleName();
+
/**
* API to determine if the caller has permissions to get cell location.
*
* @param pkgName Package name of the application requesting access
* @param uid The uid of the package
* @param pid The pid of the package
+ * @param throwOnDeniedPermission Whether to throw if the location permission is denied.
* @return boolean true or false if permissions is granted
*/
public static boolean canAccessCellLocation(@NonNull Context context, @NonNull String pkgName,
- int uid, int pid) throws SecurityException {
- Trace.beginSection("TelephonyLocationCheck");
+ int uid, int pid, boolean throwOnDeniedPermission) throws SecurityException {
+ Trace.beginSection("TelephonyLohcationCheck");
try {
// Always allow the phone process to access location. This avoid breaking legacy code
// that rely on public-facing APIs to access cell location, and it doesn't create a
@@ -65,9 +67,11 @@
// where a legacy app the user is not using tracks their location.
// Granting ACCESS_FINE_LOCATION to an app automatically grants it
// ACCESS_COARSE_LOCATION.
-
- if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, pid, uid) ==
- PackageManager.PERMISSION_DENIED) {
+ if (throwOnDeniedPermission) {
+ context.enforcePermission(Manifest.permission.ACCESS_COARSE_LOCATION,
+ pid, uid, "canAccessCellLocation");
+ } else if (context.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION,
+ pid, uid) == PackageManager.PERMISSION_DENIED) {
return false;
}
final int opCode = AppOpsManager.permissionToOpCode(
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index 77413d9c..936505c 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -335,7 +335,7 @@
return this.mCountryIso;
}
- /** @return whether the subscription is an embedded one. */
+ /** @return whether the subscription is an eUICC one. */
public boolean isEmbedded() {
return this.mIsEmbedded;
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 472a6fb..7664b94 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -1925,26 +1925,28 @@
*
* @param info The subscription to check.
* @return whether the app is authorized to manage this subscription per its metadata.
- * @throws UnsupportedOperationException if this subscription is not embedded.
+ * @throws IllegalArgumentException if this subscription is not embedded.
*/
public boolean canManageSubscription(SubscriptionInfo info) {
return canManageSubscription(info, mContext.getPackageName());
}
/**
- * Checks whether the given app is authorized to manage the given subscription according to its
- * metadata. Only supported for embedded subscriptions (if {@code SubscriptionInfo#isEmbedded}
+ * Checks whether the given app is authorized to manage the given subscription. An app can only
+ * be authorized if it is included in the {@link android.telephony.UiccAccessRule} of the
+ * {@link android.telephony.SubscriptionInfo} with the access status.
+ * Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded}
* returns true).
*
* @param info The subscription to check.
* @param packageName Package name of the app to check.
- * @return whether the app is authorized to manage this subscription per its metadata.
- * @throws UnsupportedOperationException if this subscription is not embedded.
+ * @return whether the app is authorized to manage this subscription per its access rules.
+ * @throws IllegalArgumentException if this subscription is not embedded.
* @hide
*/
public boolean canManageSubscription(SubscriptionInfo info, String packageName) {
if (!info.isEmbedded()) {
- throw new UnsupportedOperationException("Not an embedded subscription");
+ throw new IllegalArgumentException("Not an embedded subscription");
}
if (info.getAccessRules() == null) {
return false;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a12a7a0..da5bd84 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -6349,34 +6349,39 @@
*
* @param enable Whether to enable mobile data.
*
- * @deprecated use {@link #setUserMobileDataEnabled(boolean)} instead.
*/
- @Deprecated
@SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setDataEnabled(boolean enable) {
- setUserMobileDataEnabled(enable);
+ setDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enable);
}
/**
* @hide
- * @deprecated use {@link #setUserMobileDataEnabled(boolean)} instead.
+ * @deprecated use {@link #setDataEnabled(boolean)} instead.
*/
@SystemApi
@Deprecated
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setDataEnabled(int subId, boolean enable) {
- setUserMobileDataEnabled(subId, enable);
+ try {
+ Log.d(TAG, "setDataEnabled: enabled=" + enable);
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ telephony.setUserDataEnabled(subId, enable);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#setUserDataEnabled", e);
+ }
}
/**
- * @deprecated use {@link #isUserMobileDataEnabled()} instead.
+ * @deprecated use {@link #isDataEnabled()} instead.
* @hide
*/
@SystemApi
@Deprecated
public boolean getDataEnabled() {
- return isUserMobileDataEnabled();
+ return isDataEnabled();
}
/**
@@ -6396,22 +6401,28 @@
* {@link ConnectivityManager#getRestrictBackgroundStatus}.
*
* @return true if mobile data is enabled.
- *
- * @deprecated use {@link #isUserMobileDataEnabled()} instead.
*/
- @Deprecated
public boolean isDataEnabled() {
- return isUserMobileDataEnabled();
+ return getDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
}
/**
- * @deprecated use {@link #isUserMobileDataEnabled()} instead.
+ * @deprecated use {@link #isDataEnabled()} instead.
* @hide
*/
@Deprecated
@SystemApi
public boolean getDataEnabled(int subId) {
- return isUserMobileDataEnabled(subId);
+ boolean retVal = false;
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null)
+ retVal = telephony.isUserDataEnabled(subId);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#isUserDataEnabled", e);
+ } catch (NullPointerException e) {
+ }
+ return retVal;
}
/** @hide */
@@ -7684,56 +7695,12 @@
}
/**
- * Turns mobile data on or off.
- * If the {@link TelephonyManager} object has been created with
- * {@link #createForSubscriptionId}, this API applies to the given subId.
- * Otherwise, it applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the calling
- * app has carrier privileges (see {@link #hasCarrierPrivileges}.
- *
- * @param enable Whether to enable mobile data.
- */
- @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public void setUserMobileDataEnabled(boolean enable) {
- setUserMobileDataEnabled(
- getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enable);
- }
-
- /**
- * Returns whether mobile data is enabled or not per user setting. There are other factors
- * that could disable mobile data, but they are not considered here.
- *
- * If this object has been created with {@link #createForSubscriptionId}, applies to the given
- * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
- *
- * <p>Requires one of the following permissions:
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE ACCESS_NETWORK_STATE},
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}, or that the
- * calling app has carrier privileges (see {@link #hasCarrierPrivileges}.
- *
- * <p>Note that this does not take into account any data restrictions that may be present on the
- * calling app. Such restrictions may be inspected with
- * {@link ConnectivityManager#getRestrictBackgroundStatus}.
- *
- * @return true if mobile data is enabled.
- */
- @RequiresPermission(anyOf = {
- android.Manifest.permission.ACCESS_NETWORK_STATE,
- android.Manifest.permission.MODIFY_PHONE_STATE
- })
- public boolean isUserMobileDataEnabled() {
- return isUserMobileDataEnabled(
- getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
- }
-
- /**
* @hide
- * Unlike isUserMobileDataEnabled, this API also evaluates carrierDataEnabled,
- * policyDataEnabled etc to give a final decision.
+ * It's similar to isDataEnabled, but unlike isDataEnabled, this API also evaluates
+ * carrierDataEnabled, policyDataEnabled etc to give a final decision of whether mobile data is
+ * capable of using.
*/
- public boolean isMobileDataEnabled() {
+ public boolean isDataCapable() {
boolean retVal = false;
try {
int subId = getSubId(SubscriptionManager.getDefaultDataSubscriptionId());
@@ -7748,35 +7715,6 @@
}
/**
- * Utility class of {@link #isUserMobileDataEnabled()};
- */
- private boolean isUserMobileDataEnabled(int subId) {
- boolean retVal = false;
- try {
- ITelephony telephony = getITelephony();
- if (telephony != null)
- retVal = telephony.isUserDataEnabled(subId);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#isUserDataEnabled", e);
- } catch (NullPointerException e) {
- }
- return retVal;
- }
-
- /** Utility method of {@link #setUserMobileDataEnabled(boolean)} */
- @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- private void setUserMobileDataEnabled(int subId, boolean enable) {
- try {
- Log.d(TAG, "setUserMobileDataEnabled: enabled=" + enable);
- ITelephony telephony = getITelephony();
- if (telephony != null)
- telephony.setUserDataEnabled(subId, enable);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#setUserDataEnabled", e);
- }
- }
-
- /**
* In this mode, modem will not send specified indications when screen is off.
* @hide
*/
diff --git a/telephony/java/android/telephony/euicc/DownloadableSubscription.java b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
index 88db22b..edf3b08 100644
--- a/telephony/java/android/telephony/euicc/DownloadableSubscription.java
+++ b/telephony/java/android/telephony/euicc/DownloadableSubscription.java
@@ -17,6 +17,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.app.PendingIntent;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.UiccAccessRule;
@@ -26,7 +27,14 @@
import com.android.internal.util.Preconditions;
-/** Information about a subscription which is available for download. */
+/**
+ * Information about a subscription which is downloadable to an eUICC using
+ * {@link EuiccManager#downloadSubscription(DownloadableSubscription, boolean, PendingIntent).
+ *
+ * <p>For example, a DownloadableSubscription can be created through an activation code parsed from
+ * a QR code. A server address can be parsed from the activation code to download more information
+ * about the profile, such as carrier name, access rules, etc.
+ */
public final class DownloadableSubscription implements Parcelable {
public static final Creator<DownloadableSubscription> CREATOR =
@@ -136,7 +144,15 @@
/**
* Create a DownloadableSubscription for the given activation code.
*
- * @param encodedActivationCode the activation code to use. Must not be null.
+ * <p>This fills the encodedActivationCode field. Other fields like confirmationCode,
+ * carrierName and accessRules may be filled in the implementation of
+ * {@code android.service.euicc.EuiccService} if exists.
+ *
+ * @param encodedActivationCode the activation code to use. An activation code can be parsed
+ * from a user scanned QR code. The format of activation code is defined in SGP.22. For
+ * example, "1$SMDP.GSMA.COM$04386-AGYFT-A74Y8-3F815$1.3.6.1.4.1.31746". For detail, see
+ * {@code com.android.euicc.data.ActivationCode}. Must not be null.
+ *
* @return the {@link DownloadableSubscription} which may be passed to
* {@link EuiccManager#downloadSubscription}.
*/
@@ -157,6 +173,9 @@
/**
* Returns the confirmation code.
+ *
+ * <p>As an example, the confirmation code can be input by the user through a carrier app or the
+ * UI component of the eUICC local profile assistant (LPA) application.
*/
@Nullable
public String getConfirmationCode() {
diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java
index dff1c6f..b732d4d 100644
--- a/telephony/java/android/telephony/euicc/EuiccManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccManager.java
@@ -142,11 +142,9 @@
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DETAILED_CODE";
/**
- * Key for an extra set on {@link #getDownloadableSubscriptionMetadata} PendingIntent result
+ * Key for an extra set on {@code #getDownloadableSubscriptionMetadata} PendingIntent result
* callbacks providing the downloadable subscription metadata.
- * @hide
*/
- @SystemApi
public static final String EXTRA_EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION =
"android.telephony.euicc.extra.EMBEDDED_SUBSCRIPTION_DOWNLOADABLE_SUBSCRIPTION";
diff --git a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
index 8b81b0d..bcad554 100644
--- a/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
+++ b/telephony/java/com/android/internal/telephony/CarrierAppUtils.java
@@ -26,6 +26,7 @@
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -49,10 +50,11 @@
/**
* Handle preinstalled carrier apps which should be disabled until a matching SIM is inserted.
*
- * Evaluates the list of applications in config_disabledUntilUsedPreinstalledCarrierApps. We
- * want to disable each such application which is present on the system image until the user
- * inserts a SIM which causes that application to gain carrier privilege (indicating a "match"),
- * without interfering with the user if they opt to enable/disable the app explicitly.
+ * Evaluates the list of applications in
+ * {@link SystemConfig#getDisabledUntilUsedPreinstalledCarrierApps()}. We want to disable each
+ * such application which is present on the system image until the user inserts a SIM which
+ * causes that application to gain carrier privilege (indicating a "match"), without interfering
+ * with the user if they opt to enable/disable the app explicitly.
*
* So, for each such app, we either disable until used IFF the app is not carrier privileged AND
* in the default state (e.g. not explicitly DISABLED/DISABLED_BY_USER/ENABLED), or we enable if
@@ -76,8 +78,8 @@
Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
}
SystemConfig config = SystemConfig.getInstance();
- String[] systemCarrierAppsDisabledUntilUsed = Resources.getSystem().getStringArray(
- com.android.internal.R.array.config_disabledUntilUsedPreinstalledCarrierApps);
+ ArraySet<String> systemCarrierAppsDisabledUntilUsed =
+ config.getDisabledUntilUsedPreinstalledCarrierApps();
ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
disableCarrierAppsUntilPrivileged(callingPackage, packageManager, telephonyManager,
@@ -102,8 +104,10 @@
Slog.d(TAG, "disableCarrierAppsUntilPrivileged");
}
SystemConfig config = SystemConfig.getInstance();
- String[] systemCarrierAppsDisabledUntilUsed = Resources.getSystem().getStringArray(
- com.android.internal.R.array.config_disabledUntilUsedPreinstalledCarrierApps);
+ ArraySet<String> systemCarrierAppsDisabledUntilUsed =
+ config.getDisabledUntilUsedPreinstalledCarrierApps();
+
+
ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed =
config.getDisabledUntilUsedPreinstalledCarrierAssociatedApps();
disableCarrierAppsUntilPrivileged(callingPackage, packageManager,
@@ -116,7 +120,7 @@
public static void disableCarrierAppsUntilPrivileged(String callingPackage,
IPackageManager packageManager, @Nullable TelephonyManager telephonyManager,
ContentResolver contentResolver, int userId,
- String[] systemCarrierAppsDisabledUntilUsed,
+ ArraySet<String> systemCarrierAppsDisabledUntilUsed,
ArrayMap<String, List<String>> systemCarrierAssociatedAppsDisabledUntilUsed) {
List<ApplicationInfo> candidates = getDefaultCarrierAppCandidatesHelper(packageManager,
userId, systemCarrierAppsDisabledUntilUsed);
@@ -286,8 +290,8 @@
*/
public static List<ApplicationInfo> getDefaultCarrierAppCandidates(
IPackageManager packageManager, int userId) {
- String[] systemCarrierAppsDisabledUntilUsed = Resources.getSystem().getStringArray(
- com.android.internal.R.array.config_disabledUntilUsedPreinstalledCarrierApps);
+ ArraySet<String> systemCarrierAppsDisabledUntilUsed =
+ SystemConfig.getInstance().getDisabledUntilUsedPreinstalledCarrierApps();
return getDefaultCarrierAppCandidatesHelper(packageManager, userId,
systemCarrierAppsDisabledUntilUsed);
}
@@ -295,14 +299,19 @@
private static List<ApplicationInfo> getDefaultCarrierAppCandidatesHelper(
IPackageManager packageManager,
int userId,
- String[] systemCarrierAppsDisabledUntilUsed) {
- if (systemCarrierAppsDisabledUntilUsed == null
- || systemCarrierAppsDisabledUntilUsed.length == 0) {
+ ArraySet<String> systemCarrierAppsDisabledUntilUsed) {
+ if (systemCarrierAppsDisabledUntilUsed == null) {
return null;
}
- List<ApplicationInfo> apps = new ArrayList<>(systemCarrierAppsDisabledUntilUsed.length);
- for (int i = 0; i < systemCarrierAppsDisabledUntilUsed.length; i++) {
- String packageName = systemCarrierAppsDisabledUntilUsed[i];
+
+ int size = systemCarrierAppsDisabledUntilUsed.size();
+ if (size == 0) {
+ return null;
+ }
+
+ List<ApplicationInfo> apps = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ String packageName = systemCarrierAppsDisabledUntilUsed.valueAt(i);
ApplicationInfo ai =
getApplicationInfoIfSystemApp(packageManager, userId, packageName);
if (ai != null) {
diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java
index c866371..941c94d 100644
--- a/tests/net/java/android/net/NetworkCapabilitiesTest.java
+++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java
@@ -315,28 +315,26 @@
@Test
public void testEqualsNetCapabilities() {
- int CAPABILITY = NET_CAPABILITY_MMS; // An arbitrary not mutable capability.
-
NetworkCapabilities nc1 = new NetworkCapabilities();
NetworkCapabilities nc2 = new NetworkCapabilities();
assertTrue(nc1.equalsNetCapabilities(nc2));
assertEquals(nc1, nc2);
- nc1.addCapability(CAPABILITY);
+ nc1.addCapability(NET_CAPABILITY_MMS);
assertFalse(nc1.equalsNetCapabilities(nc2));
assertNotEquals(nc1, nc2);
- nc2.addCapability(CAPABILITY);
+ nc2.addCapability(NET_CAPABILITY_MMS);
assertTrue(nc1.equalsNetCapabilities(nc2));
assertEquals(nc1, nc2);
- nc1.addUnwantedCapability(CAPABILITY);
+ nc1.addUnwantedCapability(NET_CAPABILITY_INTERNET);
assertFalse(nc1.equalsNetCapabilities(nc2));
- nc2.addUnwantedCapability(CAPABILITY);
+ nc2.addUnwantedCapability(NET_CAPABILITY_INTERNET);
assertTrue(nc1.equalsNetCapabilities(nc2));
- nc1.removeCapability(CAPABILITY);
+ nc1.removeCapability(NET_CAPABILITY_INTERNET);
assertFalse(nc1.equalsNetCapabilities(nc2));
- nc2.removeCapability(CAPABILITY);
+ nc2.removeCapability(NET_CAPABILITY_INTERNET);
assertTrue(nc1.equalsNetCapabilities(nc2));
}
diff --git a/tools/stringslint/stringslint_sha.sh b/tools/stringslint/stringslint_sha.sh
index c79ba04..bd80bb4 100755
--- a/tools/stringslint/stringslint_sha.sh
+++ b/tools/stringslint/stringslint_sha.sh
@@ -1,4 +1,5 @@
#!/bin/bash
+LOCAL_DIR="$( dirname ${BASH_SOURCE} )"
git show --name-only --pretty=format: $1 | grep values/strings.xml | while read file; do
- python $ANDROID_BUILD_TOP/frameworks/base/tools/stringslint/stringslint.py <(git show $1:$file) <(git show $1^:$file)
+ python $LOCAL_DIR/stringslint.py <(git show $1:$file) <(git show $1^:$file)
done