summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/LauncherApps.java34
-rw-r--r--core/java/android/view/View.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java3
-rw-r--r--core/res/res/anim/watch_switch_thumb_to_off_animation.xml21
-rw-r--r--core/res/res/anim/watch_switch_thumb_to_on_animation.xml18
-rw-r--r--core/res/res/layout-notround-watch/alert_dialog_title_material.xml (renamed from core/res/res/layout-notround-watch/alert_dialog_header_micro.xml)7
-rw-r--r--core/res/res/layout-round-watch/alert_dialog_title_material.xml (renamed from core/res/res/layout-round-watch/alert_dialog_header_micro.xml)8
-rw-r--r--core/res/res/layout-watch/alert_dialog_material.xml6
-rw-r--r--core/res/res/values-notround-watch/config_material.xml (renamed from core/res/res/values-notround-watch/styles_material.xml)13
-rw-r--r--core/res/res/values-round-watch/config_material.xml3
-rw-r--r--core/res/res/values-round-watch/styles_material.xml20
-rw-r--r--core/res/res/values-w180dp-notround-watch/dimens_material.xml36
-rw-r--r--core/res/res/values-w210dp-round-watch/dimens_material.xml36
-rw-r--r--core/res/res/values-watch/config_material.xml3
-rw-r--r--core/res/res/values-watch/dimens_material.xml20
-rw-r--r--core/res/res/values-watch/styles_material.xml11
-rw-r--r--core/res/res/values/config_material.xml3
-rw-r--r--core/res/res/values/styles_material.xml5
-rw-r--r--core/res/res/values/themes_material.xml12
-rw-r--r--core/res/res/xml-watch/default_zen_mode_config.xml6
-rw-r--r--packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml2
-rw-r--r--packages/SettingsLib/res/values-ca/strings.xml2
-rwxr-xr-xservices/core/java/com/android/server/am/ActiveServices.java29
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java38
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java71
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java315
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java14
27 files changed, 465 insertions, 277 deletions
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index b9b609b5cad4..6b23da93bb86 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -492,7 +492,7 @@ public class LauncherApps {
* If the calling launcher application contains pinned shortcuts, they will still work,
* even though the caller no longer has the shortcut host permission.
*
- * <p>Returns {@code false} when the user is locked.
+ * @throws IllegalStateException when the user is locked.
*
* @see ShortcutManager
*/
@@ -510,13 +510,12 @@ public class LauncherApps {
* <p>Callers must be allowed to access the shortcut information, as defined in {@link
* #hasShortcutHostPermission()}.
*
- * <p>Returns am empty list when the user is locked, or when the {@code user} user
- * is locked or not running.
- *
* @param query result includes shortcuts matching this query.
* @param user The UserHandle of the profile.
*
* @return the IDs of {@link ShortcutInfo}s that match the query.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
*/
@@ -556,12 +555,11 @@ public class LauncherApps {
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Call will be ignored when the user is locked, or when the {@code user} user
- * is locked or not running.
- *
* @param packageName The target package name.
* @param shortcutIds The IDs of the shortcut to be pinned.
* @param user The UserHandle of the profile.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
*/
@@ -630,13 +628,12 @@ public class LauncherApps {
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Returns {@code null} when the user is locked, or when the user owning the shortcut
- * is locked or not running.
- *
* @param density The preferred density of the icon, zero for default density. Use
* density DPI values from {@link DisplayMetrics}.
*
* @return The drawable associated with the shortcut.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
* @see #getShortcutBadgedIconDrawable(ShortcutInfo, int)
@@ -681,11 +678,10 @@ public class LauncherApps {
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Returns {@code 0} when the user is locked, or when the user owning the shortcut
- * is locked or not running.
- *
* @param density Optional density for the icon, or 0 to use the default density. Use
* @return A badged icon for the shortcut.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @see ShortcutManager
* @see #getShortcutIconDrawable(ShortcutInfo, int)
@@ -704,15 +700,13 @@ public class LauncherApps {
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Throws {@link android.content.ActivityNotFoundException}
- * when the user is locked, or when the {@code user} user
- * is locked or not running.
- *
* @param packageName The target shortcut package name.
* @param shortcutId The target shortcut ID.
* @param sourceBounds The Rect containing the source bounds of the clicked icon.
* @param startActivityOptions Options to pass to startActivity.
* @param user The UserHandle of the profile.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @throws android.content.ActivityNotFoundException failed to start shortcut. (e.g.
* the shortcut no longer exists, is disabled, the intent receiver activity doesn't exist, etc)
@@ -730,13 +724,11 @@ public class LauncherApps {
* <p>The calling launcher application must be allowed to access the shortcut information,
* as defined in {@link #hasShortcutHostPermission()}.
*
- * <p>Throws {@link android.content.ActivityNotFoundException}
- * when the user is locked, or when the user owning the shortcut
- * is locked or not running.
- *
* @param shortcut The target shortcut.
* @param sourceBounds The Rect containing the source bounds of the clicked icon.
* @param startActivityOptions Options to pass to startActivity.
+ * @throws IllegalStateException when the user is locked, or when the {@code user} user
+ * is locked or not running.
*
* @throws android.content.ActivityNotFoundException failed to start shortcut. (e.g.
* the shortcut no longer exists, is disabled, the intent receiver activity doesn't exist, etc)
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index dab494b385c4..69f174771900 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12359,6 +12359,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
ensureTransformationInfo();
if (mTransformationInfo.mAlpha != alpha) {
+ // Report visibility changes, which can affect children, to accessibility
+ if ((alpha == 0) ^ (mTransformationInfo.mAlpha == 0)) {
+ notifySubtreeAccessibilityStateChangedIfNeeded();
+ }
mTransformationInfo.mAlpha = alpha;
if (onSetAlpha((int) (alpha * 255))) {
mPrivateFlags |= PFLAG_ALPHA_SET;
@@ -12369,8 +12373,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags &= ~PFLAG_ALPHA_SET;
invalidateViewProperty(true, false);
mRenderNode.setAlpha(getFinalAlpha());
- notifyViewAccessibilityStateChangedIfNeeded(
- AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED);
}
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 4dc1009fe446..03c97bd9b00c 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6039,7 +6039,8 @@ public final class ViewRootImpl implements ViewParent,
return true;
}
return mEvent instanceof MotionEvent
- && mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
+ && (mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER)
+ || mEvent.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER));
}
public boolean shouldSendToSynthesizer() {
diff --git a/core/res/res/anim/watch_switch_thumb_to_off_animation.xml b/core/res/res/anim/watch_switch_thumb_to_off_animation.xml
index cd02e0db2fd5..c300894d5541 100644
--- a/core/res/res/anim/watch_switch_thumb_to_off_animation.xml
+++ b/core/res/res/anim/watch_switch_thumb_to_off_animation.xml
@@ -1,4 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?><!-- Copyright (C) 2016 The Android Open Source Project
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@@ -17,20 +18,34 @@
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueType="pathType" />
+ <objectAnimator
+ android:duration="49"
+ android:interpolator="@android:interpolator/linear"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueType="pathType" />
<objectAnimator
- android:duration="66"
+ android:duration="83"
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueType="pathType" />
<objectAnimator
- android:duration="66"
+ android:duration="50"
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueType="pathType" />
+ <objectAnimator
+ android:duration="33"
+ android:interpolator="@android:interpolator/linear"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueType="pathType" />
</set>
diff --git a/core/res/res/anim/watch_switch_thumb_to_on_animation.xml b/core/res/res/anim/watch_switch_thumb_to_on_animation.xml
index e64421776605..c300894d5541 100644
--- a/core/res/res/anim/watch_switch_thumb_to_on_animation.xml
+++ b/core/res/res/anim/watch_switch_thumb_to_on_animation.xml
@@ -18,20 +18,34 @@
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueType="pathType" />
+ <objectAnimator
+ android:duration="49"
+ android:interpolator="@android:interpolator/linear"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueType="pathType" />
<objectAnimator
- android:duration="66"
+ android:duration="83"
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueTo="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueType="pathType" />
<objectAnimator
- android:duration="66"
+ android:duration="50"
android:interpolator="@android:interpolator/linear"
android:propertyName="pathData"
android:valueFrom="M -3.0,-7.0 l 6.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l -6.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
android:valueType="pathType" />
+ <objectAnimator
+ android:duration="33"
+ android:interpolator="@android:interpolator/linear"
+ android:propertyName="pathData"
+ android:valueFrom="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueTo="M 0.0,-7.0 l 0.0,0.0 c 3.8659932486,0.0 7.0,3.1340067514 7.0,7.0 l 0.0,0.0 c 0.0,3.8659932486 -3.1340067514,7.0 -7.0,7.0 l 0.0,0.0 c -3.8659932486,0.0 -7.0,-3.1340067514 -7.0,-7.0 l 0.0,0.0 c 0.0,-3.8659932486 3.1340067514,-7.0 7.0,-7.0 Z"
+ android:valueType="pathType" />
</set>
diff --git a/core/res/res/layout-notround-watch/alert_dialog_header_micro.xml b/core/res/res/layout-notround-watch/alert_dialog_title_material.xml
index fc840d9fa73f..307c6db91c3a 100644
--- a/core/res/res/layout-notround-watch/alert_dialog_header_micro.xml
+++ b/core/res/res/layout-notround-watch/alert_dialog_title_material.xml
@@ -30,12 +30,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@null" />
- <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
+ <TextView android:id="@+id/alertTitle"
style="?android:attr/windowTitleStyle"
- android:ellipsize="end"
- android:layout_marginStart="8dp"
android:layout_marginBottom="8dp"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAlignment="viewStart" />
+ android:layout_height="wrap_content" />
</LinearLayout>
diff --git a/core/res/res/layout-round-watch/alert_dialog_header_micro.xml b/core/res/res/layout-round-watch/alert_dialog_title_material.xml
index 6f7ae02388a3..027991106c5a 100644
--- a/core/res/res/layout-round-watch/alert_dialog_header_micro.xml
+++ b/core/res/res/layout-round-watch/alert_dialog_title_material.xml
@@ -27,12 +27,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@null" />
- <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
+ <TextView android:id="@+id/alertTitle"
style="?android:attr/windowTitleStyle"
- android:ellipsize="end"
android:layout_marginTop="36dp"
- android:layout_marginBottom="4dp"
+ android:layout_marginBottom="8dp"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textAlignment="center" />
+ android:layout_height="wrap_content" />
</FrameLayout>
diff --git a/core/res/res/layout-watch/alert_dialog_material.xml b/core/res/res/layout-watch/alert_dialog_material.xml
index ce8e20a12187..002dde83cd93 100644
--- a/core/res/res/layout-watch/alert_dialog_material.xml
+++ b/core/res/res/layout-watch/alert_dialog_material.xml
@@ -39,7 +39,7 @@
<include android:id="@+id/title_template"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- layout="@layout/alert_dialog_header_micro"/>
+ layout="@layout/alert_dialog_title_material"/>
</FrameLayout>
<!-- Content Panel -->
@@ -50,7 +50,8 @@
<TextView android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.Material.Body1"
+ android:gravity="@integer/config_dialogTextGravity"
+ android:textAppearance="@style/TextAppearance.Material.Subhead"
android:paddingStart="?dialogPreferredPadding"
android:paddingEnd="?dialogPreferredPadding"
android:paddingTop="8dip"
@@ -77,6 +78,7 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
android:orientation="vertical"
android:minHeight="@dimen/alert_dialog_button_bar_height"
android:paddingBottom="?dialogPreferredPadding"
diff --git a/core/res/res/values-notround-watch/styles_material.xml b/core/res/res/values-notround-watch/config_material.xml
index cd8521f48421..a99674f3f060 100644
--- a/core/res/res/values-notround-watch/styles_material.xml
+++ b/core/res/res/values-notround-watch/config_material.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
@@ -13,6 +13,13 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<resources>
- <style name="TextAppearance.Material.AlertDialogMessage" parent="TextAppearance.Material.Body1"/>
+
+<!-- These resources are around just to allow their values to be customized
+ for different hardware and product builds, only for Material theme. Do not translate.
+
+ NOTE: The naming convention is "config_camelCaseValue". -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Gravity that should be used for dialog text styles. Equivalent to: Gravity.START | Gravity.TOP -->
+ <integer name="config_dialogTextGravity">0x00800033</integer>
</resources>
diff --git a/core/res/res/values-round-watch/config_material.xml b/core/res/res/values-round-watch/config_material.xml
index bf445ef3fd0e..871e910eb042 100644
--- a/core/res/res/values-round-watch/config_material.xml
+++ b/core/res/res/values-round-watch/config_material.xml
@@ -19,4 +19,7 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Don't clip on round screens so the list can scroll past the rounded edges. -->
<bool name="config_preferenceFragmentClipToPadding">false</bool>
+
+ <!-- Gravity that should be used for dialog text styles. Equivalent to: Gravity.CENTER_HORIZONTAL | Gravity.TOP -->
+ <integer name="config_dialogTextGravity">0x00000031</integer>
</resources>
diff --git a/core/res/res/values-round-watch/styles_material.xml b/core/res/res/values-round-watch/styles_material.xml
deleted file mode 100644
index a2f3c0243189..000000000000
--- a/core/res/res/values-round-watch/styles_material.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<resources>
- <style name="TextAppearance.Material.AlertDialogMessage" parent="TextAppearance.Material.Body1">
- <item name="textAlignment">center</item>
- </style>
-</resources>
diff --git a/core/res/res/values-w180dp-notround-watch/dimens_material.xml b/core/res/res/values-w180dp-notround-watch/dimens_material.xml
new file mode 100644
index 000000000000..79acf84b7e3f
--- /dev/null
+++ b/core/res/res/values-w180dp-notround-watch/dimens_material.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="text_size_display_4_material">80sp</dimen>
+ <dimen name="text_size_display_3_material">50sp</dimen>
+ <dimen name="text_size_display_2_material">40sp</dimen>
+ <dimen name="text_size_display_1_material">30sp</dimen>
+ <dimen name="text_size_headline_material">20sp</dimen>
+ <dimen name="text_size_title_material">18sp</dimen>
+ <dimen name="text_size_subhead_material">18sp</dimen>
+ <dimen name="text_size_title_material_toolbar">18dp</dimen>
+ <dimen name="text_size_subtitle_material_toolbar">18dp</dimen>
+ <dimen name="text_size_menu_material">18sp</dimen>
+ <dimen name="text_size_menu_header_material">16sp</dimen>
+ <dimen name="text_size_body_2_material">16sp</dimen>
+ <dimen name="text_size_body_1_material">16sp</dimen>
+ <dimen name="text_size_caption_material">14sp</dimen>
+ <dimen name="text_size_button_material">16sp</dimen>
+
+ <dimen name="text_size_large_material">18sp</dimen>
+ <dimen name="text_size_medium_material">16sp</dimen>
+ <dimen name="text_size_small_material">14sp</dimen>
+</resources>
diff --git a/core/res/res/values-w210dp-round-watch/dimens_material.xml b/core/res/res/values-w210dp-round-watch/dimens_material.xml
new file mode 100644
index 000000000000..79acf84b7e3f
--- /dev/null
+++ b/core/res/res/values-w210dp-round-watch/dimens_material.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources>
+ <dimen name="text_size_display_4_material">80sp</dimen>
+ <dimen name="text_size_display_3_material">50sp</dimen>
+ <dimen name="text_size_display_2_material">40sp</dimen>
+ <dimen name="text_size_display_1_material">30sp</dimen>
+ <dimen name="text_size_headline_material">20sp</dimen>
+ <dimen name="text_size_title_material">18sp</dimen>
+ <dimen name="text_size_subhead_material">18sp</dimen>
+ <dimen name="text_size_title_material_toolbar">18dp</dimen>
+ <dimen name="text_size_subtitle_material_toolbar">18dp</dimen>
+ <dimen name="text_size_menu_material">18sp</dimen>
+ <dimen name="text_size_menu_header_material">16sp</dimen>
+ <dimen name="text_size_body_2_material">16sp</dimen>
+ <dimen name="text_size_body_1_material">16sp</dimen>
+ <dimen name="text_size_caption_material">14sp</dimen>
+ <dimen name="text_size_button_material">16sp</dimen>
+
+ <dimen name="text_size_large_material">18sp</dimen>
+ <dimen name="text_size_medium_material">16sp</dimen>
+ <dimen name="text_size_small_material">14sp</dimen>
+</resources>
diff --git a/core/res/res/values-watch/config_material.xml b/core/res/res/values-watch/config_material.xml
index 81b53e71b5d7..104d122e01d3 100644
--- a/core/res/res/values-watch/config_material.xml
+++ b/core/res/res/values-watch/config_material.xml
@@ -29,7 +29,4 @@
<!-- Always overscan by default to ensure onApplyWindowInsets will always be called. -->
<bool name="config_windowOverscanByDefault">true</bool>
-
- <!-- Due to the smaller screen size, have dialog titles occupy more than 1 line. -->
- <integer name="config_dialogWindowTitleMaxLines">3</integer>
</resources>
diff --git a/core/res/res/values-watch/dimens_material.xml b/core/res/res/values-watch/dimens_material.xml
index d579434d5e30..96e91a5fb175 100644
--- a/core/res/res/values-watch/dimens_material.xml
+++ b/core/res/res/values-watch/dimens_material.xml
@@ -14,5 +14,25 @@
limitations under the License.
-->
<resources>
+ <dimen name="text_size_display_4_material">71sp</dimen>
+ <dimen name="text_size_display_3_material">44sp</dimen>
+ <dimen name="text_size_display_2_material">36sp</dimen>
+ <dimen name="text_size_display_1_material">27sp</dimen>
+ <dimen name="text_size_headline_material">18sp</dimen>
+ <dimen name="text_size_title_material">16sp</dimen>
+ <dimen name="text_size_subhead_material">16sp</dimen>
+ <dimen name="text_size_title_material_toolbar">16dp</dimen>
+ <dimen name="text_size_subtitle_material_toolbar">16dp</dimen>
+ <dimen name="text_size_menu_material">16sp</dimen>
+ <dimen name="text_size_menu_header_material">14sp</dimen>
+ <dimen name="text_size_body_2_material">14sp</dimen>
+ <dimen name="text_size_body_1_material">14sp</dimen>
+ <dimen name="text_size_caption_material">12sp</dimen>
+ <dimen name="text_size_button_material">14sp</dimen>
+
+ <dimen name="text_size_large_material">16sp</dimen>
+ <dimen name="text_size_medium_material">14sp</dimen>
+ <dimen name="text_size_small_material">12sp</dimen>
+
<item name="text_line_spacing_multiplier_material" format="float" type="dimen">1.2</item>
</resources>
diff --git a/core/res/res/values-watch/styles_material.xml b/core/res/res/values-watch/styles_material.xml
index f5735e69347a..e8d3d743854c 100644
--- a/core/res/res/values-watch/styles_material.xml
+++ b/core/res/res/values-watch/styles_material.xml
@@ -61,6 +61,9 @@ please see styles_device_defaults.xml.
<item name="divider">@empty</item>
</style>
+ <style name="TextAppearance.Material.ListItem" parent="TextAppearance.Material.Body1" />
+ <style name="TextAppearance.Material.ListItemSecondary" parent="TextAppearance.Material.Caption" />
+
<style name="Widget.Material.TextView" parent="Widget.TextView">
<item name="breakStrategy">balanced</item>
</style>
@@ -89,6 +92,14 @@ please see styles_device_defaults.xml.
<item name="descendantFocusability">blocksDescendants</item>
</style>
+ <style name="DialogWindowTitle.Material">
+ <item name="maxLines">3</item>
+ <item name="scrollHorizontally">false</item>
+ <item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item>
+ <item name="gravity">@integer/config_dialogTextGravity</item>
+ <item name="ellipsize">end</item>
+ </style>
+
<!-- DO NOTE TRANSLATE Spans within this text are applied to style composing regions
within an EditText widget. The text content is ignored and not used.
Note: This is @color/material_deep_teal_200, cannot use @color references here. -->
diff --git a/core/res/res/values/config_material.xml b/core/res/res/values/config_material.xml
index a37be837d9f1..397635f402b1 100644
--- a/core/res/res/values/config_material.xml
+++ b/core/res/res/values/config_material.xml
@@ -32,9 +32,6 @@
<!-- True if windowOverscan should be on by default. -->
<bool name="config_windowOverscanByDefault">false</bool>
- <!-- Max number of lines for the dialog title. -->
- <integer name="config_dialogWindowTitleMaxLines">1</integer>
-
<!-- True if preference fragment should clip to padding. -->
<bool name="config_preferenceFragmentClipToPadding">true</bool>
</resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 443553754193..c66bc10bb708 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -475,6 +475,9 @@ please see styles_device_defaults.xml.
<item name="textColor">#66000000</item>
</style>
+ <style name="TextAppearance.Material.ListItem" parent="TextAppearance.Material.Subhead" />
+ <style name="TextAppearance.Material.ListItemSecondary" parent="TextAppearance.Material.Body1" />
+
<style name="Widget.Material.Notification.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
<style name="Widget.Material.Notification.MessagingText" parent="Widget.Material.Light.TextView">
@@ -1246,7 +1249,7 @@ please see styles_device_defaults.xml.
<style name="DialogWindowTitleBackground.Material.Light" />
<style name="DialogWindowTitle.Material">
- <item name="maxLines">@integer/config_dialogWindowTitleMaxLines</item>
+ <item name="maxLines">1</item>
<item name="scrollHorizontally">true</item>
<item name="textAppearance">@style/TextAppearance.Material.DialogWindowTitle</item>
</style>
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 7e2867de1d7a..0eb4c8d86928 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -114,9 +114,9 @@ please see themes_device_defaults.xml.
<item name="listPreferredItemHeightSmall">48dip</item>
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
- <item name="textAppearanceListItem">@style/TextAppearance.Material.Subhead</item>
- <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.Subhead</item>
- <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.Body1</item>
+ <item name="textAppearanceListItem">@style/TextAppearance.Material.ListItem</item>
+ <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.ListItem</item>
+ <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.ListItemSecondary</item>
<item name="listPreferredItemPaddingLeft">@dimen/list_item_padding_horizontal_material</item>
<item name="listPreferredItemPaddingRight">@dimen/list_item_padding_horizontal_material</item>
<item name="listPreferredItemPaddingStart">@dimen/list_item_padding_start_material</item>
@@ -475,9 +475,9 @@ please see themes_device_defaults.xml.
<item name="listPreferredItemHeightSmall">48dip</item>
<item name="listPreferredItemHeightLarge">80dip</item>
<item name="dropdownListPreferredItemHeight">?attr/listPreferredItemHeightSmall</item>
- <item name="textAppearanceListItem">@style/TextAppearance.Material.Subhead</item>
- <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.Subhead</item>
- <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.Body1</item>
+ <item name="textAppearanceListItem">@style/TextAppearance.Material.ListItem</item>
+ <item name="textAppearanceListItemSmall">@style/TextAppearance.Material.ListItem</item>
+ <item name="textAppearanceListItemSecondary">@style/TextAppearance.Material.ListItemSecondary</item>
<item name="listPreferredItemPaddingLeft">@dimen/list_item_padding_horizontal_material</item>
<item name="listPreferredItemPaddingRight">@dimen/list_item_padding_horizontal_material</item>
<item name="listPreferredItemPaddingStart">@dimen/list_item_padding_start_material</item>
diff --git a/core/res/res/xml-watch/default_zen_mode_config.xml b/core/res/res/xml-watch/default_zen_mode_config.xml
index 26af10c1809e..938cc0c3f7c0 100644
--- a/core/res/res/xml-watch/default_zen_mode_config.xml
+++ b/core/res/res/xml-watch/default_zen_mode_config.xml
@@ -17,8 +17,8 @@
<!-- Default configuration for zen mode. See android.service.notification.ZenModeConfig. -->
<zen version="2">
- <!-- Allow starred contacts to go through only. Repeated calls on.
- Calls, messages, reminders, events off.-->
- <allow from="2" repeatCallers="true" calls="false" messages="false" reminders="false"
+ <!-- Allow starred contacts to go through only.
+ Repeated calls, calls, messages, reminders, events off. -->
+ <allow from="2" repeatCallers="false" calls="false" messages="false" reminders="false"
events="false"/>
</zen>
diff --git a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
index 20173b0dc3bf..24cbfbd6430e 100644
--- a/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
+++ b/packages/CaptivePortalLogin/res/values-bn-rBD/strings.xml
@@ -4,7 +4,7 @@
<string name="app_name" msgid="5934709770924185752">"CaptivePortalLogin"</string>
<string name="action_use_network" msgid="6076184727448466030">"যেভাবে আছে সেভাবেই এই নেটওয়ার্ক ব্যবহার করুন"</string>
<string name="action_do_not_use_network" msgid="4577366536956516683">"এই নেটওয়ার্ক ব্যবহার করবেন না"</string>
- <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে প্রবেশ করুন করুন"</string>
+ <string name="action_bar_label" msgid="917235635415966620">"নেটওয়ার্কে প্রবেশ করুন"</string>
<string name="ssl_error_warning" msgid="6653188881418638872">"আপনি যে নেটওয়ার্কে যোগ দেওয়ার চেষ্টা করছেন তাতে নিরাপত্তার সমস্যা আছে।"</string>
<string name="ssl_error_example" msgid="647898534624078900">"উদাহরণস্বরূপ, লগইন পৃষ্ঠাটি প্রদর্শিত প্রতিষ্ঠানের অন্তর্গত নাও হতে পারে৷"</string>
<string name="ssl_error_continue" msgid="6492718244923937110">"যাই হোক না কেন ব্রাউজারের মাধ্যমে অবিরত রাখুন"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 99850a5d5cd4..fb7180a0a3b8 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -111,7 +111,7 @@
<string name="tts_play_example_summary" msgid="8029071615047894486">"Reprodueix una breu demostració de síntesi de veu"</string>
<string name="tts_install_data_title" msgid="4264378440508149986">"Instal·la dades de veu"</string>
<string name="tts_install_data_summary" msgid="5742135732511822589">"Instal·la les dades de veu necessàries per a la síntesi de veu"</string>
- <string name="tts_engine_security_warning" msgid="8786238102020223650">"Pot ser que aquest motor de síntesi de la parla pugui recopilar tot el text que es dirà en veu alta, incloses les dades personals, com ara les contrasenyes i els números de les targetes de crèdit. Ve del motor <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Vols activar l\'ús d\'aquest motor de síntesi de la parla?"</string>
+ <string name="tts_engine_security_warning" msgid="8786238102020223650">"Pot ser que aquest motor de síntesi de la parla pugui recopilar tot el text que es dirà en veu alta, incloses les dades personals, com ara les contrasenyes i els números de les targetes de crèdit. Ve del motor <xliff:g id="TTS_PLUGIN_ENGINE_NAME">%s</xliff:g>. Voleu activar l\'ús d\'aquest motor de síntesi de la parla?"</string>
<string name="tts_engine_network_required" msgid="1190837151485314743">"Aquest idioma requereix una connexió de xarxa activa per a la sortida de síntesi de veu."</string>
<string name="tts_default_sample_string" msgid="4040835213373086322">"Això és un exemple de síntesi de veu"</string>
<string name="tts_status_title" msgid="7268566550242584413">"Estat de l\'idioma predeterminat"</string>
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index ee2fa51c8666..a3d2ebbba9c3 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -699,7 +699,7 @@ public final class ActiveServices {
throw new IllegalArgumentException("null notification");
}
if (r.foregroundId != id) {
- r.cancelNotification();
+ cancelForegroudNotificationLocked(r);
r.foregroundId = id;
}
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -721,7 +721,7 @@ public final class ActiveServices {
}
}
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
- r.cancelNotification();
+ cancelForegroudNotificationLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
@@ -738,6 +738,27 @@ public final class ActiveServices {
}
}
+ private void cancelForegroudNotificationLocked(ServiceRecord r) {
+ if (r.foregroundId != 0) {
+ // First check to see if this app has any other active foreground services
+ // with the same notification ID. If so, we shouldn't actually cancel it,
+ // because that would wipe away the notification that still needs to be shown
+ // due the other service.
+ ServiceMap sm = getServiceMap(r.userId);
+ if (sm != null) {
+ for (int i = sm.mServicesByName.size()-1; i >= 0; i--) {
+ ServiceRecord other = sm.mServicesByName.valueAt(i);
+ if (other.foregroundId == r.foregroundId
+ && other.packageName.equals(r.packageName)) {
+ // Found one! Abort the cancel.
+ return;
+ }
+ }
+ }
+ r.cancelNotification();
+ }
+ }
+
private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
boolean anyForeground = false;
for (int i=proc.services.size()-1; i>=0; i--) {
@@ -1560,7 +1581,7 @@ public final class ActiveServices {
r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
}
- r.cancelNotification();
+ cancelForegroudNotificationLocked(r);
mAm.mHandler.removeCallbacks(r.restarter);
mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
@@ -2022,7 +2043,7 @@ public final class ActiveServices {
}
}
- r.cancelNotification();
+ cancelForegroudNotificationLocked(r);
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 2bfc4021f887..71c7fd348fb3 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -543,27 +543,25 @@ final class ServiceRecord extends Binder {
}
public void cancelNotification() {
- if (foregroundId != 0) {
- // Do asynchronous communication with notification manager to
- // avoid deadlocks.
- final String localPackageName = packageName;
- final int localForegroundId = foregroundId;
- ams.mHandler.post(new Runnable() {
- public void run() {
- INotificationManager inm = NotificationManager.getService();
- if (inm == null) {
- return;
- }
- try {
- inm.cancelNotificationWithTag(localPackageName, null,
- localForegroundId, userId);
- } catch (RuntimeException e) {
- Slog.w(TAG, "Error canceling notification for service", e);
- } catch (RemoteException e) {
- }
+ // Do asynchronous communication with notification manager to
+ // avoid deadlocks.
+ final String localPackageName = packageName;
+ final int localForegroundId = foregroundId;
+ ams.mHandler.post(new Runnable() {
+ public void run() {
+ INotificationManager inm = NotificationManager.getService();
+ if (inm == null) {
+ return;
}
- });
- }
+ try {
+ inm.cancelNotificationWithTag(localPackageName, null,
+ localForegroundId, userId);
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Error canceling notification for service", e);
+ } catch (RemoteException e) {
+ }
+ }
+ });
}
public void stripForegroundServiceFlagFromNotification() {
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index cd5bcd41515d..53e328c7ee5f 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -768,41 +768,46 @@ public class LauncherAppsService extends SystemService {
private void onShortcutChangedInner(@NonNull String packageName,
@UserIdInt int userId) {
- final UserHandle user = UserHandle.of(userId);
-
- final int n = mListeners.beginBroadcast();
- for (int i = 0; i < n; i++) {
- IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
- BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
- if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue;
-
- final int launcherUserId = cookie.user.getIdentifier();
-
- // Make sure the caller has the permission.
- if (!mShortcutServiceInternal.hasShortcutHostPermission(
- launcherUserId, cookie.packageName)) {
- continue;
- }
- // Each launcher has a different set of pinned shortcuts, so we need to do a
- // query in here.
- // (As of now, only one launcher has the permission at a time, so it's bit
- // moot, but we may change the permission model eventually.)
- final List<ShortcutInfo> list =
- mShortcutServiceInternal.getShortcuts(launcherUserId,
- cookie.packageName,
- /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
- /* component= */ null,
- ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
- | ShortcutQuery.FLAG_GET_ALL_KINDS
- , userId);
- try {
- listener.onShortcutChanged(user, packageName,
- new ParceledListSlice<>(list));
- } catch (RemoteException re) {
- Slog.d(TAG, "Callback failed ", re);
+ try {
+ final UserHandle user = UserHandle.of(userId);
+
+ final int n = mListeners.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ IOnAppsChangedListener listener = mListeners.getBroadcastItem(i);
+ BroadcastCookie cookie = (BroadcastCookie) mListeners.getBroadcastCookie(i);
+ if (!isEnabledProfileOf(user, cookie.user, "onShortcutChanged")) continue;
+
+ final int launcherUserId = cookie.user.getIdentifier();
+
+ // Make sure the caller has the permission.
+ if (!mShortcutServiceInternal.hasShortcutHostPermission(
+ launcherUserId, cookie.packageName)) {
+ continue;
+ }
+ // Each launcher has a different set of pinned shortcuts, so we need to do a
+ // query in here.
+ // (As of now, only one launcher has the permission at a time, so it's bit
+ // moot, but we may change the permission model eventually.)
+ final List<ShortcutInfo> list =
+ mShortcutServiceInternal.getShortcuts(launcherUserId,
+ cookie.packageName,
+ /* changedSince= */ 0, packageName, /* shortcutIds=*/ null,
+ /* component= */ null,
+ ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY
+ | ShortcutQuery.FLAG_GET_ALL_KINDS
+ , userId);
+ try {
+ listener.onShortcutChanged(user, packageName,
+ new ParceledListSlice<>(list));
+ } catch (RemoteException re) {
+ Slog.d(TAG, "Callback failed ", re);
+ }
}
+ mListeners.finishBroadcast();
+ } catch (RuntimeException e) {
+ // When the user is locked we get IllegalState, so just catch all.
+ Log.w(TAG, e.getMessage(), e);
}
- mListeners.finishBroadcast();
}
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index d875f1e97cac..8d400b5ed38b 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -77,6 +77,7 @@ import android.util.KeyValueListParser;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseLongArray;
import android.util.TypedValue;
@@ -85,7 +86,6 @@ import android.view.IWindowManager;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.content.PackageMonitor;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
@@ -301,6 +301,9 @@ public class ShortcutService extends IShortcutService.Stub {
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE
| PackageManager.MATCH_UNINSTALLED_PACKAGES;
+ @GuardedBy("mLock")
+ final SparseBooleanArray mUnlockedUsers = new SparseBooleanArray();
+
// Stats
@VisibleForTesting
interface Stats {
@@ -522,6 +525,8 @@ public class ShortcutService extends IShortcutService.Stub {
Slog.d(TAG, "handleUnlockUser: user=" + userId);
}
synchronized (mLock) {
+ mUnlockedUsers.put(userId, true);
+
// Preload the user's shortcuts.
// Also see if the locale has changed.
// Note as of nyc, the locale is per-user, so the locale shouldn't change
@@ -534,8 +539,13 @@ public class ShortcutService extends IShortcutService.Stub {
/** lifecycle event */
void handleCleanupUser(int userId) {
+ if (DEBUG) {
+ Slog.d(TAG, "handleCleanupUser: user=" + userId);
+ }
synchronized (mLock) {
unloadUserLocked(userId);
+
+ mUnlockedUsers.put(userId, false);
}
}
@@ -978,16 +988,20 @@ public class ShortcutService extends IShortcutService.Stub {
if (DEBUG) {
Slog.d(TAG, "saveDirtyInfo");
}
- synchronized (mLock) {
- for (int i = mDirtyUserIds.size() - 1; i >= 0; i--) {
- final int userId = mDirtyUserIds.get(i);
- if (userId == UserHandle.USER_NULL) { // USER_NULL for base state.
- saveBaseStateLocked();
- } else {
- saveUserLocked(userId);
+ try {
+ synchronized (mLock) {
+ for (int i = mDirtyUserIds.size() - 1; i >= 0; i--) {
+ final int userId = mDirtyUserIds.get(i);
+ if (userId == UserHandle.USER_NULL) { // USER_NULL for base state.
+ saveBaseStateLocked();
+ } else {
+ saveUserLocked(userId);
+ }
}
+ mDirtyUserIds.clear();
}
- mDirtyUserIds.clear();
+ } catch (Exception e) {
+ wtf("Exception in saveDirtyInfo", e);
}
}
@@ -1037,20 +1051,14 @@ public class ShortcutService extends IShortcutService.Stub {
}
}
- private boolean isUserUnlocked(@UserIdInt int userId) {
- final long token = injectClearCallingIdentity();
- try {
- // Weird: when SystemService.onUnlockUser() is called, the user state is still
- // unlocking, as opposed to unlocked. So we need to accept the "unlocking" state too.
- // We know when the user is unlocking, the CE storage is already unlocked.
- return mUserManager.isUserUnlockingOrUnlocked(userId);
- } finally {
- injectRestoreCallingIdentity(token);
- }
+ // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L".
+ protected boolean isUserUnlockedL(@UserIdInt int userId) {
+ return mUnlockedUsers.get(userId);
}
- void throwIfUserLocked(@UserIdInt int userId) {
- if (!isUserUnlocked(userId)) {
+ // Requires mLock held, but "Locked" prefix would look weired so we jsut say "L".
+ void throwIfUserLockedL(@UserIdInt int userId) {
+ if (!isUserUnlockedL(userId)) {
throw new IllegalStateException("User " + userId + " is locked or not running");
}
}
@@ -1065,9 +1073,8 @@ public class ShortcutService extends IShortcutService.Stub {
@GuardedBy("mLock")
@NonNull
ShortcutUser getUserShortcutsLocked(@UserIdInt int userId) {
- if (!isUserUnlocked(userId)) {
+ if (!isUserUnlockedL(userId)) {
wtf("User still locked");
- return new ShortcutUser(this, userId);
}
ShortcutUser userPackages = mUsers.get(userId);
@@ -1471,22 +1478,21 @@ public class ShortcutService extends IShortcutService.Stub {
}
private void notifyListeners(@NonNull String packageName, @UserIdInt int userId) {
- final long token = injectClearCallingIdentity();
- try {
- if (!mUserManager.isUserRunning(userId)) {
- return;
- }
- } finally {
- injectRestoreCallingIdentity(token);
- }
injectPostToHandler(() -> {
- final ArrayList<ShortcutChangeListener> copy;
- synchronized (mLock) {
- copy = new ArrayList<>(mListeners);
- }
- // Note onShortcutChanged() needs to be called with the system service permissions.
- for (int i = copy.size() - 1; i >= 0; i--) {
- copy.get(i).onShortcutChanged(packageName, userId);
+ try {
+ final ArrayList<ShortcutChangeListener> copy;
+ synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ return;
+ }
+
+ copy = new ArrayList<>(mListeners);
+ }
+ // Note onShortcutChanged() needs to be called with the system service permissions.
+ for (int i = copy.size() - 1; i >= 0; i--) {
+ copy.get(i).onShortcutChanged(packageName, userId);
+ }
+ } catch (Exception ignore) {
}
});
}
@@ -1558,12 +1564,13 @@ public class ShortcutService extends IShortcutService.Stub {
public boolean setDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
final int size = newShortcuts.size();
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1609,12 +1616,13 @@ public class ShortcutService extends IShortcutService.Stub {
public boolean updateShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
final int size = newShortcuts.size();
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1689,12 +1697,13 @@ public class ShortcutService extends IShortcutService.Stub {
public boolean addDynamicShortcuts(String packageName, ParceledListSlice shortcutInfoList,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList();
final int size = newShortcuts.size();
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1741,9 +1750,10 @@ public class ShortcutService extends IShortcutService.Stub {
CharSequence disabledMessage, int disabledMessageResId, @UserIdInt int userId) {
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1770,9 +1780,10 @@ public class ShortcutService extends IShortcutService.Stub {
public void enableShortcuts(String packageName, List shortcutIds, @UserIdInt int userId) {
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1792,9 +1803,10 @@ public class ShortcutService extends IShortcutService.Stub {
@UserIdInt int userId) {
verifyCaller(packageName, userId);
Preconditions.checkNotNull(shortcutIds, "shortcutIds must be provided");
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1816,9 +1828,10 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public void removeAllDynamicShortcuts(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
ps.deleteAllDynamicShortcuts();
@@ -1832,9 +1845,10 @@ public class ShortcutService extends IShortcutService.Stub {
public ParceledListSlice<ShortcutInfo> getDynamicShortcuts(String packageName,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
ShortcutInfo::isDynamic);
@@ -1845,9 +1859,10 @@ public class ShortcutService extends IShortcutService.Stub {
public ParceledListSlice<ShortcutInfo> getManifestShortcuts(String packageName,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
ShortcutInfo::isManifestShortcut);
@@ -1858,9 +1873,10 @@ public class ShortcutService extends IShortcutService.Stub {
public ParceledListSlice<ShortcutInfo> getPinnedShortcuts(String packageName,
@UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getShortcutsWithQueryLocked(
packageName, userId, ShortcutInfo.CLONE_REMOVE_FOR_CREATOR,
ShortcutInfo::isPinned);
@@ -1890,9 +1906,10 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public int getRemainingCallCount(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
return mMaxUpdatesPerInterval - ps.getApiCallCount();
@@ -1902,9 +1919,10 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public long getRateLimitResetTime(String packageName, @UserIdInt int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
return getNextResetTimeLocked();
}
}
@@ -1921,7 +1939,6 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public void reportShortcutUsed(String packageName, String shortcutId, int userId) {
verifyCaller(packageName, userId);
- throwIfUserLocked(userId);
Preconditions.checkNotNull(shortcutId);
@@ -1931,6 +1948,8 @@ public class ShortcutService extends IShortcutService.Stub {
}
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutPackage ps = getPackageShortcutsLocked(packageName, userId);
ps.getUser().onCalledByPublisher(packageName);
@@ -1962,6 +1981,11 @@ public class ShortcutService extends IShortcutService.Stub {
void resetThrottlingInner(@UserIdInt int userId) {
synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ Log.w(TAG, "User " + userId + " is locked or not running");
+ return;
+ }
+
getUserShortcutsLocked(userId).resetThrottling();
}
scheduleSaveUser(userId);
@@ -1976,25 +2000,23 @@ public class ShortcutService extends IShortcutService.Stub {
Slog.i(TAG, "ShortcutManager: throttling counter reset for all users");
}
- void resetPackageThrottling(String packageName, int userId) {
- synchronized (mLock) {
- getPackageShortcutsLocked(packageName, userId)
- .resetRateLimitingForCommandLineNoSaving();
- saveUserLocked(userId);
- }
- }
-
@Override
public void onApplicationActive(String packageName, int userId) {
if (DEBUG) {
Slog.d(TAG, "onApplicationActive: package=" + packageName + " userid=" + userId);
}
enforceResetThrottlingPermission();
- if (!isUserUnlocked(userId)) {
- // This is called by system UI, so no need to throw. Just ignore.
- return;
+
+ synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ // This is called by system UI, so no need to throw. Just ignore.
+ return;
+ }
+
+ getPackageShortcutsLocked(packageName, userId)
+ .resetRateLimitingForCommandLineNoSaving();
+ saveUserLocked(userId);
}
- resetPackageThrottling(packageName, userId);
}
// We override this method in unit tests to do a simpler check.
@@ -2011,9 +2033,9 @@ public class ShortcutService extends IShortcutService.Stub {
// even when hasShortcutPermission() is overridden.
@VisibleForTesting
boolean hasShortcutHostPermissionInner(@NonNull String callingPackage, int userId) {
- throwIfUserLocked(userId);
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+
final ShortcutUser user = getUserShortcutsLocked(userId);
// Always trust the in-memory cache.
@@ -2170,9 +2192,6 @@ public class ShortcutService extends IShortcutService.Stub {
@Nullable ComponentName componentName,
int queryFlags, int userId) {
final ArrayList<ShortcutInfo> ret = new ArrayList<>();
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return ret;
- }
final boolean cloneKeyFieldOnly =
((queryFlags & ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY) != 0);
@@ -2183,6 +2202,9 @@ public class ShortcutService extends IShortcutService.Stub {
}
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2251,11 +2273,10 @@ public class ShortcutService extends IShortcutService.Stub {
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return false;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2271,9 +2292,8 @@ public class ShortcutService extends IShortcutService.Stub {
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return null;
- }
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
final ShortcutPackage p = getUserShortcutsLocked(userId)
.getPackageShortcutsIfExists(packageName);
@@ -2296,11 +2316,10 @@ public class ShortcutService extends IShortcutService.Stub {
Preconditions.checkStringNotEmpty(packageName, "packageName");
Preconditions.checkNotNull(shortcutIds, "shortcutIds");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
final ShortcutLauncher launcher =
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId);
launcher.attemptToRestoreIfNeededAndSave();
@@ -2320,11 +2339,10 @@ public class ShortcutService extends IShortcutService.Stub {
Preconditions.checkStringNotEmpty(packageName, "packageName can't be empty");
Preconditions.checkStringNotEmpty(shortcutId, "shortcutId can't be empty");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return null;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2354,11 +2372,10 @@ public class ShortcutService extends IShortcutService.Stub {
Preconditions.checkNotNull(packageName, "packageName");
Preconditions.checkNotNull(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return 0;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2382,11 +2399,10 @@ public class ShortcutService extends IShortcutService.Stub {
Preconditions.checkNotNull(packageName, "packageName");
Preconditions.checkNotNull(shortcutId, "shortcutId");
- if (!isUserUnlocked(userId) || !isUserUnlocked(launcherUserId)) {
- return null;
- }
-
synchronized (mLock) {
+ throwIfUserLockedL(userId);
+ throwIfUserLockedL(launcherUserId);
+
getLauncherShortcutsLocked(callingPackage, userId, launcherUserId)
.attemptToRestoreIfNeededAndSave();
@@ -2418,9 +2434,6 @@ public class ShortcutService extends IShortcutService.Stub {
@Override
public boolean hasShortcutHostPermission(int launcherUserId,
@NonNull String callingPackage) {
- if (!isUserUnlocked(launcherUserId)) {
- return false;
- }
return ShortcutService.this.hasShortcutHostPermission(callingPackage, launcherUserId);
}
}
@@ -2431,8 +2444,12 @@ public class ShortcutService extends IShortcutService.Stub {
if (!mBootCompleted.get()) {
return; // Boot not completed, ignore the broadcast.
}
- if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
- handleLocaleChanged();
+ try {
+ if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) {
+ handleLocaleChanged();
+ }
+ } catch (Exception e) {
+ wtf("Exception in mReceiver.onReceive", e);
}
}
};
@@ -2443,11 +2460,13 @@ public class ShortcutService extends IShortcutService.Stub {
}
scheduleSaveBaseState();
- final long token = injectClearCallingIdentity();
- try {
- forEachLoadedUserLocked(user -> user.detectLocaleChange());
- } finally {
- injectRestoreCallingIdentity(token);
+ synchronized (mLock) {
+ final long token = injectClearCallingIdentity();
+ try {
+ forEachLoadedUserLocked(user -> user.detectLocaleChange());
+ } finally {
+ injectRestoreCallingIdentity(token);
+ }
}
}
@@ -2470,18 +2489,17 @@ public class ShortcutService extends IShortcutService.Stub {
// but we still check it in unit tests.
final long token = injectClearCallingIdentity();
try {
-
- if (!isUserUnlocked(userId)) {
- if (DEBUG) {
- Slog.d(TAG, "Ignoring package broadcast " + action
- + " for locked/stopped user " + userId);
+ synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Ignoring package broadcast " + action
+ + " for locked/stopped user " + userId);
+ }
+ return;
}
- return;
- }
- // Whenever we get one of those package broadcasts, or get
- // ACTION_PREFERRED_ACTIVITY_CHANGED, we purge the default launcher cache.
- synchronized (mLock) {
+ // Whenever we get one of those package broadcasts, or get
+ // ACTION_PREFERRED_ACTIVITY_CHANGED, we purge the default launcher cache.
final ShortcutUser user = getUserShortcutsLocked(userId);
user.clearLauncher();
}
@@ -2521,6 +2539,8 @@ public class ShortcutService extends IShortcutService.Stub {
handlePackageDataCleared(packageName, userId);
break;
}
+ } catch (Exception e) {
+ wtf("Exception in mPackageMonitor.onReceive", e);
} finally {
injectRestoreCallingIdentity(token);
}
@@ -3031,9 +3051,14 @@ public class ShortcutService extends IShortcutService.Stub {
Slog.d(TAG, "Backing up user " + userId);
}
synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ wtf("Can't backup: user " + userId + " is locked or not running");
+ return null;
+ }
+
final ShortcutUser user = getUserShortcutsLocked(userId);
if (user == null) {
- Slog.w(TAG, "Can't backup: user not found: id=" + userId);
+ wtf("Can't backup: user not found: id=" + userId);
return null;
}
@@ -3058,15 +3083,19 @@ public class ShortcutService extends IShortcutService.Stub {
if (DEBUG) {
Slog.d(TAG, "Restoring user " + userId);
}
- final ShortcutUser user;
- final ByteArrayInputStream is = new ByteArrayInputStream(payload);
- try {
- user = loadUserInternal(userId, is, /* fromBackup */ true);
- } catch (XmlPullParserException | IOException e) {
- Slog.w(TAG, "Restoration failed.", e);
- return;
- }
synchronized (mLock) {
+ if (!isUserUnlockedL(userId)) {
+ wtf("Can't restore: user " + userId + " is locked or not running");
+ return;
+ }
+ final ShortcutUser user;
+ final ByteArrayInputStream is = new ByteArrayInputStream(payload);
+ try {
+ user = loadUserInternal(userId, is, /* fromBackup */ true);
+ } catch (XmlPullParserException | IOException e) {
+ Slog.w(TAG, "Restoration failed.", e);
+ return;
+ }
mUsers.put(userId, user);
// Then purge all the save images.
@@ -3276,7 +3305,7 @@ public class ShortcutService extends IShortcutService.Stub {
private int mUserId = UserHandle.USER_SYSTEM;
- private void parseOptions(boolean takeUser)
+ private void parseOptionsLocked(boolean takeUser)
throws CommandException {
String opt;
while ((opt = getNextOption()) != null) {
@@ -3284,7 +3313,7 @@ public class ShortcutService extends IShortcutService.Stub {
case "--user":
if (takeUser) {
mUserId = UserHandle.parseUserArg(getNextArgRequired());
- if (!isUserUnlocked(mUserId)) {
+ if (!isUserUnlockedL(mUserId)) {
throw new CommandException(
"User " + mUserId + " is not running or locked");
}
@@ -3376,11 +3405,13 @@ public class ShortcutService extends IShortcutService.Stub {
}
private void handleResetThrottling() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- Slog.i(TAG, "cmd: handleResetThrottling: user=" + mUserId);
+ Slog.i(TAG, "cmd: handleResetThrottling: user=" + mUserId);
- resetThrottlingInner(mUserId);
+ resetThrottlingInner(mUserId);
+ }
}
private void handleResetAllThrottling() {
@@ -3426,34 +3457,42 @@ public class ShortcutService extends IShortcutService.Stub {
}
private void handleClearDefaultLauncher() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- clearLauncher();
+ clearLauncher();
+ }
}
private void handleGetDefaultLauncher() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- clearLauncher();
- showLauncher();
+ clearLauncher();
+ showLauncher();
+ }
}
private void handleUnloadUser() throws CommandException {
- parseOptions(/* takeUser =*/ true);
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
- Slog.i(TAG, "cmd: handleUnloadUser: user=" + mUserId);
+ Slog.i(TAG, "cmd: handleUnloadUser: user=" + mUserId);
- ShortcutService.this.handleCleanupUser(mUserId);
+ ShortcutService.this.handleCleanupUser(mUserId);
+ }
}
private void handleClearShortcuts() throws CommandException {
- parseOptions(/* takeUser =*/ true);
- final String packageName = getNextArgRequired();
+ synchronized (mLock) {
+ parseOptionsLocked(/* takeUser =*/ true);
+ final String packageName = getNextArgRequired();
- Slog.i(TAG, "cmd: handleClearShortcuts: user" + mUserId + ", " + packageName);
+ Slog.i(TAG, "cmd: handleClearShortcuts: user" + mUserId + ", " + packageName);
- ShortcutService.this.cleanUpPackageForAllLoadedUsers(packageName, mUserId,
- /* appStillExists = */ true);
+ ShortcutService.this.cleanUpPackageForAllLoadedUsers(packageName, mUserId,
+ /* appStillExists = */ true);
+ }
}
private void handleVerifyStates() throws CommandException {
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index 0515a9a10245..d003e5647c03 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -246,6 +246,20 @@ public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
}
@Override
+ protected boolean isUserUnlockedL(@UserIdInt int userId) {
+ // Note due to a late change, now ShortcutManager doesn't use
+ // UserManager.isUserUnlockingOrUnlocked(). But all unit tests are still using it,
+ // so we convert here.
+
+ final long token = injectClearCallingIdentity();
+ try {
+ return mMockUserManager.isUserUnlockingOrUnlocked(userId);
+ } finally {
+ injectRestoreCallingIdentity(token);
+ }
+ }
+
+ @Override
int injectDipToPixel(int dip) {
return dip;
}