Merge "GM2 icon updates" into pi-dev
diff --git a/Android.mk b/Android.mk
index ccf3894..66c9529 100644
--- a/Android.mk
+++ b/Android.mk
@@ -945,21 +945,21 @@
$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
$(call assert-has-no-overlap,$@,$(LOCAL_SRC_FORCE_BLACKLIST))
-# Generate dark greylist as remaining members of classes on the light greylist,
-# as well as the members of their inner classes.
+# Generate dark greylist as remaining classes and class members in the same
+# package as classes listed in the light greylist.
# The algorithm is as follows:
# (1) extract the class descriptor from each entry in LOCAL_LIGHT_GREYLIST
-# (2) strip the final semicolon and anything after (and including) a dollar sign,
-# e.g. 'Lpackage/class$inner;' turns into 'Lpackage/class'
-# (3) insert all entries from LOCAL_SRC_PRIVATE_API which begin with the stripped
-# descriptor followed by a semi-colon or a dollar sign, e.g. matching a regex
-# '^Lpackage/class[;$]'
+# (2) strip everything after the last forward-slash,
+# e.g. 'Lpackage/subpackage/class$inner;' turns into 'Lpackage/subpackage/'
+# (3) insert all entries from LOCAL_SRC_PRIVATE_API which begin with the package
+# name but do not contain another forward-slash in the class name, e.g.
+# matching '^Lpackage/subpackage/[^/;]*;'
# (4) subtract entries shared with LOCAL_LIGHT_GREYLIST
$(LOCAL_DARK_GREYLIST): $(LOCAL_SRC_ALL) $(LOCAL_LIGHT_GREYLIST)
comm -13 <(sort $(LOCAL_LIGHT_GREYLIST) $(LOCAL_SRC_FORCE_BLACKLIST)) \
- <(sed 's/;\->.*//' $(LOCAL_LIGHT_GREYLIST) | sed 's/$$.*//' | sort | uniq | \
- while read CLASS_DESC; do \
- grep -E "^$${CLASS_DESC}[;$$]" $(LOCAL_SRC_PRIVATE_API); \
+ <(sed 's/\->.*//' $(LOCAL_LIGHT_GREYLIST) | sed 's/\(.*\/\).*/\1/' | sort | uniq | \
+ while read PKG_NAME; do \
+ grep -E "^$${PKG_NAME}[^/;]*;" $(LOCAL_SRC_PRIVATE_API); \
done | sort | uniq) \
> $@
$(call assert-is-subset,$@,$(LOCAL_SRC_PRIVATE_API))
@@ -988,4 +988,3 @@
endif
endif # ANDROID_BUILD_EMBEDDED
-
diff --git a/config/hiddenapi-force-blacklist.txt b/config/hiddenapi-force-blacklist.txt
index 2a10f77..0c689e8 100644
--- a/config/hiddenapi-force-blacklist.txt
+++ b/config/hiddenapi-force-blacklist.txt
@@ -1 +1,37 @@
Ldalvik/system/VMRuntime;->setHiddenApiExemptions([Ljava/lang/String;)V
+Ljava/lang/invoke/VarHandle;->acquireFence()V
+Ljava/lang/invoke/VarHandle;->compareAndExchange([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndExchangeAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndExchangeRelease([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->compareAndSet([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->fullFence()V
+Ljava/lang/invoke/VarHandle;->get([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAdd([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAddAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndAddRelease([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAnd([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAndAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseAndRelease([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOr([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOrAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseOrRelease([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXor([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXorAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndBitwiseXorRelease([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSet([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSetAcquire([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getAndSetRelease([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getOpaque([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->getVolatile([[Ljava/lang/Object;)Ljava/lang/Object;
+Ljava/lang/invoke/VarHandle;->loadLoadFence()V
+Ljava/lang/invoke/VarHandle;->releaseFence()V
+Ljava/lang/invoke/VarHandle;->set([[Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setOpaque([[Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setRelease([[Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->setVolatile([[Ljava/lang/Object;)V
+Ljava/lang/invoke/VarHandle;->storeStoreFence()V
+Ljava/lang/invoke/VarHandle;->weakCompareAndSet([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetAcquire([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetPlain([[Ljava/lang/Object;)Z
+Ljava/lang/invoke/VarHandle;->weakCompareAndSetRelease([[Ljava/lang/Object;)Z
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index e47a1cf..b9ead8b 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -376,6 +376,7 @@
Landroid/app/AppOpsManager;->OP_AUDIO_RING_VOLUME:I
Landroid/app/AppOpsManager;->OP_AUDIO_VOICE_VOLUME:I
Landroid/app/AppOpsManager;->OP_BIND_ACCESSIBILITY_SERVICE:I
+Landroid/app/AppOpsManager;->OP_BLUETOOTH_SCAN:I
Landroid/app/AppOpsManager;->OP_BODY_SENSORS:I
Landroid/app/AppOpsManager;->OP_CALL_PHONE:I
Landroid/app/AppOpsManager;->OP_CAMERA:I
@@ -634,6 +635,7 @@
Landroid/app/IActivityManager;->unregisterProcessObserver(Landroid/app/IProcessObserver;)V
Landroid/app/IActivityManager;->unregisterReceiver(Landroid/content/IIntentReceiver;)V
Landroid/app/IActivityManager;->unstableProviderDied(Landroid/os/IBinder;)V
+Landroid/app/IActivityManager;->updateConfiguration(Landroid/content/res/Configuration;)Z
Landroid/app/IActivityManager;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IAlarmManager$Stub;-><init>()V
@@ -654,6 +656,7 @@
Landroid/app/IApplicationThread;->updateTimeZone()V
Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
Landroid/app/IBackupAgent$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IBackupAgent;
+Landroid/app/IInputForwarder;->forwardEvent(Landroid/view/InputEvent;)Z
Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
Landroid/app/IInstrumentationWatcher$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IInstrumentationWatcher;
Landroid/app/IInstrumentationWatcher;->instrumentationFinished(Landroid/content/ComponentName;ILandroid/os/Bundle;)V
@@ -2376,6 +2379,7 @@
Landroid/hardware/input/IInputManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/input/IInputManager;
Landroid/hardware/input/IInputManager$Stub;->TRANSACTION_injectInputEvent:I
Landroid/hardware/input/IInputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
+Landroid/hardware/input/InputManager;->createInputForwarder(I)Landroid/app/IInputForwarder;
Landroid/hardware/input/InputManager;->getInstance()Landroid/hardware/input/InputManager;
Landroid/hardware/input/InputManager;->injectInputEvent(Landroid/view/InputEvent;I)Z
Landroid/hardware/input/InputManager;->INJECT_INPUT_EVENT_MODE_WAIT_FOR_FINISH:I
@@ -3958,6 +3962,7 @@
Landroid/os/storage/StorageVolume;->allowMassStorage()Z
Landroid/os/storage/StorageVolume;->getFatVolumeId()I
Landroid/os/storage/StorageVolume;->getMaxFileSize()J
+Landroid/os/storage/StorageVolume;->getOwner()Landroid/os/UserHandle;
Landroid/os/storage/StorageVolume;->getPath()Ljava/lang/String;
Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;
Landroid/os/storage/StorageVolume;->getUserLabel()Ljava/lang/String;
@@ -4916,6 +4921,7 @@
Landroid/telecom/TelecomManager;->TTY_MODE_OFF:I
Landroid/telecom/VideoCallImpl;->destroy()V
Landroid/telephony/CarrierConfigManager;->KEY_CARRIER_DEFAULT_ACTIONS_ON_REDIRECTION_STRING_ARRAY:Ljava/lang/String;
+Landroid/telephony/CarrierConfigManager;->KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL:Ljava/lang/String;
Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
Landroid/telephony/CellBroadcastMessage;-><init>(Landroid/telephony/SmsCbMessage;)V
Landroid/telephony/CellBroadcastMessage;->createFromCursor(Landroid/database/Cursor;)Landroid/telephony/CellBroadcastMessage;
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index 22df6c0..f682ec1 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -23,6 +23,7 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemService;
+import android.annotation.WorkerThread;
import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.Context;
@@ -217,6 +218,7 @@
* @return All slices within the space.
* @see SliceProvider#onGetSliceDescendants(Uri)
*/
+ @WorkerThread
public @NonNull Collection<Uri> getSliceDescendants(@NonNull Uri uri) {
ContentResolver resolver = mContext.getContentResolver();
try (ContentProviderClient provider = resolver.acquireContentProviderClient(uri)) {
diff --git a/core/java/android/app/slice/SliceProvider.java b/core/java/android/app/slice/SliceProvider.java
index 9e4e97a..6c57d81 100644
--- a/core/java/android/app/slice/SliceProvider.java
+++ b/core/java/android/app/slice/SliceProvider.java
@@ -398,12 +398,7 @@
private Collection<Uri> handleGetDescendants(Uri uri) {
mCallback = "onGetSliceDescendants";
- Handler.getMain().postDelayed(mAnr, SLICE_BIND_ANR);
- try {
- return onGetSliceDescendants(uri);
- } finally {
- Handler.getMain().removeCallbacks(mAnr);
- }
+ return onGetSliceDescendants(uri);
}
private void handlePinSlice(Uri sliceUri) {
diff --git a/core/java/android/app/usage/UsageStatsManager.java b/core/java/android/app/usage/UsageStatsManager.java
index 7fb97d3..1b05402 100644
--- a/core/java/android/app/usage/UsageStatsManager.java
+++ b/core/java/android/app/usage/UsageStatsManager.java
@@ -572,13 +572,14 @@
* the sum of usages of apps in the packages array exceeds the {@code timeLimit} specified. The
* observer will automatically be unregistered when the time limit is reached and the intent
* is delivered. Registering an {@code observerId} that was already registered will override
- * the previous one.
+ * the previous one. No more than 1000 unique {@code observerId} may be registered by a single
+ * uid at any one time.
* @param observerId A unique id associated with the group of apps to be monitored. There can
* be multiple groups with common packages and different time limits.
* @param packages The list of packages to observe for foreground activity time. Cannot be null
* and must include at least one package.
* @param timeLimit The total time the set of apps can be in the foreground before the
- * callbackIntent is delivered. Must be greater than 0.
+ * callbackIntent is delivered. Must be at least one minute.
* @param timeUnit The unit for time specified in {@code timeLimit}. Cannot be null.
* @param callbackIntent The PendingIntent that will be dispatched when the time limit is
* exceeded by the group of apps. The delivered Intent will also contain
diff --git a/core/java/android/content/om/OverlayInfo.java b/core/java/android/content/om/OverlayInfo.java
index a10cc12..edacbb0 100644
--- a/core/java/android/content/om/OverlayInfo.java
+++ b/core/java/android/content/om/OverlayInfo.java
@@ -18,7 +18,6 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -39,6 +38,7 @@
STATE_NO_IDMAP,
STATE_DISABLED,
STATE_ENABLED,
+ STATE_ENABLED_STATIC,
STATE_TARGET_UPGRADING,
STATE_OVERLAY_UPGRADING,
})
@@ -91,7 +91,16 @@
public static final int STATE_OVERLAY_UPGRADING = 5;
/**
- * Category for theme overlays.
+ * The overlay package is currently enabled because it is marked as
+ * 'static'. It cannot be disabled but will change state if for instance
+ * its target is uninstalled.
+ */
+ public static final int STATE_ENABLED_STATIC = 6;
+
+ /**
+ * Overlay category: theme.
+ * <p>
+ * Change how Android (including the status bar, dialogs, ...) looks.
*/
public static final String CATEGORY_THEME = "android.theme";
@@ -126,6 +135,23 @@
public final int userId;
/**
+ * Priority as read from the manifest. Used if isStatic is true. Not
+ * intended to be exposed to 3rd party.
+ *
+ * @hide
+ */
+ public final int priority;
+
+ /**
+ * isStatic as read from the manifest. If true, the overlay is
+ * unconditionally loaded and cannot be unloaded. Not intended to be
+ * exposed to 3rd party.
+ *
+ * @hide
+ */
+ public final boolean isStatic;
+
+ /**
* Create a new OverlayInfo based on source with an updated state.
*
* @param source the source OverlayInfo to base the new instance on
@@ -133,17 +159,20 @@
*/
public OverlayInfo(@NonNull OverlayInfo source, @State int state) {
this(source.packageName, source.targetPackageName, source.category, source.baseCodePath,
- state, source.userId);
+ state, source.userId, source.priority, source.isStatic);
}
public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName,
- @Nullable String category, @NonNull String baseCodePath, int state, int userId) {
+ @NonNull String category, @NonNull String baseCodePath, int state, int userId,
+ int priority, boolean isStatic) {
this.packageName = packageName;
this.targetPackageName = targetPackageName;
this.category = category;
this.baseCodePath = baseCodePath;
this.state = state;
this.userId = userId;
+ this.priority = priority;
+ this.isStatic = isStatic;
ensureValidState();
}
@@ -154,6 +183,8 @@
baseCodePath = source.readString();
state = source.readInt();
userId = source.readInt();
+ priority = source.readInt();
+ isStatic = source.readBoolean();
ensureValidState();
}
@@ -173,6 +204,7 @@
case STATE_NO_IDMAP:
case STATE_DISABLED:
case STATE_ENABLED:
+ case STATE_ENABLED_STATIC:
case STATE_TARGET_UPGRADING:
case STATE_OVERLAY_UPGRADING:
break;
@@ -194,6 +226,8 @@
dest.writeString(baseCodePath);
dest.writeInt(state);
dest.writeInt(userId);
+ dest.writeInt(priority);
+ dest.writeBoolean(isStatic);
}
public static final Parcelable.Creator<OverlayInfo> CREATOR =
@@ -220,6 +254,7 @@
public boolean isEnabled() {
switch (state) {
case STATE_ENABLED:
+ case STATE_ENABLED_STATIC:
return true;
default:
return false;
@@ -244,6 +279,8 @@
return "STATE_DISABLED";
case STATE_ENABLED:
return "STATE_ENABLED";
+ case STATE_ENABLED_STATIC:
+ return "STATE_ENABLED_STATIC";
case STATE_TARGET_UPGRADING:
return "STATE_TARGET_UPGRADING";
case STATE_OVERLAY_UPGRADING:
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 10ee728..29bbddc 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -12740,6 +12740,25 @@
public static final String SHOW_ZEN_UPGRADE_NOTIFICATION = "show_zen_upgrade_notification";
/**
+ * If nonzero, will show the zen update settings suggestion.
+ * @hide
+ */
+ public static final String SHOW_ZEN_SETTINGS_SUGGESTION = "show_zen_settings_suggestion";
+
+ /**
+ * If nonzero, zen has not been updated to reflect new changes.
+ * @hide
+ */
+ public static final String ZEN_SETTINGS_UPDATED = "zen_settings_updated";
+
+ /**
+ * If nonzero, zen setting suggestion has beem viewed by user
+ * @hide
+ */
+ public static final String ZEN_SETTINGS_SUGGESTION_VIEWED =
+ "zen_settings_suggestion_viewed";
+
+ /**
* Backup and restore agent timeout parameters.
* These parameters are represented by a comma-delimited key-value list.
*
diff --git a/core/java/android/security/keystore/recovery/TrustedRootCertificates.java b/core/java/android/security/keystore/recovery/TrustedRootCertificates.java
index a96dab6..c5f82c1 100644
--- a/core/java/android/security/keystore/recovery/TrustedRootCertificates.java
+++ b/core/java/android/security/keystore/recovery/TrustedRootCertificates.java
@@ -73,34 +73,34 @@
"INSECURE_PSWD_";
private static final String GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_BASE64 = ""
- + "MIIFJjCCAw6gAwIBAgIJAIobXsJlzhNdMA0GCSqGSIb3DQEBDQUAMCAxHjAcBgNV"
- + "BAMMFUdvb2dsZSBDcnlwdEF1dGhWYXVsdDAeFw0xODAyMDIxOTM5MTRaFw0zODAx"
- + "MjgxOTM5MTRaMCAxHjAcBgNVBAMMFUdvb2dsZSBDcnlwdEF1dGhWYXVsdDCCAiIw"
- + "DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2OT5i40/H7LINg/lq/0G0hR65P"
- + "Q4Mud3OnuVt6UIYV2T18+v6qW1yJd5FcnND/ZKPau4aUAYklqJuSVjOXQD0BjgS2"
- + "98Xa4dSn8Ci1rUR+5tdmrxqbYUdT2ZvJIUMMR6fRoqi+LlAbKECrV+zYQTyLU68w"
- + "V66hQpAButjJKiZzkXjmKLfJ5IWrNEn17XM988rk6qAQn/BYCCQGf3rQuJeksGmA"
- + "N1lJOwNYxmWUyouVwqwZthNEWqTuEyBFMkAT+99PXW7oVDc7oU5cevuihxQWNTYq"
- + "viGB8cck6RW3cmqrDSaJF/E+N0cXFKyYC7FDcggt6k3UrxNKTuySdDEa8+2RTQqU"
- + "Y9npxBlQE+x9Ig56OI1BG3bSBsGdPgjpyHadZeh2tgk+oqlGsSsum24YxaxuSysT"
- + "Qfcu/XhyfUXavfmGrBOXerTzIl5oBh/F5aHTV85M2tYEG0qsPPvSpZAWtdJ/2rca"
- + "OxvhwOL+leZKr8McjXVR00lBsRuKXX4nTUMwya09CO3QHFPFZtZvqjy2HaMOnVLQ"
- + "I6b6dHEfmsHybzVOe3yPEoFQSU9UhUdmi71kwwoanPD3j9fJHmXTx4PzYYBRf1ZE"
- + "o+uPgMPk7CDKQFZLjnR40z1uzu3O8aZ3AKZzP+j7T4XQKJLQLmllKtPgLgNdJyib"
- + "2Glg7QhXH/jBTL6hAgMBAAGjYzBhMB0GA1UdDgQWBBSbZfrqOYH54EJpkdKMZjMc"
- + "z/Hp+DAfBgNVHSMEGDAWgBSbZfrqOYH54EJpkdKMZjMcz/Hp+DAPBgNVHRMBAf8E"
- + "BTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQ0FAAOCAgEAKh9nm/vW"
- + "glMWp3vcCwWwJW286ecREDlI+CjGh5h+f2N4QRrXd/tKE3qQJWCqGx8sFfIUjmI7"
- + "KYdsC2gyQ2cA2zl0w7pB2QkuqE6zVbnh1D17Hwl19IMyAakFaM9ad4/EoH7oQmqX"
- + "nF/f5QXGZw4kf1HcgKgoCHWXjqR8MqHOcXR8n6WFqxjzJf1jxzi6Yo2dZ7PJbnE6"
- + "+kHIJuiCpiHL75v5g1HM41gT3ddFFSrn88ThNPWItT5Z8WpFjryVzank2Yt02LLl"
- + "WqZg9IC375QULc5B58NMnaiVJIDJQ8zoNgj1yaxqtUMnJX570lotO2OXe4ec9aCQ"
- + "DIJ84YLM/qStFdeZ9416E80dchskbDG04GuVJKlzWjxAQNMRFhyaPUSBTLLg+kwP"
- + "t9+AMmc+A7xjtFQLZ9fBYHOBsndJOmeSQeYeckl+z/1WQf7DdwXn/yijon7mxz4z"
- + "cCczfKwTJTwBh3wR5SQr2vQm7qaXM87qxF8PCAZrdZaw5I80QwkgTj0WTZ2/GdSw"
- + "d3o5SyzzBAjpwtG+4bO/BD9h9wlTsHpT6yWOZs4OYAKU5ykQrncI8OyavMggArh3"
- + "/oM58v0orUWINtIc2hBlka36PhATYQiLf+AiWKnwhCaaHExoYKfQlMtXBodNvOK8"
- + "xqx69x05q/qbHKEcTHrsss630vxrp1niXvA=";
+ + "MIIFDzCCAvegAwIBAgIQbNdueU2o0vM9gGq4N6bhjzANBgkqhkiG9w0BAQsFADAx"
+ + "MS8wLQYDVQQDEyZHb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgUm9vdCBD"
+ + "QTAeFw0xODA1MDcxODI0MDJaFw0zODA1MDgxOTI0MDJaMDExLzAtBgNVBAMTJkdv"
+ + "b2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBSb290IENBMIICIjANBgkqhkiG"
+ + "9w0BAQEFAAOCAg8AMIICCgKCAgEArUgzu+4o9yl22eql1BiGBq3gWXooh2ql3J+v"
+ + "Vuzf/ThjzdIg0xkkkw/NAFxYFi49Eo1fa/hf8wCIoAqCEs1lD6tE3cCD3T3+EQPq"
+ + "uh6CB2KmZDJ6mPnXvVUlUuFr0O2MwZkwylqBETzK0x5NCHgL/p47vkjhHx6LqVao"
+ + "bigKlHxszvVi4fkt/qq7KW3YTVxhwdLGEab+OqSfwMxdBLhMfE0K0dvFt8bs8yJA"
+ + "F04DJsMbRChFFBpT17Z0u53iIAAu5qVQhKrQXiIAwgboZqd+JkHLXU1fJeVT5WJO"
+ + "JgoJFWHkdWkHta4mSYlS72J1Q927JD1JdET1kFtH+EDtYAtx7x7F9xAAbb2tMITw"
+ + "s/wwd2rAzZTX/kxRbDlXVLToU05LFYPr+dFV1wvXmi0jlkIxnhdaVBqWC93p528U"
+ + "iUcLpib+HVzMWGdYI3G1NOa/lTp0c8LcbJjapiiVneRQJ3cIqDPOSEnEq40hyZd1"
+ + "jx3JnOxJMwHs8v4s9GIlb3BcOmDvA/Mu09xEMKwpHBm4TFDKXeGHOWha7ccWEECb"
+ + "yO5ncu6XuN2iyz9S+TuMyjZBE552p6Pu5gEC2xk+qab0NGDTHdLKLbyWn3IxdmBH"
+ + "yTr7iPCqmpyHngkC/pbGfvGusc5BpBugsBtlz67m4RWLJ72yAeVPO/ly/8w4orNs"
+ + "GWjn3s0CAwEAAaMjMCEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w"
+ + "DQYJKoZIhvcNAQELBQADggIBAGiWlu+4qyxgPb6RsA0mwR7V21UJ9rEpYhSN+ARp"
+ + "TWGiI22RCJSGK0ZrPGeFQzE2BpnVRdmLTV5jf9JUStjHoPvNYFnwLTJ0E2e9Olj8"
+ + "MrHrAucAUFLhl4woWz0kU/X0EB1j6Y2SXrAaZPiMMpq8BKj3mH1MbV4stZ0kiHUp"
+ + "Zu6PEmrojYG7FKKN30na2xXfiOfl2JusVsyHDqmUn/HjTh6zASKqE6hxE+FJRl2V"
+ + "Q4dcr4SviHtdbimMy2LghLnZ4FE4XhJgRnw9TeRV5C9Sn7pmnAA5X0C8ZXhXvfvr"
+ + "dx4fL3UKlk1Lqlb5skxoK1R9wwr+aNIO+cuR8JA5DmEDWFw5Budh/uWWZlBTyVW2"
+ + "ybbTB6tkmOc8c08XOgxBaKrsXALmJcluabjmN1jp81ae1epeN31jJ4N5IE5aq7Xb"
+ + "TFmKkwpgTTvJmqCR2XzWujlvdbdjfiABliWsnLzLQCP8eZwcM4LA5UK3f1ktHolr"
+ + "1OI9etSOkebE2py8LPYBJWlX36tRAagZhU/NoyOtvhRzq9rb3rbf96APEHKUFsXG"
+ + "9nBEd2BUKZghLKPf+JNCU/2pOGx0jdMcf+K+a1DeG0YzGYMRkFvpN3hvHYrJdByL"
+ + "3kSP3UtD0H2g8Ps7gRLELG2HODxbSn8PV3XtuSvxVanA6uyaaS3AZ6SxeVLvmw50"
+ + "7aYI";
private static final String TEST_ONLY_INSECURE_CERTIFICATE_BASE64 = ""
+ "MIIFMDCCAxigAwIBAgIJAIZ9/G8KQie9MA0GCSqGSIb3DQEBDQUAMCUxIzAhBgNV"
@@ -134,8 +134,6 @@
/**
* The X509 certificate of the trusted root CA cert for the recoverable key store service.
- *
- * TODO: Change it to the production certificate root CA before the final launch.
*/
private static final X509Certificate GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_CERTIFICATE =
parseBase64Certificate(GOOGLE_CLOUD_KEY_VAULT_SERVICE_V1_BASE64);
diff --git a/core/java/android/view/textclassifier/SelectionSessionLogger.java b/core/java/android/view/textclassifier/SelectionSessionLogger.java
index f2fb63e..cdacdd5 100644
--- a/core/java/android/view/textclassifier/SelectionSessionLogger.java
+++ b/core/java/android/view/textclassifier/SelectionSessionLogger.java
@@ -86,8 +86,10 @@
.addTaggedData(SMART_START, event.getSmartStart())
.addTaggedData(SMART_END, event.getSmartEnd())
.addTaggedData(EVENT_START, event.getStart())
- .addTaggedData(EVENT_END, event.getEnd())
- .addTaggedData(SESSION_ID, event.getSessionId().flattenToString());
+ .addTaggedData(EVENT_END, event.getEnd());
+ if (event.getSessionId() != null) {
+ log.addTaggedData(SESSION_ID, event.getSessionId().flattenToString());
+ }
mMetricsLogger.write(log);
debugLog(log);
}
diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java
index da86b55..10191e0 100644
--- a/core/java/android/view/textclassifier/SystemTextClassifier.java
+++ b/core/java/android/view/textclassifier/SystemTextClassifier.java
@@ -129,6 +129,18 @@
return mFallback.generateLinks(request);
}
+ @Override
+ public void onSelectionEvent(SelectionEvent event) {
+ Preconditions.checkNotNull(event);
+ Utils.checkMainThread();
+
+ try {
+ mManagerService.onSelectionEvent(mSessionId, event);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Error reporting selection event.", e);
+ }
+ }
+
/**
* @inheritDoc
*/
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index b7395cd..0697c97 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -126,7 +126,6 @@
android:visibility="gone"
android:contentDescription="@string/notification_work_profile_content_description"
/>
-
<LinearLayout
android:id="@+id/app_ops"
android:layout_height="match_parent"
@@ -140,6 +139,8 @@
android:src="@drawable/ic_camera"
android:background="?android:selectableItemBackgroundBorderless"
android:visibility="gone"
+ android:clickable="false"
+ android:contentDescription="@string/notification_appops_camera_active"
/>
<ImageButton
android:id="@+id/mic"
@@ -149,6 +150,8 @@
android:background="?android:selectableItemBackgroundBorderless"
android:layout_marginStart="4dp"
android:visibility="gone"
+ android:clickable="false"
+ android:contentDescription="@string/notification_appops_microphone_active"
/>
<ImageButton
android:id="@+id/overlay"
@@ -158,6 +161,8 @@
android:background="?android:selectableItemBackgroundBorderless"
android:layout_marginStart="4dp"
android:visibility="gone"
+ android:clickable="false"
+ android:contentDescription="@string/notification_appops_overlay_active"
/>
</LinearLayout>
</NotificationHeaderView>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 749d3c1..3c5159c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4969,6 +4969,14 @@
<!-- Application name displayed in notifications [CHAR LIMIT=60] -->
<string name="notification_app_name_settings">Settings</string>
+ <!-- Active Permission - accessibility support -->
+ <!-- Content description of the camera icon in the notification. [CHAR LIMIT=NONE] -->
+ <string name="notification_appops_camera_active">Camera</string>
+ <!-- Content description of the mic icon in the notification. [CHAR LIMIT=NONE] -->
+ <string name="notification_appops_microphone_active">Microphone</string>
+ <!-- Content description of the overlay icon in the notification. [CHAR LIMIT=NONE] -->
+ <string name="notification_appops_overlay_active">displaying over other apps on your screen</string>
+
<!-- Strings for car -->
<!-- String displayed when loading a user in the car [CHAR LIMIT=30] -->
<string name="car_loading_profile">Loading</string>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 18bc20c..ab9fc13 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -385,6 +385,9 @@
Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
Settings.Global.SHOW_TEMPERATURE_WARNING,
Settings.Global.SHOW_ZEN_UPGRADE_NOTIFICATION,
+ Settings.Global.SHOW_ZEN_SETTINGS_SUGGESTION,
+ Settings.Global.ZEN_SETTINGS_UPDATED,
+ Settings.Global.ZEN_SETTINGS_SUGGESTION_VIEWED,
Settings.Global.SMART_SELECTION_UPDATE_CONTENT_URL,
Settings.Global.SMART_SELECTION_UPDATE_METADATA_URL,
Settings.Global.SMS_OUTGOING_CHECK_INTERVAL_MS,
diff --git a/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java b/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java
index 7381d97..55cd1ab 100644
--- a/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java
+++ b/media/java/android/media/soundtrigger/SoundTriggerDetectionService.java
@@ -191,13 +191,14 @@
client = mClients.get(uuid);
if (client == null) {
- throw new IllegalStateException("operationFinished called, but no client for "
+ Log.w(LOG_TAG, "operationFinished called, but no client for "
+ uuid + ". Was this called after onDisconnected?");
+ return;
}
}
client.onOpFinished(opId);
} catch (RemoteException e) {
- e.rethrowFromSystemServer();
+ Log.e(LOG_TAG, "operationFinished, remote exception for client " + uuid, e);
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
index 6b99024..24037a6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java
@@ -94,6 +94,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.A2DP;
+ }
+
A2dpProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
index a1c8de5..ac5f537 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpSinkProfile.java
@@ -85,6 +85,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.A2DP_SINK;
+ }
+
A2dpSinkProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
index bab59f1..c7f8c20 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothCallback.java
@@ -30,4 +30,7 @@
void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state);
void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile);
void onAudioModeChanged();
+ default void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice,
+ int state, int bluetoothProfile) {
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index e7d7ab3..4e9e566 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -497,4 +497,13 @@
}
}
}
+
+ void dispatchProfileConnectionStateChanged(CachedBluetoothDevice device, int state,
+ int bluetoothProfile) {
+ synchronized (mCallbacks) {
+ for (BluetoothCallback callback : mCallbacks) {
+ callback.onProfileConnectionStateChanged(device, state, bluetoothProfile);
+ }
+ }
+ }
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
index ad81336..f7518cd 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HeadsetProfile.java
@@ -92,6 +92,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.HEADSET;
+ }
+
HeadsetProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
index da2ae7f..a0dfb5d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java
@@ -93,6 +93,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.HEARING_AID;
+ }
+
HearingAidProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
index 169aac9..d081909 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HfpClientProfile.java
@@ -92,6 +92,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.HEADSET_CLIENT;
+ }
+
HfpClientProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
index 941964a..45ec4a1 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidDeviceProfile.java
@@ -98,6 +98,11 @@
}
@Override
+ public int getProfileId() {
+ return BluetoothProfile.HID_DEVICE;
+ }
+
+ @Override
public boolean isConnectable() {
return true;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
index 93c4017..93e5621 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HidProfile.java
@@ -80,6 +80,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.HID_HOST;
+ }
+
HidProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
index abcb989..0447f37 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfile.java
@@ -49,6 +49,8 @@
boolean isProfileReady();
+ int getProfileId();
+
/** Display order for device profile settings. */
int getOrdinal();
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 0715d69..62f8724 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -375,6 +375,8 @@
}
}
+ mEventManager.dispatchProfileConnectionStateChanged(cachedDevice, newState,
+ mProfile.getProfileId());
cachedDevice.onProfileStateChanged(mProfile, newState);
cachedDevice.refresh();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
index 6efa468..ad0d8ba 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapClientProfile.java
@@ -94,6 +94,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.MAP_CLIENT;
+ }
+
MapClientProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
index 0b45f51..aa7a7af 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/MapProfile.java
@@ -93,6 +93,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.MAP;
+ }
+
MapProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
index 31e675c..e5c0b14 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/OppProfile.java
@@ -67,6 +67,11 @@
return true;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.OPP;
+ }
+
public String toString() {
return NAME;
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
index e077a67..b18b19b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PanProfile.java
@@ -69,6 +69,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.PAN;
+ }
+
PanProfile(Context context, LocalBluetoothAdapter adapter) {
mLocalAdapter = adapter;
mLocalAdapter.getProfileProxy(context, new PanServiceListener(),
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
index 28137ff..b735c23 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java
@@ -100,6 +100,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.PBAP_CLIENT;
+ }
+
PbapClientProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
index 58465f2..e9d8cb5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapServerProfile.java
@@ -71,6 +71,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.PBAP;
+ }
+
PbapServerProfile(Context context) {
BluetoothPbap pbap = new BluetoothPbap(context, new PbapServiceListener());
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
index 25c53e6..93e6be6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/SapProfile.java
@@ -91,6 +91,11 @@
return mIsProfileReady;
}
+ @Override
+ public int getProfileId() {
+ return BluetoothProfile.SAP;
+ }
+
SapProfile(Context context, LocalBluetoothAdapter adapter,
CachedBluetoothDeviceManager deviceManager,
LocalBluetoothProfileManager profileManager) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
index 6a2a04a..dd8bfda 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/CategoryKey.java
@@ -49,8 +49,8 @@
"com.android.settings.category.ia.notifications";
public static final String CATEGORY_DO_NOT_DISTURB = "com.android.settings.category.ia.dnd";
public static final String CATEGORY_GESTURES = "com.android.settings.category.ia.gestures";
- public static final String CATEGORY_NIGHT_LIGHT =
- "com.android.settings.category.ia.night_light";
+ public static final String CATEGORY_NIGHT_DISPLAY =
+ "com.android.settings.category.ia.night_display";
public static final Map<String, String> KEY_COMPAT_MAP;
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
index d1e37f6..466980c 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
@@ -15,13 +15,17 @@
*/
package com.android.settingslib.bluetooth;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.verify;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -39,6 +43,8 @@
private CachedBluetoothDeviceManager mCachedDeviceManager;
@Mock
private BluetoothCallback mBluetoothCallback;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
private Context mContext;
private Intent mIntent;
@@ -78,4 +84,19 @@
verify(mBluetoothCallback).onAudioModeChanged();
}
+
+ /**
+ * dispatchProfileConnectionStateChanged should dispatch to onProfileConnectionStateChanged
+ * callback.
+ */
+ @Test
+ public void dispatchProfileConnectionStateChanged_registerCallback_shouldDispatchCallback() {
+ mBluetoothEventManager.registerCallback(mBluetoothCallback);
+
+ mBluetoothEventManager.dispatchProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
+
+ verify(mBluetoothCallback).onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
index 88c7a55..d342bc8 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManagerTest.java
@@ -18,12 +18,23 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothHearingAid;
+import android.bluetooth.BluetoothPan;
+import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
+import android.content.Intent;
import android.os.ParcelUuid;
import java.util.ArrayList;
@@ -41,18 +52,29 @@
@RunWith(RobolectricTestRunner.class)
@Config(resourceDir = "../../res")
public class LocalBluetoothProfileManagerTest {
- @Mock private CachedBluetoothDeviceManager mDeviceManager;
- @Mock private BluetoothEventManager mEventManager;
- @Mock private LocalBluetoothAdapter mAdapter;
- @Mock private BluetoothDevice mDevice;
+ @Mock
+ private CachedBluetoothDeviceManager mDeviceManager;
+ @Mock
+ private BluetoothEventManager mEventManager;
+ @Mock
+ private LocalBluetoothAdapter mAdapter;
+ @Mock
+ private BluetoothDevice mDevice;
+ @Mock
+ private CachedBluetoothDevice mCachedBluetoothDevice;
+
private Context mContext;
private LocalBluetoothProfileManager mProfileManager;
+ private Intent mIntent;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
+ mContext = spy(RuntimeEnvironment.application);
+ mEventManager = spy(new BluetoothEventManager(mAdapter,
+ mDeviceManager, mContext));
when(mAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
+ when(mDeviceManager.findDevice(mDevice)).thenReturn(mCachedBluetoothDevice);
}
/**
@@ -74,7 +96,7 @@
public void updateLocalProfiles_addA2dpToLocalProfiles() {
mProfileManager =
new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager, mEventManager);
- when(mAdapter.getUuids()).thenReturn(new ParcelUuid[] {BluetoothUuid.AudioSource});
+ when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
assertThat(mProfileManager.getA2dpProfile()).isNull();
assertThat(mProfileManager.getHeadsetProfile()).isNull();
@@ -104,4 +126,143 @@
assertThat(profiles.contains(mProfileManager.getHidProfile())).isTrue();
assertThat(removedProfiles.contains(mProfileManager.getHidProfile())).isFalse();
}
+
+ /**
+ * Verify BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
+ * profile connection state changed callback
+ */
+ @Test
+ public void stateChangedHandler_receiveA2dpConnectionStateChanged_shouldDispatchCallback() {
+ when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
+ // LocalBluetoothProfileManager created.
+ mEventManager.setReceiverHandler(null);
+ mIntent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mEventManager).dispatchProfileConnectionStateChanged(
+ mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP);
+ }
+
+ /**
+ * Verify BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
+ * profile connection state changed callback
+ */
+ @Test
+ public void stateChangedHandler_receiveHeadsetConnectionStateChanged_shouldDispatchCallback() {
+ when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.Handsfree_AG});
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
+ // LocalBluetoothProfileManager created.
+ mEventManager.setReceiverHandler(null);
+ mIntent = new Intent(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mEventManager).dispatchProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEADSET);
+ }
+
+ /**
+ * Verify BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED with uuid intent will dispatch to
+ * profile connection state changed callback
+ */
+ @Test
+ public void stateChangedHandler_receiveHAPConnectionStateChanged_shouldDispatchCallback() {
+ ArrayList<Integer> supportProfiles = new ArrayList<>();
+ supportProfiles.add(BluetoothProfile.HEARING_AID);
+ when(mAdapter.getSupportedProfiles()).thenReturn(supportProfiles);
+ when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.HearingAid});
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
+ // LocalBluetoothProfileManager created.
+ mEventManager.setReceiverHandler(null);
+ mIntent = new Intent(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mEventManager).dispatchProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
+ }
+
+ /**
+ * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuid will dispatch to
+ * profile connection state changed callback
+ */
+ @Test
+ public void stateChangedHandler_receivePanConnectionStateChanged_shouldNotDispatchCallback() {
+ when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
+ // LocalBluetoothProfileManager created.
+ mEventManager.setReceiverHandler(null);
+ mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mEventManager).dispatchProfileConnectionStateChanged(
+ any(CachedBluetoothDevice.class), anyInt(), anyInt());
+ }
+
+ /**
+ * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent without uuids will not dispatch to
+ * handler and refresh CachedBluetoothDevice
+ */
+ @Test
+ public void stateChangedHandler_receivePanConnectionStateChangedWithoutUuid_shouldNotRefresh() {
+ when(mAdapter.getUuids()).thenReturn(null);
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
+ // LocalBluetoothProfileManager created.
+ mEventManager.setReceiverHandler(null);
+ mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mCachedBluetoothDevice).refresh();
+ }
+
+ /**
+ * Verify BluetoothPan.ACTION_CONNECTION_STATE_CHANGED intent with uuids will dispatch to
+ * handler and refresh CachedBluetoothDevice
+ */
+ @Test
+ public void stateChangedHandler_receivePanConnectionStateChangedWithUuids_shouldRefresh() {
+ when(mAdapter.getUuids()).thenReturn(new ParcelUuid[]{BluetoothUuid.AudioSource});
+ mProfileManager = new LocalBluetoothProfileManager(mContext, mAdapter, mDeviceManager,
+ mEventManager);
+ // Refer to BluetoothControllerImpl, it will call setReceiverHandler after
+ // LocalBluetoothProfileManager created.
+ mEventManager.setReceiverHandler(null);
+ mIntent = new Intent(BluetoothPan.ACTION_CONNECTION_STATE_CHANGED);
+ mIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
+ mIntent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, BluetoothProfile.STATE_CONNECTING);
+ mIntent.putExtra(BluetoothProfile.EXTRA_STATE, BluetoothProfile.STATE_CONNECTED);
+
+ mContext.sendBroadcast(mIntent);
+
+ verify(mCachedBluetoothDevice).refresh();
+ }
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
index f34605c..605c861 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/CategoryKeyTest.java
@@ -58,7 +58,7 @@
allKeys.add(CategoryKey.CATEGORY_SYSTEM_LANGUAGE);
allKeys.add(CategoryKey.CATEGORY_SYSTEM_DEVELOPMENT);
allKeys.add(CategoryKey.CATEGORY_GESTURES);
- allKeys.add(CategoryKey.CATEGORY_NIGHT_LIGHT);
+ allKeys.add(CategoryKey.CATEGORY_NIGHT_DISPLAY);
// DO NOT REMOVE ANYTHING ABOVE
assertThat(allKeys.size()).isEqualTo(18);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 32aafea..7b76fce 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -2935,7 +2935,7 @@
}
private final class UpgradeController {
- private static final int SETTINGS_VERSION = 165;
+ private static final int SETTINGS_VERSION = 166;
private final int mUserId;
@@ -3733,7 +3733,7 @@
}
if (currentVersion == 164) {
- // Version 164: Add a gesture for silencing phones
+ // Version 164: show zen upgrade notification
final SettingsState settings = getGlobalSettingsLocked();
final Setting currentSetting = settings.getSettingLocked(
Global.SHOW_ZEN_UPGRADE_NOTIFICATION);
@@ -3747,6 +3747,36 @@
currentVersion = 165;
}
+ if (currentVersion == 165) {
+ // Version 165: Show zen settings suggestion and zen updated
+ final SettingsState settings = getGlobalSettingsLocked();
+ final Setting currentSetting = settings.getSettingLocked(
+ Global.SHOW_ZEN_SETTINGS_SUGGESTION);
+ if (currentSetting.isNull()) {
+ settings.insertSettingLocked(
+ Global.SHOW_ZEN_SETTINGS_SUGGESTION, "1",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ final Setting currentUpdatedSetting = settings.getSettingLocked(
+ Global.ZEN_SETTINGS_UPDATED);
+ if (currentUpdatedSetting.isNull()) {
+ settings.insertSettingLocked(
+ Global.ZEN_SETTINGS_UPDATED, "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ final Setting currentSettingSuggestionViewed = settings.getSettingLocked(
+ Global.ZEN_SETTINGS_SUGGESTION_VIEWED);
+ if (currentSettingSuggestionViewed.isNull()) {
+ settings.insertSettingLocked(
+ Global.ZEN_SETTINGS_SUGGESTION_VIEWED, "0",
+ null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ }
+
+ currentVersion = 166;
+ }
+
// vXXX: Add new settings above this point.
if (currentVersion != newVersion) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 00cd5a7..48b4134 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -246,7 +246,12 @@
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- onUserInput();
+ // Fingerprint sensor sends a KeyEvent.KEYCODE_UNKNOWN.
+ // We don't want to consider it valid user input because the UI
+ // will already respond to the event.
+ if (keyCode != KeyEvent.KEYCODE_UNKNOWN) {
+ onUserInput();
+ }
return false;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
index a2befef..cb8c119 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -31,8 +31,7 @@
public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
implements View.OnKeyListener, View.OnTouchListener {
- @VisibleForTesting
- PasswordTextView mPasswordEntry;
+ protected PasswordTextView mPasswordEntry;
private View mOkButton;
private View mDeleteButton;
private View mButton0;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fb13925..9f382b00 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -55,6 +55,7 @@
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.IRemoteCallback;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -244,7 +245,7 @@
private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
- private final Handler mHandler = new Handler() {
+ private final Handler mHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
@@ -339,6 +340,9 @@
case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
updateLogoutEnabled();
break;
+ default:
+ super.handleMessage(msg);
+ break;
}
}
};
@@ -1181,12 +1185,12 @@
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
- context.registerReceiver(mBroadcastReceiver, filter);
+ context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
final IntentFilter bootCompleteFilter = new IntentFilter();
bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
- context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
+ context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
final IntentFilter allUserFilter = new IntentFilter();
allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
@@ -1196,7 +1200,7 @@
allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
allUserFilter.addAction(ACTION_USER_UNLOCKED);
context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
- null, null);
+ null, mHandler);
mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 991b47e..82cf93e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -1651,6 +1651,45 @@
mMenuRow.resetMenu();
}
+ void onGutsOpened() {
+ resetTranslation();
+ updateContentAccessibilityImportanceForGuts(false /* isEnabled */);
+ }
+
+ void onGutsClosed() {
+ updateContentAccessibilityImportanceForGuts(true /* isEnabled */);
+ }
+
+ /**
+ * Updates whether all the non-guts content inside this row is important for accessibility.
+ *
+ * @param isEnabled whether the content views should be enabled for accessibility
+ */
+ private void updateContentAccessibilityImportanceForGuts(boolean isEnabled) {
+ if (mChildrenContainer != null) {
+ updateChildAccessibilityImportance(mChildrenContainer, isEnabled);
+ }
+ if (mLayouts != null) {
+ for (View view : mLayouts) {
+ updateChildAccessibilityImportance(view, isEnabled);
+ }
+ }
+
+ if (isEnabled) {
+ this.requestAccessibilityFocus();
+ }
+ }
+
+ /**
+ * Updates whether the given childView is important for accessibility based on
+ * {@code isEnabled}.
+ */
+ private void updateChildAccessibilityImportance(View childView, boolean isEnabled) {
+ childView.setImportantForAccessibility(isEnabled
+ ? View.IMPORTANT_FOR_ACCESSIBILITY_AUTO
+ : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
+ }
+
public CharSequence getActiveRemoteInputText() {
return mPrivateLayout.getActiveRemoteInputText();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
index 46600cf..8d7668a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGutsManager.java
@@ -159,6 +159,7 @@
row.setGutsView(item);
row.setTag(sbn.getPackageName());
row.getGuts().setClosedListener((NotificationGuts g) -> {
+ row.onGutsClosed();
if (!g.willBeRemoved() && !row.isRemoved()) {
mListContainer.onHeightChanged(
row, !mPresenter.isPresenterFullyCollapsed() /* needsAnimation */);
@@ -390,7 +391,7 @@
x,
y,
needsFalsingProtection,
- row::resetTranslation);
+ row::onGutsOpened);
row.closeRemoteInput();
mListContainer.onHeightChanged(row, true /* needsAnimation */);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index c279e63..cc802a8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -495,12 +495,14 @@
// measured with the wrong number of lines).
if (child.getPaddingLeft() != buttonPaddingHorizontal) {
requiresNewMeasure = true;
- if (buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) {
- // Decrease padding (2->1 line).
- newWidth -= mSingleToDoubleLineButtonWidthIncrease;
- } else {
- // Increase padding (1->2 lines).
- newWidth += mSingleToDoubleLineButtonWidthIncrease;
+ if (newWidth != Integer.MAX_VALUE) {
+ if (buttonPaddingHorizontal == mSingleLineButtonPaddingHorizontal) {
+ // Change padding (2->1 line).
+ newWidth -= mSingleToDoubleLineButtonWidthIncrease;
+ } else {
+ // Change padding (1->2 lines).
+ newWidth += mSingleToDoubleLineButtonWidthIncrease;
+ }
}
child.setPadding(buttonPaddingHorizontal, child.getPaddingTop(),
buttonPaddingHorizontal, child.getPaddingBottom());
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 176905a..236ead0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -2222,7 +2222,7 @@
}
private void updateScrollability() {
- boolean scrollable = getScrollRange() > 0;
+ boolean scrollable = !mQsExpanded && getScrollRange() > 0;
if (scrollable != mScrollable) {
mScrollable = scrollable;
setFocusable(scrollable);
@@ -4500,6 +4500,7 @@
public void setQsExpanded(boolean qsExpanded) {
mQsExpanded = qsExpanded;
updateAlgorithmLayoutMinHeight();
+ updateScrollability();
}
public void setQsExpansionFraction(float qsExpansionFraction) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java
index e79c9d0..359832f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinBasedInputViewTest.java
@@ -16,11 +16,15 @@
package com.android.keyguard;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
+import android.view.KeyEvent;
import android.view.LayoutInflater;
import com.android.systemui.SysuiTestCase;
@@ -28,6 +32,7 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -37,21 +42,35 @@
public class KeyguardPinBasedInputViewTest extends SysuiTestCase {
@Mock
- private PasswordTextView mPasswordTextView;
+ private PasswordTextView mPasswordEntry;
+ @Mock
+ private SecurityMessageDisplay mSecurityMessageDisplay;
+ @InjectMocks
private KeyguardPinBasedInputView mKeyguardPinView;
@Before
public void setup() {
- MockitoAnnotations.initMocks(this);
LayoutInflater inflater = LayoutInflater.from(getContext());
mKeyguardPinView =
(KeyguardPinBasedInputView) inflater.inflate(R.layout.keyguard_pin_view, null);
- mKeyguardPinView.mPasswordEntry = mPasswordTextView;
+ MockitoAnnotations.initMocks(this);
}
@Test
public void onResume_requestsFocus() {
mKeyguardPinView.onResume(KeyguardSecurityView.SCREEN_ON);
- verify(mPasswordTextView).requestFocus();
+ verify(mPasswordEntry).requestFocus();
+ }
+
+ @Test
+ public void onKeyDown_clearsSecurityMessage() {
+ mKeyguardPinView.onKeyDown(KeyEvent.KEYCODE_0, mock(KeyEvent.class));
+ verify(mSecurityMessageDisplay).setMessage(eq(""));
+ }
+
+ @Test
+ public void onKeyDown_noSecurityMessageInteraction() {
+ mKeyguardPinView.onKeyDown(KeyEvent.KEYCODE_UNKNOWN, mock(KeyEvent.class));
+ verifyZeroInteractions(mSecurityMessageDisplay);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index f3d79fd..c573ca8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -347,6 +347,30 @@
assertEqualLayouts(expectedView.getChildAt(2), mView.getChildAt(2));
}
+ @Test
+ public void testMeasure_dropLongest() {
+ final CharSequence[] choices = new CharSequence[]{"Short", "Short",
+ "LooooooongUnbreakableReplyyyyy"};
+
+ // Short choices should be shown as single line views
+ ViewGroup expectedView = buildExpectedView(
+ new CharSequence[]{"Short", "Short"}, 1);
+ expectedView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
+ expectedView.layout(10, 10, 10 + expectedView.getMeasuredWidth(),
+ 10 + expectedView.getMeasuredHeight());
+
+ setRepliesFromRemoteInput(choices);
+ mView.measure(
+ MeasureSpec.makeMeasureSpec(expectedView.getMeasuredWidth(), MeasureSpec.AT_MOST),
+ MeasureSpec.UNSPECIFIED);
+ mView.layout(10, 10, 10 + mView.getMeasuredWidth(), 10 + mView.getMeasuredHeight());
+
+ assertEqualLayouts(expectedView, mView);
+ assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(0), mView.getChildAt(0));
+ assertReplyButtonShownWithEqualMeasures(expectedView.getChildAt(1), mView.getChildAt(1));
+ assertReplyButtonHidden(mView.getChildAt(2));
+ }
+
private void setRepliesFromRemoteInput(CharSequence[] choices) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0,
new Intent(TEST_ACTION), 0);
@@ -407,10 +431,7 @@
private static void assertReplyButtonShownWithEqualMeasures(View expected, View actual) {
assertReplyButtonShown(actual);
assertEqualMeasures(expected, actual);
- assertEquals(expected.getPaddingLeft(), actual.getPaddingLeft());
- assertEquals(expected.getPaddingTop(), actual.getPaddingTop());
- assertEquals(expected.getPaddingRight(), actual.getPaddingRight());
- assertEquals(expected.getPaddingBottom(), actual.getPaddingBottom());
+ assertEqualPadding(expected, actual);
}
private static void assertReplyButtonShown(View view) {
@@ -427,4 +448,11 @@
assertEquals(expected.getRight(), actual.getRight());
assertEquals(expected.getBottom(), actual.getBottom());
}
+
+ private static void assertEqualPadding(View expected, View actual) {
+ assertEquals(expected.getPaddingLeft(), actual.getPaddingLeft());
+ assertEquals(expected.getPaddingTop(), actual.getPaddingTop());
+ assertEquals(expected.getPaddingRight(), actual.getPaddingRight());
+ assertEquals(expected.getPaddingBottom(), actual.getPaddingBottom());
+ }
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 7c05b2b..95dc3ab 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5828,6 +5828,30 @@
// OS: P
DIALOG_SWITCH_HFP_DEVICES = 1416;
+ // ACTION: User has started or ended charging
+ // Type TYPE_DISMISS: Charging has ended
+ // Type TYPE_ACTION: Charging has started, contains fields: battery level
+ // Tag FIELD_BATTERY_LEVEL_START: Battery level at the start
+ // Tag FIELD_BATTERY_LEVEL_END: Battery level at the end
+ // Tag FIELD_CHARGING_DURATION: Time in ms phone was charging
+ // Tag FIELD_PLUG_TYPE: Charging plug type
+ ACTION_CHARGE = 1417;
+
+ // Tag used to determine battery level when device started charging
+ FIELD_BATTERY_LEVEL_START = 1418;
+
+ // Tag used to determine battery level when device ended charging
+ FIELD_BATTERY_LEVEL_END = 1419;
+
+ // Tag used to determine length of charging
+ FIELD_CHARGING_DURATION_MILLIS = 1420;
+
+ // Tag used to determine what type of charging was started/ended
+ // 1 = Plugged AC
+ // 2 = Plugged USB
+ // 3 = Wireless
+ FIELD_PLUG_TYPE = 1421;
+
// ---- End P Constants, all P constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index 7f26575..169f2a8 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -228,7 +228,7 @@
public void startMonitoring(ContentResolver resolver) {
mResolver = resolver;
mResolver.registerContentObserver(
- Settings.Global.getUriFor(Settings.Global.DEVICE_IDLE_CONSTANTS),
+ Settings.Global.getUriFor(Settings.Global.APP_OPS_CONSTANTS),
false, this);
updateConstants();
}
@@ -239,20 +239,17 @@
}
private void updateConstants() {
+ String value = mResolver != null ? Settings.Global.getString(mResolver,
+ Settings.Global.APP_OPS_CONSTANTS) : "";
+
synchronized (AppOpsService.this) {
try {
- if (mResolver != null) {
- mParser.setString(Settings.Global.getString(mResolver,
- Settings.Global.APP_OPS_CONSTANTS));
- } else {
- mParser.setString("");
- }
+ mParser.setString(value);
} catch (IllegalArgumentException e) {
// Failed to parse the settings string, log this and move on
// with defaults.
Slog.e(TAG, "Bad app ops settings", e);
}
-
STATE_SETTLE_TIME = mParser.getDurationMillis(
KEY_STATE_SETTLE_TIME, 10 * 1000L);
}
@@ -557,8 +554,9 @@
}
public void systemReady() {
+ mConstants.startMonitoring(mContext.getContentResolver());
+
synchronized (this) {
- mConstants.startMonitoring(mContext.getContentResolver());
boolean changed = false;
for (int i = mUidStates.size() - 1; i >= 0; i--) {
UidState uidState = mUidStates.valueAt(i);
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index d31a605..87647ca 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -16,36 +16,27 @@
package com.android.server;
-import android.app.ActivityManagerInternal;
-import android.database.ContentObserver;
-import android.os.BatteryStats;
-
-import android.os.Bundle;
-import android.os.PowerManager;
-import android.os.ResultReceiver;
-import android.os.ShellCallback;
-import android.os.ShellCommand;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.app.IBatteryStats;
-import com.android.internal.util.DumpUtils;
-import com.android.server.am.BatteryStatsService;
-import com.android.server.lights.Light;
-import com.android.server.lights.LightsManager;
+import static com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import android.app.ActivityManager;
+import android.app.ActivityManagerInternal;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
+import android.database.ContentObserver;
+import android.hardware.health.V1_0.HealthInfo;
+import android.hardware.health.V2_0.IHealth;
+import android.hardware.health.V2_0.IHealthInfoCallback;
+import android.hardware.health.V2_0.Result;
import android.hidl.manager.V1_0.IServiceManager;
import android.hidl.manager.V1_0.IServiceNotification;
-import android.hardware.health.V1_0.HealthInfo;
-import android.hardware.health.V2_0.IHealthInfoCallback;
-import android.hardware.health.V2_0.IHealth;
-import android.hardware.health.V2_0.Result;
+import android.metrics.LogMaker;
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
import android.os.BatteryProperty;
+import android.os.BatteryStats;
import android.os.Binder;
+import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.FileUtils;
import android.os.Handler;
@@ -54,8 +45,12 @@
import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
import android.os.OsProtoEnums;
+import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.os.ServiceManager;
+import android.os.ShellCallback;
+import android.os.ShellCommand;
import android.os.SystemClock;
import android.os.Trace;
import android.os.UEventObserver;
@@ -67,12 +62,19 @@
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.app.IBatteryStats;
+import com.android.internal.logging.MetricsLogger;
+import com.android.internal.util.DumpUtils;
+import com.android.server.am.BatteryStatsService;
+import com.android.server.lights.Light;
+import com.android.server.lights.LightsManager;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
@@ -171,6 +173,9 @@
private long mDischargeStartTime;
private int mDischargeStartLevel;
+ private long mChargeStartTime;
+ private int mChargeStartLevel;
+
private boolean mUpdatesStopped;
private Led mLed;
@@ -185,6 +190,8 @@
private ArrayDeque<Bundle> mBatteryLevelsEventQueue;
private long mLastBatteryLevelChangedSentMs;
+ private MetricsLogger mMetricsLogger;
+
public BatteryService(Context context) {
super(context);
@@ -204,6 +211,7 @@
com.android.internal.R.integer.config_shutdownBatteryTemperature);
mBatteryLevelsEventQueue = new ArrayDeque<>();
+ mMetricsLogger = new MetricsLogger();
// watch for invalid charger messages if the invalid_charger switch exists
if (new File("/sys/devices/virtual/switch/invalid_charger/state").exists()) {
@@ -476,6 +484,15 @@
if (mPlugType != mLastPlugType) {
if (mLastPlugType == BATTERY_PLUGGED_NONE) {
// discharging -> charging
+ mChargeStartLevel = mHealthInfo.batteryLevel;
+ mChargeStartTime = SystemClock.elapsedRealtime();
+
+ final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);
+ builder.setType(MetricsEvent.TYPE_ACTION);
+ builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mPlugType);
+ builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,
+ mHealthInfo.batteryLevel);
+ mMetricsLogger.write(builder);
// There's no value in this data unless we've discharged at least once and the
// battery level has changed; so don't log until it does.
@@ -491,6 +508,21 @@
// charging -> discharging or we just powered up
mDischargeStartTime = SystemClock.elapsedRealtime();
mDischargeStartLevel = mHealthInfo.batteryLevel;
+
+ long chargeDuration = SystemClock.elapsedRealtime() - mChargeStartTime;
+ if (mChargeStartTime != 0 && chargeDuration != 0) {
+ final LogMaker builder = new LogMaker(MetricsEvent.ACTION_CHARGE);
+ builder.setType(MetricsEvent.TYPE_DISMISS);
+ builder.addTaggedData(MetricsEvent.FIELD_PLUG_TYPE, mLastPlugType);
+ builder.addTaggedData(MetricsEvent.FIELD_CHARGING_DURATION_MILLIS,
+ chargeDuration);
+ builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_START,
+ mChargeStartLevel);
+ builder.addTaggedData(MetricsEvent.FIELD_BATTERY_LEVEL_END,
+ mHealthInfo.batteryLevel);
+ mMetricsLogger.write(builder);
+ }
+ mChargeStartTime = 0;
}
}
if (mHealthInfo.batteryStatus != mLastBatteryStatus ||
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 48090f2..f83d9e6 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20722,7 +20722,7 @@
// BROADCASTS
// =========================================================
- private boolean isInstantApp(ProcessRecord record, String callerPackage, int uid) {
+ private boolean isInstantApp(ProcessRecord record, @Nullable String callerPackage, int uid) {
if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) {
return false;
}
@@ -20731,13 +20731,17 @@
return record.info.isInstantApp();
}
// Otherwise check with PackageManager.
- if (callerPackage == null) {
- Slog.e(TAG, "isInstantApp with an application's uid, no record, and no package name");
- throw new IllegalArgumentException("Calling application did not provide package name");
- }
- mAppOpsService.checkPackage(uid, callerPackage);
+ IPackageManager pm = AppGlobals.getPackageManager();
try {
- IPackageManager pm = AppGlobals.getPackageManager();
+ if (callerPackage == null) {
+ final String[] packageNames = pm.getPackagesForUid(uid);
+ if (packageNames == null || packageNames.length == 0) {
+ throw new IllegalArgumentException("Unable to determine caller package name");
+ }
+ // Instant Apps can't use shared uids, so its safe to only check the first package.
+ callerPackage = packageNames[0];
+ }
+ mAppOpsService.checkPackage(uid, callerPackage);
return pm.isInstantApp(callerPackage, UserHandle.getUserId(uid));
} catch (RemoteException e) {
Slog.e(TAG, "Error looking up if " + callerPackage + " is an instant app.", e);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index a5dfd8c..d194db3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1224,7 +1224,7 @@
ActivityRecord topRunningActivityLocked(boolean considerKeyguardState) {
final ActivityStack focusedStack = mFocusedStack;
ActivityRecord r = focusedStack.topRunningActivityLocked();
- if (r != null) {
+ if (r != null && isValidTopRunningActivity(r, considerKeyguardState)) {
return r;
}
@@ -1257,12 +1257,11 @@
continue;
}
- final boolean keyguardLocked = getKeyguardController().isKeyguardLocked();
// This activity can be considered the top running activity if we are not
// considering the locked state, the keyguard isn't locked, or we can show when
// locked.
- if (!considerKeyguardState || !keyguardLocked || topActivity.canShowWhenLocked()) {
+ if (isValidTopRunningActivity(topActivity, considerKeyguardState)) {
return topActivity;
}
}
@@ -1270,6 +1269,25 @@
return null;
}
+ /**
+ * Verifies an {@link ActivityRecord} can be the top activity based on keyguard state and
+ * whether we are considering it.
+ */
+ private boolean isValidTopRunningActivity(ActivityRecord record,
+ boolean considerKeyguardState) {
+ if (!considerKeyguardState) {
+ return true;
+ }
+
+ final boolean keyguardLocked = getKeyguardController().isKeyguardLocked();
+
+ if (!keyguardLocked) {
+ return true;
+ }
+
+ return record.canShowWhenLocked();
+ }
+
@VisibleForTesting
void getRunningTasks(int maxNum, List<RunningTaskInfo> list,
@ActivityType int ignoreActivityType, @WindowingMode int ignoreWindowingMode,
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 658c7f1..669d556 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -508,6 +508,8 @@
public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason) {
setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/);
+ Settings.Global.putInt(mContext.getContentResolver(), Global.SHOW_ZEN_SETTINGS_SUGGESTION,
+ 0);
}
private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller,
@@ -635,6 +637,10 @@
appendDefaultRules(config);
reason += ", reset to default rules";
}
+ } else {
+ // devices not restoring/upgrading already have updated zen settings
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Global.ZEN_SETTINGS_UPDATED, 1);
}
if (DEBUG) Log.d(TAG, reason);
synchronized (mConfig) {
@@ -813,6 +819,12 @@
for (ZenRule automaticRule : mConfig.automaticRules.values()) {
if (automaticRule.isAutomaticActive()) {
if (zenSeverity(automaticRule.zenMode) > zenSeverity(zen)) {
+ // automatic rule triggered dnd and user hasn't seen update dnd dialog
+ if (Settings.Global.getInt(mContext.getContentResolver(),
+ Global.ZEN_SETTINGS_SUGGESTION_VIEWED, 1) == 0) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Global.SHOW_ZEN_SETTINGS_SUGGESTION, 1);
+ }
zen = automaticRule.zenMode;
}
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 3639082..112059d 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -18,6 +18,7 @@
import static android.content.om.OverlayInfo.STATE_DISABLED;
import static android.content.om.OverlayInfo.STATE_ENABLED;
+import static android.content.om.OverlayInfo.STATE_ENABLED_STATIC;
import static android.content.om.OverlayInfo.STATE_MISSING_TARGET;
import static android.content.om.OverlayInfo.STATE_NO_IDMAP;
import static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING;
@@ -63,6 +64,38 @@
private final String[] mDefaultOverlays;
private final OverlayChangeListener mListener;
+ /**
+ * Helper method to merge the overlay manager's (as read from overlays.xml)
+ * and package manager's (as parsed from AndroidManifest.xml files) views
+ * on overlays.
+ *
+ * Both managers are usually in agreement, but especially after an OTA things
+ * may differ. The package manager is always providing the truth; the overlay
+ * manager has to adapt. Depending on what has changed about an overlay, we
+ * should either scrap the overlay manager's previous settings or merge the old
+ * settings with the new.
+ */
+ private static boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth,
+ @Nullable final OverlayInfo oldSettings) {
+ if (oldSettings == null) {
+ return true;
+ }
+ if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) {
+ return true;
+ }
+ if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) {
+ return true;
+ }
+ // a change in priority is only relevant for static RROs: specifically,
+ // a regular RRO should not have its state reset only because a change
+ // in priority
+ if (theTruth.isStaticOverlayPackage() &&
+ theTruth.overlayPriority != oldSettings.priority) {
+ return true;
+ }
+ return false;
+ }
+
OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
@NonNull final IdmapManager idmapManager,
@NonNull final OverlayManagerSettings settings,
@@ -99,42 +132,29 @@
}
}
+ // Reset overlays if something critical like the target package name
+ // has changed
List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId);
final int overlayPackagesSize = overlayPackages.size();
for (int i = 0; i < overlayPackagesSize; i++) {
final PackageInfo overlayPackage = overlayPackages.get(i);
final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
- if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
- // Reset the overlay if it didn't exist or had the wrong target package.
+
+ if (mustReinitializeOverlay(overlayPackage, oi)) {
+ // if targetPackageName has changed the package that *used* to
+ // be the target must also update its assets
+ if (oi != null) {
+ packagesToUpdateAssets.add(oi.targetPackageName);
+ }
+
mSettings.init(overlayPackage.packageName, newUserId,
overlayPackage.overlayTarget,
overlayPackage.applicationInfo.getBaseCodePath(),
overlayPackage.isStaticOverlayPackage(),
overlayPackage.overlayPriority,
overlayPackage.overlayCategory);
-
- if (oi != null) {
- // The targetPackageName we have stored doesn't match the overlay's target.
- // Queue the old target for an update as well.
- packagesToUpdateAssets.add(oi.targetPackageName);
- }
- } else {
- // Update all other components of an overlay that don't require a hard reset.
- if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) {
- // When changing categories, it is ok just to update our internal state.
- mSettings.setCategory(overlayPackage.packageName, newUserId,
- overlayPackage.overlayCategory);
- }
}
- try {
- updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0);
- } catch (OverlayManagerSettings.BadKeyException e) {
- Slog.e(TAG, "failed to update settings", e);
- mSettings.remove(overlayPackage.packageName, newUserId);
- }
-
- packagesToUpdateAssets.add(overlayPackage.overlayTarget);
storedOverlayInfos.remove(overlayPackage.packageName);
}
@@ -148,6 +168,22 @@
packagesToUpdateAssets.add(oi.targetPackageName);
}
+ // make sure every overlay's state is up-to-date; this needs to happen
+ // after old overlays have been removed, or we risk removing a
+ // legitimate idmap file if a new overlay package has the same apk path
+ // as the removed overlay package used to have
+ for (int i = 0; i < overlayPackagesSize; i++) {
+ final PackageInfo overlayPackage = overlayPackages.get(i);
+ try {
+ updateState(overlayPackage.overlayTarget, overlayPackage.packageName,
+ newUserId, 0);
+ } catch (OverlayManagerSettings.BadKeyException e) {
+ Slog.e(TAG, "failed to update settings", e);
+ mSettings.remove(overlayPackage.packageName, newUserId);
+ }
+ packagesToUpdateAssets.add(overlayPackage.overlayTarget);
+ }
+
// remove target packages that are not installed
final Iterator<String> iter = packagesToUpdateAssets.iterator();
while (iter.hasNext()) {
@@ -355,15 +391,13 @@
try {
final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId);
- if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) {
+ if (mustReinitializeOverlay(pkg, oldOi)) {
+ if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) {
+ mListener.onOverlaysChanged(pkg.overlayTarget, userId);
+ }
mSettings.init(packageName, userId, pkg.overlayTarget,
pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
pkg.overlayPriority, pkg.overlayCategory);
- } else {
- if (!Objects.equals(oldOi.category, pkg.overlayCategory)) {
- // Update the category in-place.
- mSettings.setCategory(packageName, userId, pkg.overlayCategory);
- }
}
if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
@@ -608,6 +642,8 @@
if (overlayPackage != null) {
modified |= mSettings.setBaseCodePath(overlayPackageName, userId,
overlayPackage.applicationInfo.getBaseCodePath());
+ modified |= mSettings.setCategory(overlayPackageName, userId,
+ overlayPackage.overlayCategory);
}
final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId);
@@ -650,6 +686,10 @@
return STATE_NO_IDMAP;
}
+ if (overlayPackage.isStaticOverlayPackage()) {
+ return STATE_ENABLED_STATIC;
+ }
+
final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId);
return enabled ? STATE_ENABLED : STATE_DISABLED;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index e176351..36bf83d 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -309,6 +309,7 @@
pw.print("mState.............: "); pw.println(OverlayInfo.stateToString(item.getState()));
pw.print("mIsEnabled.........: "); pw.println(item.isEnabled());
pw.print("mIsStatic..........: "); pw.println(item.isStatic());
+ pw.print("mPriority..........: "); pw.println(item.mPriority);
pw.print("mCategory..........: "); pw.println(item.mCategory);
pw.decreaseIndent();
@@ -528,7 +529,7 @@
private OverlayInfo getOverlayInfo() {
if (mCache == null) {
mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
- mState, mUserId);
+ mState, mUserId, mPriority, mIsStatic);
}
return mCache;
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
index 54bb115..d576d33 100644
--- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
+++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java
@@ -126,6 +126,7 @@
final OverlayInfo oi = overlaysForTarget.get(i);
String status;
switch (oi.state) {
+ case OverlayInfo.STATE_ENABLED_STATIC:
case OverlayInfo.STATE_ENABLED:
status = "[x]";
break;
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index d0a3757..9a5dd5e 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -47,7 +47,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
-import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -164,6 +163,11 @@
Log.d(TAG, "[" + token + "] Phase1; No results matched");
}
}
+ // if the match external flag is set, return an empty resolve info instead of a null result.
+ if (resolveInfo == null && (origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
+ return new AuxiliaryResolveInfo(token, false, createFailureIntent(origIntent, token),
+ null /* filters */);
+ }
return resolveInfo;
}
@@ -365,23 +369,20 @@
InstantAppDigest digest, String token) {
final int[] shaPrefix = digest.getDigestPrefix();
final byte[][] digestBytes = digest.getDigestBytes();
- final Intent failureIntent = new Intent(origIntent);
boolean requiresSecondPhase = false;
- failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
- failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
- failureIntent.setLaunchToken(token);
ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null;
- boolean isWebIntent = origIntent.isWebIntent();
+ boolean requiresPrefixMatch = origIntent.isWebIntent() || (shaPrefix.length > 0
+ && (origIntent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0);
for (InstantAppResolveInfo instantAppResolveInfo : instantAppResolveInfoList) {
- if (shaPrefix.length > 0 && instantAppResolveInfo.shouldLetInstallerDecide()) {
- Slog.e(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest"
- + " provided; ignoring");
+ if (requiresPrefixMatch && instantAppResolveInfo.shouldLetInstallerDecide()) {
+ Slog.d(TAG, "InstantAppResolveInfo with mShouldLetInstallerDecide=true when digest"
+ + " required; ignoring");
continue;
}
byte[] filterDigestBytes = instantAppResolveInfo.getDigestBytes();
// Only include matching digests if we have a prefix and we're either dealing with a
- // web intent or the resolveInfo specifies digest details.
- if (shaPrefix.length > 0 && (isWebIntent || filterDigestBytes.length > 0)) {
+ // prefixed request or the resolveInfo specifies digest details.
+ if (shaPrefix.length > 0 && (requiresPrefixMatch || filterDigestBytes.length > 0)) {
boolean matchFound = false;
// Go in reverse order so we match the narrowest scope first.
for (int i = shaPrefix.length - 1; i >= 0; --i) {
@@ -409,17 +410,26 @@
}
}
if (filters != null && !filters.isEmpty()) {
- return new AuxiliaryResolveInfo(token, requiresSecondPhase, failureIntent, filters);
- }
- // if the match external flag is set, return an empty resolve info
- if ((origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
- return new AuxiliaryResolveInfo(token, false, failureIntent, null /* filters */);
+ return new AuxiliaryResolveInfo(token, requiresSecondPhase,
+ createFailureIntent(origIntent, token), filters);
}
// Hash or filter mis-match; no instant apps for this domain.
return null;
}
/**
+ * Creates a failure intent for the installer to send in the case that the instant app cannot be
+ * launched for any reason.
+ */
+ private static Intent createFailureIntent(Intent origIntent, String token) {
+ final Intent failureIntent = new Intent(origIntent);
+ failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
+ failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
+ failureIntent.setLaunchToken(token);
+ return failureIntent;
+ }
+
+ /**
* Returns one of three states: <p/>
* <ul>
* <li>{@code null} if there are no matches will not be; resolution is unnecessary.</li>
diff --git a/services/core/java/com/android/server/slice/SlicePermissionManager.java b/services/core/java/com/android/server/slice/SlicePermissionManager.java
index d25ec89..c67f94b 100644
--- a/services/core/java/com/android/server/slice/SlicePermissionManager.java
+++ b/services/core/java/com/android/server/slice/SlicePermissionManager.java
@@ -251,6 +251,9 @@
}
// Can't read or no permissions exist, create a clean object.
client = new SliceClientPermissions(pkgUser, this);
+ synchronized (mCachedClients) {
+ mCachedClients.put(pkgUser, client);
+ }
}
return client;
}
@@ -278,6 +281,9 @@
}
// Can't read or no permissions exist, create a clean object.
provider = new SliceProviderPermissions(pkgUser, this);
+ synchronized (mCachedProviders) {
+ mCachedProviders.put(pkgUser, provider);
+ }
}
return provider;
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index ee03aff..e637df4 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -923,10 +923,12 @@
}
void detachChildren() {
+ SurfaceControl.openTransaction();
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState w = mChildren.get(i);
w.mWinAnimator.detachChildren();
}
+ SurfaceControl.closeTransaction();
}
void finishRelaunching() {
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 1415ada..1ce41a6 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityStackSupervisorTests.java
@@ -325,13 +325,12 @@
}
/**
- * Verifies the correct activity is returned when querying the top running activity with an
- * empty focused stack.
+ * Verifies the correct activity is returned when querying the top running activity.
*/
@Test
- public void testNonFocusedTopRunningActivity() throws Exception {
+ public void testTopRunningActivity() throws Exception {
// Create stack to hold focus
- final ActivityStack focusedStack = mService.mStackSupervisor.getDefaultDisplay()
+ final ActivityStack emptyStack = mService.mStackSupervisor.getDefaultDisplay()
.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
final KeyguardController keyguard = mSupervisor.getKeyguardController();
@@ -340,7 +339,7 @@
final ActivityRecord activity = new ActivityBuilder(mService).setCreateTask(true)
.setStack(stack).build();
- mSupervisor.mFocusedStack = focusedStack;
+ mSupervisor.mFocusedStack = emptyStack;
doAnswer((InvocationOnMock invocationOnMock) -> {
final SparseIntArray displayIds = invocationOnMock.<SparseIntArray>getArgument(0);
@@ -359,6 +358,12 @@
assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
true /* considerKeyguardState */));
+ // Change focus to stack with activity.
+ mSupervisor.mFocusedStack = stack;
+ assertEquals(activity, mService.mStackSupervisor.topRunningActivityLocked());
+ assertEquals(null, mService.mStackSupervisor.topRunningActivityLocked(
+ true /* considerKeyguardState */));
+
// Add activity that should be shown on the keyguard.
final ActivityRecord showWhenLockedActivity = new ActivityBuilder(mService)
.setCreateTask(true)
@@ -370,6 +375,13 @@
assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
true /* considerKeyguardState */));
+
+ // Change focus back to empty stack
+ mSupervisor.mFocusedStack = emptyStack;
+ // Ensure the show when locked activity is returned when not the focused stack
+ assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked());
+ assertEquals(showWhenLockedActivity, mService.mStackSupervisor.topRunningActivityLocked(
+ true /* considerKeyguardState */));
}
/**
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
index a9d6c29..90947f4 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/KeySyncTaskTest.java
@@ -503,7 +503,8 @@
@Test
public void run_sendsEncryptedKeysIfAvailableToSync_withRawPublicKey() throws Exception {
mRecoverableKeyStoreDb.setRecoveryServiceCertPath(
- TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS, TestData.CERT_PATH_1);
+ TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_ROOT_CERT_ALIAS,
+ TestData.getInsecureCertPathForEndpoint1());
mRecoverableKeyStoreDb.setServerParams(
TEST_USER_ID, TEST_RECOVERY_AGENT_UID, TEST_VAULT_HANDLE);
@@ -528,7 +529,8 @@
lockScreenHash,
keyChainSnapshot.getEncryptedRecoveryKeyBlob(),
/*vaultParams=*/ KeySyncUtils.packVaultParams(
- TestData.CERT_1_PUBLIC_KEY,
+ TestData.getInsecureCertPathForEndpoint1().getCertificates().get(0)
+ .getPublicKey(),
counterId,
/*maxAttempts=*/ 10,
TEST_VAULT_HANDLE));
@@ -537,7 +539,7 @@
assertThat(keyChainSnapshot.getCounterId()).isEqualTo(counterId);
assertThat(keyChainSnapshot.getMaxAttempts()).isEqualTo(10);
assertThat(keyChainSnapshot.getTrustedHardwareCertPath())
- .isEqualTo(TestData.CERT_PATH_1);
+ .isEqualTo(TestData.getInsecureCertPathForEndpoint1());
assertThat(keyChainSnapshot.getServerParams()).isEqualTo(TEST_VAULT_HANDLE);
WrappedApplicationKey keyData = applicationKeys.get(0);
assertEquals(TEST_APP_KEY_ALIAS, keyData.getAlias());
@@ -805,7 +807,7 @@
private byte[] decryptThmEncryptedKey(
byte[] lockScreenHash, byte[] encryptedKey, byte[] vaultParams) throws Exception {
byte[] locallyEncryptedKey = SecureBox.decrypt(
- TestData.CERT_1_PRIVATE_KEY,
+ TestData.getInsecurePrivateKeyForEndpoint1(),
/*sharedSecret=*/ KeySyncUtils.calculateThmKfHash(lockScreenHash),
/*header=*/ KeySyncUtils.concat(THM_ENCRYPTED_RECOVERY_KEY_HEADER, vaultParams),
encryptedKey
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 e82478f..8e86a87 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
@@ -101,35 +101,22 @@
private static final String INSECURE_CERTIFICATE_ALIAS =
TrustedRootCertificates.TEST_ONLY_INSECURE_CERTIFICATE_ALIAS;
private static final String TEST_SESSION_ID = "karlin";
- private static final byte[] TEST_PUBLIC_KEY = new byte[] {
- (byte) 0x30, (byte) 0x59, (byte) 0x30, (byte) 0x13, (byte) 0x06, (byte) 0x07, (byte) 0x2a,
- (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x02, (byte) 0x01, (byte) 0x06,
- (byte) 0x08, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x3d, (byte) 0x03,
- (byte) 0x01, (byte) 0x07, (byte) 0x03, (byte) 0x42, (byte) 0x00, (byte) 0x04, (byte) 0xb8,
- (byte) 0x00, (byte) 0x11, (byte) 0x18, (byte) 0x98, (byte) 0x1d, (byte) 0xf0, (byte) 0x6e,
- (byte) 0xb4, (byte) 0x94, (byte) 0xfe, (byte) 0x86, (byte) 0xda, (byte) 0x1c, (byte) 0x07,
- (byte) 0x8d, (byte) 0x01, (byte) 0xb4, (byte) 0x3a, (byte) 0xf6, (byte) 0x8d, (byte) 0xdc,
- (byte) 0x61, (byte) 0xd0, (byte) 0x46, (byte) 0x49, (byte) 0x95, (byte) 0x0f, (byte) 0x10,
- (byte) 0x86, (byte) 0x93, (byte) 0x24, (byte) 0x66, (byte) 0xe0, (byte) 0x3f, (byte) 0xd2,
- (byte) 0xdf, (byte) 0xf3, (byte) 0x79, (byte) 0x20, (byte) 0x1d, (byte) 0x91, (byte) 0x55,
- (byte) 0xb0, (byte) 0xe5, (byte) 0xbd, (byte) 0x7a, (byte) 0x8b, (byte) 0x32, (byte) 0x7d,
- (byte) 0x25, (byte) 0x53, (byte) 0xa2, (byte) 0xfc, (byte) 0xa5, (byte) 0x65, (byte) 0xe1,
- (byte) 0xbd, (byte) 0x21, (byte) 0x44, (byte) 0x7e, (byte) 0x78, (byte) 0x52, (byte) 0xfa};
+ private static final byte[] TEST_PUBLIC_KEY = TestData.CERT_1_PUBLIC_KEY.getEncoded();
private static final byte[] TEST_SALT = getUtf8Bytes("salt");
private static final byte[] TEST_SECRET = getUtf8Bytes("password1234");
private static final byte[] TEST_VAULT_CHALLENGE = getUtf8Bytes("vault_challenge");
private static final byte[] TEST_VAULT_PARAMS = new byte[] {
// backend_key
- (byte) 0x04, (byte) 0xb8, (byte) 0x00, (byte) 0x11, (byte) 0x18, (byte) 0x98, (byte) 0x1d,
- (byte) 0xf0, (byte) 0x6e, (byte) 0xb4, (byte) 0x94, (byte) 0xfe, (byte) 0x86, (byte) 0xda,
- (byte) 0x1c, (byte) 0x07, (byte) 0x8d, (byte) 0x01, (byte) 0xb4, (byte) 0x3a, (byte) 0xf6,
- (byte) 0x8d, (byte) 0xdc, (byte) 0x61, (byte) 0xd0, (byte) 0x46, (byte) 0x49, (byte) 0x95,
- (byte) 0x0f, (byte) 0x10, (byte) 0x86, (byte) 0x93, (byte) 0x24, (byte) 0x66, (byte) 0xe0,
- (byte) 0x3f, (byte) 0xd2, (byte) 0xdf, (byte) 0xf3, (byte) 0x79, (byte) 0x20, (byte) 0x1d,
- (byte) 0x91, (byte) 0x55, (byte) 0xb0, (byte) 0xe5, (byte) 0xbd, (byte) 0x7a, (byte) 0x8b,
- (byte) 0x32, (byte) 0x7d, (byte) 0x25, (byte) 0x53, (byte) 0xa2, (byte) 0xfc, (byte) 0xa5,
- (byte) 0x65, (byte) 0xe1, (byte) 0xbd, (byte) 0x21, (byte) 0x44, (byte) 0x7e, (byte) 0x78,
- (byte) 0x52, (byte) 0xfa,
+ (byte) 0x04, (byte) 0x8e, (byte) 0x0c, (byte) 0x11, (byte) 0x4a, (byte) 0x79, (byte) 0x20,
+ (byte) 0x7c, (byte) 0x00, (byte) 0x4c, (byte) 0xd7, (byte) 0xe9, (byte) 0x06, (byte) 0xe2,
+ (byte) 0x58, (byte) 0x21, (byte) 0x45, (byte) 0xfa, (byte) 0x24, (byte) 0xcb, (byte) 0x07,
+ (byte) 0x66, (byte) 0xde, (byte) 0xfd, (byte) 0xf1, (byte) 0x83, (byte) 0xb4, (byte) 0x26,
+ (byte) 0x55, (byte) 0x98, (byte) 0xcb, (byte) 0xa9, (byte) 0xd5, (byte) 0x55, (byte) 0xad,
+ (byte) 0x65, (byte) 0xc5, (byte) 0xff, (byte) 0x5c, (byte) 0xfb, (byte) 0x1c, (byte) 0x4e,
+ (byte) 0x34, (byte) 0x98, (byte) 0x7e, (byte) 0x4f, (byte) 0x96, (byte) 0xa2, (byte) 0xa3,
+ (byte) 0x7e, (byte) 0xf4, (byte) 0x46, (byte) 0x52, (byte) 0x04, (byte) 0xba, (byte) 0x2a,
+ (byte) 0xb9, (byte) 0x47, (byte) 0xbb, (byte) 0xc2, (byte) 0x1e, (byte) 0xdd, (byte) 0x15,
+ (byte) 0x1a, (byte) 0xc0,
// counter_id
(byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x00, (byte) 0x00, (byte) 0x00,
(byte) 0x00,
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java
index 64eb49b..5d4be1b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/recoverablekeystore/TestData.java
@@ -29,6 +29,7 @@
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.KeyGenerator;
@@ -37,56 +38,56 @@
public final class TestData {
private static final String KEY_ALGORITHM = "AES";
- private static final long DEFAULT_SERIAL = 1000;
+ private static final long DEFAULT_SERIAL = 10001;
private static final String CERT_PATH_ENCODING = "PkiPath";
private static final String CERT_PATH_1_BASE64 = ""
- + "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"
- + "Zus8";
- private static String CERT_PATH_2_BASE64 = ""
+ + "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";
+ private static final String CERT_PATH_2_BASE64 = ""
+ "MIIFMzCCBS8wggMXoAMCAQICAhAAMA0GCSqGSIb3DQEBCwUAMCAxHjAcBgNVBAMM"
+ "FUdvb2dsZSBDcnlwdEF1dGhWYXVsdDAeFw0xODAyMDMwMDQyMDNaFw0yODAyMDEw"
+ "MDQyMDNaMC0xKzApBgNVBAMMIkdvb2dsZSBDcnlwdEF1dGhWYXVsdCBJbnRlcm1l"
@@ -117,194 +118,44 @@
+ "6Qmlk0rfCszh7bGCoCQNxXmuDsQ5BC+pQUqJplTqds1smyi29xs3";
private static final String THM_CERT_XML_BEFORE_SERIAL = ""
- + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- + "<certificates>\n"
- + " <metadata>\n"
- + " <serial>\n"
- + " ";
- private static final String THM_CERT_XML_AFTER_SERIAL = "\n"
- + " </serial>\n"
- + " <creation-time>\n"
- + " 1515697631\n"
- + " </creation-time>\n"
- + " <refresh-interval>\n"
- + " 2592000\n"
- + " </refresh-interval>\n"
+ + "<certificate>\n"
+ + " <metadata>\n"
+ + " <serial>";
+ private static final String THM_CERT_XML_AFTER_SERIAL = ""
+ + "</serial>\n"
+ + " <creation-time>1525817891</creation-time>\n"
+ + " <refresh-interval>2592000</refresh-interval>\n"
+ " <previous>\n"
- + " <serial>\n"
- + " 0\n"
- + " </serial>\n"
- + " <hash>\n"
- + " 47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=\n"
- + " </hash>\n"
+ + " <serial>10000</serial>\n"
+ + " <hash>ahyI+59KW2tVxi0inRdUSo1Y8kmx5xK1isDvYfzxWbo=</hash>\n"
+ " </previous>\n"
+ " </metadata>\n"
+ " <intermediates>\n"
- + " <cert>\n"
- + " MIIFLzCCAxegAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UEAwwVR29v\n"
- + " Z2xlIENyeXB0QXV0aFZhdWx0MB4XDTE4MDIwMzAwNDIwM1oXDTI4MDIwMTAwNDIw\n"
- + " M1owLTErMCkGA1UEAwwiR29vZ2xlIENyeXB0QXV0aFZhdWx0IEludGVybWVkaWF0\n"
- + " ZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANyQeJvRfqtDIOqTjnX1\n"
- + " vl27Q6sI+TfRdcrDP4fPnLhwZlpYoZwc4dZLZf1gClHM7TT8Ru8WRZVRNUbbvAnn\n"
- + " hX4LccdI4BRYeESB8Va+8fB+f0dMPHUESTv1pConsO4nTpKf9Y6Iy0pUBPnoyLyZ\n"
- + " 6QHGkw6t1mrCVwutRWxnEQezDn9x5m7hxJbNztLOWds0rVwKDJEMapZ/oaneEYTz\n"
- + " qRQ60zWL3lGBQinD7D/PTDGkXqQjJBOMr4qOJgf9EE4kgRybqxJZmUyi0otKfaWF\n"
- + " /5cvzJTETEgdOix95vTvtBZbjDYEHY1kzjA8A7fDhrDfcU2KANBzZJBiadQRiYhw\n"
- + " PyTHvv4lYKALEElzbNMde0HFa5cBD6J6C3xE75AP3ul3pcoz3E+wA6RxYunv2j4A\n"
- + " miXg/l/C+Bgzr2YziXAfXa/zpEjhqm09A5qDQoMgdfIpuNpDICC/fSXgqQOl/a5Y\n"
- + " 4OE45PA1tU9hSbexhSWEFxvKFOTxio32w9ThABqjmwpMBhmAH+aWF5DKlNTDK+rP\n"
- + " ptHMZ6FUHeW0/2ALIp0jThVcRS5QFaTdJPJXZERB6fn8soCezq/XULPbZmsR0K80\n"
- + " uB62fJXsImw5r/AP8aJRYvZNrunOyGL1qEmqutw09FsDM4tw0pmQV7GHM+mie6j+\n"
- + " k2txpF1rV+t6lfFWSZuyA5QvAgMBAAGjZjBkMB0GA1UdDgQWBBR3qZ3aEI+WZ/dW\n"
- + " QRfkV8PEoEttoDAfBgNVHSMEGDAWgBSbZfrqOYH54EJpkdKMZjMcz/Hp+DASBgNV\n"
- + " HRMBAf8ECDAGAQH/AgEBMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC\n"
- + " AgEAWBKGG5b5ZVOjA3TzQ8t/RNY+UcAIcdQ+CF/usUbGBSMnKkKWgTzgF6DdE6k/\n"
- + " mXX0IOpn07I/MDXPpUDN4ZfIWFm9vLsba1kMFE/+/S7ymdIB0LkXyXxWHZgZ2ATe\n"
- + " xkPbm+l0GLs/QR/othB604lefzo+qCaBbUXqXPEOMoKyL2Sl5TQBbAN05WDvjzCS\n"
- + " 7nSjxQTOxXDHMV322gaWB7+efcUfknsS4bMCUXBOgeqnBNUR6BoB3SX2avn6tLtS\n"
- + " t3dfzQEcOoIFxcTtSpu3PDlj6WajAwKdbSQU3TZ0L10u3Zz0jEL72w8gDl5OStkG\n"
- + " SuRNVEYuPavb2PucL2blVopwGpwtkNbLylGdrzJpmmuA10Tx39ZNj2dWyJzT03zM\n"
- + " 0XlDRuGFZrdCieUH1dblmoOC6JyW+f7lO1ETNIC1I7LEz6B8beXTCM7LAiTVoVrn\n"
- + " ZFqoBY8vrso4zobe8o2kydbmGuYeuKO4rGJqsYihl+RkxHmKMrS4WC/f+no0cv9h\n"
- + " AFockmGQp63lOGI/HBb37WT9lxdV5jbpeH7bYan/y2jtlbyC48+I3WF+kP7t/Uh1\n"
- + " KYcOuxlBDtt/NXRummzI00Ht7YRzLD4ZCfLbufK0EskMZ1EG6tvBC/OmlA7pCaWT\n"
- + " St8KzOHtsYKgJA3Fea4OxDkEL6lBSommVOp2zWybKLb3Gzc=\n"
- + " </cert>\n"
+ + " <cert>MIIFGjCCAwKgAwIBAgIQHflnDNWkj2yxeD1IB6GdTTANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDEyZHb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgUm9vdCBDQTAeFw0xODA1MDcxODU4MTBaFw0yODA1MDgxODU4MTBaMDkxNzA1BgNVBAMTLkdvb2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDvdOu8fePrMSKalxzfa3HaK6lbB/LN0TmXgSNzkQFjPHRpkfpv8oO663C6y2TQijKOUbJIwHP/bViBZ6Mib6d24CWmTtZjmRgenRda3N2bFmSeZZOq6A941l6IoSOgOanIhtjo35/XeFDZFWH5YNMSjBD+LThYEvvlyGyGUgb7cDjaDlCvsNkQp1P2glCqSe3OPRwbInlfwHCN5OImu9iTYqf/Tnnn8qmnrkbdF/b1U89TeLruS2EBPdJq8sGkfTdLhZn5CV+sCIZDOLJ23P23uZKTXF5+NrHllYC4kB8Jsp8jdVYBxpSvg/nsHOYNxKLSOCzVoze3YGs98AxHFa/fnINmesL4eKnOSPIMYF8eYWCiCXKFz178qPeZK6w7RGrXCC5VcqzaEpdGhoYm4e17dgjBMLWkvOeq+iWEPWc+hd/yszOAdHOVz0fyJeyAHWnv3vmeHlYI+swNfZ4CZh1rTFMxxxN4HMgzaiHFCzGWHmuyNdU1TeKFtaQeq7MiLAVwC2V0/d0ySyPR2f8OdgPKiSMSBT/PYjbXoT3fH2GYqQSTo+nujy3/PqXAxP0Uki7Ons1ESdYJKL57mzYTsUOPpLvFjbMQhQeubC64lzSPMmfB1n7SbKKdpOYEO8FdHlxTVyYQBmiF4IChG/1n/qgBJzMsXQLi65V8DkZdwCbXhwIDAQABoyYwJDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBATANBgkqhkiG9w0BAQsFAAOCAgEAQ+G3v3JCbzChBs8HUGx6i2TMm1NZM71+chbA2JF9De8kVd/r2CETvvBRLXcTPcWWA0+PRDGaDmi4TR3bJhXgBStecQZkQtzI3ZcdFfI0rTNeCevfHp5nJjtB+AYomCTKNrlNLpk9YbJosqEKVLQBhlLNYm3PT4CQYJ1NubLLtKF1cn4Z+eayxud1kDrZWFyN5CYewOrtXc8oCynj8H0/NydOuCRQU2c/UXWmvsmlRRffHJEXLqCMitTHV9w4VHEVg9YYssxno/jWtp+b4z8JsE2vkJjs2tmOvfiMupbJx9h6zj2j04rjhf/A+vGPRKOD5WtbbX4An2+szsNLmERBfWUNsO1AaSTc3W+AJOjrG30tewS7jFRPluTtgB+kmozSW0MU/BgAYJuNKRVP8zklVmQqJRbrrxSzrvHzJlz/lvFu9MD7nGtiFqT9VggFjqq5vgn5srBp3Dq4GDGerg+HCDCN9qgnL1gBcKzCMK1oT0bCRWZGckT28WMnfcgZ/fuEVNgQcEXLgWiZWZDBEVlMh7u2QoOr2LXwXuXME8k87rAQbxvGLhyxq2uNxUdH16uljm7p5u2Qobyqxqf2rOGJYCBLK2JP74d6Nl6hD5FGBBaO6mN0Ojn/ShJ1Cq9o3wCHoLYn55wJnXYu7QXAX6230h7ekXpbxPPHO4x0Var5p+8=</cert>\n"
+ " </intermediates>\n"
+ " <endpoints>\n"
- + " <cert>\n"
- + " MIIDCDCB8aADAgECAgYBYVkuU0cwDQYJKoZIhvcNAQELBQAwLTErMCkGA1UEAwwi\n"
- + " R29vZ2xlIENyeXB0QXV0aFZhdWx0IEludGVybWVkaWF0ZTAeFw0xODAyMDIwMTAx\n"
- + " MDNaFw0yMDAyMDMwMTAxMDNaMCkxJzAlBgNVBAMTHkdvb2dsZSBDcnlwdEF1dGhW\n"
- + " YXVsdCBJbnN0YW5jZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLgAERiYHfBu\n"
- + " tJT+htocB40BtDr2jdxh0EZJlQ8QhpMkZuA/0t/zeSAdkVWw5b16izJ9JVOi/KVl\n"
- + " 4b0hRH54UvowDQYJKoZIhvcNAQELBQADggIBAJ3PM4GNTNYzMr8E/IGsWZkLx9AR\n"
- + " AALqBXz7As59F8y5UcLMqkXD/ewOfBZgF5VzjlAePyE/wSw0wc3xzvrDVVDiZaMB\n"
- + " W1DVtSlbn25q00m00mmcUeyyMc7vuRkPoDshIMQTc8+U3yyYsVScSV+B4TvSx6wP\n"
- + " Z9FpwnSPjVPD2GkqeMTWszuxNVEWq0wmm0K5lMaX0hfiak+4/IZxOPPGIg2py1KL\n"
- + " A/H2gdyeqyJRcAsyEkfwLlushR5T9abSiPsIRcYoX8Ck8Lt+gQ7RCMefnm8CoOBK\n"
- + " IfcjuV4PGOoeXrq57VR5SsOeT07bL+D7B+mohYFI1v2G3WClAE8XgM3q8NoFFvaY\n"
- + " moi0+UcTduil47qvozjdNmjRAgu5j6vMKXEdG5Rqsja8hy0LG1hwfnR0gNiwcZ5L\n"
- + " e3GyFnwH1IgqvsGOUM0ohnDUAU0zJY7nG0QYrDYe5/QPRNhWDpYkwHDiqcG28wIQ\n"
- + " COTPAZHU2EoSKjSqEG2l0S5JPcor2BEde9ikSkcmK8foxlOHIdFn+n7RNF3bSEfK\n"
- + " n1IOuXoqPidmeBQLevqG8KTy/C9CHqlaCNlpbIA9h+WVfsjm2s6JXBu0YbcfoIbJ\n"
- + " AmSuZVeqB/+ZVvpfiad/jQWzY49fRnsSmV7VveTFPGtJxC89EadbMAinMZo+72u5\n"
- + " 9319RqN5wsP2Zus8\n"
- + " </cert>\n"
+ // The public key is chosen by using the following hash as the first 32 bytes (x-axis)
+ // SHA256("Google Cloud Key Vault Service Test Endpoint") = 8e0c114a79207c004cd7e906e2582145fa24cb0766defdf183b4265598cba9d5
+ // so its private key is unknown.
+ + " <cert>MIIDOzCCASOgAwIBAgIRAOTj/iNQb6/Qit7zAW9ncL0wDQYJKoZIhvcNAQELBQAwOTE3MDUGA1UEAxMuR29vZ2xlIENsb3VkIEtleSBWYXVsdCBTZXJ2aWNlIEludGVybWVkaWF0ZSBDQTAeFw0xODA1MDcyMjE4MTFaFw0yMzA1MDgyMjE4MTFaMDIxMDAuBgNVBAMTJ0dvb2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBFbmRwb2ludDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABI4MEUp5IHwATNfpBuJYIUX6JMsHZt798YO0JlWYy6nVVa1lxf9c+xxONJh+T5aio370RlIEuiq5R7vCHt0VGsCjEDAOMAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAGf6QU58lU+gGzy8hnp0suR/ixC++CExtf39pDHkdfU/e3ui4ROR+pjQ5F7okDFWeKSCNcJZ7tyXMJ9g7/I0qVY8Bj/gRnlVokdl/wD5PiL9GIzqWfnHNe3T+xrAAAgOD0bEmjgwNYmekfUIYQczd04d7ZMGnmAkpVH/0O2mf9q5x9fMlbKuAygUqQ/gmnlgxKfl9DSRWi4oMBOqlKlCRP1XAh3anu92+M/EhsFbyc07CWZY0SByX5M/cHVMLhUXjZHvcYLyOmJWJmXznidgyNeIR6t9yDB55iCt7WSn3qMY+9vA9ELzt8jYpBNaKc0GbWQkRzYWegkf4kMis98eQ3SnAKbRz6669nmuAdxKs9/LK6BlFOFw1xvsTRQ96dBaoiX2XGhou+Im0Td/AMs0Aigz2N+Ujq/yW//35GZQfdGGIYtFbkcltStygjIJyAM1pBhyBBkJhOhRpO4fXh98aq8H5J7R9i5A9WpnDstAxPxcNCDWn0O/WxhPvVZkFTpiNXh9dnlJ/kZe+j+z5ZMaxW435drLPx2AQKjXA9GgGrFPltTUyGycmEGtuxLvSnm/zPlmk5FUk7x2wEr0+bZ3cx0JHHgAtgXpe0jkDi8Bw8O3X7mUOjxVhYU6auiYJezW9LGmweaKwYvS04UCWOReolUVexob9LI/VX1JrrwD3s7k</cert>\n"
+ " </endpoints>\n"
- + "</certificates>\n";
+ + "</certificate>\n";
private static final String THM_SIG_XML = ""
- + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<signature>\n"
- + " <intermediates>\n"
- + " </intermediates>\n"
- + " <certificate>\n"
- + " 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\n"
- + " </certificate>\n"
- + " <value>\n"
- + " uKJ4W8BPCdVaIBe2ZiMxxk5L5vGBV9QwaOEGU80LgtA/gEqkiO2IMUBlQJFqvvhh6RSph5lWpLuv\n"
- + " /Xt7WBzDsZOcxXNffg2+pWNpbpwZdHohlwQEI1OqiVYVnfG4euAkzeWZZLsRUuAjHfcWVIzDoSoK\n"
- + " wC+gqdUQHBV+pWyn6PXVslS0JIldeegbiwF076M1D7ybeCABXoQelSZRHkx1szO8UnxSR3X7Cemu\n"
- + " p9De/7z9+WPPclqybINVIPy6Kvl8mHrGSlzawQRDKtoMrJa8bo93PookF8sbg5EoGapV0yNpMEiA\n"
- + " spq3DEcdXB6mGDGPnLbS2WXq4zjKopASRKkZvOMdgfS6NdUMDtKS1TsOrv2KKTkLnGYfvdAeWiMg\n"
- + " oFbuyYQ0mnDlLH1UW6anI8RxXn+wmdyZA+/ksapGvRmkvz0Mb997WzqNl7v7UTr0SU3Ws01hFsm6\n"
- + " lW++MsotkyfpR9mWB8/dqVNVShLmIlt7U/YFVfziYSrVdjcAdIlgJ6Ihxb92liQHOU+Qr1YDOmm1\n"
- + " JSnhlQVvFxWZG7hm5laNL6lqXz5VV6Gk5IeLtMb8kdHz3zj4ascdldapVPLJIa5741GNNgQNU0nH\n"
- + " FhAyKk0zN7PbL1/XGWPU+s5lai4HE6JM2CKA7jE7cYrdaDZxbba+9iWzQ4YEBDr5Z3OoloK5dvs=\n"
- + " </value>\n"
+ + " <intermediates></intermediates>\n"
+ + " <certificate>MIIFGjCCAwKgAwIBAgIQHflnDNWkj2yxeD1IB6GdTTANBgkqhkiG9w0BAQsFADAxMS8wLQYDVQQDEyZHb29nbGUgQ2xvdWQgS2V5IFZhdWx0IFNlcnZpY2UgUm9vdCBDQTAeFw0xODA1MDcxODU4MTBaFw0yODA1MDgxODU4MTBaMDkxNzA1BgNVBAMTLkdvb2dsZSBDbG91ZCBLZXkgVmF1bHQgU2VydmljZSBJbnRlcm1lZGlhdGUgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDvdOu8fePrMSKalxzfa3HaK6lbB/LN0TmXgSNzkQFjPHRpkfpv8oO663C6y2TQijKOUbJIwHP/bViBZ6Mib6d24CWmTtZjmRgenRda3N2bFmSeZZOq6A941l6IoSOgOanIhtjo35/XeFDZFWH5YNMSjBD+LThYEvvlyGyGUgb7cDjaDlCvsNkQp1P2glCqSe3OPRwbInlfwHCN5OImu9iTYqf/Tnnn8qmnrkbdF/b1U89TeLruS2EBPdJq8sGkfTdLhZn5CV+sCIZDOLJ23P23uZKTXF5+NrHllYC4kB8Jsp8jdVYBxpSvg/nsHOYNxKLSOCzVoze3YGs98AxHFa/fnINmesL4eKnOSPIMYF8eYWCiCXKFz178qPeZK6w7RGrXCC5VcqzaEpdGhoYm4e17dgjBMLWkvOeq+iWEPWc+hd/yszOAdHOVz0fyJeyAHWnv3vmeHlYI+swNfZ4CZh1rTFMxxxN4HMgzaiHFCzGWHmuyNdU1TeKFtaQeq7MiLAVwC2V0/d0ySyPR2f8OdgPKiSMSBT/PYjbXoT3fH2GYqQSTo+nujy3/PqXAxP0Uki7Ons1ESdYJKL57mzYTsUOPpLvFjbMQhQeubC64lzSPMmfB1n7SbKKdpOYEO8FdHlxTVyYQBmiF4IChG/1n/qgBJzMsXQLi65V8DkZdwCbXhwIDAQABoyYwJDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBATANBgkqhkiG9w0BAQsFAAOCAgEAQ+G3v3JCbzChBs8HUGx6i2TMm1NZM71+chbA2JF9De8kVd/r2CETvvBRLXcTPcWWA0+PRDGaDmi4TR3bJhXgBStecQZkQtzI3ZcdFfI0rTNeCevfHp5nJjtB+AYomCTKNrlNLpk9YbJosqEKVLQBhlLNYm3PT4CQYJ1NubLLtKF1cn4Z+eayxud1kDrZWFyN5CYewOrtXc8oCynj8H0/NydOuCRQU2c/UXWmvsmlRRffHJEXLqCMitTHV9w4VHEVg9YYssxno/jWtp+b4z8JsE2vkJjs2tmOvfiMupbJx9h6zj2j04rjhf/A+vGPRKOD5WtbbX4An2+szsNLmERBfWUNsO1AaSTc3W+AJOjrG30tewS7jFRPluTtgB+kmozSW0MU/BgAYJuNKRVP8zklVmQqJRbrrxSzrvHzJlz/lvFu9MD7nGtiFqT9VggFjqq5vgn5srBp3Dq4GDGerg+HCDCN9qgnL1gBcKzCMK1oT0bCRWZGckT28WMnfcgZ/fuEVNgQcEXLgWiZWZDBEVlMh7u2QoOr2LXwXuXME8k87rAQbxvGLhyxq2uNxUdH16uljm7p5u2Qobyqxqf2rOGJYCBLK2JP74d6Nl6hD5FGBBaO6mN0Ojn/ShJ1Cq9o3wCHoLYn55wJnXYu7QXAX6230h7ekXpbxPPHO4x0Var5p+8=</certificate>\n"
+ + " <value>WkmYBCY4heNutMf3tEbyg+Omm+MvWF4EoDmv2vCd259oy3t8URqDqu5vEi3TqQguX0GO3r5mRKCcEYged121xJltC6zShbDMZZNAlB6sqvS6/vIVBBx5jKecUaEpRuQ4ruTyF93YXDi7DgaCNGaYCjkDrnr8lSAyelZl2tfe2BbpOMiwH1fNvI6Xmb++iyMmZGoJo91ovucC635SnnULNUtivL2CjLgU3mKb2uZMB8XPr1t1FOTJEA81ghDU+p3ZrPLxLB3KBTtfAwPQyqStRuY8+3bnPqi7VWeZgfoesvJiPF6q1PraoaL/inlRFo7wr37CS9EtNR/k5cq1UJ4/4Ernvj5k2Zw/IclzYHUGSd3ljCOTJJB6cDtR7WDqprlr1J4nr9hf1Ya4DFJmlX3FXix43Dw6lfk/1gCiWu0y2i1A2NCn0QRxuPh5b385Epj98QlZnd2roB2GfzchJTAxI+oeLc3CowkyLDS5jjuTMERbKbPpkhQu9gtskYtB0I4fEGOMn17+ZrXRcTPJexCS2NGgSqiF4X9Fwe+9XRg3Nk+SoUj9gBCysP8UeSz1POZHQIlZ24mQzxOK2hwGwDtxVchGCrNyf8rh5bZE2hUKHYNH9UWQ+YWrieKeulfP+o1wL9NLZOTz3SHcV/kCv5WqgynzkrKf382FwunxF56NapA=</value>\n"
+ "</signature>\n";
- public static final PublicKey CERT_1_PUBLIC_KEY;
- public static final PrivateKey CERT_1_PRIVATE_KEY;
-
- static {
- try {
- CERT_1_PUBLIC_KEY =
- SecureBox.decodePublicKey(
- new byte[] {
- (byte) 0x04, (byte) 0xb8, (byte) 0x00, (byte) 0x11, (byte) 0x18,
- (byte) 0x98, (byte) 0x1d, (byte) 0xf0, (byte) 0x6e, (byte) 0xb4,
- (byte) 0x94, (byte) 0xfe, (byte) 0x86, (byte) 0xda, (byte) 0x1c,
- (byte) 0x07, (byte) 0x8d, (byte) 0x01, (byte) 0xb4, (byte) 0x3a,
- (byte) 0xf6, (byte) 0x8d, (byte) 0xdc, (byte) 0x61, (byte) 0xd0,
- (byte) 0x46, (byte) 0x49, (byte) 0x95, (byte) 0x0f, (byte) 0x10,
- (byte) 0x86, (byte) 0x93, (byte) 0x24, (byte) 0x66, (byte) 0xe0,
- (byte) 0x3f, (byte) 0xd2, (byte) 0xdf, (byte) 0xf3, (byte) 0x79,
- (byte) 0x20, (byte) 0x1d, (byte) 0x91, (byte) 0x55, (byte) 0xb0,
- (byte) 0xe5, (byte) 0xbd, (byte) 0x7a, (byte) 0x8b, (byte) 0x32,
- (byte) 0x7d, (byte) 0x25, (byte) 0x53, (byte) 0xa2, (byte) 0xfc,
- (byte) 0xa5, (byte) 0x65, (byte) 0xe1, (byte) 0xbd, (byte) 0x21,
- (byte) 0x44, (byte) 0x7e, (byte) 0x78, (byte) 0x52, (byte) 0xfa
- });
- CERT_1_PRIVATE_KEY =
- decodePrivateKey(
- new byte[] {
- (byte) 0x70, (byte) 0x01, (byte) 0xc7, (byte) 0x87, (byte) 0x32,
- (byte) 0x2f, (byte) 0x1c, (byte) 0x9a, (byte) 0x6e, (byte) 0xb1,
- (byte) 0x91, (byte) 0xca, (byte) 0x4e, (byte) 0xb5, (byte) 0x44,
- (byte) 0xba, (byte) 0xc8, (byte) 0x68, (byte) 0xc6, (byte) 0x0a,
- (byte) 0x76, (byte) 0xcb, (byte) 0xd3, (byte) 0x63, (byte) 0x67,
- (byte) 0x7c, (byte) 0xb0, (byte) 0x11, (byte) 0x82, (byte) 0x65,
- (byte) 0x77, (byte) 0x01
- });
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
-
- public static byte[] getCertPath1Bytes() {
- try {
- return CertUtils.decodeBase64(CERT_PATH_1_BASE64);
- } catch (Exception e){
- throw new RuntimeException(e);
- }
- }
-
- public static byte[] getCertPath2Bytes() {
- try {
- return CertUtils.decodeBase64(CERT_PATH_2_BASE64);
- } catch (Exception e){
- throw new RuntimeException(e);
- }
- }
-
public static final CertPath CERT_PATH_1;
public static final CertPath CERT_PATH_2;
+ public static final PublicKey CERT_1_PUBLIC_KEY;
static {
try {
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- CERT_PATH_1 = certFactory.generateCertPath(
- new ByteArrayInputStream(getCertPath1Bytes()), CERT_PATH_ENCODING);
- CERT_PATH_2 = certFactory.generateCertPath(
- new ByteArrayInputStream(getCertPath2Bytes()), CERT_PATH_ENCODING);
+ CERT_PATH_1 = decodeCertPath(CERT_PATH_1_BASE64);
+ CERT_PATH_2 = decodeCertPath(CERT_PATH_2_BASE64);
+ CERT_1_PUBLIC_KEY = CERT_PATH_1.getCertificates().get(0).getPublicKey();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -323,13 +174,6 @@
return THM_SIG_XML.getBytes(StandardCharsets.UTF_8);
}
- private static PrivateKey decodePrivateKey(byte[] keyBytes) throws Exception {
- assertThat(keyBytes.length).isEqualTo(32);
- BigInteger priv = new BigInteger(/*signum=*/ 1, keyBytes);
- KeyFactory keyFactory = KeyFactory.getInstance("EC");
- return keyFactory.generatePrivate(new ECPrivateKeySpec(priv, SecureBox.EC_PARAM_SPEC));
- }
-
public static SecretKey generateKey() throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
keyGenerator.init(/*keySize=*/ 256);
@@ -576,6 +420,10 @@
+ "2nxygOQKtfb0EPTvVYMErvWrA69rr+wPMSWPetvcDGEZ8hWFr3iRtduExC9sRqnV"
+ "5DhvZROQSZQtQ+Ja6g8BehUC9gPCES93EOQUYPpRQEeD1CE+1IKTyuH+ApynIKSj"
+ "5+U1x+OE3UZYTTzEck/TJxTm+Sv4FfCvpwdmDAMTjEZXfuFR+7+5Og==";
+ private static final String INSECURE_PRIVATE_KEY_FOR_ENDPOINT1_BASE64 = ""
+ + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgdCqcARU7lWJVXKY/"
+ + "+DTlFC0dzcTvh1ufkfZdnoZoR7ShRANCAAS3S6JtfbCyXlLSA+WZHwk0Rr2hdjJX"
+ + "xGeJLnsAbVkESmoGL9wG2Qty2InpFQ9jFFJHvGR8a73RMQVqmNxwQvFh";
public static byte[] getInsecureCertXmlBytesWithEndpoint1(int serial) {
String str = INSECURE_CERT_XML_HEADER;
@@ -603,6 +451,13 @@
return decodeCertPath(INSECURE_CERT_PATH_FOR_ENDPOINT2_BASE64);
}
+ public static PrivateKey getInsecurePrivateKeyForEndpoint1() throws Exception {
+ byte[] keyBytes = Base64.getDecoder().decode(INSECURE_PRIVATE_KEY_FOR_ENDPOINT1_BASE64);
+ KeyFactory kf = KeyFactory.getInstance("EC");
+ PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(keyBytes);
+ return kf.generatePrivate(skSpec);
+ }
+
private static CertPath decodeCertPath(String base64CertPath) throws Exception {
byte[] certPathBytes = Base64.getDecoder().decode(base64CertPath);
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
index 6b52ee5..84475bb 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppTimeLimitControllerTests.java
@@ -19,6 +19,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import android.app.PendingIntent;
import android.os.HandlerThread;
@@ -49,9 +50,20 @@
private static final int OBS_ID1 = 1;
private static final int OBS_ID2 = 2;
private static final int OBS_ID3 = 3;
+ private static final int OBS_ID4 = 4;
+ private static final int OBS_ID5 = 5;
+ private static final int OBS_ID6 = 6;
+ private static final int OBS_ID7 = 7;
+ private static final int OBS_ID8 = 8;
+ private static final int OBS_ID9 = 9;
+ private static final int OBS_ID10 = 10;
+ private static final int OBS_ID11 = 11;
- private static final long TIME_30_MIN = 30 * 60_1000L;
- private static final long TIME_10_MIN = 10 * 60_1000L;
+ private static final long TIME_30_MIN = 30 * 60_000L;
+ private static final long TIME_10_MIN = 10 * 60_000L;
+
+ private static final long MAX_OBSERVER_PER_UID = 10;
+ private static final long MIN_TIME_LIMIT = 4_000L;
private static final String[] GROUP1 = {
PKG_SOC1, PKG_GAME1, PKG_PROD
@@ -93,6 +105,16 @@
protected long getUptimeMillis() {
return mUptimeMillis;
}
+
+ @Override
+ protected long getObserverPerUidLimit() {
+ return MAX_OBSERVER_PER_UID;
+ }
+
+ @Override
+ protected long getMinTimeLimit() {
+ return MIN_TIME_LIMIT;
+ }
}
@Before
@@ -233,6 +255,47 @@
assertFalse(hasObserver(OBS_ID1));
}
+ /** Verify that App Time Limit Controller will limit the number of observerIds */
+ @Test
+ public void testMaxObserverLimit() throws Exception {
+ boolean receivedException = false;
+ int ANOTHER_UID = UID + 1;
+ addObserver(OBS_ID1, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID2, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID3, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID4, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID5, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID6, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID7, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID8, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID9, GROUP1, TIME_30_MIN);
+ addObserver(OBS_ID10, GROUP1, TIME_30_MIN);
+ // Readding an observer should not cause an IllegalStateException
+ addObserver(OBS_ID5, GROUP1, TIME_30_MIN);
+ // Adding an observer for a different uid shouldn't cause an IllegalStateException
+ mController.addObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, null, USER_ID);
+ try {
+ addObserver(OBS_ID11, GROUP1, TIME_30_MIN);
+ } catch (IllegalStateException ise) {
+ receivedException = true;
+ }
+ assertTrue("Should have caused an IllegalStateException", receivedException);
+ }
+
+ /** Verify that addObserver minimum time limit is one minute */
+ @Test
+ public void testMinimumTimeLimit() throws Exception {
+ boolean receivedException = false;
+ // adding an observer with a one minute time limit should not cause an exception
+ addObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT);
+ try {
+ addObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1);
+ } catch (IllegalArgumentException iae) {
+ receivedException = true;
+ }
+ assertTrue("Should have caused an IllegalArgumentException", receivedException);
+ }
+
private void moveToForeground(String packageName) {
mController.moveToForeground(packageName, "class", USER_ID);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
index 5443e73..dc057d5 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SlicePermissionManagerTest.java
@@ -26,7 +26,6 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import android.util.Log;
import android.util.Xml.Encoding;
import com.android.server.UiServiceTestCase;
@@ -49,6 +48,20 @@
public class SlicePermissionManagerTest extends UiServiceTestCase {
@Test
+ public void testGrant() {
+ File sliceDir = new File(mContext.getDataDir(), "system/slices");
+ SlicePermissionManager permissions = new SlicePermissionManager(mContext,
+ TestableLooper.get(this).getLooper(), sliceDir);
+ Uri uri = new Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ .authority("authority")
+ .path("something").build();
+
+ permissions.grantSliceAccess("my.pkg", 0, "provider.pkg", 0, uri);
+
+ assertTrue(permissions.hasPermission("my.pkg", 0, uri));
+ }
+
+ @Test
public void testBackup() throws XmlPullParserException, IOException {
File sliceDir = new File(mContext.getDataDir(), "system/slices");
Uri uri = new Builder().scheme(ContentResolver.SCHEME_CONTENT)
diff --git a/services/usage/java/com/android/server/usage/AppTimeLimitController.java b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
index e201851..e7c54d8 100644
--- a/services/usage/java/com/android/server/usage/AppTimeLimitController.java
+++ b/services/usage/java/com/android/server/usage/AppTimeLimitController.java
@@ -26,6 +26,7 @@
import android.util.ArrayMap;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseIntArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -58,6 +59,10 @@
private OnLimitReachedListener mListener;
+ private static final long MAX_OBSERVER_PER_UID = 1000;
+
+ private static final long ONE_MINUTE = 60_000L;
+
@GuardedBy("mLock")
private final SparseArray<UserData> mUsers = new SparseArray<>();
@@ -77,6 +82,9 @@
/** Map of observerId to details of the time limit group */
private SparseArray<TimeLimitGroup> groups = new SparseArray<>();
+ /** Map of the number of observerIds registered by uid */
+ private SparseIntArray observerIdCounts = new SparseIntArray();
+
private UserData(@UserIdInt int userId) {
this.userId = userId;
}
@@ -147,6 +155,18 @@
return SystemClock.uptimeMillis();
}
+ /** Overrideable for testing purposes */
+ @VisibleForTesting
+ protected long getObserverPerUidLimit() {
+ return MAX_OBSERVER_PER_UID;
+ }
+
+ /** Overrideable for testing purposes */
+ @VisibleForTesting
+ protected long getMinTimeLimit() {
+ return ONE_MINUTE;
+ }
+
/** Returns an existing UserData object for the given userId, or creates one */
private UserData getOrCreateUserDataLocked(int userId) {
UserData userData = mUsers.get(userId);
@@ -171,10 +191,20 @@
*/
public void addObserver(int requestingUid, int observerId, String[] packages, long timeLimit,
PendingIntent callbackIntent, @UserIdInt int userId) {
+
+ if (timeLimit < getMinTimeLimit()) {
+ throw new IllegalArgumentException("Time limit must be >= " + getMinTimeLimit());
+ }
synchronized (mLock) {
UserData user = getOrCreateUserDataLocked(userId);
+ removeObserverLocked(user, requestingUid, observerId, /*readding =*/ true);
- removeObserverLocked(user, requestingUid, observerId);
+ final int observerIdCount = user.observerIdCounts.get(requestingUid, 0);
+ if (observerIdCount >= getObserverPerUidLimit()) {
+ throw new IllegalStateException(
+ "Too many observers added by uid " + requestingUid);
+ }
+ user.observerIdCounts.put(requestingUid, observerIdCount + 1);
TimeLimitGroup group = new TimeLimitGroup();
group.observerId = observerId;
@@ -216,7 +246,7 @@
public void removeObserver(int requestingUid, int observerId, @UserIdInt int userId) {
synchronized (mLock) {
UserData user = getOrCreateUserDataLocked(userId);
- removeObserverLocked(user, requestingUid, observerId);
+ removeObserverLocked(user, requestingUid, observerId, /*readding =*/ false);
}
}
@@ -232,12 +262,19 @@
}
@GuardedBy("mLock")
- private void removeObserverLocked(UserData user, int requestingUid, int observerId) {
+ private void removeObserverLocked(UserData user, int requestingUid, int observerId,
+ boolean readding) {
TimeLimitGroup group = user.groups.get(observerId);
if (group != null && group.requestingUid == requestingUid) {
removeGroupFromPackageMapLocked(user, group);
user.groups.remove(observerId);
mHandler.removeMessages(MyHandler.MSG_CHECK_TIMEOUT, group);
+ final int observerIdCount = user.observerIdCounts.get(requestingUid);
+ if (observerIdCount <= 1 && !readding) {
+ user.observerIdCounts.delete(requestingUid);
+ } else {
+ user.observerIdCounts.put(requestingUid, observerIdCount - 1);
+ }
}
}
@@ -321,7 +358,7 @@
// Unregister since the limit has been met and observer was informed.
synchronized (mLock) {
UserData user = getOrCreateUserDataLocked(group.userId);
- removeObserverLocked(user, group.requestingUid, group.observerId);
+ removeObserverLocked(user, group.requestingUid, group.observerId, false);
}
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index f777f1d..243718a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -115,6 +115,7 @@
PackageManagerInternal mPackageManagerInternal;
PackageMonitor mPackageMonitor;
IDeviceIdleController mDeviceIdleController;
+ // Do not use directly. Call getDpmInternal() instead
DevicePolicyManagerInternal mDpmInternal;
private final SparseArray<UserUsageStatsService> mUserState = new SparseArray<>();
@@ -159,7 +160,6 @@
mUserManager = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mPackageManager = getContext().getPackageManager();
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
- mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
mHandler = new H(BackgroundThread.get().getLooper());
mAppStandby = new AppStandbyController(getContext(), BackgroundThread.get().getLooper());
@@ -209,6 +209,8 @@
public void onBootPhase(int phase) {
if (phase == PHASE_SYSTEM_SERVICES_READY) {
mAppStandby.onBootPhase(phase);
+ // initialize mDpmInternal
+ getDpmInternal();
mDeviceIdleController = IDeviceIdleController.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_IDLE_CONTROLLER));
@@ -228,6 +230,13 @@
}
}
+ private DevicePolicyManagerInternal getDpmInternal() {
+ if (mDpmInternal == null) {
+ mDpmInternal = LocalServices.getService(DevicePolicyManagerInternal.class);
+ }
+ return mDpmInternal;
+ }
+
private class UserActionsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@@ -675,9 +684,10 @@
private boolean hasObserverPermission(String callingPackage) {
final int callingUid = Binder.getCallingUid();
+ DevicePolicyManagerInternal dpmInternal = getDpmInternal();
if (callingUid == Process.SYSTEM_UID
- || (mDpmInternal != null
- && mDpmInternal.isActiveAdminWithPolicy(callingUid,
+ || (dpmInternal != null
+ && dpmInternal.isActiveAdminWithPolicy(callingUid,
DeviceAdminInfo.USES_POLICY_PROFILE_OWNER))) {
// Caller is the system or the profile owner, so proceed.
return true;
@@ -1042,9 +1052,6 @@
if (packages == null || packages.length == 0) {
throw new IllegalArgumentException("Must specify at least one package");
}
- if (timeLimitMs <= 0) {
- throw new IllegalArgumentException("Time limit must be > 0");
- }
if (callbackIntent == null) {
throw new NullPointerException("callbackIntent can't be null");
}
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 165702c..bfff148 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -275,6 +275,23 @@
options_.version_code_default.value()});
}
}
+
+ if (el->FindAttribute("", "platformBuildVersionCode") == nullptr) {
+ auto versionCode = el->FindAttribute(xml::kSchemaAndroid, "versionCode");
+ if (versionCode != nullptr) {
+ el->attributes.push_back(xml::Attribute{"", "platformBuildVersionCode",
+ versionCode->value});
+ }
+ }
+
+ if (el->FindAttribute("", "platformBuildVersionName") == nullptr) {
+ auto versionName = el->FindAttribute(xml::kSchemaAndroid, "versionName");
+ if (versionName != nullptr) {
+ el->attributes.push_back(xml::Attribute{"", "platformBuildVersionName",
+ versionName->value});
+ }
+ }
+
return true;
});
diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp
index 8db9374..5f406e8 100644
--- a/tools/aapt2/link/ManifestFixer_test.cpp
+++ b/tools/aapt2/link/ManifestFixer_test.cpp
@@ -556,6 +556,58 @@
ASSERT_THAT(manifest, IsNull());
}
+TEST_F(ManifestFixerTest, InsertPlatformBuildVersions) {
+ // Test for insertion when versionCode and versionName are included in the manifest
+ {
+ std::string input = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"
+ android:versionCode="27" android:versionName="O"/>)";
+ std::unique_ptr<xml::XmlResource> manifest = Verify(input);
+ ASSERT_THAT(manifest, NotNull());
+
+ xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("27"));
+ attr = manifest->root->FindAttribute("", "platformBuildVersionName");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("O"));
+ }
+
+ // Test for insertion when versionCode and versionName defaults are specified
+ {
+ std::string input = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"/>)";
+ ManifestFixerOptions options;
+ options.version_code_default = {"27"};
+ options.version_name_default = {"O"};
+ std::unique_ptr<xml::XmlResource> manifest = VerifyWithOptions(input, options);
+ ASSERT_THAT(manifest, NotNull());
+
+ xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("27"));
+ attr = manifest->root->FindAttribute("", "platformBuildVersionName");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("O"));
+ }
+
+ // Test that the platform build version attributes are not changed if they are currently present
+ {
+ std::string input = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"
+ android:versionCode="28" android:versionName="P"
+ platformBuildVersionCode="27" platformBuildVersionName="O"/>)";
+ std::unique_ptr<xml::XmlResource> manifest = Verify(input);
+ ASSERT_THAT(manifest, NotNull());
+
+ xml::Attribute* attr = manifest->root->FindAttribute("", "platformBuildVersionCode");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("27"));
+ attr = manifest->root->FindAttribute("", "platformBuildVersionName");
+ ASSERT_THAT(attr, NotNull());
+ EXPECT_THAT(attr->value, StrEq("O"));
+ }
+}
TEST_F(ManifestFixerTest, UsesLibraryMustHaveNonEmptyName) {
std::string input = R"(