diff options
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; } |