diff options
77 files changed, 2787 insertions, 2069 deletions
diff --git a/PERFORMANCE_OWNERS b/PERFORMANCE_OWNERS index 48a020130445..02b0a1ec75e7 100644 --- a/PERFORMANCE_OWNERS +++ b/PERFORMANCE_OWNERS @@ -6,3 +6,4 @@ philipcuadra@google.com shayba@google.com jdduke@google.com shombert@google.com +kevinjeon@google.com diff --git a/ZYGOTE_OWNERS b/ZYGOTE_OWNERS index f6d15e03a892..6918c16840dd 100644 --- a/ZYGOTE_OWNERS +++ b/ZYGOTE_OWNERS @@ -1,4 +1,4 @@ chriswailes@google.com +hboehm@google.com maco@google.com -narayan@google.com ngeoffray@google.com diff --git a/config/preloaded-classes-denylist b/config/preloaded-classes-denylist index dd2569a240d0..a413bbd68f60 100644 --- a/config/preloaded-classes-denylist +++ b/config/preloaded-classes-denylist @@ -1,23 +1,13 @@ android.content.AsyncTaskLoader$LoadTask -android.media.MediaCodecInfo$CodecCapabilities$FeatureList -android.media.MediaCodecInfo$LazyHolder android.net.ConnectivityThread$Singleton -android.net.rtp.AudioGroup -android.net.rtp.AudioStream -android.net.rtp.RtpStream android.os.FileObserver android.os.NullVibrator -android.permission.PermissionManager -android.provider.MediaStore android.speech.tts.TextToSpeech$Connection$SetupConnectionAsyncTask -android.view.HdrRenderState -android.text.TextFlags android.widget.Magnifier -com.android.internal.jank.InteractionJankMonitor$InstanceHolder -com.android.internal.os.BinderCallsStats$SettingsObserver -com.android.internal.util.LatencyTracker$SLatencyTrackerHolder -com.android.server.BootReceiver$2 gov.nist.core.net.DefaultNetworkLayer -java.util.ImmutableCollections +android.net.rtp.AudioGroup +android.net.rtp.AudioStream +android.net.rtp.RtpStream java.util.concurrent.ThreadLocalRandom -sun.nio.fs.UnixChannelFactory +java.util.ImmutableCollections +com.android.internal.jank.InteractionJankMonitor$InstanceHolder diff --git a/core/java/android/app/DisabledWallpaperManager.java b/core/java/android/app/DisabledWallpaperManager.java index 4a5836cef76d..b06fb9e2f284 100644 --- a/core/java/android/app/DisabledWallpaperManager.java +++ b/core/java/android/app/DisabledWallpaperManager.java @@ -15,11 +15,16 @@ */ package android.app; +import android.annotation.FloatRange; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.compat.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Point; import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; @@ -27,9 +32,12 @@ import android.os.Handler; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.util.Log; +import android.util.SparseArray; import java.io.IOException; import java.io.InputStream; +import java.util.List; +import java.util.Map; /** * A no-op implementation of {@link WallpaperManager}. @@ -54,29 +62,19 @@ final class DisabledWallpaperManager extends WallpaperManager { private DisabledWallpaperManager() { } - @Override - public boolean isWallpaperSupported() { - return false; + @UnsupportedAppUsage + public IWallpaperManager getIWallpaperManager() { + return unsupported(); } @Override - public boolean isSetWallpaperAllowed() { - return false; - } - - private static <T> T unsupported() { - if (DEBUG) Log.w(TAG, "unsupported method called; returning null", new Exception()); - return null; - } - - private static boolean unsupportedBoolean() { - if (DEBUG) Log.w(TAG, "unsupported method called; returning false", new Exception()); - return false; + public boolean isLockscreenLiveWallpaperEnabled() { + return unsupportedBoolean(); } - private static int unsupportedInt() { - if (DEBUG) Log.w(TAG, "unsupported method called; returning -1", new Exception()); - return -1; + @Override + public boolean shouldEnableWideColorGamut() { + return unsupportedBoolean(); } @Override @@ -122,6 +120,11 @@ final class DisabledWallpaperManager extends WallpaperManager { } @Override + public boolean wallpaperSupportsWcg(int which) { + return unsupportedBoolean(); + } + + @Override public Bitmap getBitmap() { return unsupported(); } @@ -131,12 +134,61 @@ final class DisabledWallpaperManager extends WallpaperManager { return unsupported(); } + @Nullable + public Bitmap getBitmap(boolean hardware, @SetWallpaperFlags int which) { + return unsupported(); + } + @Override public Bitmap getBitmapAsUser(int userId, boolean hardware) { return unsupported(); } @Override + public Bitmap getBitmapAsUser(int userId, boolean hardware, @SetWallpaperFlags int which) { + return unsupported(); + } + + @Override + public Bitmap getBitmapAsUser(int userId, boolean hardware, + @SetWallpaperFlags int which, boolean returnDefault) { + return unsupported(); + } + + @Override + public Rect peekBitmapDimensions() { + return unsupported(); + } + + @Override + public Rect peekBitmapDimensions(@SetWallpaperFlags int which) { + return unsupported(); + } + + @Nullable + public Rect peekBitmapDimensions(@SetWallpaperFlags int which, boolean returnDefault) { + return unsupported(); + } + + @Override + public List<Rect> getBitmapCrops(@NonNull List<Point> displaySizes, + @SetWallpaperFlags int which, boolean originalBitmap) { + return unsupported(); + } + + @Override + public List<Rect> getBitmapCrops(@NonNull Point bitmapSize, @NonNull List<Point> displaySizes, + @Nullable Map<Point, Rect> cropHints) { + return unsupported(); + } + + @Override + public WallpaperColors getWallpaperColors(@NonNull Bitmap bitmap, + @Nullable Map<Point, Rect> cropHints) { + return unsupported(); + } + + @Override public ParcelFileDescriptor getWallpaperFile(int which) { return unsupported(); } @@ -173,6 +225,17 @@ final class DisabledWallpaperManager extends WallpaperManager { } @Override + public void addOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback, + List<RectF> regions, int which) throws IllegalArgumentException { + unsupported(); + } + + @Override + public void removeOnColorsChangedListener(@NonNull LocalWallpaperColorConsumer callback) { + unsupported(); + } + + @Override public ParcelFileDescriptor getWallpaperFile(int which, int userId) { return unsupported(); } @@ -192,23 +255,22 @@ final class DisabledWallpaperManager extends WallpaperManager { return unsupported(); } - @Override - public ParcelFileDescriptor getWallpaperInfoFile() { + public WallpaperInfo getWallpaperInfoForUser(int userId) { return unsupported(); } @Override - public WallpaperInfo getWallpaperInfoForUser(int userId) { + public WallpaperInfo getWallpaperInfo(@SetWallpaperFlags int which) { return unsupported(); } @Override - public WallpaperInfo getWallpaperInfo(@SetWallpaperFlags int which) { + public WallpaperInfo getWallpaperInfo(@SetWallpaperFlags int which, int userId) { return unsupported(); } @Override - public WallpaperInfo getWallpaperInfo(@SetWallpaperFlags int which, int userId) { + public ParcelFileDescriptor getWallpaperInfoFile() { return unsupported(); } @@ -264,6 +326,11 @@ final class DisabledWallpaperManager extends WallpaperManager { return 0; } + public int setBitmapWithCrops(@Nullable Bitmap fullImage, @NonNull Map<Point, Rect> cropHints, + boolean allowBackup, @SetWallpaperFlags int which) throws IOException { + return unsupportedInt(); + } + @Override public void setStream(InputStream bitmapData) throws IOException { unsupported(); @@ -284,6 +351,19 @@ final class DisabledWallpaperManager extends WallpaperManager { } @Override + public int setStreamWithCrops(InputStream bitmapData, @NonNull Map<Point, Rect> cropHints, + boolean allowBackup, @SetWallpaperFlags int which) throws IOException { + return unsupportedInt(); + } + + + @Override + public int setStreamWithCrops(InputStream bitmapData, @NonNull SparseArray<Rect> cropHints, + boolean allowBackup, @SetWallpaperFlags int which) throws IOException { + return unsupportedInt(); + } + + @Override public boolean hasResourceWallpaper(int resid) { return unsupportedBoolean(); } @@ -328,12 +408,40 @@ final class DisabledWallpaperManager extends WallpaperManager { return unsupportedBoolean(); } + + @Override + public void setWallpaperDimAmount(@FloatRange(from = 0f, to = 1f) float dimAmount) { + unsupported(); + } + + @Override + public @FloatRange(from = 0f, to = 1f) float getWallpaperDimAmount() { + return unsupportedInt(); + } + + @Override + public boolean lockScreenWallpaperExists() { + return unsupportedBoolean(); + } + @Override public boolean setWallpaperComponent(ComponentName name, int userId) { return unsupportedBoolean(); } @Override + public boolean setWallpaperComponentWithFlags(@NonNull ComponentName name, + @SetWallpaperFlags int which) { + return unsupportedBoolean(); + } + + @Override + public boolean setWallpaperComponentWithFlags(@NonNull ComponentName name, + @SetWallpaperFlags int which, int userId) { + return unsupportedBoolean(); + } + + @Override public void setWallpaperOffsets(IBinder windowToken, float xOffset, float yOffset) { unsupported(); } @@ -350,6 +458,21 @@ final class DisabledWallpaperManager extends WallpaperManager { } @Override + public void setWallpaperZoomOut(@NonNull IBinder windowToken, float zoom) { + unsupported(); + } + + @Override + public boolean isWallpaperSupported() { + return false; + } + + @Override + public boolean isSetWallpaperAllowed() { + return false; + } + + @Override public void clearWallpaperOffsets(IBinder windowToken) { unsupported(); } @@ -369,8 +492,18 @@ final class DisabledWallpaperManager extends WallpaperManager { return unsupportedBoolean(); } - @Override - public boolean wallpaperSupportsWcg(int which) { - return unsupportedBoolean(); + private static <T> T unsupported() { + if (DEBUG) Log.w(TAG, "unsupported method called; returning null", new Exception()); + return null; + } + + private static boolean unsupportedBoolean() { + if (DEBUG) Log.w(TAG, "unsupported method called; returning false", new Exception()); + return false; + } + + private static int unsupportedInt() { + if (DEBUG) Log.w(TAG, "unsupported method called; returning -1", new Exception()); + return -1; } } diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 1a72df10fbd6..5903a7ff619c 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -123,6 +123,8 @@ import java.util.concurrent.TimeUnit; * <p> An app can check whether wallpapers are supported for the current user, by calling * {@link #isWallpaperSupported()}, and whether setting of wallpapers is allowed, by calling * {@link #isSetWallpaperAllowed()}. + * Any public APIs added to WallpaperManager should have a corresponding stub in + * {@link DisabledWallpaperManager}. */ @SystemService(Context.WALLPAPER_SERVICE) public class WallpaperManager { diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig index 835459e09ca2..e370e85278d5 100644 --- a/core/java/android/content/pm/multiuser.aconfig +++ b/core/java/android/content/pm/multiuser.aconfig @@ -381,8 +381,9 @@ flag { } flag { - name: "unicorn_mode_refactoring_for_hsum" + name: "unicorn_mode_refactoring_for_hsum_read_only" namespace: "multiuser" - description: "Refactorings related to unicorn mode to work on HSUM mode" + description: "Refactorings related to unicorn mode to work on HSUM mode (Read only flag)" bug: "339201286" -} + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 7f3c49dbb580..1e7f70bf5a72 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -918,7 +918,7 @@ public class CameraDeviceImpl extends CameraDevice checkIfCameraClosedOrInError(); for (String physicalId : physicalCameraIdSet) { - if (physicalId == getId()) { + if (Objects.equals(physicalId, getId())) { throw new IllegalStateException("Physical id matches the logical id!"); } } diff --git a/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java b/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java index 540243c4fe92..bfa95f7a75c7 100644 --- a/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java +++ b/core/java/android/inputmethodservice/navigationbar/KeyButtonView.java @@ -22,6 +22,7 @@ import static android.view.KeyEvent.KEYCODE_UNKNOWN; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; +import android.annotation.Nullable; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; @@ -126,15 +127,29 @@ public class KeyButtonView extends ImageView implements ButtonInterface { @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - if (mCode != KEYCODE_UNKNOWN) { + if (isClickable()) { info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null)); if (isLongClickable()) { info.addAction( - new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null)); + new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, + getAccessibilityLongClickActionLabel())); } } } + /** + * Gets the accessibility long click action label for the button, or {@code null} for no label. + */ + @Nullable + private CharSequence getAccessibilityLongClickActionLabel() { + if (Flags.imeSwitcherRevamp() + && getId() == com.android.internal.R.id.input_method_nav_ime_switcher) { + return getContext().getText( + com.android.internal.R.string.input_method_ime_switch_long_click_action_desc); + } + return null; + } + @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); diff --git a/core/java/android/os/vibrator/flags.aconfig b/core/java/android/os/vibrator/flags.aconfig index 40dd91fcb4ae..0ed9b0316e4a 100644 --- a/core/java/android/os/vibrator/flags.aconfig +++ b/core/java/android/os/vibrator/flags.aconfig @@ -20,13 +20,6 @@ flag { flag { namespace: "haptics" - name: "keyboard_category_enabled" - description: "Enables the independent keyboard vibration settings feature" - bug: "289107579" -} - -flag { - namespace: "haptics" name: "adaptive_haptics_enabled" description: "Enables the adaptive haptics feature" bug: "305961689" @@ -95,3 +88,14 @@ flag { purpose: PURPOSE_BUGFIX } } + +flag { + namespace: "haptics" + name: "load_haptic_feedback_vibration_customization_from_resources" + description: "Load haptic feedback vibrations customization from resources." + is_fixed_read_only: true + bug: "295142743" + metadata { + purpose: PURPOSE_FEATURE + } +} diff --git a/core/java/android/service/notification/DeviceEffectsApplier.java b/core/java/android/service/notification/DeviceEffectsApplier.java index 5194cdd47933..2472860ae14b 100644 --- a/core/java/android/service/notification/DeviceEffectsApplier.java +++ b/core/java/android/service/notification/DeviceEffectsApplier.java @@ -16,8 +16,6 @@ package android.service.notification; -import android.service.notification.ZenModeConfig.ConfigChangeOrigin; - /** * Responsible for making any service calls needed to apply the set of {@link ZenDeviceEffects} that * make sense for the current platform. @@ -43,5 +41,5 @@ public interface DeviceEffectsApplier { * changing as a result of an explicit user action, then it makes sense to * apply them immediately regardless. */ - void apply(ZenDeviceEffects effects, @ConfigChangeOrigin int source); + void apply(ZenDeviceEffects effects, @ZenModeConfig.ConfigOrigin int source); } diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 7ca248da3dd8..5e15e0160be4 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -112,68 +112,83 @@ public class ZenModeConfig implements Parcelable { private static final String TAG = "ZenModeConfig"; /** - * The {@link ZenModeConfig} is being updated because of an unknown reason. + * The {@link ZenModeConfig} is updated because of an unknown reason. */ - public static final int UPDATE_ORIGIN_UNKNOWN = 0; + public static final int ORIGIN_UNKNOWN = 0; /** - * The {@link ZenModeConfig} is being updated because of system initialization (i.e. load from + * The {@link ZenModeConfig} is updated because of system initialization (i.e. load from * storage, on device boot). */ - public static final int UPDATE_ORIGIN_INIT = 1; + public static final int ORIGIN_INIT = 1; - /** The {@link ZenModeConfig} is being updated (replaced) because of a user switch or unlock. */ - public static final int UPDATE_ORIGIN_INIT_USER = 2; + /** The {@link ZenModeConfig} is updated (replaced) because of a user switch or unlock. */ + public static final int ORIGIN_INIT_USER = 2; - /** The {@link ZenModeConfig} is being updated because of a user action, for example: + /** + * The {@link ZenModeConfig} is updated because of a <em>user action</em> performed from a + * system surface, such as: * <ul> - * <li>{@link NotificationManager#setAutomaticZenRuleState} with a - * {@link Condition#source} equal to {@link Condition#SOURCE_USER_ACTION}.</li> - * <li>Adding, updating, or removing a rule from Settings.</li> - * <li>Directly activating or deactivating/snoozing a rule through some UI affordance (e.g. - * Quick Settings).</li> + * <li>Adding, updating, or removing a rule from Settings. + * <li>Activating or deactivating a rule through the System (e.g. from Settings/Modes). + * <li>Activating or deactivating a rule through SystemUi (e.g. with Quick Settings). * </ul> + * + * <p>This does <em>not</em> include user actions from apps ({@link #ORIGIN_USER_IN_APP} nor + * non-user actions from the system ({@link #ORIGIN_SYSTEM}). */ - public static final int UPDATE_ORIGIN_USER = 3; + public static final int ORIGIN_USER_IN_SYSTEMUI = 3; /** - * The {@link ZenModeConfig} is being "independently" updated by an app, and not as a result of - * a user's action inside that app (for example, activating an {@link AutomaticZenRule} based on - * a previously set schedule). + * The {@link ZenModeConfig} is updated by an app, but (probably) not as a result of a user + * action (for example, activating an {@link AutomaticZenRule} based on a previously set + * schedule). + * + * <p>Note that {@code ORIGIN_APP} is the only option for all public APIs except + * {@link NotificationManager#setAutomaticZenRuleState} -- apps cannot claim to be adding or + * updating a rule on behalf of the user. */ - public static final int UPDATE_ORIGIN_APP = 4; + public static final int ORIGIN_APP = 4; /** - * The {@link ZenModeConfig} is being updated by the System or SystemUI. Note that this only - * includes cases where the call is coming from the System/SystemUI but the change is not due to - * a user action (e.g. automatically activating a schedule-based rule). If the change is a - * result of a user action (e.g. activating a rule by tapping on its QS tile) then - * {@link #UPDATE_ORIGIN_USER} is used instead. + * The {@link ZenModeConfig} is updated by the System (or SystemUI). This only includes cases + * where the call is coming from the System/SystemUI but the change is not due to a user action + * (e.g. automatically activating a schedule-based rule, or some service toggling Do Not + * Disturb). See {@link #ORIGIN_USER_IN_SYSTEMUI}. */ - public static final int UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI = 5; + public static final int ORIGIN_SYSTEM = 5; /** * The {@link ZenModeConfig} is being updated (replaced) because the user's DND configuration * is being restored from a backup. */ - public static final int UPDATE_ORIGIN_RESTORE_BACKUP = 6; - - @IntDef(prefix = { "UPDATE_ORIGIN_" }, value = { - UPDATE_ORIGIN_UNKNOWN, - UPDATE_ORIGIN_INIT, - UPDATE_ORIGIN_INIT_USER, - UPDATE_ORIGIN_USER, - UPDATE_ORIGIN_APP, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - UPDATE_ORIGIN_RESTORE_BACKUP + public static final int ORIGIN_RESTORE_BACKUP = 6; + + /** + * The {@link ZenModeConfig} is updated from an app, and the app reports it's the result + * of a user action (e.g. tapping a button in the Wellbeing App to start Bedtime Mode). + * Corresponds to {@link NotificationManager#setAutomaticZenRuleState} with a + * {@link Condition#source} equal to {@link Condition#SOURCE_USER_ACTION}.</li> + */ + public static final int ORIGIN_USER_IN_APP = 7; + + @IntDef(prefix = { "ORIGIN_" }, value = { + ORIGIN_UNKNOWN, + ORIGIN_INIT, + ORIGIN_INIT_USER, + ORIGIN_USER_IN_SYSTEMUI, + ORIGIN_APP, + ORIGIN_SYSTEM, + ORIGIN_RESTORE_BACKUP, + ORIGIN_USER_IN_APP }) @Retention(RetentionPolicy.SOURCE) - public @interface ConfigChangeOrigin {} + public @interface ConfigOrigin {} public static final int SOURCE_ANYONE = Policy.PRIORITY_SENDERS_ANY; public static final int SOURCE_CONTACT = Policy.PRIORITY_SENDERS_CONTACTS; public static final int SOURCE_STAR = Policy.PRIORITY_SENDERS_STARRED; - public static final int MAX_SOURCE = SOURCE_STAR; + private static final int MAX_SOURCE = SOURCE_STAR; private static final int DEFAULT_SOURCE = SOURCE_STAR; private static final int DEFAULT_CALLS_SOURCE = SOURCE_STAR; @@ -1174,7 +1189,7 @@ public class ZenModeConfig implements Parcelable { } if (Flags.modesUi()) { rt.disabledOrigin = safeInt(parser, RULE_ATT_DISABLED_ORIGIN, - UPDATE_ORIGIN_UNKNOWN); + ORIGIN_UNKNOWN); rt.legacySuppressedEffects = safeInt(parser, RULE_ATT_LEGACY_SUPPRESSED_EFFECTS, 0); } @@ -2537,7 +2552,8 @@ public class ZenModeConfig implements Parcelable { @ZenDeviceEffects.ModifiableField public int zenDeviceEffectsUserModifiedFields; @Nullable public Instant deletionInstant; // Only set on deleted rules. @FlaggedApi(Flags.FLAG_MODES_UI) - @ConfigChangeOrigin public int disabledOrigin = UPDATE_ORIGIN_UNKNOWN; + @ConfigOrigin + public int disabledOrigin = ORIGIN_UNKNOWN; // The obsolete suppressed effects in NM.Policy (SCREEN_ON, SCREEN_OFF) cannot be put in a // ZenPolicy, so we store them here, only for the manual rule. @FlaggedApi(Flags.FLAG_MODES_UI) diff --git a/core/res/res/layout/input_method_switch_dialog_new.xml b/core/res/res/layout/input_method_switch_dialog_new.xml index 5a4d6b14a52b..ab5d38f52f7d 100644 --- a/core/res/res/layout/input_method_switch_dialog_new.xml +++ b/core/res/res/layout/input_method_switch_dialog_new.xml @@ -21,21 +21,30 @@ android:layout_height="wrap_content" android:orientation="vertical"> - <com.android.internal.widget.MaxHeightFrameLayout - android:layout_width="320dp" + <LinearLayout + android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" - android:maxHeight="373dp"> + android:orientation="horizontal"> - <com.android.internal.widget.RecyclerView - android:id="@+id/list" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:paddingVertical="8dp" - android:clipToPadding="false" - android:layoutManager="com.android.internal.widget.LinearLayoutManager"/> + <!-- TODO(b/357644229): Enable shrinking width without three levels of nesting. --> + <com.android.internal.widget.MaxHeightFrameLayout + android:layout_width="320dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:maxHeight="373dp"> + + <com.android.internal.widget.RecyclerView + android:id="@+id/list" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingVertical="8dp" + android:clipToPadding="false" + android:layoutManager="com.android.internal.widget.LinearLayoutManager"/> - </com.android.internal.widget.MaxHeightFrameLayout> + </com.android.internal.widget.MaxHeightFrameLayout> + + </LinearLayout> <LinearLayout style="?android:attr/buttonBarStyle" @@ -51,7 +60,8 @@ <Space android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_weight="1"/> + android:layout_weight="1" + android:importantForAccessibility="no"/> <Button style="?attr/buttonBarButtonStyle" diff --git a/core/res/res/layout/input_method_switch_item_new.xml b/core/res/res/layout/input_method_switch_item_new.xml index 16a97c4b39ee..09ed65093b39 100644 --- a/core/res/res/layout/input_method_switch_item_new.xml +++ b/core/res/res/layout/input_method_switch_item_new.xml @@ -31,7 +31,8 @@ android:layout_marginTop="8dp" android:layout_marginEnd="24dp" android:layout_marginBottom="12dp" - android:visibility="gone"/> + android:visibility="gone" + android:importantForAccessibility="no"/> <TextView android:id="@+id/header_text" @@ -81,7 +82,8 @@ android:layout_marginStart="12dp" android:src="@drawable/ic_check_24dp" android:tint="?attr/materialColorOnSurface" - android:visibility="gone"/> + android:visibility="gone" + android:importantForAccessibility="no"/> </LinearLayout> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 9104379cfbed..cb58339f5ef3 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -3277,6 +3277,9 @@ <string name="input_method_nav_back_button_desc">Back</string> <!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="input_method_ime_switch_button_desc">Switch input method</string> + <!-- Accessibility text for the long click action on the switch input method button. This will + be used following "Double-tap and hold to..." [CHAR LIMIT=NONE] --> + <string name="input_method_ime_switch_long_click_action_desc">Open input method picker</string> <!-- If the device is getting low on internal storage, a notification is shown to the user. This is the title of that notification. --> <string name="low_internal_storage_view_title">Storage space running out</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 8f4018f38403..0d16e9c939d9 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -2245,6 +2245,7 @@ <java-symbol type="string" name="heavy_weight_notification_detail" /> <java-symbol type="string" name="image_wallpaper_component" /> <java-symbol type="string" name="input_method_binding_label" /> + <java-symbol type="string" name="input_method_ime_switch_long_click_action_desc" /> <java-symbol type="string" name="launch_warning_original" /> <java-symbol type="string" name="launch_warning_replace" /> <java-symbol type="string" name="launch_warning_title" /> @@ -5461,7 +5462,9 @@ <java-symbol type="bool" name="config_enable_a11y_fullscreen_magnification_overscroll_handler" /> <java-symbol type="dimen" name="accessibility_fullscreen_magnification_gesture_edge_slop" /> + <!-- For HapticFeedbackConstants configurability defined at HapticFeedbackCustomization --> <java-symbol type="string" name="config_hapticFeedbackCustomizationFile" /> + <java-symbol type="xml" name="haptic_feedback_customization" /> <!-- For ActivityManager PSS profiling configurability --> <java-symbol type="bool" name="config_am_disablePssProfiling" /> diff --git a/core/res/res/xml/haptic_feedback_customization.xml b/core/res/res/xml/haptic_feedback_customization.xml new file mode 100644 index 000000000000..7ac0787ab7a0 --- /dev/null +++ b/core/res/res/xml/haptic_feedback_customization.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2024 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. + --> + +<haptic-feedback-constants/> diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS index cb422eab372b..2e19d52fb4bb 100644 --- a/libs/WindowManager/Shell/OWNERS +++ b/libs/WindowManager/Shell/OWNERS @@ -1,5 +1,5 @@ xutan@google.com # Give submodule owners in shell resource approval -per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com +per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com per-file res*/*/tv_*.xml = bronger@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS index b01b2b7ad520..afdda8ff865e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS @@ -5,3 +5,6 @@ madym@google.com pbdr@google.com tkachenkoi@google.com vaniadesmonda@google.com +pragyabajoria@google.com +uysalorhan@google.com +gsennton@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS index 8a0eea0a9bdd..93351c3f5f86 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/OWNERS @@ -5,3 +5,7 @@ madym@google.com nmusgrave@google.com pbdr@google.com tkachenkoi@google.com +vaniadesmonda@google.com +pragyabajoria@google.com +uysalorhan@google.com +gsennton@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 284620e7d0c4..da6221efdaee 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -632,6 +632,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb public void insetsChanged(InsetsState insetsState) { DisplayLayout pendingLayout = mDisplayController .getDisplayLayout(mPipDisplayLayoutState.getDisplayId()); + if (pendingLayout == null) { + ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE, + "insetsChanged: no display layout for displayId=%d", + mPipDisplayLayoutState.getDisplayId()); + return; + } if (mIsInFixedRotation || mIsKeyguardShowingOrAnimating || pendingLayout.rotation() diff --git a/libs/WindowManager/Shell/tests/OWNERS b/libs/WindowManager/Shell/tests/OWNERS index 9f735c46eceb..d1be12f6d1bb 100644 --- a/libs/WindowManager/Shell/tests/OWNERS +++ b/libs/WindowManager/Shell/tests/OWNERS @@ -15,3 +15,6 @@ tkachenkoi@google.com mpodolian@google.com jeremysim@google.com peanutbutter@google.com +pragyabajoria@google.com +uysalorhan@google.com +gsennton@google.com diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java index 77337a03ef55..d8f395d76b39 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeWindowGeometryTests.java @@ -56,7 +56,7 @@ import org.junit.runner.RunWith; public class DragResizeWindowGeometryTests extends ShellTestCase { private static final Size TASK_SIZE = new Size(500, 1000); private static final int TASK_CORNER_RADIUS = 10; - private static final int EDGE_RESIZE_THICKNESS = 15; + private static final int EDGE_RESIZE_THICKNESS = 12; private static final int FINE_CORNER_SIZE = EDGE_RESIZE_THICKNESS * 2 + 10; private static final int LARGE_CORNER_SIZE = FINE_CORNER_SIZE + 10; private static final DragResizeWindowGeometry GEOMETRY = new DragResizeWindowGeometry( diff --git a/media/jni/JetPlayer.h b/media/jni/JetPlayer.h index bb569bcad7be..4cc266dec445 100644 --- a/media/jni/JetPlayer.h +++ b/media/jni/JetPlayer.h @@ -40,7 +40,7 @@ public: static const int JET_NUMQUEUEDSEGMENT_UPDATE = 3; static const int JET_PAUSE_UPDATE = 4; - JetPlayer(void *javaJetPlayer, + explicit JetPlayer(void *javaJetPlayer, int maxTracks = 32, int trackBufferSize = 1200); ~JetPlayer(); @@ -69,7 +69,6 @@ private: void fireUpdateOnStatusChange(); void fireEventsFromJetQueue(); - JetPlayer() {} // no default constructor void dump(); void dumpJetStatus(S_JET_STATUS* pJetStatus); @@ -96,7 +95,7 @@ private: class JetPlayerThread : public Thread { public: - JetPlayerThread(JetPlayer *player) : mPlayer(player) { + explicit JetPlayerThread(JetPlayer *player) : mPlayer(player) { } protected: @@ -106,8 +105,7 @@ private: JetPlayer *mPlayer; bool threadLoop() { - int result; - result = mPlayer->render(); + mPlayer->render(); return false; } diff --git a/nfc/java/android/nfc/NfcActivityManager.java b/nfc/java/android/nfc/NfcActivityManager.java index 0e40db612708..0eb846d6c72a 100644 --- a/nfc/java/android/nfc/NfcActivityManager.java +++ b/nfc/java/android/nfc/NfcActivityManager.java @@ -236,11 +236,7 @@ public final class NfcActivityManager extends IAppCallback.Stub public void setReaderMode(Binder token, int flags, Bundle extras) { if (DBG) Log.d(TAG, "Setting reader mode"); - try { - NfcAdapter.sService.setReaderMode(token, this, flags, extras); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService(() -> NfcAdapter.sService.setReaderMode(token, this, flags, extras)); } /** @@ -248,19 +244,11 @@ public final class NfcActivityManager extends IAppCallback.Stub * Makes IPC call - do not hold lock. */ void requestNfcServiceCallback() { - try { - NfcAdapter.sService.setAppCallback(this); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService(() -> NfcAdapter.sService.setAppCallback(this)); } void verifyNfcPermission() { - try { - NfcAdapter.sService.verifyNfcPermission(); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService(() -> NfcAdapter.sService.verifyNfcPermission()); } @Override @@ -406,11 +394,8 @@ public final class NfcActivityManager extends IAppCallback.Stub } private void changeDiscoveryTech(Binder token, int pollTech, int listenTech) { - try { - NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService( + () -> NfcAdapter.sService.updateDiscoveryTechnology(token, pollTech, listenTech)); } } diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java index 0ffab4ba3eaf..b36b705245cd 100644 --- a/nfc/java/android/nfc/NfcAdapter.java +++ b/nfc/java/android/nfc/NfcAdapter.java @@ -922,8 +922,8 @@ public final class NfcAdapter { * @hide */ @UnsupportedAppUsage - public INfcAdapter getService() { - isEnabled(); // NOP call to recover sService if it is stale + public static INfcAdapter getService() { + isEnabledStatic(); // NOP call to recover sService if it is stale return sService; } @@ -931,8 +931,8 @@ public final class NfcAdapter { * Returns the binder interface to the tag service. * @hide */ - public INfcTag getTagService() { - isEnabled(); // NOP call to recover sTagService if it is stale + public static INfcTag getTagService() { + isEnabledStatic(); // NOP call to recover sTagService if it is stale return sTagService; } @@ -940,8 +940,8 @@ public final class NfcAdapter { * Returns the binder interface to the card emulation service. * @hide */ - public INfcCardEmulation getCardEmulationService() { - isEnabled(); + public static INfcCardEmulation getCardEmulationService() { + isEnabledStatic(); return sCardEmulationService; } @@ -949,8 +949,8 @@ public final class NfcAdapter { * Returns the binder interface to the NFC-F card emulation service. * @hide */ - public INfcFCardEmulation getNfcFCardEmulationService() { - isEnabled(); + public static INfcFCardEmulation getNfcFCardEmulationService() { + isEnabledStatic(); return sNfcFCardEmulationService; } @@ -973,14 +973,14 @@ public final class NfcAdapter { * @hide */ @UnsupportedAppUsage - public void attemptDeadServiceRecovery(Exception e) { + public static void attemptDeadServiceRecovery(RemoteException e) { Log.e(TAG, "NFC service dead - attempting to recover", e); INfcAdapter service = getServiceInterface(); if (service == null) { Log.e(TAG, "could not retrieve NFC service during service recovery"); // nothing more can be done now, sService is still stale, we'll hit // this recovery path again later - return; + e.rethrowAsRuntimeException(); } // assigning to sService is not thread-safe, but this is best-effort code // and on a well-behaved system should never happen @@ -993,7 +993,7 @@ public final class NfcAdapter { Log.e(TAG, "could not retrieve NFC tag service during service recovery"); // nothing more can be done now, sService is still stale, we'll hit // this recovery path again later - return; + ee.rethrowAsRuntimeException(); } } @@ -1014,24 +1014,27 @@ public final class NfcAdapter { "could not retrieve NFC-F card emulation service during service recovery"); } } - - return; } - private boolean isCardEmulationEnabled() { + private static boolean isCardEmulationEnabled() { if (sHasCeFeature) { return (sCardEmulationService != null || sNfcFCardEmulationService != null); } return false; } - private boolean isTagReadingEnabled() { + private static boolean isTagReadingEnabled() { if (sHasNfcFeature) { return sTagService != null; } return false; } + private static boolean isEnabledStatic() { + boolean serviceState = callServiceReturn(() -> sService.getState() == STATE_ON, false); + return serviceState + && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature); + } /** * Return true if this NFC Adapter has any features enabled. @@ -1046,24 +1049,7 @@ public final class NfcAdapter { * @return true if this NFC Adapter has any features enabled */ public boolean isEnabled() { - boolean serviceState = false; - try { - serviceState = sService.getState() == STATE_ON; - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - // Try one more time - if (sService == null) { - Log.e(TAG, "Failed to recover NFC Service."); - return false; - } - try { - serviceState = sService.getState() == STATE_ON; - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover NFC Service."); - } - } - return serviceState - && (isTagReadingEnabled() || isCardEmulationEnabled() || sHasNfcWlcFeature); + return isEnabledStatic(); } /** @@ -1157,11 +1143,7 @@ public final class NfcAdapter { * @hide */ public void pausePolling(int timeoutInMs) { - try { - sService.pausePolling(timeoutInMs); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + callService(() -> sService.pausePolling(timeoutInMs)); } @@ -1222,11 +1204,7 @@ public final class NfcAdapter { * @hide */ public void resumePolling() { - try { - sService.resumePolling(); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + callService(() -> sService.resumePolling()); } /** @@ -1645,15 +1623,10 @@ public final class NfcAdapter { if (activity == null || intent == null) { throw new NullPointerException(); } - try { - TechListParcel parcel = null; - if (techLists != null && techLists.length > 0) { - parcel = new TechListParcel(techLists); - } - sService.setForegroundDispatch(intent, filters, parcel); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + final TechListParcel parcel = (techLists != null && techLists.length > 0) + ? new TechListParcel(techLists) + : null; + callService(() -> sService.setForegroundDispatch(intent, filters, parcel)); } /** @@ -1677,11 +1650,7 @@ public final class NfcAdapter { throw new UnsupportedOperationException(); } } - try { - sService.setForegroundDispatch(null, null, null); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + callService(() -> sService.setForegroundDispatch(null, null, null)); } /** @@ -1762,11 +1731,7 @@ public final class NfcAdapter { } Binder token = new Binder(); int flags = enable ? ENABLE_POLLING_FLAGS : DISABLE_POLLING_FLAGS; - try { - NfcAdapter.sService.setReaderMode(token, null, flags, null); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + callService(() -> sService.setReaderMode(token, null, flags, null)); } /** @@ -1838,12 +1803,8 @@ public final class NfcAdapter { && ((pollTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH || (listenTechnology & FLAG_SET_DEFAULT_TECH) == FLAG_SET_DEFAULT_TECH)) { Binder token = new Binder(); - try { - NfcAdapter.sService.updateDiscoveryTechnology(token, - pollTechnology, listenTechnology); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + callService( () -> + sService.updateDiscoveryTechnology(token, pollTechnology, listenTechnology)); } else { mNfcActivityManager.setDiscoveryTech(activity, pollTechnology, listenTechnology); } @@ -2227,11 +2188,7 @@ public final class NfcAdapter { if (tag == null) { throw new NullPointerException("tag cannot be null"); } - try { - sService.dispatch(tag); - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - } + callService(() -> sService.dispatch(tag)); } /** @@ -2267,8 +2224,10 @@ public final class NfcAdapter { synchronized (mLock) { if (mNfcUnlockHandlers.containsKey(unlockHandler)) { // update the tag technologies - sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler)); - mNfcUnlockHandlers.remove(unlockHandler); + callService(() -> { + sService.removeNfcUnlockHandler(mNfcUnlockHandlers.get(unlockHandler)); + mNfcUnlockHandlers.remove(unlockHandler); + }); } INfcUnlockHandler.Stub iHandler = new INfcUnlockHandler.Stub() { @@ -2277,20 +2236,18 @@ public final class NfcAdapter { return unlockHandler.onUnlockAttempted(tag); } }; - - sService.addNfcUnlockHandler(iHandler, - Tag.getTechCodesFromStrings(tagTechnologies)); - mNfcUnlockHandlers.put(unlockHandler, iHandler); + return callServiceReturn(() -> { + sService.addNfcUnlockHandler( + iHandler, Tag.getTechCodesFromStrings(tagTechnologies)); + mNfcUnlockHandlers.put(unlockHandler, iHandler); + return true; + }, false); } - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - return false; } catch (IllegalArgumentException e) { Log.e(TAG, "Unable to register LockscreenDispatch", e); return false; } - return true; } /** @@ -2307,17 +2264,14 @@ public final class NfcAdapter { throw new UnsupportedOperationException(); } } - try { - synchronized (mLock) { - if (mNfcUnlockHandlers.containsKey(unlockHandler)) { + synchronized (mLock) { + if (mNfcUnlockHandlers.containsKey(unlockHandler)) { + return callServiceReturn(() -> { sService.removeNfcUnlockHandler(mNfcUnlockHandlers.remove(unlockHandler)); - } - - return true; + return true; + }, false); } - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - return false; + return true; } } @@ -2525,26 +2479,8 @@ public final class NfcAdapter { Log.e(TAG, "TagIntentAppPreference is not supported"); throw new UnsupportedOperationException(); } - try { - Map<String, Boolean> result = (Map<String, Boolean>) sService - .getTagIntentAppPreferenceForUser(userId); - return result; - } catch (RemoteException e) { - attemptDeadServiceRecovery(e); - // Try one more time - if (sService == null) { - Log.e(TAG, "Failed to recover NFC Service."); - return Collections.emptyMap(); - } - try { - Map<String, Boolean> result = (Map<String, Boolean>) sService - .getTagIntentAppPreferenceForUser(userId); - return result; - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover NFC Service."); - } - return Collections.emptyMap(); - } + return callServiceReturn( () -> + sService.getTagIntentAppPreferenceForUser(userId), Collections.emptyMap()); } /** @@ -2590,50 +2526,44 @@ public final class NfcAdapter { callService(() -> sService.notifyTestHceData(technology, data)); } + /** @hide */ interface ServiceCall { void call() throws RemoteException; } - - void callService(ServiceCall call) { + /** @hide */ + static void callService(ServiceCall call) { try { if (sService == null) { - attemptDeadServiceRecovery(null); + attemptDeadServiceRecovery(new RemoteException("NFC Service is null")); } call.call(); } catch (RemoteException e) { attemptDeadServiceRecovery(e); - // Try one more time - if (sService == null) { - Log.e(TAG, "Failed to recover NFC Service."); - return; - } try { call.call(); } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover NFC Service."); + ee.rethrowAsRuntimeException(); } } } + /** @hide */ interface ServiceCallReturn<T> { T call() throws RemoteException; } - <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) { + /** @hide */ + static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) { try { if (sService == null) { - attemptDeadServiceRecovery(null); + attemptDeadServiceRecovery(new RemoteException("NFC Service is null")); } return call.call(); } catch (RemoteException e) { attemptDeadServiceRecovery(e); // Try one more time - if (sService == null) { - Log.e(TAG, "Failed to recover NFC Service."); - return defaultReturn; - } try { return call.call(); } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover NFC Service."); + ee.rethrowAsRuntimeException(); } } return defaultReturn; diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java index f6138a63fae4..2ec819cdc1a9 100644 --- a/nfc/java/android/nfc/NfcOemExtension.java +++ b/nfc/java/android/nfc/NfcOemExtension.java @@ -89,13 +89,11 @@ public final class NfcOemExtension { + "registering"); throw new IllegalArgumentException(); } - try { + NfcAdapter.callService(() -> { NfcAdapter.sService.registerOemExtensionCallback(mOemNfcExtensionCallback); mCallback = callback; mExecutor = executor; - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + }); } } @@ -117,13 +115,11 @@ public final class NfcOemExtension { Log.e(TAG, "Callback not registered"); throw new IllegalArgumentException(); } - try { + NfcAdapter.callService(() -> { NfcAdapter.sService.unregisterOemExtensionCallback(mOemNfcExtensionCallback); mCallback = null; mExecutor = null; - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + }); } } @@ -134,11 +130,7 @@ public final class NfcOemExtension { @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference() { - try { - NfcAdapter.sService.clearPreference(); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService(() -> NfcAdapter.sService.clearPreference()); } /** @@ -147,11 +139,7 @@ public final class NfcOemExtension { @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState() { - try { - NfcAdapter.sService.setScreenState(); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService(() -> NfcAdapter.sService.setScreenState()); } /** @@ -162,11 +150,7 @@ public final class NfcOemExtension { @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate() { - try { - NfcAdapter.sService.checkFirmware(); - } catch (RemoteException e) { - mAdapter.attemptDeadServiceRecovery(e); - } + NfcAdapter.callService(() -> NfcAdapter.sService.checkFirmware()); } private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub { diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java index 2fe2ce39813b..e0438ce9258c 100644 --- a/nfc/java/android/nfc/cardemulation/CardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java @@ -219,24 +219,9 @@ public final class CardEmulation { * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. */ public boolean isDefaultServiceForCategory(ComponentName service, String category) { - try { - return sService.isDefaultServiceForCategory(mContext.getUser().getIdentifier(), - service, category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.isDefaultServiceForCategory(mContext.getUser().getIdentifier(), - service, category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.isDefaultServiceForCategory( + mContext.getUser().getIdentifier(), service, category), false); } /** @@ -251,24 +236,9 @@ public final class CardEmulation { * <p class="note">Requires the {@link android.Manifest.permission#NFC} permission. */ public boolean isDefaultServiceForAid(ComponentName service, String aid) { - try { - return sService.isDefaultServiceForAid(mContext.getUser().getIdentifier(), - service, aid); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.isDefaultServiceForAid(mContext.getUser().getIdentifier(), - service, aid); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.isDefaultServiceForAid( + mContext.getUser().getIdentifier(), service, aid), false); } /** @@ -331,22 +301,8 @@ public final class CardEmulation { */ public int getSelectionModeForCategory(String category) { if (CATEGORY_PAYMENT.equals(category)) { - boolean paymentRegistered = false; - try { - paymentRegistered = sService.isDefaultPaymentRegistered(); - } catch (RemoteException e) { - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return SELECTION_MODE_ALWAYS_ASK; - } - try { - paymentRegistered = sService.isDefaultPaymentRegistered(); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return SELECTION_MODE_ALWAYS_ASK; - } - } + boolean paymentRegistered = callServiceReturn(() -> + sService.isDefaultPaymentRegistered(), false); if (paymentRegistered) { return SELECTION_MODE_PREFER_DEFAULT; } else { @@ -369,13 +325,9 @@ public final class CardEmulation { @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE) public boolean setShouldDefaultToObserveModeForService(@NonNull ComponentName service, boolean enable) { - try { - return sService.setShouldDefaultToObserveModeForService( - mContext.getUser().getIdentifier(), service, enable); - } catch (RemoteException e) { - Log.e(TAG, "Failed to reach CardEmulationService."); - } - return false; + return callServiceReturn(() -> + sService.setShouldDefaultToObserveModeForService( + mContext.getUser().getIdentifier(), service, enable), false); } /** @@ -396,27 +348,11 @@ public final class CardEmulation { @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) public boolean registerPollingLoopFilterForService(@NonNull ComponentName service, @NonNull String pollingLoopFilter, boolean autoTransact) { - pollingLoopFilter = validatePollingLoopFilter(pollingLoopFilter); - - try { - return sService.registerPollingLoopFilterForService(mContext.getUser().getIdentifier(), - service, pollingLoopFilter, autoTransact); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.registerPollingLoopFilterForService( - mContext.getUser().getIdentifier(), service, - pollingLoopFilter, autoTransact); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter); + return callServiceReturn(() -> + sService.registerPollingLoopFilterForService( + mContext.getUser().getIdentifier(), service, pollingLoopFilterV, autoTransact), + false); } /** @@ -431,27 +367,10 @@ public final class CardEmulation { @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) public boolean removePollingLoopFilterForService(@NonNull ComponentName service, @NonNull String pollingLoopFilter) { - pollingLoopFilter = validatePollingLoopFilter(pollingLoopFilter); - - try { - return sService.removePollingLoopFilterForService(mContext.getUser().getIdentifier(), - service, pollingLoopFilter); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.removePollingLoopFilterForService( - mContext.getUser().getIdentifier(), service, - pollingLoopFilter); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + final String pollingLoopFilterV = validatePollingLoopFilter(pollingLoopFilter); + return callServiceReturn(() -> + sService.removePollingLoopFilterForService( + mContext.getUser().getIdentifier(), service, pollingLoopFilterV), false); } @@ -477,28 +396,13 @@ public final class CardEmulation { @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) public boolean registerPollingLoopPatternFilterForService(@NonNull ComponentName service, @NonNull String pollingLoopPatternFilter, boolean autoTransact) { - pollingLoopPatternFilter = validatePollingLoopPatternFilter(pollingLoopPatternFilter); - - try { - return sService.registerPollingLoopPatternFilterForService( - mContext.getUser().getIdentifier(), - service, pollingLoopPatternFilter, autoTransact); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.registerPollingLoopPatternFilterForService( - mContext.getUser().getIdentifier(), service, - pollingLoopPatternFilter, autoTransact); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + final String pollingLoopPatternFilterV = + validatePollingLoopPatternFilter(pollingLoopPatternFilter); + return callServiceReturn(() -> + sService.registerPollingLoopPatternFilterForService( + mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV, + autoTransact), + false); } /** @@ -518,27 +422,11 @@ public final class CardEmulation { @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) public boolean removePollingLoopPatternFilterForService(@NonNull ComponentName service, @NonNull String pollingLoopPatternFilter) { - pollingLoopPatternFilter = validatePollingLoopPatternFilter(pollingLoopPatternFilter); - - try { - return sService.removePollingLoopPatternFilterForService( - mContext.getUser().getIdentifier(), service, pollingLoopPatternFilter); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.removePollingLoopPatternFilterForService( - mContext.getUser().getIdentifier(), service, - pollingLoopPatternFilter); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + final String pollingLoopPatternFilterV = + validatePollingLoopPatternFilter(pollingLoopPatternFilter); + return callServiceReturn(() -> + sService.removePollingLoopPatternFilterForService( + mContext.getUser().getIdentifier(), service, pollingLoopPatternFilterV), false); } /** @@ -563,25 +451,10 @@ public final class CardEmulation { */ public boolean registerAidsForService(ComponentName service, String category, List<String> aids) { - AidGroup aidGroup = new AidGroup(aids, category); - try { - return sService.registerAidGroupForService(mContext.getUser().getIdentifier(), - service, aidGroup); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.registerAidGroupForService(mContext.getUser().getIdentifier(), - service, aidGroup); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + final AidGroup aidGroup = new AidGroup(aids, category); + return callServiceReturn(() -> + sService.registerAidGroupForService( + mContext.getUser().getIdentifier(), service, aidGroup), false); } /** @@ -603,27 +476,9 @@ public final class CardEmulation { @RequiresPermission(android.Manifest.permission.NFC) @NonNull public boolean unsetOffHostForService(@NonNull ComponentName service) { - NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); - if (adapter == null) { - return false; - } - - try { - return sService.unsetOffHostForService(mContext.getUser().getIdentifier(), service); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.unsetOffHostForService(mContext.getUser().getIdentifier(), service); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.unsetOffHostForService( + mContext.getUser().getIdentifier(), service), false); } /** @@ -662,8 +517,6 @@ public final class CardEmulation { @NonNull public boolean setOffHostForService(@NonNull ComponentName service, @NonNull String offHostSecureElement) { - boolean validSecureElement = false; - NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); if (adapter == null || offHostSecureElement == null) { return false; @@ -684,25 +537,10 @@ public final class CardEmulation { } else if (offHostSecureElement.equals("SIM")) { offHostSecureElement = "SIM1"; } - - try { - return sService.setOffHostForService(mContext.getUser().getIdentifier(), service, - offHostSecureElement); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setOffHostForService(mContext.getUser().getIdentifier(), service, - offHostSecureElement); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + final String offHostSecureElementV = new String(offHostSecureElement); + return callServiceReturn(() -> + sService.setOffHostForService( + mContext.getUser().getIdentifier(), service, offHostSecureElementV), false); } /** @@ -720,25 +558,10 @@ public final class CardEmulation { * @return The list of AIDs registered for this category, or null if it couldn't be found. */ public List<String> getAidsForService(ComponentName service, String category) { - try { - AidGroup group = sService.getAidGroupForService(mContext.getUser().getIdentifier(), - service, category); - return (group != null ? group.getAids() : null); - } catch (RemoteException e) { - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return null; - } - try { - AidGroup group = sService.getAidGroupForService(mContext.getUser().getIdentifier(), - service, category); - return (group != null ? group.getAids() : null); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return null; - } - } + AidGroup group = callServiceReturn(() -> + sService.getAidGroupForService( + mContext.getUser().getIdentifier(), service, category), null); + return (group != null ? group.getAids() : null); } /** @@ -757,24 +580,9 @@ public final class CardEmulation { * @return whether the group was successfully removed. */ public boolean removeAidsForService(ComponentName service, String category) { - try { - return sService.removeAidGroupForService(mContext.getUser().getIdentifier(), service, - category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.removeAidGroupForService(mContext.getUser().getIdentifier(), - service, category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.removeAidGroupForService( + mContext.getUser().getIdentifier(), service, category), false); } /** @@ -811,22 +619,7 @@ public final class CardEmulation { if (activity == null || service == null) { throw new NullPointerException("activity or service or category is null"); } - try { - return sService.setPreferredService(service); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setPreferredService(service); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> sService.setPreferredService(service), false); } /** @@ -843,22 +636,7 @@ public final class CardEmulation { if (activity == null) { throw new NullPointerException("activity is null"); } - try { - return sService.unsetPreferredService(); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.unsetPreferredService(); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> sService.unsetPreferredService(), false); } /** @@ -872,21 +650,7 @@ public final class CardEmulation { * @return whether AID prefix registering is supported on this device. */ public boolean supportsAidPrefixRegistration() { - try { - return sService.supportsAidPrefixRegistration(); - } catch (RemoteException e) { - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.supportsAidPrefixRegistration(); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> sService.supportsAidPrefixRegistration(), false); } /** @@ -897,25 +661,9 @@ public final class CardEmulation { @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) @Nullable public List<String> getAidsForPreferredPaymentService() { - try { - ApduServiceInfo serviceInfo = sService.getPreferredPaymentService( - mContext.getUser().getIdentifier()); - return (serviceInfo != null ? serviceInfo.getAids() : null); - } catch (RemoteException e) { - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - throw e.rethrowFromSystemServer(); - } - try { - ApduServiceInfo serviceInfo = - sService.getPreferredPaymentService(mContext.getUser().getIdentifier()); - return (serviceInfo != null ? serviceInfo.getAids() : null); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover CardEmulationService."); - throw e.rethrowFromSystemServer(); - } - } + ApduServiceInfo serviceInfo = callServiceReturn(() -> + sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null); + return (serviceInfo != null ? serviceInfo.getAids() : null); } /** @@ -944,40 +692,16 @@ public final class CardEmulation { @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) @Nullable public String getRouteDestinationForPreferredPaymentService() { - try { - ApduServiceInfo serviceInfo = sService.getPreferredPaymentService( - mContext.getUser().getIdentifier()); - if (serviceInfo != null) { - if (!serviceInfo.isOnHost()) { - return serviceInfo.getOffHostSecureElement() == null ? - "OffHost" : serviceInfo.getOffHostSecureElement(); - } - return "Host"; - } - return null; - } catch (RemoteException e) { - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - throw e.rethrowFromSystemServer(); - } - try { - ApduServiceInfo serviceInfo = - sService.getPreferredPaymentService(mContext.getUser().getIdentifier()); - if (serviceInfo != null) { - if (!serviceInfo.isOnHost()) { - return serviceInfo.getOffHostSecureElement() == null ? - "Offhost" : serviceInfo.getOffHostSecureElement(); - } - return "Host"; - } - return null; - - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover CardEmulationService."); - throw e.rethrowFromSystemServer(); + ApduServiceInfo serviceInfo = callServiceReturn(() -> + sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null); + if (serviceInfo != null) { + if (!serviceInfo.isOnHost()) { + return serviceInfo.getOffHostSecureElement() == null ? + "OffHost" : serviceInfo.getOffHostSecureElement(); } + return "Host"; } + return null; } /** @@ -995,115 +719,44 @@ public final class CardEmulation { @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) @Nullable public CharSequence getDescriptionForPreferredPaymentService() { - try { - ApduServiceInfo serviceInfo = sService.getPreferredPaymentService( - mContext.getUser().getIdentifier()); - return (serviceInfo != null ? serviceInfo.getDescription() : null); - } catch (RemoteException e) { - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - throw e.rethrowFromSystemServer(); - } - try { - ApduServiceInfo serviceInfo = - sService.getPreferredPaymentService(mContext.getUser().getIdentifier()); - return (serviceInfo != null ? serviceInfo.getDescription() : null); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to recover CardEmulationService."); - throw e.rethrowFromSystemServer(); - } - } + ApduServiceInfo serviceInfo = callServiceReturn(() -> + sService.getPreferredPaymentService(mContext.getUser().getIdentifier()), null); + return (serviceInfo != null ? serviceInfo.getDescription() : null); } /** * @hide */ public boolean setDefaultServiceForCategory(ComponentName service, String category) { - try { - return sService.setDefaultServiceForCategory(mContext.getUser().getIdentifier(), - service, category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setDefaultServiceForCategory(mContext.getUser().getIdentifier(), - service, category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.setDefaultServiceForCategory( + mContext.getUser().getIdentifier(), service, category), false); } /** * @hide */ public boolean setDefaultForNextTap(ComponentName service) { - try { - return sService.setDefaultForNextTap(mContext.getUser().getIdentifier(), service); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setDefaultForNextTap(mContext.getUser().getIdentifier(), service); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.setDefaultForNextTap( + mContext.getUser().getIdentifier(), service), false); } /** * @hide */ public boolean setDefaultForNextTap(int userId, ComponentName service) { - try { - return sService.setDefaultForNextTap(userId, service); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setDefaultForNextTap(userId, service); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.setDefaultForNextTap(userId, service), false); } /** * @hide */ public List<ApduServiceInfo> getServices(String category) { - try { - return sService.getServices(mContext.getUser().getIdentifier(), category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return null; - } - try { - return sService.getServices(mContext.getUser().getIdentifier(), category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return null; - } - } + return callServiceReturn(() -> + sService.getServices( + mContext.getUser().getIdentifier(), category), null); } /** @@ -1117,22 +770,8 @@ public final class CardEmulation { @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) @NonNull public List<ApduServiceInfo> getServices(@NonNull String category, @UserIdInt int userId) { - try { - return sService.getServices(userId, category); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return null; - } - try { - return sService.getServices(userId, category); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return null; - } - } + return callServiceReturn(() -> + sService.getServices(userId, category), null); } /** @@ -1222,22 +861,8 @@ public final class CardEmulation { if (service == null) { throw new NullPointerException("activity or service or category is null"); } - try { - return sService.setServiceEnabledForCategoryOther(userId, service, status); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.setServiceEnabledForCategoryOther(userId, service, status); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.setServiceEnabledForCategoryOther(userId, service, status), false); } /** @@ -1269,22 +894,9 @@ public final class CardEmulation { if (!activity.isResumed()) { throw new IllegalArgumentException("Activity must be resumed."); } - try { - return sService.overrideRoutingTable(UserHandle.myUserId(), protocol, technology); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.overrideRoutingTable(UserHandle.myUserId(), protocol, technology); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } + return callServiceReturn(() -> + sService.overrideRoutingTable( + mContext.getUser().getIdentifier(), protocol, technology), false); } /** @@ -1303,27 +915,9 @@ public final class CardEmulation { if (!activity.isResumed()) { throw new IllegalArgumentException("Activity must be resumed."); } - try { - return sService.recoverRoutingTable(UserHandle.myUserId()); - } catch (RemoteException e) { - // Try one more time - recoverService(); - if (sService == null) { - Log.e(TAG, "Failed to recover CardEmulationService."); - return false; - } - try { - return sService.recoverRoutingTable(UserHandle.myUserId()); - } catch (RemoteException ee) { - Log.e(TAG, "Failed to reach CardEmulationService."); - return false; - } - } - } - - void recoverService() { - NfcAdapter adapter = NfcAdapter.getDefaultAdapter(mContext); - sService = adapter.getCardEmulationService(); + return callServiceReturn(() -> + sService.recoverRoutingTable( + mContext.getUser().getIdentifier()), false); } /** @@ -1351,4 +945,53 @@ public final class CardEmulation { return ComponentName.unflattenFromString(defaultPaymentComponent); } + + /** @hide */ + interface ServiceCall { + void call() throws RemoteException; + } + /** @hide */ + public static void callService(ServiceCall call) { + try { + if (sService == null) { + NfcAdapter.attemptDeadServiceRecovery( + new RemoteException("NFC CardEmulation Service is null")); + sService = NfcAdapter.getCardEmulationService(); + } + call.call(); + } catch (RemoteException e) { + NfcAdapter.attemptDeadServiceRecovery(e); + sService = NfcAdapter.getCardEmulationService(); + try { + call.call(); + } catch (RemoteException ee) { + ee.rethrowAsRuntimeException(); + } + } + } + /** @hide */ + interface ServiceCallReturn<T> { + T call() throws RemoteException; + } + /** @hide */ + public static <T> T callServiceReturn(ServiceCallReturn<T> call, T defaultReturn) { + try { + if (sService == null) { + NfcAdapter.attemptDeadServiceRecovery( + new RemoteException("NFC CardEmulation Service is null")); + sService = NfcAdapter.getCardEmulationService(); + } + return call.call(); + } catch (RemoteException e) { + NfcAdapter.attemptDeadServiceRecovery(e); + sService = NfcAdapter.getCardEmulationService(); + // Try one more time + try { + return call.call(); + } catch (RemoteException ee) { + ee.rethrowAsRuntimeException(); + } + } + return defaultReturn; + } } diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp index 2fe446d24b34..f9fe03e06cb0 100644 --- a/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp +++ b/packages/SettingsLib/SelectorWithWidgetPreference/Android.bp @@ -20,6 +20,7 @@ android_library { static_libs: [ "androidx.preference_preference", "SettingsLibSettingsTheme", + "settingslib_selectorwithwidgetpreference_flags_lib", ], sdk_version: "system_current", @@ -30,3 +31,24 @@ android_library { "com.android.mediaprovider", ], } + +aconfig_declarations { + name: "settingslib_selectorwithwidgetpreference_flags", + package: "com.android.settingslib.widget.selectorwithwidgetpreference.flags", + container: "system", + srcs: [ + "aconfig/selectorwithwidgetpreference.aconfig", + ], +} + +java_aconfig_library { + name: "settingslib_selectorwithwidgetpreference_flags_lib", + aconfig_declarations: "settingslib_selectorwithwidgetpreference_flags", + + min_sdk_version: "30", + apex_available: [ + "//apex_available:platform", + "com.android.permission", + "com.android.mediaprovider", + ], +} diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/aconfig/selectorwithwidgetpreference.aconfig b/packages/SettingsLib/SelectorWithWidgetPreference/aconfig/selectorwithwidgetpreference.aconfig new file mode 100644 index 000000000000..70cda476bff6 --- /dev/null +++ b/packages/SettingsLib/SelectorWithWidgetPreference/aconfig/selectorwithwidgetpreference.aconfig @@ -0,0 +1,13 @@ +package: "com.android.settingslib.widget.selectorwithwidgetpreference.flags" +container: "system" + +flag { + name: "allow_set_title_max_lines" + namespace: "accessibility" + description: "Allow changes to the title max lines so it's not always fixed to 2" + bug: "356726764" + metadata { + purpose: PURPOSE_BUGFIX + } +} + diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/res/values/attrs.xml b/packages/SettingsLib/SelectorWithWidgetPreference/res/values/attrs.xml new file mode 100644 index 000000000000..7ffde2578cc1 --- /dev/null +++ b/packages/SettingsLib/SelectorWithWidgetPreference/res/values/attrs.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Copyright (C) 2024 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> + <declare-styleable name="SelectorWithWidgetPreference"> + <!-- The maximum number of lines for rendering the title. --> + <attr name="titleMaxLines" format="integer" /> + </declare-styleable> +</resources>
\ No newline at end of file diff --git a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java index f2ce8a965dfa..34de5c4a5d75 100644 --- a/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java +++ b/packages/SettingsLib/SelectorWithWidgetPreference/src/com/android/settingslib/widget/SelectorWithWidgetPreference.java @@ -17,15 +17,21 @@ package com.android.settingslib.widget; import android.content.Context; +import android.content.res.TypedArray; import android.text.TextUtils; import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import androidx.preference.CheckBoxPreference; import androidx.preference.PreferenceViewHolder; import com.android.settingslib.widget.preference.selector.R; +import com.android.settingslib.widget.selectorwithwidgetpreference.flags.Flags; /** * Selector preference (checkbox or radio button) with an optional additional widget. @@ -41,6 +47,8 @@ import com.android.settingslib.widget.preference.selector.R; * on the right side that can open another page. */ public class SelectorWithWidgetPreference extends CheckBoxPreference { + @VisibleForTesting + static final int DEFAULT_MAX_LINES = 2; /** * Interface definition for a callback to be invoked when the preference is clicked. @@ -63,6 +71,8 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { private boolean mIsCheckBox = false; // whether to display this button as a checkbox private View.OnClickListener mExtraWidgetOnClickListener; + private int mTitleMaxLines; + /** * Perform inflation from XML and apply a class-specific base style. @@ -74,9 +84,10 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { * resource that supplies default values for the view. Can be 0 to not * look for defaults. */ - public SelectorWithWidgetPreference(Context context, AttributeSet attrs, int defStyle) { + public SelectorWithWidgetPreference(@NonNull Context context, @Nullable AttributeSet attrs, + int defStyle) { super(context, attrs, defStyle); - init(); + init(context, attrs, defStyle, /* defStyleRes= */ 0); } /** @@ -88,7 +99,7 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { */ public SelectorWithWidgetPreference(Context context, AttributeSet attrs) { super(context, attrs); - init(); + init(context, attrs, /* defStyleAttr= */ 0, /* defStyleRes= */ 0); } /** @@ -100,7 +111,7 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { public SelectorWithWidgetPreference(Context context, boolean isCheckbox) { super(context, null); mIsCheckBox = isCheckbox; - init(); + init(context, /* attrs= */ null, /* defStyleAttr= */ 0, /* defStyleRes= */ 0); } /** @@ -161,6 +172,11 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { mExtraWidgetContainer = holder.findViewById(R.id.selector_extra_widget_container); setExtraWidgetOnClickListener(mExtraWidgetOnClickListener); + + if (Flags.allowSetTitleMaxLines()) { + TextView title = (TextView) holder.findViewById(android.R.id.title); + title.setMaxLines(mTitleMaxLines); + } } /** @@ -200,7 +216,8 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { return mIsCheckBox; } - private void init() { + private void init(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, + int defStyleRes) { if (mIsCheckBox) { setWidgetLayoutResource(R.layout.preference_widget_checkbox); } else { @@ -208,5 +225,16 @@ public class SelectorWithWidgetPreference extends CheckBoxPreference { } setLayoutResource(R.layout.preference_selector_with_widget); setIconSpaceReserved(false); + + if (Flags.allowSetTitleMaxLines()) { + final TypedArray a = + context.obtainStyledAttributes( + attrs, R.styleable.SelectorWithWidgetPreference, defStyleAttr, + defStyleRes); + mTitleMaxLines = + a.getInt(R.styleable.SelectorWithWidgetPreference_titleMaxLines, + DEFAULT_MAX_LINES); + a.recycle(); + } } } diff --git a/packages/SettingsLib/aconfig/settingslib.aconfig b/packages/SettingsLib/aconfig/settingslib.aconfig index 754d9423773f..0d124e80dfcf 100644 --- a/packages/SettingsLib/aconfig/settingslib.aconfig +++ b/packages/SettingsLib/aconfig/settingslib.aconfig @@ -108,4 +108,14 @@ flag { namespace: "android_settings" description: "Settings catalyst project migration" bug: "323791114" -}
\ No newline at end of file +} + +flag { + name: "asha_profile_access_profile_enabled_true" + namespace: "accessibility" + description: "Changes the return value of HearingAidProfile.accessProfileEnabled() to true" + bug: "356530795" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java index f2450de60878..fb9b4dfc5382 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidProfile.java @@ -34,6 +34,7 @@ import androidx.annotation.NonNull; import com.android.settingslib.R; import com.android.settingslib.Utils; +import com.android.settingslib.flags.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -141,7 +142,7 @@ public class HearingAidProfile implements LocalBluetoothProfile { } public boolean accessProfileEnabled() { - return false; + return Flags.ashaProfileAccessProfileEnabledTrue(); } public boolean isAutoConnectable() { diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java index a06f0849c0bc..22e6133a3019 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/TestModeBuilder.java @@ -16,8 +16,8 @@ package com.android.settingslib.notification.modes; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_UNKNOWN; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_UNKNOWN; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; import android.app.AutomaticZenRule; import android.app.NotificationManager; @@ -154,7 +154,7 @@ public class TestModeBuilder { mRule.setEnabled(enabled); mConfigZenRule.enabled = enabled; if (!enabled) { - mConfigZenRule.disabledOrigin = byUser ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_UNKNOWN; + mConfigZenRule.disabledOrigin = byUser ? ORIGIN_USER_IN_SYSTEMUI : ORIGIN_UNKNOWN; } return this; } diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java index 88af7ee3a54f..88497a393ce8 100644 --- a/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java +++ b/packages/SettingsLib/src/com/android/settingslib/notification/modes/ZenMode.java @@ -66,7 +66,7 @@ public class ZenMode implements Parcelable { private static final String TAG = "ZenMode"; - static final String MANUAL_DND_MODE_ID = "manual_dnd"; + static final String MANUAL_DND_MODE_ID = ZenModeConfig.MANUAL_RULE_ID; static final String TEMP_NEW_MODE_ID = "temp_new_mode"; // Must match com.android.server.notification.ZenModeHelper#applyCustomPolicy. @@ -119,7 +119,7 @@ public class ZenMode implements Parcelable { return Status.ENABLED; } } else { - if (zenRuleExtraData.disabledOrigin == ZenModeConfig.UPDATE_ORIGIN_USER) { + if (zenRuleExtraData.disabledOrigin == ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI) { return Status.DISABLED_BY_USER; } else { return Status.DISABLED_BY_OTHER; // by APP, SYSTEM, UNKNOWN. diff --git a/packages/SettingsLib/tests/robotests/Android.bp b/packages/SettingsLib/tests/robotests/Android.bp index 75c40bfa8b60..f380e7f7e7a6 100644 --- a/packages/SettingsLib/tests/robotests/Android.bp +++ b/packages/SettingsLib/tests/robotests/Android.bp @@ -56,6 +56,7 @@ android_robolectric_test { "flag-junit", "settingslib_media_flags_lib", "settingslib_illustrationpreference_flags_lib", + "settingslib_selectorwithwidgetpreference_flags_lib", "testng", // TODO: remove once JUnit on Android provides assertThrows ], java_resource_dirs: ["config"], diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java index 651e57c184d7..d9fdcc38b576 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/notification/modes/ZenModeTest.java @@ -93,7 +93,7 @@ public class ZenModeTest { public void constructor_disabledRuleByUser_statusDisabledByUser() { AutomaticZenRule azr = new AutomaticZenRule.Builder(ZEN_RULE).setEnabled(false).build(); ZenModeConfig.ZenRule configZenRule = zenConfigRuleFor(azr, false); - configZenRule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_USER; + configZenRule.disabledOrigin = ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; ZenMode mode = new ZenMode("id", azr, configZenRule); assertThat(mode.getStatus()).isEqualTo(ZenMode.Status.DISABLED_BY_USER); @@ -103,7 +103,7 @@ public class ZenModeTest { public void constructor_disabledRuleByOther_statusDisabledByOther() { AutomaticZenRule azr = new AutomaticZenRule.Builder(ZEN_RULE).setEnabled(false).build(); ZenModeConfig.ZenRule configZenRule = zenConfigRuleFor(azr, false); - configZenRule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_APP; + configZenRule.disabledOrigin = ZenModeConfig.ORIGIN_APP; ZenMode mode = new ZenMode("id", azr, configZenRule); assertThat(mode.getStatus()).isEqualTo(ZenMode.Status.DISABLED_BY_OTHER); diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java index 60885f1079d3..243ce85bd579 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/widget/SelectorWithWidgetPreferenceTest.java @@ -23,22 +23,31 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.app.Application; +import android.platform.test.annotations.DisableFlags; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; +import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; +import android.widget.TextView; import androidx.preference.PreferenceViewHolder; +import androidx.test.core.app.ApplicationProvider; import com.android.settingslib.widget.preference.selector.R; +import com.android.settingslib.widget.selectorwithwidgetpreference.flags.Flags; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; -import org.robolectric.RuntimeEnvironment; @RunWith(RobolectricTestRunner.class) public class SelectorWithWidgetPreferenceTest { + @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); private Application mContext; private SelectorWithWidgetPreference mPreference; @@ -55,7 +64,7 @@ public class SelectorWithWidgetPreferenceTest { @Before public void setUp() { - mContext = RuntimeEnvironment.application; + mContext = ApplicationProvider.getApplicationContext(); mPreference = new SelectorWithWidgetPreference(mContext); View view = LayoutInflater.from(mContext) @@ -121,6 +130,60 @@ public class SelectorWithWidgetPreferenceTest { } @Test + @DisableFlags(Flags.FLAG_ALLOW_SET_TITLE_MAX_LINES) + public void onBindViewHolder_titleMaxLinesSet_flagOff_titleMaxLinesMatchesDefault() { + final int titleMaxLines = 5; + AttributeSet attributeSet = Robolectric.buildAttributeSet() + .addAttribute(R.attr.titleMaxLines, String.valueOf(titleMaxLines)) + .build(); + mPreference = new SelectorWithWidgetPreference(mContext, attributeSet); + View view = LayoutInflater.from(mContext) + .inflate(mPreference.getLayoutResource(), null /* root */); + PreferenceViewHolder preferenceViewHolder = + PreferenceViewHolder.createInstanceForTests(view); + + mPreference.onBindViewHolder(preferenceViewHolder); + + TextView title = (TextView) preferenceViewHolder.findViewById(android.R.id.title); + assertThat(title.getMaxLines()).isEqualTo(SelectorWithWidgetPreference.DEFAULT_MAX_LINES); + } + + @Test + @EnableFlags(Flags.FLAG_ALLOW_SET_TITLE_MAX_LINES) + public void onBindViewHolder_noTitleMaxLinesSet_titleMaxLinesMatchesDefault() { + AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + mPreference = new SelectorWithWidgetPreference(mContext, attributeSet); + View view = LayoutInflater.from(mContext) + .inflate(mPreference.getLayoutResource(), null /* root */); + PreferenceViewHolder preferenceViewHolder = + PreferenceViewHolder.createInstanceForTests(view); + + mPreference.onBindViewHolder(preferenceViewHolder); + + TextView title = (TextView) preferenceViewHolder.findViewById(android.R.id.title); + assertThat(title.getMaxLines()).isEqualTo(SelectorWithWidgetPreference.DEFAULT_MAX_LINES); + } + + @Test + @EnableFlags(Flags.FLAG_ALLOW_SET_TITLE_MAX_LINES) + public void onBindViewHolder_titleMaxLinesSet_titleMaxLinesUpdated() { + final int titleMaxLines = 5; + AttributeSet attributeSet = Robolectric.buildAttributeSet() + .addAttribute(R.attr.titleMaxLines, String.valueOf(titleMaxLines)) + .build(); + mPreference = new SelectorWithWidgetPreference(mContext, attributeSet); + View view = LayoutInflater.from(mContext) + .inflate(mPreference.getLayoutResource(), null /* root */); + PreferenceViewHolder preferenceViewHolder = + PreferenceViewHolder.createInstanceForTests(view); + + mPreference.onBindViewHolder(preferenceViewHolder); + + TextView title = (TextView) preferenceViewHolder.findViewById(android.R.id.title); + assertThat(title.getMaxLines()).isEqualTo(titleMaxLines); + } + + @Test public void nullSummary_containerShouldBeGone() { mPreference.setSummary(null); View summaryContainer = new View(mContext); diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt new file mode 100644 index 000000000000..50fdb31b0414 --- /dev/null +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/EditWidgetsActivityControllerTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.communal.widgets + +import android.app.Activity +import android.app.Application.ActivityLifecycleCallbacks +import android.os.Bundle +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import kotlinx.coroutines.ExperimentalCoroutinesApi +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.clearInvocations +import org.mockito.kotlin.mock +import org.mockito.kotlin.never +import org.mockito.kotlin.verify + +@ExperimentalCoroutinesApi +@SmallTest +@RunWith(AndroidJUnit4::class) +class EditWidgetsActivityControllerTest : SysuiTestCase() { + @Test + fun activityLifecycle_stoppedWhenNotWaitingForResult() { + val activity = mock<Activity>() + val controller = EditWidgetsActivity.ActivityController(activity) + + val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>() + verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture()) + + callbackCapture.lastValue.onActivityStopped(activity) + + verify(activity).finish() + } + + @Test + fun activityLifecycle_notStoppedWhenNotWaitingForResult() { + val activity = mock<Activity>() + val controller = EditWidgetsActivity.ActivityController(activity) + + val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>() + verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture()) + + controller.onWaitingForResult(true) + callbackCapture.lastValue.onActivityStopped(activity) + + verify(activity, never()).finish() + } + + @Test + fun activityLifecycle_stoppedAfterResultReturned() { + val activity = mock<Activity>() + val controller = EditWidgetsActivity.ActivityController(activity) + + val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>() + verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture()) + + controller.onWaitingForResult(true) + controller.onWaitingForResult(false) + callbackCapture.lastValue.onActivityStopped(activity) + + verify(activity).finish() + } + + @Test + fun activityLifecycle_statePreservedThroughInstanceSave() { + val activity = mock<Activity>() + val bundle = Bundle(1) + + run { + val controller = EditWidgetsActivity.ActivityController(activity) + val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>() + verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture()) + + controller.onWaitingForResult(true) + callbackCapture.lastValue.onActivitySaveInstanceState(activity, bundle) + } + + clearInvocations(activity) + + run { + val controller = EditWidgetsActivity.ActivityController(activity) + val callbackCapture = argumentCaptor<ActivityLifecycleCallbacks>() + verify(activity).registerActivityLifecycleCallbacks(callbackCapture.capture()) + + callbackCapture.lastValue.onActivityCreated(activity, bundle) + callbackCapture.lastValue.onActivityStopped(activity) + + verify(activity, never()).finish() + } + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt index add33dacf669..6a886643cebb 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModelTest.kt @@ -43,7 +43,7 @@ class NotificationShadeWindowModelTest : SysuiTestCase() { } @Test - fun transitionToOccluded() = + fun transitionToOccludedByOCCLUDEDTransition() = testScope.runTest { val isKeyguardOccluded by collectLastValue(underTest.isKeyguardOccluded) assertThat(isKeyguardOccluded).isFalse() @@ -62,4 +62,25 @@ class NotificationShadeWindowModelTest : SysuiTestCase() { ) assertThat(isKeyguardOccluded).isFalse() } + + @Test + fun transitionToOccludedByDREAMINGTransition() = + testScope.runTest { + val isKeyguardOccluded by collectLastValue(underTest.isKeyguardOccluded) + assertThat(isKeyguardOccluded).isFalse() + + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.DREAMING, + testScope, + ) + assertThat(isKeyguardOccluded).isTrue() + + keyguardTransitionRepository.sendTransitionSteps( + from = KeyguardState.DREAMING, + to = KeyguardState.AOD, + testScope, + ) + assertThat(isKeyguardOccluded).isFalse() + } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt index 03ef17b6ec5b..2bcbc9aa74ac 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/EditWidgetsActivity.kt @@ -16,7 +16,10 @@ package com.android.systemui.communal.widgets +import android.app.Activity +import android.app.Application.ActivityLifecycleCallbacks import android.content.Intent +import android.content.IntentSender import android.os.Bundle import android.os.RemoteException import android.util.Log @@ -66,12 +69,78 @@ constructor( const val EXTRA_OPEN_WIDGET_PICKER_ON_START = "open_widget_picker_on_start" } + /** + * [ActivityController] handles closing the activity in the case it is backgrounded without + * waiting for an activity result + */ + class ActivityController(activity: Activity) { + companion object { + private const val STATE_EXTRA_IS_WAITING_FOR_RESULT = "extra_is_waiting_for_result" + } + + private var waitingForResult: Boolean = false + + init { + activity.registerActivityLifecycleCallbacks( + object : ActivityLifecycleCallbacks { + override fun onActivityCreated( + activity: Activity, + savedInstanceState: Bundle? + ) { + waitingForResult = + savedInstanceState?.getBoolean(STATE_EXTRA_IS_WAITING_FOR_RESULT) + ?: false + } + + override fun onActivityStarted(activity: Activity) { + // Nothing to implement. + } + + override fun onActivityResumed(activity: Activity) { + // Nothing to implement. + } + + override fun onActivityPaused(activity: Activity) { + // Nothing to implement. + } + + override fun onActivityStopped(activity: Activity) { + // If we're not backgrounded due to waiting for a resul (either widget + // selection + // or configuration), finish activity. + if (!waitingForResult) { + activity.finish() + } + } + + override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) { + outState.putBoolean(STATE_EXTRA_IS_WAITING_FOR_RESULT, waitingForResult) + } + + override fun onActivityDestroyed(activity: Activity) { + // Nothing to implement. + } + } + ) + } + + /** + * Invoked when waiting for an activity result changes, either initiating such wait or + * finishing due to the return of a result. + */ + fun onWaitingForResult(waitingForResult: Boolean) { + this.waitingForResult = waitingForResult + } + } + private val logger = Logger(logBuffer, "EditWidgetsActivity") private val widgetConfigurator by lazy { widgetConfiguratorFactory.create(this) } private var shouldOpenWidgetPickerOnStart = false + private val activityController: ActivityController = ActivityController(this) + private val addWidgetActivityLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(StartActivityForResult()) { result -> when (result.resultCode) { @@ -154,6 +223,13 @@ constructor( // edit mode communalViewModel.currentScene.first { it == CommunalScenes.Blank } communalViewModel.setEditModeState(EditModeState.SHOWING) + + // Show the widget picker, if necessary, after the edit activity has animated in. + // Waiting until after the activity has appeared avoids transitions issues. + if (shouldOpenWidgetPickerOnStart) { + onOpenWidgetPicker() + shouldOpenWidgetPickerOnStart = false + } } } } @@ -186,7 +262,34 @@ constructor( } } + override fun startActivityForResult(intent: Intent, requestCode: Int, options: Bundle?) { + activityController.onWaitingForResult(true) + super.startActivityForResult(intent, requestCode, options) + } + + override fun startIntentSenderForResult( + intent: IntentSender, + requestCode: Int, + fillInIntent: Intent?, + flagsMask: Int, + flagsValues: Int, + extraFlags: Int, + options: Bundle? + ) { + activityController.onWaitingForResult(true) + super.startIntentSenderForResult( + intent, + requestCode, + fillInIntent, + flagsMask, + flagsValues, + extraFlags, + options + ) + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + activityController.onWaitingForResult(false) super.onActivityResult(requestCode, resultCode, data) if (requestCode == WidgetConfigurationController.REQUEST_CODE) { widgetConfigurator.setConfigurationResult(resultCode) @@ -198,11 +301,6 @@ constructor( communalViewModel.setEditActivityShowing(true) - if (shouldOpenWidgetPickerOnStart) { - onOpenWidgetPicker() - shouldOpenWidgetPickerOnStart = false - } - logger.i("Starting the communal widget editor activity") uiEventLogger.log(CommunalUiEvent.COMMUNAL_HUB_EDIT_MODE_SHOWN) } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt index 42866465a0cc..b0f2c18db565 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt +++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt @@ -30,7 +30,7 @@ import com.android.systemui.dreams.AssistantAttentionMonitor import com.android.systemui.dreams.DreamMonitor import com.android.systemui.dreams.homecontrols.HomeControlsDreamStartable import com.android.systemui.globalactions.GlobalActionsComponent -import com.android.systemui.inputdevice.oobe.KeyboardTouchpadOobeTutorialCoreStartable +import com.android.systemui.inputdevice.tutorial.KeyboardTouchpadTutorialCoreStartable import com.android.systemui.keyboard.KeyboardUI import com.android.systemui.keyboard.PhysicalKeyboardCoreStartable import com.android.systemui.keyguard.KeyguardViewConfigurator @@ -258,9 +258,9 @@ abstract class SystemUICoreStartableModule { @Binds @IntoMap - @ClassKey(KeyboardTouchpadOobeTutorialCoreStartable::class) - abstract fun bindOobeSchedulerCoreStartable( - listener: KeyboardTouchpadOobeTutorialCoreStartable + @ClassKey(KeyboardTouchpadTutorialCoreStartable::class) + abstract fun bindKeyboardTouchpadTutorialCoreStartable( + listener: KeyboardTouchpadTutorialCoreStartable ): CoreStartable @Binds diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadOobeTutorialCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt index 701d3da1ee66..e8e1dd4c85d0 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/KeyboardTouchpadOobeTutorialCoreStartable.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/KeyboardTouchpadTutorialCoreStartable.kt @@ -14,23 +14,24 @@ * limitations under the License. */ -package com.android.systemui.inputdevice.oobe +package com.android.systemui.inputdevice.tutorial import com.android.systemui.CoreStartable import com.android.systemui.dagger.SysUISingleton -import com.android.systemui.inputdevice.oobe.domain.interactor.OobeSchedulerInteractor +import com.android.systemui.inputdevice.tutorial.domain.interactor.TutorialSchedulerInteractor import com.android.systemui.shared.Flags.newTouchpadGesturesTutorial import dagger.Lazy import javax.inject.Inject -/** A [CoreStartable] to launch a scheduler for keyboard and touchpad OOBE education */ +/** A [CoreStartable] to launch a scheduler for keyboard and touchpad education */ @SysUISingleton -class KeyboardTouchpadOobeTutorialCoreStartable +class KeyboardTouchpadTutorialCoreStartable @Inject -constructor(private val oobeSchedulerInteractor: Lazy<OobeSchedulerInteractor>) : CoreStartable { +constructor(private val tutorialSchedulerInteractor: Lazy<TutorialSchedulerInteractor>) : + CoreStartable { override fun start() { if (newTouchpadGesturesTutorial()) { - oobeSchedulerInteractor.get().start() + tutorialSchedulerInteractor.get().start() } } } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/data/model/OobeSchedulerInfo.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt index e5aedc031ebe..cfe64e269c95 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/data/model/OobeSchedulerInfo.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/model/TutorialSchedulerInfo.kt @@ -14,14 +14,14 @@ * limitations under the License. */ -package com.android.systemui.inputdevice.oobe.data.model +package com.android.systemui.inputdevice.tutorial.data.model -data class OobeSchedulerInfo( +data class TutorialSchedulerInfo( val keyboard: DeviceSchedulerInfo = DeviceSchedulerInfo(), val touchpad: DeviceSchedulerInfo = DeviceSchedulerInfo() ) -data class DeviceSchedulerInfo(var isLaunched: Boolean = false, var connectionTime: Long? = null) { +data class DeviceSchedulerInfo(var isLaunched: Boolean = false, var connectTime: Long? = null) { val wasEverConnected: Boolean - get() = connectionTime != null + get() = connectTime != null } diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt new file mode 100644 index 000000000000..31ff01836428 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/data/repository/TutorialSchedulerRepository.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.inputdevice.tutorial.data.repository + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.booleanPreferencesKey +import androidx.datastore.preferences.core.edit +import androidx.datastore.preferences.core.longPreferencesKey +import androidx.datastore.preferences.preferencesDataStore +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.inputdevice.tutorial.data.model.DeviceSchedulerInfo +import com.android.systemui.inputdevice.tutorial.data.model.TutorialSchedulerInfo +import javax.inject.Inject +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.map + +@SysUISingleton +class TutorialSchedulerRepository +@Inject +constructor(@Application private val applicationContext: Context) { + + private val Context.dataStore: DataStore<Preferences> by + preferencesDataStore(name = DATASTORE_NAME) + + suspend fun loadData(): TutorialSchedulerInfo { + return applicationContext.dataStore.data.map { pref -> getSchedulerInfo(pref) }.first() + } + + suspend fun updateConnectTime(device: DeviceType, time: Long) { + applicationContext.dataStore.edit { pref -> pref[getConnectKey(device)] = time } + } + + suspend fun updateLaunch(device: DeviceType) { + applicationContext.dataStore.edit { pref -> pref[getLaunchedKey(device)] = true } + } + + private fun getSchedulerInfo(pref: Preferences): TutorialSchedulerInfo { + return TutorialSchedulerInfo( + keyboard = getDeviceSchedulerInfo(pref, DeviceType.KEYBOARD), + touchpad = getDeviceSchedulerInfo(pref, DeviceType.TOUCHPAD) + ) + } + + private fun getDeviceSchedulerInfo(pref: Preferences, device: DeviceType): DeviceSchedulerInfo { + val isLaunched = pref[getLaunchedKey(device)] ?: false + val connectionTime = pref[getConnectKey(device)] ?: null + return DeviceSchedulerInfo(isLaunched, connectionTime) + } + + private fun getLaunchedKey(device: DeviceType) = + booleanPreferencesKey(device.name + IS_LAUNCHED_SUFFIX) + + private fun getConnectKey(device: DeviceType) = + longPreferencesKey(device.name + CONNECT_TIME_SUFFIX) + + companion object { + const val DATASTORE_NAME = "TutorialScheduler" + const val IS_LAUNCHED_SUFFIX = "_IS_LAUNCHED" + const val CONNECT_TIME_SUFFIX = "_CONNECTED_TIME" + } +} + +enum class DeviceType { + KEYBOARD, + TOUCHPAD +} diff --git a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeSchedulerInteractor.kt b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt index b014c08d4564..05e104468f67 100644 --- a/packages/SystemUI/src/com/android/systemui/inputdevice/oobe/domain/interactor/OobeSchedulerInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/inputdevice/tutorial/domain/interactor/TutorialSchedulerInteractor.kt @@ -14,14 +14,15 @@ * limitations under the License. */ -package com.android.systemui.inputdevice.oobe.domain.interactor +package com.android.systemui.inputdevice.tutorial.domain.interactor import android.content.Context import android.content.Intent import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Application -import com.android.systemui.inputdevice.oobe.data.model.DeviceSchedulerInfo -import com.android.systemui.inputdevice.oobe.data.model.OobeSchedulerInfo +import com.android.systemui.inputdevice.tutorial.data.model.DeviceSchedulerInfo +import com.android.systemui.inputdevice.tutorial.data.repository.DeviceType +import com.android.systemui.inputdevice.tutorial.data.repository.TutorialSchedulerRepository import com.android.systemui.keyboard.data.repository.KeyboardRepository import com.android.systemui.touchpad.data.repository.TouchpadRepository import java.time.Duration @@ -35,49 +36,65 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.launch /** - * When the first time a keyboard or touchpad id connected, wait for [LAUNCH_DELAY], then launch the + * When the first time a keyboard or touchpad is connected, wait for [LAUNCH_DELAY], then launch the * tutorial as soon as there's a connected device */ @SysUISingleton -class OobeSchedulerInteractor +class TutorialSchedulerInteractor @Inject constructor( @Application private val context: Context, @Application private val applicationScope: CoroutineScope, private val keyboardRepository: KeyboardRepository, - private val touchpadRepository: TouchpadRepository + private val touchpadRepository: TouchpadRepository, + private val tutorialSchedulerRepository: TutorialSchedulerRepository ) { - private val info = OobeSchedulerInfo() - fun start() { - if (!info.keyboard.isLaunched) { - applicationScope.launch { - schedule(keyboardRepository.isAnyKeyboardConnected, info.keyboard) + applicationScope.launch { + val info = tutorialSchedulerRepository.loadData() + if (!info.keyboard.isLaunched) { + applicationScope.launch { + schedule( + keyboardRepository.isAnyKeyboardConnected, + info.keyboard, + DeviceType.KEYBOARD + ) + } } - } - if (!info.touchpad.isLaunched) { - applicationScope.launch { - schedule(touchpadRepository.isAnyTouchpadConnected, info.touchpad) + if (!info.touchpad.isLaunched) { + applicationScope.launch { + schedule( + touchpadRepository.isAnyTouchpadConnected, + info.touchpad, + DeviceType.TOUCHPAD + ) + } } } } - private suspend fun schedule(isAnyDeviceConnected: Flow<Boolean>, info: DeviceSchedulerInfo) { + private suspend fun schedule( + isAnyDeviceConnected: Flow<Boolean>, + info: DeviceSchedulerInfo, + deviceType: DeviceType + ) { if (!info.wasEverConnected) { waitForDeviceConnection(isAnyDeviceConnected) - info.connectionTime = Instant.now().toEpochMilli() + info.connectTime = Instant.now().toEpochMilli() + tutorialSchedulerRepository.updateConnectTime(deviceType, info.connectTime!!) } - delay(remainingTimeMillis(info.connectionTime!!)) + delay(remainingTimeMillis(info.connectTime!!)) waitForDeviceConnection(isAnyDeviceConnected) info.isLaunched = true - launchOobe() + tutorialSchedulerRepository.updateLaunch(deviceType) + launchTutorial() } private suspend fun waitForDeviceConnection(isAnyDeviceConnected: Flow<Boolean>): Boolean { return isAnyDeviceConnected.filter { it }.first() } - private fun launchOobe() { + private fun launchTutorial() { val intent = Intent(TUTORIAL_ACTION) intent.addCategory(Intent.CATEGORY_DEFAULT) intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK) @@ -90,7 +107,6 @@ constructor( } companion object { - const val TAG = "OobeSchedulerInteractor" const val TUTORIAL_ACTION = "com.android.systemui.action.TOUCHPAD_TUTORIAL" private val LAUNCH_DELAY = Duration.ofHours(72).toMillis() } diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java index 133d14ddb9f4..111a2d43f881 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/buttons/KeyButtonView.java @@ -21,6 +21,7 @@ import static android.view.KeyEvent.KEYCODE_UNKNOWN; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; +import android.annotation.Nullable; import android.app.ActivityManager; import android.content.Context; import android.content.res.Configuration; @@ -49,6 +50,7 @@ import android.view.View; import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.inputmethod.Flags; import android.widget.ImageView; import com.android.internal.annotations.VisibleForTesting; @@ -231,15 +233,28 @@ public class KeyButtonView extends ImageView implements ButtonInterface { @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); - if (mCode != KEYCODE_UNKNOWN) { + if (isClickable()) { info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, null)); if (isLongClickable()) { info.addAction( - new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, null)); + new AccessibilityNodeInfo.AccessibilityAction(ACTION_LONG_CLICK, + getAccessibilityLongClickActionLabel())); } } } + /** + * Gets the accessibility long click action label for the button, or {@code null} for no label. + */ + @Nullable + private CharSequence getAccessibilityLongClickActionLabel() { + if (Flags.imeSwitcherRevamp() && getId() == R.id.ime_switcher) { + return getContext().getText( + com.android.internal.R.string.input_method_ime_switch_long_click_action_desc); + } + return null; + } + @Override protected void onWindowVisibilityChanged(int visibility) { super.onWindowVisibilityChanged(visibility); diff --git a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java index 8d0a386bc3b0..432a35a1a3dd 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java +++ b/packages/SystemUI/src/com/android/systemui/recents/ScreenPinningRequest.java @@ -16,7 +16,9 @@ package com.android.systemui.recents; +import static com.android.systemui.Flags.enableViewCaptureTracing; import static com.android.systemui.shared.recents.utilities.Utilities.isLargeScreen; +import static com.android.systemui.util.ConvenienceExtensionsKt.toKotlinLazy; import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; @@ -53,6 +55,8 @@ import android.widget.TextView; import androidx.annotation.NonNull; +import com.android.app.viewcapture.ViewCapture; +import com.android.app.viewcapture.ViewCaptureAwareWindowManager; import com.android.systemui.CoreStartable; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; @@ -83,6 +87,7 @@ public class ScreenPinningRequest implements private final Lazy<NavigationBarController> mNavigationBarControllerLazy; private final AccessibilityManager mAccessibilityService; private final WindowManager mWindowManager; + private final ViewCaptureAwareWindowManager mViewCaptureAwareWindowManager; private final BroadcastDispatcher mBroadcastDispatcher; private final UserTracker mUserTracker; @@ -106,13 +111,16 @@ public class ScreenPinningRequest implements NavigationModeController navigationModeController, Lazy<NavigationBarController> navigationBarControllerLazy, BroadcastDispatcher broadcastDispatcher, - UserTracker userTracker) { + UserTracker userTracker, + Lazy<ViewCapture> daggerLazyViewCapture) { mContext = context; mNavigationBarControllerLazy = navigationBarControllerLazy; mAccessibilityService = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); + mViewCaptureAwareWindowManager = new ViewCaptureAwareWindowManager(mWindowManager, + toKotlinLazy(daggerLazyViewCapture), enableViewCaptureTracing()); mNavBarMode = navigationModeController.addListener(this); mBroadcastDispatcher = broadcastDispatcher; mUserTracker = userTracker; @@ -123,7 +131,7 @@ public class ScreenPinningRequest implements public void clearPrompt() { if (mRequestWindow != null) { - mWindowManager.removeView(mRequestWindow); + mViewCaptureAwareWindowManager.removeView(mRequestWindow); mRequestWindow = null; } } @@ -144,7 +152,7 @@ public class ScreenPinningRequest implements // show the confirmation WindowManager.LayoutParams lp = getWindowLayoutParams(); - mWindowManager.addView(mRequestWindow, lp); + mViewCaptureAwareWindowManager.addView(mRequestWindow, lp); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt index e1289af58f06..2f9848863059 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt +++ b/packages/SystemUI/src/com/android/systemui/shade/ui/viewmodel/NotificationShadeWindowModel.kt @@ -17,8 +17,11 @@ package com.android.systemui.shade.ui.viewmodel import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED +import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map @@ -29,7 +32,11 @@ class NotificationShadeWindowModel @Inject constructor( keyguardTransitionInteractor: KeyguardTransitionInteractor, + keyguardInteractor: KeyguardInteractor, ) { val isKeyguardOccluded: Flow<Boolean> = - keyguardTransitionInteractor.transitionValue(OCCLUDED).map { it == 1f } + anyOf( + keyguardTransitionInteractor.transitionValue(OCCLUDED).map { it == 1f }, + keyguardTransitionInteractor.transitionValue(DREAMING).map { it == 1f }, + ) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 2c7ce00adbeb..b6d58d6a23d9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -2269,7 +2269,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces { // applying the dimming effect twice. mUiBgExecutor.execute(() -> { float dimAmount = 0f; - if (mWallpaperManager.lockScreenWallpaperExists()) { + // Note that access to WallpaperManager APIs should be guarded by a check into + // WallpaperManager#isWallpaperSupported. Form factors that do not use wallpaper + // may crash SysUI during improper access. ref: b/355307617 + if (!mWallpaperSupported || mWallpaperManager.lockScreenWallpaperExists()) { dimAmount = mWallpaperManager.getWallpaperDimAmount(); } final float scrimDimAmount = dimAmount; diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeWindowModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeWindowModelKosmos.kt index cd4fab8d2970..6252d4498a5e 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeWindowModelKosmos.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/shade/ui/viewmodel/NotificationsShadeWindowModelKosmos.kt @@ -16,8 +16,14 @@ package com.android.systemui.shade.ui.viewmodel +import com.android.systemui.keyguard.domain.interactor.keyguardInteractor import com.android.systemui.keyguard.domain.interactor.keyguardTransitionInteractor import com.android.systemui.kosmos.Kosmos val Kosmos.notificationShadeWindowModel: NotificationShadeWindowModel by - Kosmos.Fixture { NotificationShadeWindowModel(keyguardTransitionInteractor) } + Kosmos.Fixture { + NotificationShadeWindowModel( + keyguardTransitionInteractor, + keyguardInteractor, + ) + } diff --git a/services/core/java/com/android/server/audio/TEST_MAPPING b/services/core/java/com/android/server/audio/TEST_MAPPING index 2cea32af2396..f050090e69c1 100644 --- a/services/core/java/com/android/server/audio/TEST_MAPPING +++ b/services/core/java/com/android/server/audio/TEST_MAPPING @@ -10,6 +10,9 @@ "include-filter": "android.media.audio.cts.AudioFocusTest" }, { + "include-filter": "android.media.audio.cts.AudioPlaybackCaptureTest" + }, + { "include-filter": "android.media.audio.cts.SpatializerTest" } ] diff --git a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java index a380bc1ca171..0047ec20d691 100644 --- a/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java +++ b/services/core/java/com/android/server/inputmethod/IInputMethodInvoker.java @@ -112,7 +112,8 @@ final class IInputMethodInvoker { } @AnyThread - void initializeInternal(IBinder token, IInputMethodPrivilegedOperations privilegedOperations, + void initializeInternal(@NonNull IBinder token, + @NonNull IInputMethodPrivilegedOperations privilegedOperations, @InputMethodNavButtonFlags int navigationBarFlags) { final IInputMethod.InitParams params = new IInputMethod.InitParams(); params.token = token; diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 05e8034b3460..ba01f010fdd3 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1494,27 +1494,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. }); } - /** - * Returns true iff the caller is identified to be the current input method with the token. - * - * @param token the window token given to the input method when it was started - * @param userData {@link UserData} of the calling IME process - * @return true if and only if non-null valid token is specified - */ - @GuardedBy("ImfLock.class") - private boolean calledWithValidTokenLocked(@NonNull IBinder token, @NonNull UserData userData) { - if (token == null) { - throw new InvalidParameterException("token must not be null."); - } - final var bindingController = userData.mBindingController; - if (token != bindingController.getCurToken()) { - Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token." - + " uid:" + Binder.getCallingUid() + " token:" + token); - return false; - } - return true; - } - @BinderThread @Nullable @Override @@ -2571,45 +2550,36 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread - private void updateStatusIcon(@NonNull IBinder token, String packageName, - @DrawableRes int iconId, @NonNull UserData userData) { + @GuardedBy("ImfLock.class") + private void updateStatusIconLocked(String packageName, @DrawableRes int iconId, + @NonNull UserData userData) { final int userId = userData.mUserId; - synchronized (ImfLock.class) { - // To minimize app compat risk, ignore background users' request for single-user mode. - // TODO(b/357178609): generalize the logic and remove this special rule. - if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) { - return; - } - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - final long ident = Binder.clearCallingIdentity(); + // To minimize app compat risk, ignore background users' request for single-user mode. + // TODO(b/357178609): generalize the logic and remove this special rule. + if (!mConcurrentMultiUserModeEnabled && userId != mCurrentUserId) { + return; + } + if (iconId == 0) { + if (DEBUG) Slog.d(TAG, "hide the small icon for the input method"); + hideStatusBarIconLocked(userId); + } else if (packageName != null) { + if (DEBUG) Slog.d(TAG, "show a small icon for the input method"); + final PackageManager userAwarePackageManager = + getPackageManagerForUser(mContext, userId); + ApplicationInfo applicationInfo = null; try { - if (iconId == 0) { - if (DEBUG) Slog.d(TAG, "hide the small icon for the input method"); - hideStatusBarIconLocked(userId); - } else if (packageName != null) { - if (DEBUG) Slog.d(TAG, "show a small icon for the input method"); - final PackageManager userAwarePackageManager = - getPackageManagerForUser(mContext, userId); - ApplicationInfo applicationInfo = null; - try { - applicationInfo = userAwarePackageManager.getApplicationInfo(packageName, - PackageManager.ApplicationInfoFlags.of(0)); - } catch (PackageManager.NameNotFoundException e) { - } - final CharSequence contentDescription = applicationInfo != null - ? userAwarePackageManager.getApplicationLabel(applicationInfo) - : null; - if (mStatusBarManagerInternal != null) { - mStatusBarManagerInternal.setIcon(mSlotIme, packageName, iconId, 0, - contentDescription != null - ? contentDescription.toString() : null); - mStatusBarManagerInternal.setIconVisibility(mSlotIme, true); - } - } - } finally { - Binder.restoreCallingIdentity(ident); + applicationInfo = userAwarePackageManager.getApplicationInfo(packageName, + PackageManager.ApplicationInfoFlags.of(0)); + } catch (PackageManager.NameNotFoundException e) { + } + final CharSequence contentDescription = applicationInfo != null + ? userAwarePackageManager.getApplicationLabel(applicationInfo) + : null; + if (mStatusBarManagerInternal != null) { + mStatusBarManagerInternal.setIcon(mSlotIme, packageName, iconId, 0, + contentDescription != null + ? contentDescription.toString() : null); + mStatusBarManagerInternal.setIconVisibility(mSlotIme, true); } } } @@ -2750,29 +2720,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread + @GuardedBy("ImfLock.class") @SuppressWarnings("deprecation") - private void setImeWindowStatus(@NonNull IBinder token, int vis, int backDisposition, + private void setImeWindowStatusLocked(int vis, int backDisposition, @NonNull UserData userData) { final int topFocusedDisplayId = mWindowManagerInternal.getTopFocusedDisplayId(); final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - final var bindingController = userData.mBindingController; - // Skip update IME status when current token display is not same as focused display. - // Note that we still need to update IME status when focusing external display - // that does not support system decoration and fallback to show IME on default - // display since it is intentional behavior. - final int tokenDisplayId = bindingController.getCurTokenDisplayId(); - if (tokenDisplayId != topFocusedDisplayId && tokenDisplayId != FALLBACK_DISPLAY_ID) { - return; - } - bindingController.setImeWindowVis(vis); - bindingController.setBackDisposition(backDisposition); - updateSystemUiLocked(vis, backDisposition, userId); + final var bindingController = userData.mBindingController; + // Skip update IME status when current token display is not same as focused display. + // Note that we still need to update IME status when focusing external display + // that does not support system decoration and fallback to show IME on default + // display since it is intentional behavior. + final int tokenDisplayId = bindingController.getCurTokenDisplayId(); + if (tokenDisplayId != topFocusedDisplayId && tokenDisplayId != FALLBACK_DISPLAY_ID) { + return; } + bindingController.setImeWindowVis(vis); + bindingController.setBackDisposition(backDisposition); + updateSystemUiLocked(vis, backDisposition, userId); final boolean dismissImeOnBackKeyPressed; switch (backDisposition) { @@ -2791,19 +2757,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread - private void reportStartInput(@NonNull IBinder token, IBinder startInputToken, - @NonNull UserData userData) { - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken); - if (targetWindow != null) { - mWindowManagerInternal.updateInputMethodTargetWindow(targetWindow); - } - final var visibilityStateComputer = userData.mVisibilityStateComputer; - visibilityStateComputer.setLastImeTargetWindow(targetWindow); + @GuardedBy("ImfLock.class") + private void reportStartInputLocked(IBinder startInputToken, @NonNull UserData userData) { + final IBinder targetWindow = mImeTargetWindowMap.get(startInputToken); + if (targetWindow != null) { + mWindowManagerInternal.updateInputMethodTargetWindow(targetWindow); } + final var visibilityStateComputer = userData.mVisibilityStateComputer; + visibilityStateComputer.setLastImeTargetWindow(targetWindow); } @GuardedBy("ImfLock.class") @@ -2850,8 +2811,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. final Boolean windowPerceptible = focusedWindowToken != null ? mFocusedWindowPerceptible.get(focusedWindowToken) : null; - // TODO: Move this clearing calling identity block to setImeWindowStatus after making sure - // all updateSystemUi happens on system privilege. + // TODO: Move this clearing calling identity block to setImeWindowStatusLocked after making + // sure all updateSystemUi happens on system privilege. final long ident = Binder.clearCallingIdentity(); try { if (windowPerceptible != null && !windowPerceptible) { @@ -4119,17 +4080,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. return new Pair<>(menuItems, selectedIndex); } - @BinderThread - private void onImeSwitchButtonClickFromClient(@NonNull IBinder token, int displayId, - @NonNull UserData userData) { - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - onImeSwitchButtonClickLocked(token, displayId, userData); - } - } - @IInputMethodManagerImpl.PermissionVerified(allOf = { Manifest.permission.INTERACT_ACROSS_USERS_FULL, Manifest.permission.WRITE_SECURE_SETTINGS}) @@ -4138,13 +4088,8 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. synchronized (ImfLock.class) { final int userId = resolveImeUserIdFromDisplayIdLocked(displayId); final var userData = getUserData(userId); - final var bindingController = userData.mBindingController; - final var curToken = bindingController.getCurToken(); - if (curToken == null) { - return; - } - onImeSwitchButtonClickLocked(curToken, displayId, userData); + onImeSwitchButtonClickLocked(displayId, userData); } } @@ -4152,17 +4097,16 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. * Handles a click on the IME switch button. Depending on the number of enabled IME subtypes, * this will either switch to the next IME/subtype, or show the input method picker dialog. * - * @param token The token identifying the input method that triggered this. * @param displayId The ID of the display where the input method picker dialog should be shown. * @param userData The data of the user for which to switch IMEs or show the picker dialog. */ + @BinderThread @GuardedBy("ImfLock.class") - private void onImeSwitchButtonClickLocked(@NonNull IBinder token, int displayId, - @NonNull UserData userData) { + private void onImeSwitchButtonClickLocked(int displayId, @NonNull UserData userData) { final int userId = userData.mUserId; final var settings = InputMethodSettingsRepository.get(userId); if (hasMultipleSubtypesForSwitcher(true /* nonAuxOnly */, settings)) { - switchToNextInputMethodLocked(token, false /* onlyCurrentIme */, userData); + switchToNextInputMethodLocked(false /* onlyCurrentIme */, userData); } else { showInputMethodPickerFromSystem( InputMethodManager.SHOW_IM_PICKER_MODE_INCLUDE_AUXILIARY_SUBTYPES, displayId); @@ -4176,143 +4120,104 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread - private void setInputMethod(@NonNull IBinder token, String id, @NonNull UserData userData) { + @GuardedBy("ImfLock.class") + private void setInputMethodAndSubtypeLocked(String id, @Nullable InputMethodSubtype subtype, + @NonNull UserData userData) { final int callingUid = Binder.getCallingUid(); final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); - final InputMethodInfo imi = settings.getMethodMap().get(id); - if (imi == null || !canCallerAccessInputMethod( - imi.getPackageName(), callingUid, userId, settings)) { - throw getExceptionForUnknownImeId(id); - } - setInputMethodWithSubtypeIdLocked(token, id, NOT_A_SUBTYPE_ID, userId); + final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); + final InputMethodInfo imi = settings.getMethodMap().get(id); + if (imi == null || !canCallerAccessInputMethod( + imi.getPackageName(), callingUid, userId, settings)) { + throw getExceptionForUnknownImeId(id); } + final int subtypeId = subtype != null + ? SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()) + : NOT_A_SUBTYPE_ID; + setInputMethodWithSubtypeIdLocked(id, subtypeId, userId); } @BinderThread - private void setInputMethodAndSubtype(@NonNull IBinder token, String id, - InputMethodSubtype subtype, @NonNull UserData userData) { - final int callingUid = Binder.getCallingUid(); + @GuardedBy("ImfLock.class") + private boolean switchToPreviousInputMethodLocked(@NonNull UserData userData) { final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); - final InputMethodInfo imi = settings.getMethodMap().get(id); - if (imi == null || !canCallerAccessInputMethod( - imi.getPackageName(), callingUid, userId, settings)) { - throw getExceptionForUnknownImeId(id); - } - if (subtype != null) { - setInputMethodWithSubtypeIdLocked(token, id, - SubtypeUtils.getSubtypeIdFromHashCode(imi, subtype.hashCode()), userId); - } else { - setInputMethod(token, id, userData); - } + final var bindingController = userData.mBindingController; + final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); + final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype(); + final InputMethodInfo lastImi; + if (lastIme != null) { + lastImi = settings.getMethodMap().get(lastIme.first); + } else { + lastImi = null; } - } - - @BinderThread - private boolean switchToPreviousInputMethod(@NonNull IBinder token, - @NonNull UserData userData) { - final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return false; - } - final var bindingController = userData.mBindingController; - final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); - final Pair<String, String> lastIme = settings.getLastInputMethodAndSubtype(); - final InputMethodInfo lastImi; - if (lastIme != null) { - lastImi = settings.getMethodMap().get(lastIme.first); - } else { - lastImi = null; - } - final var currentSubtype = bindingController.getCurrentSubtype(); - String targetLastImiId = null; - int subtypeId = NOT_A_SUBTYPE_ID; - if (lastIme != null && lastImi != null) { - final boolean imiIdIsSame = lastImi.getId().equals( - bindingController.getSelectedMethodId()); - final int lastSubtypeHash = Integer.parseInt(lastIme.second); - final int currentSubtypeHash = currentSubtype == null ? NOT_A_SUBTYPE_ID - : currentSubtype.hashCode(); - // If the last IME is the same as the current IME and the last subtype is not - // defined, there is no need to switch to the last IME. - if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { - targetLastImiId = lastIme.first; - subtypeId = SubtypeUtils.getSubtypeIdFromHashCode(lastImi, lastSubtypeHash); - } - } - - if (TextUtils.isEmpty(targetLastImiId) - && !InputMethodUtils.canAddToLastInputMethod(currentSubtype)) { - // This is a safety net. If the currentSubtype can't be added to the history - // and the framework couldn't find the last ime, we will make the last ime be - // the most applicable enabled keyboard subtype of the system imes. - final List<InputMethodInfo> enabled = settings.getEnabledInputMethodList(); - if (enabled != null) { - final int enabledCount = enabled.size(); - final String locale; - if (currentSubtype != null - && !TextUtils.isEmpty(currentSubtype.getLocale())) { - locale = currentSubtype.getLocale(); - } else { - locale = SystemLocaleWrapper.get(userId).get(0).toString(); - } - for (int i = 0; i < enabledCount; ++i) { - final InputMethodInfo imi = enabled.get(i); - if (imi.getSubtypeCount() > 0 && imi.isSystem()) { - InputMethodSubtype keyboardSubtype = - SubtypeUtils.findLastResortApplicableSubtype( - SubtypeUtils.getSubtypes(imi), - SubtypeUtils.SUBTYPE_MODE_KEYBOARD, locale, true); - if (keyboardSubtype != null) { - targetLastImiId = imi.getId(); - subtypeId = SubtypeUtils.getSubtypeIdFromHashCode(imi, - keyboardSubtype.hashCode()); - if (keyboardSubtype.getLocale().equals(locale)) { - break; - } + final var currentSubtype = bindingController.getCurrentSubtype(); + String targetLastImiId = null; + int subtypeId = NOT_A_SUBTYPE_ID; + if (lastIme != null && lastImi != null) { + final boolean imiIdIsSame = lastImi.getId().equals( + bindingController.getSelectedMethodId()); + final int lastSubtypeHash = Integer.parseInt(lastIme.second); + final int currentSubtypeHash = currentSubtype == null ? NOT_A_SUBTYPE_ID + : currentSubtype.hashCode(); + // If the last IME is the same as the current IME and the last subtype is not + // defined, there is no need to switch to the last IME. + if (!imiIdIsSame || lastSubtypeHash != currentSubtypeHash) { + targetLastImiId = lastIme.first; + subtypeId = SubtypeUtils.getSubtypeIdFromHashCode(lastImi, lastSubtypeHash); + } + } + + if (TextUtils.isEmpty(targetLastImiId) + && !InputMethodUtils.canAddToLastInputMethod(currentSubtype)) { + // This is a safety net. If the currentSubtype can't be added to the history + // and the framework couldn't find the last ime, we will make the last ime be + // the most applicable enabled keyboard subtype of the system imes. + final List<InputMethodInfo> enabled = settings.getEnabledInputMethodList(); + if (enabled != null) { + final int enabledCount = enabled.size(); + final String locale; + if (currentSubtype != null + && !TextUtils.isEmpty(currentSubtype.getLocale())) { + locale = currentSubtype.getLocale(); + } else { + locale = SystemLocaleWrapper.get(userId).get(0).toString(); + } + for (int i = 0; i < enabledCount; ++i) { + final InputMethodInfo imi = enabled.get(i); + if (imi.getSubtypeCount() > 0 && imi.isSystem()) { + InputMethodSubtype keyboardSubtype = + SubtypeUtils.findLastResortApplicableSubtype( + SubtypeUtils.getSubtypes(imi), + SubtypeUtils.SUBTYPE_MODE_KEYBOARD, locale, true); + if (keyboardSubtype != null) { + targetLastImiId = imi.getId(); + subtypeId = SubtypeUtils.getSubtypeIdFromHashCode(imi, + keyboardSubtype.hashCode()); + if (keyboardSubtype.getLocale().equals(locale)) { + break; } } } } } - - if (!TextUtils.isEmpty(targetLastImiId)) { - if (DEBUG) { - Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second - + ", from: " + bindingController.getSelectedMethodId() + ", " - + subtypeId); - } - setInputMethodWithSubtypeIdLocked(token, targetLastImiId, subtypeId, userId); - return true; - } else { - return false; - } } - } - @BinderThread - private boolean switchToNextInputMethod(@NonNull IBinder token, boolean onlyCurrentIme, - @NonNull UserData userData) { - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return false; + if (!TextUtils.isEmpty(targetLastImiId)) { + if (DEBUG) { + Slog.d(TAG, "Switch to: " + lastImi.getId() + ", " + lastIme.second + + ", from: " + bindingController.getSelectedMethodId() + ", " + + subtypeId); } - return switchToNextInputMethodLocked(token, onlyCurrentIme, userData); + setInputMethodWithSubtypeIdLocked(targetLastImiId, subtypeId, userId); + return true; + } else { + return false; } } + @BinderThread @GuardedBy("ImfLock.class") - private boolean switchToNextInputMethodLocked(@Nullable IBinder token, boolean onlyCurrentIme, + private boolean switchToNextInputMethodLocked(boolean onlyCurrentIme, @NonNull UserData userData) { final var bindingController = userData.mBindingController; final var currentImi = bindingController.getSelectedMethod(); @@ -4323,26 +4228,21 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. if (nextSubtype == null) { return false; } - setInputMethodWithSubtypeIdLocked(token, nextSubtype.mImi.getId(), - nextSubtype.mSubtypeId, userData.mUserId); + setInputMethodWithSubtypeIdLocked(nextSubtype.mImi.getId(), nextSubtype.mSubtypeId, + userData.mUserId); return true; } @BinderThread - private boolean shouldOfferSwitchingToNextInputMethod(@NonNull IBinder token, - @NonNull UserData userData) { - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return false; - } - final var bindingController = userData.mBindingController; - final var currentImi = bindingController.getSelectedMethod(); - final ImeSubtypeListItem nextSubtype = userData.mSwitchingController - .getNextInputMethodLocked(false /* onlyCurrentIme */, currentImi, - bindingController.getCurrentSubtype(), - MODE_AUTO, true /* forward */); - return nextSubtype != null; - } + @GuardedBy("ImfLock.class") + private boolean shouldOfferSwitchingToNextInputMethodLocked(@NonNull UserData userData) { + final var bindingController = userData.mBindingController; + final var currentImi = bindingController.getSelectedMethod(); + final ImeSubtypeListItem nextSubtype = userData.mSwitchingController + .getNextInputMethodLocked(false /* onlyCurrentIme */, currentImi, + bindingController.getCurrentSubtype(), + MODE_AUTO, true /* forward */); + return nextSubtype != null; } @Override @@ -4771,92 +4671,58 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread - private void notifyUserAction(@NonNull IBinder token, @NonNull UserData userData) { + @GuardedBy("ImfLock.class") + private void notifyUserActionLocked(@NonNull UserData userData) { if (DEBUG) { Slog.d(TAG, "Got the notification of a user action."); } - synchronized (ImfLock.class) { - final var bindingController = userData.mBindingController; - if (bindingController.getCurToken() != token) { - if (DEBUG) { - Slog.d(TAG, "Ignoring the user action notification from IMEs that are no longer" - + " active."); - } - return; - } - final InputMethodInfo imi = bindingController.getSelectedMethod(); - if (imi != null) { - userData.mSwitchingController.onUserActionLocked(imi, - bindingController.getCurrentSubtype()); - } + final var bindingController = userData.mBindingController; + final InputMethodInfo imi = bindingController.getSelectedMethod(); + if (imi != null) { + userData.mSwitchingController.onUserActionLocked(imi, + bindingController.getCurrentSubtype()); } } @BinderThread - private void applyImeVisibility(IBinder token, IBinder windowToken, boolean setVisible, + @GuardedBy("ImfLock.class") + private void applyImeVisibilityLocked(IBinder windowToken, boolean setVisible, @NonNull ImeTracker.Token statsToken, @NonNull UserData userData) { try { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibility"); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.applyImeVisibilityLocked"); final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - ImeTracker.forLogging().onFailed(statsToken, - ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); - return; - } - ImeTracker.forLogging().onProgress(statsToken, - ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); - final var visibilityStateComputer = userData.mVisibilityStateComputer; - final IBinder requestToken = visibilityStateComputer.getWindowTokenFrom( - windowToken, userId); - mVisibilityApplier.applyImeVisibility(requestToken, statsToken, - setVisible ? STATE_SHOW_IME : STATE_HIDE_IME, - SoftInputShowHideReason.NOT_SET /* ignore reason */, userId); - } + final var visibilityStateComputer = userData.mVisibilityStateComputer; + final IBinder requestToken = visibilityStateComputer.getWindowTokenFrom( + windowToken, userId); + mVisibilityApplier.applyImeVisibility(requestToken, statsToken, + setVisible ? STATE_SHOW_IME : STATE_HIDE_IME, + SoftInputShowHideReason.NOT_SET /* ignore reason */, userId); } finally { Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); } } @BinderThread - private void resetStylusHandwriting(int requestId) { - synchronized (ImfLock.class) { - final OptionalInt curRequest = mHwController.getCurrentRequestId(); - if (!curRequest.isPresent() || curRequest.getAsInt() != requestId) { - Slog.w(TAG, "IME requested to finish handwriting with a mismatched requestId: " - + requestId); - } - removeVirtualStylusIdForTestSessionLocked(); - scheduleResetStylusHandwriting(); + @GuardedBy("ImfLock.class") + private void resetStylusHandwritingLocked(int requestId) { + final OptionalInt curRequest = mHwController.getCurrentRequestId(); + if (!curRequest.isPresent() || curRequest.getAsInt() != requestId) { + Slog.w(TAG, "IME requested to finish handwriting with a mismatched requestId: " + + requestId); } + removeVirtualStylusIdForTestSessionLocked(); + scheduleResetStylusHandwriting(); } @GuardedBy("ImfLock.class") - private void setInputMethodWithSubtypeIdLocked(IBinder token, String id, int subtypeId, + private void setInputMethodWithSubtypeIdLocked(String id, int subtypeId, @UserIdInt int userId) { - final var bindingController = getInputMethodBindingController(userId); - if (token == null) { - if (mContext.checkCallingOrSelfPermission( - android.Manifest.permission.WRITE_SECURE_SETTINGS) - != PackageManager.PERMISSION_GRANTED) { - throw new SecurityException( - "Using null token requires permission " - + android.Manifest.permission.WRITE_SECURE_SETTINGS); - } - } else if (bindingController.getCurToken() != token) { - Slog.w(TAG, "Ignoring setInputMethod of uid " + Binder.getCallingUid() - + " token: " + token); - return; - } else { - // Called with current IME's token. - final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); - if (settings.getMethodMap().get(id) != null - && settings.getEnabledInputMethodListWithFilter( - (info) -> info.getId().equals(id)).isEmpty()) { - throw new IllegalStateException("Requested IME is not enabled: " + id); - } + final InputMethodSettings settings = InputMethodSettingsRepository.get(userId); + if (settings.getMethodMap().get(id) != null + && settings.getEnabledInputMethodListWithFilter( + (info) -> info.getId().equals(id)).isEmpty()) { + throw new IllegalStateException("Requested IME is not enabled: " + id); } - final long ident = Binder.clearCallingIdentity(); try { setInputMethodLocked(id, subtypeId, userId); @@ -4894,72 +4760,36 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread - private void hideMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken, + @GuardedBy("ImfLock.class") + private void hideMySoftInputLocked(@NonNull ImeTracker.Token statsToken, @InputMethodManager.HideFlags int flags, @SoftInputShowHideReason int reason, @NonNull UserData userData) { - try { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput"); - final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - ImeTracker.forLogging().onFailed(statsToken, - ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); - return; - } - ImeTracker.forLogging().onProgress(statsToken, - ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); - final long ident = Binder.clearCallingIdentity(); - try { - if (Flags.refactorInsetsController()) { - userData.mCurClient.mClient.setImeVisibility(false, statsToken); - // TODO we will loose the flags here - setImeVisibilityOnFocusedWindowClient(false, userData, statsToken); - } else { - final var visibilityStateComputer = userData.mVisibilityStateComputer; - hideCurrentInputLocked(visibilityStateComputer.getLastImeTargetWindow(), - statsToken, flags, null /* resultReceiver */, reason, userId); - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + final int userId = userData.mUserId; + if (Flags.refactorInsetsController()) { + userData.mCurClient.mClient.setImeVisibility(false, statsToken); + // TODO we will loose the flags here + setImeVisibilityOnFocusedWindowClient(false, userData, statsToken); + } else { + final var visibilityStateComputer = userData.mVisibilityStateComputer; + hideCurrentInputLocked(visibilityStateComputer.getLastImeTargetWindow(), + statsToken, flags, null /* resultReceiver */, reason, userId); } } @BinderThread - private void showMySoftInput(@NonNull IBinder token, @NonNull ImeTracker.Token statsToken, + @GuardedBy("ImfLock.class") + private void showMySoftInputLocked(@NonNull ImeTracker.Token statsToken, @InputMethodManager.ShowFlags int flags, @SoftInputShowHideReason int reason, @NonNull UserData userData) { - try { - Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput"); - final int userId = userData.mUserId; - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - ImeTracker.forLogging().onFailed(statsToken, - ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); - return; - } - ImeTracker.forLogging().onProgress(statsToken, - ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); - final long ident = Binder.clearCallingIdentity(); - try { - if (Flags.refactorInsetsController()) { - userData.mCurClient.mClient.setImeVisibility(true, statsToken); - setImeVisibilityOnFocusedWindowClient(true, userData, statsToken); - } else { - final var visibilityStateComputer = userData.mVisibilityStateComputer; - showCurrentInputLocked(visibilityStateComputer.getLastImeTargetWindow(), - statsToken, flags, MotionEvent.TOOL_TYPE_UNKNOWN, - null /* resultReceiver */, reason, userId); - } - } finally { - Binder.restoreCallingIdentity(ident); - } - } - } finally { - Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + final int userId = userData.mUserId; + if (Flags.refactorInsetsController()) { + userData.mCurClient.mClient.setImeVisibility(true, statsToken); + setImeVisibilityOnFocusedWindowClient(true, userData, statsToken); + } else { + final var visibilityStateComputer = userData.mVisibilityStateComputer; + showCurrentInputLocked(visibilityStateComputer.getLastImeTargetWindow(), + statsToken, flags, MotionEvent.TOOL_TYPE_UNKNOWN, + null /* resultReceiver */, reason, userId); } } @@ -5262,7 +5092,9 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. private record HandwritingRequest(int requestId, int pid, @NonNull UserData userData) { } @BinderThread - private void onStylusHandwritingReady(int requestId, int pid, @NonNull UserData userData) { + @GuardedBy("ImfLock.class") + private void onStylusHandwritingReadyLocked(int requestId, int pid, + @NonNull UserData userData) { mHandler.obtainMessage(MSG_START_HANDWRITING, new HandwritingRequest(requestId, pid, userData)).sendToTarget(); } @@ -6091,71 +5923,54 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } @BinderThread - private IInputContentUriToken createInputContentUriToken(@Nullable IBinder token, - @Nullable Uri contentUri, @Nullable String packageName, @NonNull UserData userData) { - if (token == null) { - throw new NullPointerException("token"); - } - if (packageName == null) { - throw new NullPointerException("packageName"); - } - if (contentUri == null) { - throw new NullPointerException("contentUri"); - } + @GuardedBy("ImfLock.class") + @Nullable + private IInputContentUriToken createInputContentUriTokenLocked(@NonNull Uri contentUri, + @NonNull String packageName, @NonNull UserData userData) { + Objects.requireNonNull(packageName, "packageName must not be null"); + Objects.requireNonNull(contentUri, "contentUri must not be null"); final String contentUriScheme = contentUri.getScheme(); if (!"content".equals(contentUriScheme)) { throw new InvalidParameterException("contentUri must have content scheme"); } - synchronized (ImfLock.class) { - final int uid = Binder.getCallingUid(); - final var bindingController = userData.mBindingController; - if (bindingController.getSelectedMethodId() == null) { - return null; - } - if (bindingController.getCurToken() != token) { - Slog.e(TAG, "Ignoring createInputContentUriToken mCurToken=" - + bindingController.getCurToken() + " token=" + token); - return null; - } - // We cannot simply distinguish a bad IME that reports an arbitrary package name from - // an unfortunate IME whose internal state is already obsolete due to the asynchronous - // nature of our system. Let's compare it with our internal record. - final var curPackageName = userData.mCurEditorInfo != null - ? userData.mCurEditorInfo.packageName : null; - if (!TextUtils.equals(curPackageName, packageName)) { - Slog.e(TAG, "Ignoring createInputContentUriToken mCurEditorInfo.packageName=" - + curPackageName + " packageName=" + packageName); - return null; - } - // This user ID can never be spoofed. - final int appUserId = UserHandle.getUserId(userData.mCurClient.mUid); - // This user ID may be invalid if "contentUri" embedded an invalid user ID. - final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(contentUri, - userData.mUserId); - final Uri contentUriWithoutUserId = ContentProvider.getUriWithoutUserId(contentUri); - // Note: InputContentUriTokenHandler.take() checks whether the IME (specified by "uid") - // actually has the right to grant a read permission for "contentUriWithoutUserId" that - // is claimed to belong to "contentUriOwnerUserId". For example, specifying random - // content URI and/or contentUriOwnerUserId just results in a SecurityException thrown - // from InputContentUriTokenHandler.take() and can never be allowed beyond what is - // actually allowed to "uid", which is guaranteed to be the IME's one. - return new InputContentUriTokenHandler(contentUriWithoutUserId, uid, - packageName, contentUriOwnerUserId, appUserId); + final int uid = Binder.getCallingUid(); + final var bindingController = userData.mBindingController; + if (bindingController.getSelectedMethodId() == null) { + return null; + } + // We cannot simply distinguish a bad IME that reports an arbitrary package name from + // an unfortunate IME whose internal state is already obsolete due to the asynchronous + // nature of our system. Let's compare it with our internal record. + final var curPackageName = userData.mCurEditorInfo != null + ? userData.mCurEditorInfo.packageName : null; + if (!TextUtils.equals(curPackageName, packageName)) { + Slog.e(TAG, "Ignoring createInputContentUriTokenLocked mCurEditorInfo.packageName=" + + curPackageName + " packageName=" + packageName); + return null; } + // This user ID can never be spoofed. + final int appUserId = UserHandle.getUserId(userData.mCurClient.mUid); + // This user ID may be invalid if "contentUri" embedded an invalid user ID. + final int contentUriOwnerUserId = ContentProvider.getUserIdFromUri(contentUri, + userData.mUserId); + final Uri contentUriWithoutUserId = ContentProvider.getUriWithoutUserId(contentUri); + // Note: InputContentUriTokenHandler.take() checks whether the IME (specified by "uid") + // actually has the right to grant a read permission for "contentUriWithoutUserId" that + // is claimed to belong to "contentUriOwnerUserId". For example, specifying random + // content URI and/or contentUriOwnerUserId just results in a SecurityException thrown + // from InputContentUriTokenHandler.take() and can never be allowed beyond what is + // actually allowed to "uid", which is guaranteed to be the IME's one. + return new InputContentUriTokenHandler(contentUriWithoutUserId, uid, + packageName, contentUriOwnerUserId, appUserId); } @BinderThread - private void reportFullscreenMode(@NonNull IBinder token, boolean fullscreen, - @NonNull UserData userData) { - synchronized (ImfLock.class) { - if (!calledWithValidTokenLocked(token, userData)) { - return; - } - if (userData.mCurClient != null && userData.mCurClient.mClient != null) { - userData.mInFullscreenMode = fullscreen; - userData.mCurClient.mClient.reportFullscreenMode(fullscreen); - } + @GuardedBy("ImfLock.class") + private void reportFullscreenModeLocked(boolean fullscreen, @NonNull UserData userData) { + if (userData.mCurClient != null && userData.mCurClient.mClient != null) { + userData.mInFullscreenMode = fullscreen; + userData.mCurClient.mClient.reportFullscreenMode(fullscreen); } } @@ -6762,17 +6577,6 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. out.print(imeId); out.print(" selected for user #"); out.println(userId); - - // Workaround for b/354782333. - final var settingsValue = SecureSettingsWrapper.getString( - Settings.Secure.DEFAULT_INPUT_METHOD, "", userId); - if (!TextUtils.equals(settingsValue, imeId)) { - Slog.w(TAG, "DEFAULT_INPUT_METHOD=" + settingsValue - + " is not updated. Fixing it up to " + imeId - + " See b/354782333."); - SecureSettingsWrapper.putString( - Settings.Secure.DEFAULT_INPUT_METHOD, imeId, userId); - } } hasFailed |= failedToSelectUnknownIme; } @@ -6959,13 +6763,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. private static final class InputMethodPrivilegedOperationsImpl extends IInputMethodPrivilegedOperations.Stub { + @NonNull private final InputMethodManagerService mImms; @NonNull private final IBinder mToken; @NonNull private final UserData mUserData; - InputMethodPrivilegedOperationsImpl(InputMethodManagerService imms, + InputMethodPrivilegedOperationsImpl(@NonNull InputMethodManagerService imms, @NonNull IBinder token, @NonNull UserData userData) { mImms = imms; mToken = token; @@ -6975,19 +6780,34 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @BinderThread @Override public void setImeWindowStatusAsync(int vis, int backDisposition) { - mImms.setImeWindowStatus(mToken, vis, backDisposition, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.setImeWindowStatusLocked(vis, backDisposition, mUserData); + } } @BinderThread @Override public void reportStartInputAsync(IBinder startInputToken) { - mImms.reportStartInput(mToken, startInputToken, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.reportStartInputLocked(startInputToken, mUserData); + } } @BinderThread @Override public void setHandwritingSurfaceNotTouchable(boolean notTouchable) { - mImms.mHwController.setNotTouchable(notTouchable); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.mHwController.setNotTouchable(notTouchable); + } } @BinderThread @@ -6996,8 +6816,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. AndroidFuture future /* T=IBinder */) { @SuppressWarnings("unchecked") final AndroidFuture<IBinder> typedFuture = future; try { - typedFuture.complete(mImms.createInputContentUriToken( - mToken, contentUri, packageName, mUserData).asBinder()); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + typedFuture.complete(null); + return; + } + typedFuture.complete(mImms.createInputContentUriTokenLocked( + contentUri, packageName, mUserData).asBinder()); + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7006,7 +6832,12 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @BinderThread @Override public void reportFullscreenModeAsync(boolean fullscreen) { - mImms.reportFullscreenMode(mToken, fullscreen, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.reportFullscreenModeLocked(fullscreen, mUserData); + } } @BinderThread @@ -7014,8 +6845,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. public void setInputMethod(String id, AndroidFuture future /* T=Void */) { @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future; try { - mImms.setInputMethod(mToken, id, mUserData); - typedFuture.complete(null); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + typedFuture.complete(null); + return; + } + mImms.setInputMethodAndSubtypeLocked(id, null /* subtype */, mUserData); + typedFuture.complete(null); + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7027,8 +6864,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. AndroidFuture future /* T=Void */) { @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future; try { - mImms.setInputMethodAndSubtype(mToken, id, subtype, mUserData); - typedFuture.complete(null); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + typedFuture.complete(null); + return; + } + mImms.setInputMethodAndSubtypeLocked(id, subtype, mUserData); + typedFuture.complete(null); + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7041,8 +6884,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. AndroidFuture future /* T=Void */) { @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future; try { - mImms.hideMySoftInput(mToken, statsToken, flags, reason, mUserData); - typedFuture.complete(null); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); + typedFuture.complete(null); + return; + } + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.hideMySoftInput"); + final long ident = Binder.clearCallingIdentity(); + try { + mImms.hideMySoftInputLocked(statsToken, flags, reason, mUserData); + typedFuture.complete(null); + } finally { + Binder.restoreCallingIdentity(ident); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7055,8 +6915,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. AndroidFuture future /* T=Void */) { @SuppressWarnings("unchecked") final AndroidFuture<Void> typedFuture = future; try { - mImms.showMySoftInput(mToken, statsToken, flags, reason, mUserData); - typedFuture.complete(null); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); + typedFuture.complete(null); + return; + } + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); + Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "IMMS.showMySoftInput"); + final long ident = Binder.clearCallingIdentity(); + try { + mImms.showMySoftInputLocked(statsToken, flags, reason, mUserData); + typedFuture.complete(null); + } finally { + Binder.restoreCallingIdentity(ident); + Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER); + } + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7065,7 +6942,17 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @BinderThread @Override public void updateStatusIconAsync(String packageName, @DrawableRes int iconId) { - mImms.updateStatusIcon(mToken, packageName, iconId, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + final long ident = Binder.clearCallingIdentity(); + try { + mImms.updateStatusIconLocked(packageName, iconId, mUserData); + } finally { + Binder.restoreCallingIdentity(ident); + } + } } @BinderThread @@ -7073,7 +6960,13 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. public void switchToPreviousInputMethod(AndroidFuture future /* T=Boolean */) { @SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future; try { - typedFuture.complete(mImms.switchToPreviousInputMethod(mToken, mUserData)); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + typedFuture.complete(false); + return; + } + typedFuture.complete(mImms.switchToPreviousInputMethodLocked(mUserData)); + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7085,8 +6978,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. AndroidFuture future /* T=Boolean */) { @SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future; try { - typedFuture.complete(mImms.switchToNextInputMethod(mToken, onlyCurrentIme, - mUserData)); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + typedFuture.complete(false); + return; + } + typedFuture.complete(mImms.switchToNextInputMethodLocked(onlyCurrentIme, + mUserData)); + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7097,8 +6996,14 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. public void shouldOfferSwitchingToNextInputMethod(AndroidFuture future /* T=Boolean */) { @SuppressWarnings("unchecked") final AndroidFuture<Boolean> typedFuture = future; try { - typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethod(mToken, - mUserData)); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + typedFuture.complete(false); + return; + } + typedFuture.complete(mImms.shouldOfferSwitchingToNextInputMethodLocked( + mUserData)); + } } catch (Throwable e) { typedFuture.completeExceptionally(e); } @@ -7107,39 +7012,68 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. @BinderThread @Override public void onImeSwitchButtonClickFromClient(int displayId) { - mImms.onImeSwitchButtonClickFromClient(mToken, displayId, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.onImeSwitchButtonClickLocked(displayId, mUserData); + } } @BinderThread @Override public void notifyUserActionAsync() { - mImms.notifyUserAction(mToken, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.notifyUserActionLocked(mUserData); + } } @BinderThread @Override public void applyImeVisibilityAsync(IBinder windowToken, boolean setVisible, @NonNull ImeTracker.Token statsToken) { - mImms.applyImeVisibility(mToken, windowToken, setVisible, statsToken, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + ImeTracker.forLogging().onFailed(statsToken, + ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); + return; + } + ImeTracker.forLogging().onProgress(statsToken, + ImeTracker.PHASE_SERVER_CURRENT_ACTIVE_IME); + mImms.applyImeVisibilityLocked(windowToken, setVisible, statsToken, mUserData); + } } @BinderThread @Override public void onStylusHandwritingReady(int requestId, int pid) { - mImms.onStylusHandwritingReady(requestId, pid, mUserData); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.onStylusHandwritingReadyLocked(requestId, pid, mUserData); + } } @BinderThread @Override public void resetStylusHandwriting(int requestId) { - mImms.resetStylusHandwriting(requestId); + synchronized (ImfLock.class) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { + return; + } + mImms.resetStylusHandwritingLocked(requestId); + } } @BinderThread @Override public void switchKeyboardLayoutAsync(int direction) { synchronized (ImfLock.class) { - if (!mImms.calledWithValidTokenLocked(mToken, mUserData)) { + if (!calledWithValidTokenLocked(mToken, mUserData)) { return; } final long ident = Binder.clearCallingIdentity(); @@ -7150,5 +7084,25 @@ public final class InputMethodManagerService implements IInputMethodManagerImpl. } } } + + /** + * Returns true iff the caller is identified to be the current input method with the token. + * + * @param token the window token given to the input method when it was started + * @param userData {@link UserData} of the calling IME process + * @return true if and only if non-null valid token is specified + */ + @GuardedBy("ImfLock.class") + private static boolean calledWithValidTokenLocked(@NonNull IBinder token, + @NonNull UserData userData) { + Objects.requireNonNull(token, "token must not be null"); + final var bindingController = userData.mBindingController; + if (token != bindingController.getCurToken()) { + Slog.e(TAG, "Ignoring " + Debug.getCaller() + " due to an invalid token." + + " uid:" + Binder.getCallingUid() + " token:" + token); + return false; + } + return true; + } } } diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index 3cc04570643f..a44e55344fe3 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -17,7 +17,7 @@ package com.android.server.notification; import static android.service.notification.Condition.STATE_TRUE; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; import android.app.INotificationManager; import android.app.NotificationManager; @@ -326,7 +326,7 @@ public class ConditionProviders extends ManagedServices { // if user turned on the mode, ignore the update unless the app also wants the // mode on. this will update the origin of the mode and let the owner turn it // off when the context ends - if (r.condition != null && r.condition.source == UPDATE_ORIGIN_USER) { + if (r.condition != null && r.condition.source == ORIGIN_USER_IN_SYSTEMUI) { if (r.condition.state == STATE_TRUE && c.state == STATE_TRUE) { r.condition = c; } diff --git a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java index d060f8f2d036..c8cb54f8a55e 100644 --- a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java +++ b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java @@ -31,7 +31,7 @@ import android.os.PowerManager; import android.service.notification.DeviceEffectsApplier; import android.service.notification.ZenDeviceEffects; import android.service.notification.ZenModeConfig; -import android.service.notification.ZenModeConfig.ConfigChangeOrigin; +import android.service.notification.ZenModeConfig.ConfigOrigin; import android.util.Slog; import com.android.internal.annotations.GuardedBy; @@ -72,7 +72,7 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { } @Override - public void apply(ZenDeviceEffects effects, @ConfigChangeOrigin int origin) { + public void apply(ZenDeviceEffects effects, @ConfigOrigin int origin) { Binder.withCleanCallingIdentity(() -> { if (mLastAppliedEffects.shouldSuppressAmbientDisplay() != effects.shouldSuppressAmbientDisplay()) { @@ -120,15 +120,16 @@ class DefaultDeviceEffectsApplier implements DeviceEffectsApplier { mLastAppliedEffects = effects; } - private void updateOrScheduleNightMode(boolean useNightMode, @ConfigChangeOrigin int origin) { + private void updateOrScheduleNightMode(boolean useNightMode, @ConfigOrigin int origin) { mPendingNightMode = useNightMode; // Changing the theme can be disruptive for the user (Activities are likely recreated, may // lose some state). Therefore we only apply the change immediately if the rule was // activated manually, or we are initializing, or the screen is currently off/dreaming. - if (origin == ZenModeConfig.UPDATE_ORIGIN_INIT - || origin == ZenModeConfig.UPDATE_ORIGIN_INIT_USER - || origin == ZenModeConfig.UPDATE_ORIGIN_USER + if (origin == ZenModeConfig.ORIGIN_INIT + || origin == ZenModeConfig.ORIGIN_INIT_USER + || origin == ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI + || origin == ZenModeConfig.ORIGIN_USER_IN_APP || !mPowerManager.isInteractive()) { unregisterScreenOffReceiver(); updateNightModeImmediately(useNightMode); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 4179eddc7bc4..45b8da5fc8ea 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -5771,16 +5771,20 @@ public class NotificationManagerService extends SystemService { Binder.getCallingUid()); } - @ZenModeConfig.ConfigChangeOrigin + @ZenModeConfig.ConfigOrigin private int computeZenOrigin(boolean fromUser) { // "fromUser" is introduced with MODES_API, so only consider it in that case. - // (Non-MODES_API behavior should also not depend at all on UPDATE_ORIGIN_USER). + // (Non-MODES_API behavior should also not depend at all on ORIGIN_USER_IN_X). if (android.app.Flags.modesApi() && fromUser) { - return ZenModeConfig.UPDATE_ORIGIN_USER; + if (isCallerSystemOrSystemUi()) { + return ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; + } else { + return ZenModeConfig.ORIGIN_USER_IN_APP; + } } else if (isCallerSystemOrSystemUi()) { - return ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI; + return ZenModeConfig.ORIGIN_SYSTEM; } else { - return ZenModeConfig.UPDATE_ORIGIN_APP; + return ZenModeConfig.ORIGIN_APP; } } @@ -6137,7 +6141,7 @@ public class NotificationManagerService extends SystemService { enforcePolicyAccess(pkg, "setNotificationPolicy"); enforceUserOriginOnlyFromSystem(fromUser, "setNotificationPolicy"); int callingUid = Binder.getCallingUid(); - @ZenModeConfig.ConfigChangeOrigin int origin = computeZenOrigin(fromUser); + @ZenModeConfig.ConfigOrigin int origin = computeZenOrigin(fromUser); boolean shouldApplyAsImplicitRule = android.app.Flags.modesApi() && !canManageGlobalZenPolicy(pkg, callingUid); diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java index c09504fa36c8..821722b15645 100644 --- a/services/core/java/com/android/server/notification/PreferencesHelper.java +++ b/services/core/java/com/android/server/notification/PreferencesHelper.java @@ -30,7 +30,6 @@ import static android.app.NotificationManager.IMPORTANCE_LOW; import static android.app.NotificationManager.IMPORTANCE_MAX; import static android.app.NotificationManager.IMPORTANCE_NONE; import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED; - import static android.os.UserHandle.USER_SYSTEM; import static android.service.notification.Flags.notificationClassification; @@ -1979,8 +1978,8 @@ public class PreferencesHelper implements RankingConfig { (areChannelsBypassingDnd ? NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND : 0), policy.priorityConversationSenders), - fromSystemOrSystemUi ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI - : ZenModeConfig.UPDATE_ORIGIN_APP, + fromSystemOrSystemUi ? ZenModeConfig.ORIGIN_SYSTEM + : ZenModeConfig.ORIGIN_APP, callingUid); } diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java index 3650536ac7f6..268d835e704c 100644 --- a/services/core/java/com/android/server/notification/ZenModeConditions.java +++ b/services/core/java/com/android/server/notification/ZenModeConditions.java @@ -116,8 +116,8 @@ public class ZenModeConditions implements ConditionProviders.Callback { if (DEBUG) Log.d(TAG, "onServiceAdded " + component); final int callingUid = Binder.getCallingUid(); mHelper.setConfig(mHelper.getConfig(), component, - callingUid == Process.SYSTEM_UID ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI - : ZenModeConfig.UPDATE_ORIGIN_APP, + callingUid == Process.SYSTEM_UID ? ZenModeConfig.ORIGIN_SYSTEM + : ZenModeConfig.ORIGIN_APP, "zmc.onServiceAdded:" + component, callingUid); } @@ -128,8 +128,8 @@ public class ZenModeConditions implements ConditionProviders.Callback { if (config == null) return; final int callingUid = Binder.getCallingUid(); mHelper.setAutomaticZenRuleState(id, condition, - callingUid == Process.SYSTEM_UID ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI - : ZenModeConfig.UPDATE_ORIGIN_APP, + callingUid == Process.SYSTEM_UID ? ZenModeConfig.ORIGIN_SYSTEM + : ZenModeConfig.ORIGIN_APP, callingUid); } diff --git a/services/core/java/com/android/server/notification/ZenModeEventLogger.java b/services/core/java/com/android/server/notification/ZenModeEventLogger.java index 4a82057ed2a2..b03a54ec0cd3 100644 --- a/services/core/java/com/android/server/notification/ZenModeEventLogger.java +++ b/services/core/java/com/android/server/notification/ZenModeEventLogger.java @@ -34,7 +34,7 @@ import android.os.Process; import android.service.notification.DNDPolicyProto; import android.service.notification.ZenAdapters; import android.service.notification.ZenModeConfig; -import android.service.notification.ZenModeConfig.ConfigChangeOrigin; +import android.service.notification.ZenModeConfig.ConfigOrigin; import android.service.notification.ZenModeConfig.ZenRule; import android.service.notification.ZenModeDiff; import android.service.notification.ZenPolicy; @@ -113,7 +113,7 @@ class ZenModeEventLogger { * @param origin The origin of the Zen change. */ public final void maybeLogZenChange(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid, - @ConfigChangeOrigin int origin) { + @ConfigOrigin int origin) { mChangeState.init(prevInfo, newInfo, callingUid, origin); if (mChangeState.shouldLogChanges()) { maybeReassignCallingUid(); @@ -250,11 +250,11 @@ class ZenModeEventLogger { ZenModeConfig mPrevConfig, mNewConfig; NotificationManager.Policy mPrevPolicy, mNewPolicy; int mCallingUid = Process.INVALID_UID; - @ConfigChangeOrigin - int mOrigin = ZenModeConfig.UPDATE_ORIGIN_UNKNOWN; + @ConfigOrigin + int mOrigin = ZenModeConfig.ORIGIN_UNKNOWN; private void init(ZenModeInfo prevInfo, ZenModeInfo newInfo, int callingUid, - @ConfigChangeOrigin int origin) { + @ConfigOrigin int origin) { // previous & new may be the same -- that would indicate that zen mode hasn't changed. mPrevZenMode = prevInfo.mZenMode; mNewZenMode = newInfo.mZenMode; @@ -484,7 +484,8 @@ class ZenModeEventLogger { */ boolean getIsUserAction() { if (Flags.modesApi()) { - return mOrigin == ZenModeConfig.UPDATE_ORIGIN_USER; + return mOrigin == ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI + || mOrigin == ZenModeConfig.ORIGIN_USER_IN_APP; } // Approach for pre-MODES_API: @@ -549,10 +550,10 @@ class ZenModeEventLogger { } boolean isFromSystemOrSystemUi() { - return mOrigin == ZenModeConfig.UPDATE_ORIGIN_INIT - || mOrigin == ZenModeConfig.UPDATE_ORIGIN_INIT_USER - || mOrigin == ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI - || mOrigin == ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP; + return mOrigin == ZenModeConfig.ORIGIN_INIT + || mOrigin == ZenModeConfig.ORIGIN_INIT_USER + || mOrigin == ZenModeConfig.ORIGIN_SYSTEM + || mOrigin == ZenModeConfig.ORIGIN_RESTORE_BACKUP; } /** diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 95d8bb953065..b164a52ff5d7 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -29,13 +29,14 @@ import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_FALSE; import static android.service.notification.Condition.STATE_TRUE; import static android.service.notification.NotificationServiceProto.ROOT_CONFIG; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT_USER; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_UNKNOWN; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_APP; +import static android.service.notification.ZenModeConfig.ORIGIN_INIT; +import static android.service.notification.ZenModeConfig.ORIGIN_INIT_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_RESTORE_BACKUP; +import static android.service.notification.ZenModeConfig.ORIGIN_SYSTEM; +import static android.service.notification.ZenModeConfig.ORIGIN_UNKNOWN; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_APP; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import static com.android.internal.util.Preconditions.checkArgument; @@ -95,7 +96,7 @@ import android.service.notification.SystemZenRules; import android.service.notification.ZenAdapters; import android.service.notification.ZenDeviceEffects; import android.service.notification.ZenModeConfig; -import android.service.notification.ZenModeConfig.ConfigChangeOrigin; +import android.service.notification.ZenModeConfig.ConfigOrigin; import android.service.notification.ZenModeConfig.ZenRule; import android.service.notification.ZenModeProto; import android.service.notification.ZenPolicy; @@ -294,7 +295,7 @@ public class ZenModeHelper { // "update" config to itself, which will have no effect in the case where a config // was read in via XML, but will initialize zen mode if nothing was read in and the // config remains the default. - updateConfigAndZenModeLocked(mConfig, UPDATE_ORIGIN_INIT, "init", + updateConfigAndZenModeLocked(mConfig, ORIGIN_INIT, "init", true /*setRingerMode*/, Process.SYSTEM_UID /* callingUid */); } } @@ -328,7 +329,7 @@ public class ZenModeHelper { } mDeviceEffectsApplier = deviceEffectsApplier; } - applyConsolidatedDeviceEffects(UPDATE_ORIGIN_INIT); + applyConsolidatedDeviceEffects(ORIGIN_INIT); } public void onUserSwitched(int user) { @@ -368,7 +369,7 @@ public class ZenModeHelper { config.user = user; } synchronized (mConfigLock) { - setConfigLocked(config, null, UPDATE_ORIGIN_INIT_USER, reason, + setConfigLocked(config, null, ORIGIN_INIT_USER, reason, Process.SYSTEM_UID); } cleanUpZenRules(); @@ -384,7 +385,7 @@ public class ZenModeHelper { final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1); if (newZen != -1) { setManualZenMode(newZen, null, - fromSystemOrSystemUi ? UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI : UPDATE_ORIGIN_APP, + fromSystemOrSystemUi ? ORIGIN_SYSTEM : ORIGIN_APP, /* reason= */ "listener:" + (name != null ? name.flattenToShortString() : null), /* caller= */ name != null ? name.getPackageName() : null, callingUid); @@ -447,8 +448,8 @@ public class ZenModeHelper { } public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule, - @ConfigChangeOrigin int origin, String reason, int callingUid) { - requirePublicOrigin("addAutomaticZenRule", origin); + @ConfigOrigin int origin, String reason, int callingUid) { + checkManageRuleOrigin("addAutomaticZenRule", origin); if (!ZenModeConfig.SYSTEM_AUTHORITY.equals(pkg)) { PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner()); if (component == null) { @@ -497,7 +498,7 @@ public class ZenModeHelper { @GuardedBy("mConfigLock") private ZenRule maybeRestoreRemovedRule(ZenModeConfig config, ZenRule ruleToAdd, - AutomaticZenRule azrToAdd, @ConfigChangeOrigin int origin) { + AutomaticZenRule azrToAdd, @ConfigOrigin int origin) { if (!Flags.modesApi()) { return ruleToAdd; } @@ -517,7 +518,7 @@ public class ZenModeHelper { config.deletedRules.remove(deletedKey); ruleToRestore.deletionInstant = null; - if (origin != UPDATE_ORIGIN_APP) { + if (origin != ORIGIN_APP) { return ruleToAdd; // Okay to create anew. } @@ -547,8 +548,8 @@ public class ZenModeHelper { } public boolean updateAutomaticZenRule(String ruleId, AutomaticZenRule automaticZenRule, - @ConfigChangeOrigin int origin, String reason, int callingUid) { - requirePublicOrigin("updateAutomaticZenRule", origin); + @ConfigOrigin int origin, String reason, int callingUid) { + checkManageRuleOrigin("updateAutomaticZenRule", origin); if (ruleId == null) { throw new IllegalArgumentException("ruleId cannot be null"); } @@ -621,7 +622,7 @@ public class ZenModeHelper { mContext.getString(R.string.zen_mode_implicit_deactivated), STATE_FALSE); setAutomaticZenRuleStateLocked(newConfig, Collections.singletonList(rule), - deactivated, UPDATE_ORIGIN_APP, callingUid); + deactivated, ORIGIN_APP, callingUid); } } else { // Either create a new rule with a default ZenPolicy, or update an existing rule's @@ -647,7 +648,7 @@ public class ZenModeHelper { mContext.getString(R.string.zen_mode_implicit_activated), STATE_TRUE); - setConfigLocked(newConfig, /* triggeringComponent= */ null, UPDATE_ORIGIN_APP, + setConfigLocked(newConfig, /* triggeringComponent= */ null, ORIGIN_APP, "applyGlobalZenModeAsImplicitZenRule", callingUid); } } @@ -701,7 +702,7 @@ public class ZenModeHelper { /* updateBitmask= */ false, isNew); - setConfigLocked(newConfig, /* triggeringComponent= */ null, UPDATE_ORIGIN_APP, + setConfigLocked(newConfig, /* triggeringComponent= */ null, ORIGIN_APP, "applyGlobalPolicyAsImplicitZenRule", callingUid); } } @@ -788,9 +789,9 @@ public class ZenModeHelper { return ruleId.startsWith(IMPLICIT_RULE_ID_PREFIX); } - boolean removeAutomaticZenRule(String id, @ConfigChangeOrigin int origin, String reason, + boolean removeAutomaticZenRule(String id, @ConfigOrigin int origin, String reason, int callingUid) { - requirePublicOrigin("removeAutomaticZenRule", origin); + checkManageRuleOrigin("removeAutomaticZenRule", origin); ZenModeConfig newConfig; synchronized (mConfigLock) { if (mConfig == null) return false; @@ -821,9 +822,9 @@ public class ZenModeHelper { } } - boolean removeAutomaticZenRules(String packageName, @ConfigChangeOrigin int origin, + boolean removeAutomaticZenRules(String packageName, @ConfigOrigin int origin, String reason, int callingUid) { - requirePublicOrigin("removeAutomaticZenRules", origin); + checkManageRuleOrigin("removeAutomaticZenRules", origin); ZenModeConfig newConfig; synchronized (mConfigLock) { if (mConfig == null) return false; @@ -837,7 +838,7 @@ public class ZenModeHelper { } // If the system is clearing all rules this means DND access is revoked or the package // was uninstalled, so also clear the preserved-deleted rules. - if (origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI) { + if (origin == ORIGIN_SYSTEM) { for (int i = newConfig.deletedRules.size() - 1; i >= 0; i--) { ZenRule rule = newConfig.deletedRules.get(newConfig.deletedRules.keyAt(i)); if (Objects.equals(rule.getPkg(), packageName)) { @@ -850,7 +851,7 @@ public class ZenModeHelper { } private void maybePreserveRemovedRule(ZenModeConfig config, ZenRule ruleToRemove, - @ConfigChangeOrigin int origin) { + @ConfigOrigin int origin) { if (!Flags.modesApi()) { return; } @@ -859,7 +860,7 @@ public class ZenModeHelper { // We don't try to preserve system-owned rules because their conditionIds (used as // deletedRuleKey) are not stable. This is almost moot anyway because an app cannot // delete a system-owned rule. - if (origin == UPDATE_ORIGIN_APP && !ruleToRemove.canBeUpdatedByApp() + if (origin == ORIGIN_APP && !ruleToRemove.canBeUpdatedByApp() && !PACKAGE_ANDROID.equals(ruleToRemove.pkg)) { String deletedKey = ZenModeConfig.deletedRuleKey(ruleToRemove); if (deletedKey != null) { @@ -888,9 +889,9 @@ public class ZenModeHelper { } } - void setAutomaticZenRuleState(String id, Condition condition, @ConfigChangeOrigin int origin, + void setAutomaticZenRuleState(String id, Condition condition, @ConfigOrigin int origin, int callingUid) { - requirePublicOrigin("setAutomaticZenRuleState", origin); + checkSetRuleStateOrigin("setAutomaticZenRuleState(String id)", origin); ZenModeConfig newConfig; synchronized (mConfigLock) { if (mConfig == null) return; @@ -911,8 +912,8 @@ public class ZenModeHelper { } void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition, - @ConfigChangeOrigin int origin, int callingUid) { - requirePublicOrigin("setAutomaticZenRuleState", origin); + @ConfigOrigin int origin, int callingUid) { + checkSetRuleStateOrigin("setAutomaticZenRuleState(Uri ruleDefinition)", origin); ZenModeConfig newConfig; synchronized (mConfigLock) { if (mConfig == null) return; @@ -932,11 +933,13 @@ public class ZenModeHelper { @GuardedBy("mConfigLock") private void setAutomaticZenRuleStateLocked(ZenModeConfig config, List<ZenRule> rules, - Condition condition, @ConfigChangeOrigin int origin, int callingUid) { + Condition condition, @ConfigOrigin int origin, int callingUid) { if (rules == null || rules.isEmpty()) return; - if (Flags.modesApi() && condition.source == SOURCE_USER_ACTION) { - origin = UPDATE_ORIGIN_USER; // Although coming from app, it's actually a user action. + if (!Flags.modesUi()) { + if (Flags.modesApi() && condition.source == SOURCE_USER_ACTION) { + origin = ORIGIN_USER_IN_APP; // Although coming from app, it's actually from user. + } } for (ZenRule rule : rules) { @@ -1062,7 +1065,7 @@ public class ZenModeHelper { } } if (updated) { - setConfigLocked(config, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, + setConfigLocked(config, null, ORIGIN_SYSTEM, "updateZenRulesOnLocaleChange", Process.SYSTEM_UID); } } @@ -1119,11 +1122,11 @@ public class ZenModeHelper { * </ul> * * <p>The rule's {@link ZenRule#condition} is cleared (meaning that an active rule will be - * deactivated) unless the update has origin == {@link ZenModeConfig#UPDATE_ORIGIN_USER}. + * deactivated) unless the update has origin == {@link ZenModeConfig#ORIGIN_USER_IN_SYSTEMUI}. */ @GuardedBy("mConfigLock") private boolean populateZenRule(String pkg, AutomaticZenRule azr, ZenRule rule, - @ConfigChangeOrigin int origin, boolean isNew) { + @ConfigOrigin int origin, boolean isNew) { if (Flags.modesApi()) { boolean modified = false; // These values can always be edited by the app, so we apply changes immediately. @@ -1137,7 +1140,7 @@ public class ZenModeHelper { // Allow updating the CPS backing system rules (e.g. for custom manual -> schedule) if (Flags.modesUi() - && (origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI || origin == UPDATE_ORIGIN_USER) + && (origin == ORIGIN_SYSTEM || origin == ORIGIN_USER_IN_SYSTEMUI) && Objects.equals(rule.pkg, SystemZenRules.PACKAGE_ANDROID) && !Objects.equals(rule.component, azr.getOwner())) { rule.component = azr.getOwner(); @@ -1151,7 +1154,7 @@ public class ZenModeHelper { rule.disabledOrigin = origin; } else if (azr.isEnabled()) { // Enabling or previously enabled. Clear disabler. - rule.disabledOrigin = UPDATE_ORIGIN_UNKNOWN; + rule.disabledOrigin = ORIGIN_UNKNOWN; } } @@ -1166,7 +1169,7 @@ public class ZenModeHelper { Flags.modesApi() && (Flags.modesUi() || isWatch) && !isNew - && origin == UPDATE_ORIGIN_USER + && origin == ORIGIN_USER_IN_SYSTEMUI && rule.enabled == azr.isEnabled() && rule.conditionId != null && rule.condition != null @@ -1232,7 +1235,7 @@ public class ZenModeHelper { } // Updates the bitmasks if the origin of the change is the user. - boolean updateBitmask = (origin == UPDATE_ORIGIN_USER); + boolean updateBitmask = (origin == ORIGIN_USER_IN_SYSTEMUI); if (updateBitmask && !TextUtils.equals(previousName, azr.getName())) { rule.userModifiedFields |= AutomaticZenRule.FIELD_NAME; @@ -1263,7 +1266,7 @@ public class ZenModeHelper { // Updates the bitmask and values for all device effect fields, based on the origin. modified |= updateZenDeviceEffects(rule, azr.getDeviceEffects(), - origin == UPDATE_ORIGIN_APP, updateBitmask); + origin == ORIGIN_APP, updateBitmask); return modified; } else { @@ -1297,8 +1300,8 @@ public class ZenModeHelper { * change. (Note that regardless of origin, fields can always be updated if they're not already * user modified.) */ - private static boolean doesOriginAlwaysUpdateValues(@ConfigChangeOrigin int origin) { - return origin == UPDATE_ORIGIN_USER || origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI; + private static boolean doesOriginAlwaysUpdateValues(@ConfigOrigin int origin) { + return origin == ORIGIN_USER_IN_SYSTEMUI || origin == ORIGIN_SYSTEM; } /** @@ -1539,7 +1542,7 @@ public class ZenModeHelper { : AUTOMATIC_RULE_STATUS_DISABLED); } - void setManualZenMode(int zenMode, Uri conditionId, @ConfigChangeOrigin int origin, + void setManualZenMode(int zenMode, Uri conditionId, @ConfigOrigin int origin, String reason, @Nullable String caller, int callingUid) { setManualZenMode(zenMode, conditionId, origin, reason, caller, true /*setRingerMode*/, callingUid); @@ -1547,7 +1550,7 @@ public class ZenModeHelper { Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0); } - private void setManualZenMode(int zenMode, Uri conditionId, @ConfigChangeOrigin int origin, + private void setManualZenMode(int zenMode, Uri conditionId, @ConfigOrigin int origin, String reason, @Nullable String caller, boolean setRingerMode, int callingUid) { ZenModeConfig newConfig; synchronized (mConfigLock) { @@ -1564,8 +1567,8 @@ public class ZenModeHelper { newConfig.manualRule.zenMode = zenMode; newConfig.manualRule.condition = new Condition(newConfig.manualRule.conditionId, "", zenMode == Global.ZEN_MODE_OFF ? STATE_FALSE : STATE_TRUE, - origin == UPDATE_ORIGIN_USER ? SOURCE_USER_ACTION : SOURCE_UNKNOWN); - if (zenMode == Global.ZEN_MODE_OFF && origin != UPDATE_ORIGIN_USER) { + origin == ORIGIN_USER_IN_SYSTEMUI ? SOURCE_USER_ACTION : SOURCE_UNKNOWN); + if (zenMode == Global.ZEN_MODE_OFF && origin != ORIGIN_USER_IN_SYSTEMUI) { // User deactivation of DND means just turning off the manual DND rule. // For API calls (different origin) keep old behavior of snoozing all rules. for (ZenRule automaticRule : newConfig.automaticRules.values()) { @@ -1602,7 +1605,7 @@ public class ZenModeHelper { } public void setManualZenRuleDeviceEffects(ZenDeviceEffects deviceEffects, - @ConfigChangeOrigin int origin, String reason, int callingUid) { + @ConfigOrigin int origin, String reason, int callingUid) { if (!Flags.modesUi()) { return; } @@ -1752,7 +1755,7 @@ public class ZenModeHelper { if (DEBUG) Log.d(TAG, reason); synchronized (mConfigLock) { setConfigLocked(config, null, - forRestore ? UPDATE_ORIGIN_RESTORE_BACKUP : UPDATE_ORIGIN_INIT, reason, + forRestore ? ORIGIN_RESTORE_BACKUP : ORIGIN_INIT, reason, Process.SYSTEM_UID); } } @@ -1787,7 +1790,7 @@ public class ZenModeHelper { /** * Sets the global notification policy used for priority only do not disturb */ - public void setNotificationPolicy(Policy policy, @ConfigChangeOrigin int origin, + public void setNotificationPolicy(Policy policy, @ConfigOrigin int origin, int callingUid) { synchronized (mConfigLock) { if (policy == null || mConfig == null) return; @@ -1843,7 +1846,7 @@ public class ZenModeHelper { } if (!newConfig.equals(mConfig)) { - setConfigLocked(newConfig, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, + setConfigLocked(newConfig, null, ORIGIN_SYSTEM, "cleanUpZenRules", Process.SYSTEM_UID); } } @@ -1893,20 +1896,20 @@ public class ZenModeHelper { @GuardedBy("mConfigLock") private boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent, - @ConfigChangeOrigin int origin, String reason, int callingUid) { + @ConfigOrigin int origin, String reason, int callingUid) { return setConfigLocked(config, origin, reason, triggeringComponent, true /*setRingerMode*/, callingUid); } void setConfig(ZenModeConfig config, ComponentName triggeringComponent, - @ConfigChangeOrigin int origin, String reason, int callingUid) { + @ConfigOrigin int origin, String reason, int callingUid) { synchronized (mConfigLock) { setConfigLocked(config, triggeringComponent, origin, reason, callingUid); } } @GuardedBy("mConfigLock") - private boolean setConfigLocked(ZenModeConfig config, @ConfigChangeOrigin int origin, + private boolean setConfigLocked(ZenModeConfig config, @ConfigOrigin int origin, String reason, ComponentName triggeringComponent, boolean setRingerMode, int callingUid) { final long identity = Binder.clearCallingIdentity(); @@ -1954,7 +1957,7 @@ public class ZenModeHelper { * If logging is enabled, will also request logging of the outcome of this change if needed. */ @GuardedBy("mConfigLock") - private void updateConfigAndZenModeLocked(ZenModeConfig config, @ConfigChangeOrigin int origin, + private void updateConfigAndZenModeLocked(ZenModeConfig config, @ConfigOrigin int origin, String reason, boolean setRingerMode, int callingUid) { final boolean logZenModeEvents = mFlagResolver.isEnabled( SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS); @@ -1963,7 +1966,7 @@ public class ZenModeHelper { mZenMode, mConfig, mConsolidatedPolicy); if (!config.equals(mConfig)) { // Schedule broadcasts. Cannot be sent during boot, though. - if (Flags.modesApi() && origin != UPDATE_ORIGIN_INIT) { + if (Flags.modesApi() && origin != ORIGIN_INIT) { for (ZenRule rule : config.automaticRules.values()) { ZenRule original = mConfig.automaticRules.get(rule.id); if (original != null) { @@ -2020,7 +2023,7 @@ public class ZenModeHelper { @VisibleForTesting @GuardedBy("mConfigLock") - protected void evaluateZenModeLocked(@ConfigChangeOrigin int origin, String reason, + protected void evaluateZenModeLocked(@ConfigOrigin int origin, String reason, boolean setRingerMode) { if (DEBUG) Log.d(TAG, "evaluateZenMode"); if (mConfig == null) return; @@ -2111,7 +2114,7 @@ public class ZenModeHelper { } @GuardedBy("mConfigLock") - private void updateAndApplyConsolidatedPolicyAndDeviceEffects(@ConfigChangeOrigin int origin, + private void updateAndApplyConsolidatedPolicyAndDeviceEffects(@ConfigOrigin int origin, String reason) { synchronized (mConfigLock) { if (mConfig == null) return; @@ -2163,7 +2166,7 @@ public class ZenModeHelper { } } - private void applyConsolidatedDeviceEffects(@ConfigChangeOrigin int source) { + private void applyConsolidatedDeviceEffects(@ConfigOrigin int source) { if (!Flags.modesApi()) { return; } @@ -2506,7 +2509,7 @@ public class ZenModeHelper { } if (newZen != -1) { - setManualZenMode(newZen, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, + setManualZenMode(newZen, null, ORIGIN_SYSTEM, "ringerModeInternal", /* caller= */ null, /* setRingerMode= */ false, Process.SYSTEM_UID); } @@ -2551,7 +2554,7 @@ public class ZenModeHelper { break; } if (newZen != -1) { - setManualZenMode(newZen, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, + setManualZenMode(newZen, null, ORIGIN_SYSTEM, "ringerModeExternal", caller, false /*setRingerMode*/, Process.SYSTEM_UID); } @@ -2708,15 +2711,33 @@ public class ZenModeHelper { } } - /** Checks that the {@code origin} supplied to a ZenModeHelper "API" method makes sense. */ - private static void requirePublicOrigin(String method, @ConfigChangeOrigin int origin) { + /** + * Checks that the {@code origin} supplied to ZenModeHelper rule-management API methods + * ({@link #addAutomaticZenRule}, {@link #removeAutomaticZenRule}, etc, makes sense. + */ + private static void checkManageRuleOrigin(String method, @ConfigOrigin int origin) { + if (!Flags.modesApi()) { + return; + } + checkArgument(origin == ORIGIN_APP || origin == ORIGIN_SYSTEM + || origin == ORIGIN_USER_IN_SYSTEMUI, + "Expected one of ORIGIN_APP, ORIGIN_SYSTEM, or " + + "ORIGIN_USER_IN_SYSTEMUI for %s, but received '%s'.", + method, origin); + } + + /** + * Checks that the {@code origin} supplied to {@link #setAutomaticZenRuleState} overloads makes + * sense. + */ + private static void checkSetRuleStateOrigin(String method, @ConfigOrigin int origin) { if (!Flags.modesApi()) { return; } - checkArgument(origin == UPDATE_ORIGIN_APP || origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI - || origin == UPDATE_ORIGIN_USER, - "Expected one of UPDATE_ORIGIN_APP, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, or " - + "UPDATE_ORIGIN_USER for %s, but received '%s'.", + checkArgument(origin == ORIGIN_APP || origin == ORIGIN_USER_IN_APP + || origin == ORIGIN_SYSTEM || origin == ORIGIN_USER_IN_SYSTEMUI, + "Expected one of ORIGIN_APP, ORIGIN_USER_IN_APP, ORIGIN_SYSTEM, or " + + "ORIGIN_USER_IN_SYSTEMUI for %s, but received '%s'.", method, origin); } @@ -2841,7 +2862,7 @@ public class ZenModeHelper { } } - private void postApplyDeviceEffects(@ConfigChangeOrigin int origin) { + private void postApplyDeviceEffects(@ConfigOrigin int origin) { removeMessages(MSG_APPLY_EFFECTS); sendMessage(obtainMessage(MSG_APPLY_EFFECTS, origin, 0)); } @@ -2862,7 +2883,7 @@ public class ZenModeHelper { updateRingerAndAudio(/* shouldApplyToRinger= */ false); break; case MSG_APPLY_EFFECTS: - @ConfigChangeOrigin int origin = msg.arg1; + @ConfigOrigin int origin = msg.arg1; applyConsolidatedDeviceEffects(origin); break; } diff --git a/services/core/java/com/android/server/pm/AppDataHelper.java b/services/core/java/com/android/server/pm/AppDataHelper.java index 8b72138898ad..29f8243cfe60 100644 --- a/services/core/java/com/android/server/pm/AppDataHelper.java +++ b/services/core/java/com/android/server/pm/AppDataHelper.java @@ -127,7 +127,7 @@ public class AppDataHelper { } // TODO(b/211761016): should we still create the profile dirs? - if (ps.getPkg() != null && !shouldHaveAppStorage(ps.getPkg())) { + if (!shouldHaveAppStorage(ps)) { Slog.w(TAG, "Skipping preparing app data for " + ps.getPackageName()); return; } @@ -172,19 +172,19 @@ public class AppDataHelper { } private void prepareAppDataAndMigrate(@NonNull Installer.Batch batch, - @NonNull AndroidPackage pkg, @UserIdInt int userId, + @NonNull PackageStateInternal psi, @UserIdInt int userId, @StorageManager.StorageFlags int flags, boolean maybeMigrateAppData) { - if (pkg == null) { + if (psi == null || psi.getPkg() == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; } - if (!shouldHaveAppStorage(pkg)) { - Slog.w(TAG, "Skipping preparing app data for " + pkg.getPackageName()); + if (!shouldHaveAppStorage(psi)) { + Slog.w(TAG, "Skipping preparing app data for " + psi.getPackageName()); return; } final PackageSetting ps; synchronized (mPm.mLock) { - ps = mPm.mSettings.getPackageLPr(pkg.getPackageName()); + ps = mPm.mSettings.getPackageLPr(psi.getPackageName()); } prepareAppData(batch, ps, Process.INVALID_UID, userId, flags).thenRun(() -> { // Note: this code block is executed with the Installer lock @@ -449,7 +449,7 @@ public class AppDataHelper { } if (ps.getUserStateOrDefault(userId).isInstalled()) { - prepareAppDataAndMigrate(batch, ps.getPkg(), userId, flags, migrateAppData); + prepareAppDataAndMigrate(batch, ps, userId, flags, migrateAppData); preparedCount++; } } @@ -484,8 +484,7 @@ public class AppDataHelper { + " or was deleted without DELETE_KEEP_DATA", PackageManagerException.INTERNAL_ERROR_STORAGE_INVALID_NOT_INSTALLED_FOR_USER); } - if (packageState.getPkg() != null - && !shouldHaveAppStorage(packageState.getPkg())) { + if (!shouldHaveAppStorage(packageState)) { throw PackageManagerException.ofInternalError( "Package " + packageName + " shouldn't have storage", PackageManagerException.INTERNAL_ERROR_STORAGE_INVALID_SHOULD_NOT_HAVE_STORAGE); @@ -535,8 +534,7 @@ public class AppDataHelper { if (packageStateInternal != null && packageStateInternal.getUserStateOrDefault( UserHandle.USER_SYSTEM).isInstalled()) { - AndroidPackage pkg = packageStateInternal.getPkg(); - prepareAppDataAndMigrate(batch, pkg, + prepareAppDataAndMigrate(batch, packageStateInternal, UserHandle.USER_SYSTEM, storageFlags, true /* maybeMigrateAppData */); count++; } @@ -637,12 +635,16 @@ public class AppDataHelper { } /** - * Returns {@code true} if app's internal storage should be created for this {@code pkg}. + * Returns {@code true} if app's internal storage should be created for this {@code ps}. */ - private boolean shouldHaveAppStorage(AndroidPackage pkg) { + private boolean shouldHaveAppStorage(PackageStateInternal ps) { + if (ps.getPkg() == null) { + // Keeps the legacy behavior + return true; + } PackageManager.Property noAppDataProp = - pkg.getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); - return (noAppDataProp == null || !noAppDataProp.getBoolean()) && pkg.getUid() >= 0; + ps.getPkg().getProperties().get(PackageManager.PROPERTY_NO_APP_DATA_STORAGE); + return (noAppDataProp == null || !noAppDataProp.getBoolean()) && ps.getAppId() >= 0; } /** diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java index 503a7268d5d3..65fc7b2c5c39 100644 --- a/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java +++ b/services/core/java/com/android/server/vibrator/HapticFeedbackCustomization.java @@ -18,6 +18,7 @@ package com.android.server.vibrator; import android.annotation.Nullable; import android.content.res.Resources; +import android.content.res.XmlResourceParser; import android.os.VibrationEffect; import android.os.VibratorInfo; import android.os.vibrator.Flags; @@ -28,6 +29,7 @@ import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import com.android.internal.util.XmlUtils; import com.android.internal.vibrator.persistence.XmlParserException; import com.android.internal.vibrator.persistence.XmlReader; import com.android.internal.vibrator.persistence.XmlValidator; @@ -39,6 +41,7 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; +import java.io.Reader; /** * Class that loads custom {@link VibrationEffect} to be performed for each @@ -127,27 +130,19 @@ final class HapticFeedbackCustomization { Slog.d(TAG, "Haptic feedback customization feature is not enabled."); return null; } - String customizationFile = - res.getString( - com.android.internal.R.string.config_hapticFeedbackCustomizationFile); - if (TextUtils.isEmpty(customizationFile)) { - Slog.d(TAG, "Customization file not configured."); - return null; - } - FileReader fileReader; - try { - fileReader = new FileReader(customizationFile); - } catch (FileNotFoundException e) { - Slog.d(TAG, "Specified customization file not found."); - return null; + // Old loading path that reads customization from file at dir defined by config. + TypedXmlPullParser parser = readCustomizationFile(res); + if (parser == null) { + // When old loading path doesn't succeed, try loading customization from resources. + parser = readCustomizationResources(res); + } + if (parser == null) { + Slog.d(TAG, "No loadable haptic feedback customization."); + return null; } - TypedXmlPullParser parser = Xml.newFastPullParser(); - parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); - parser.setInput(fileReader); - - XmlReader.readDocumentStartTag(parser, TAG_CONSTANTS); + XmlUtils.beginDocument(parser, TAG_CONSTANTS); XmlValidator.checkTagHasNoUnexpectedAttributes(parser); int rootDepth = parser.getDepth(); @@ -191,6 +186,46 @@ final class HapticFeedbackCustomization { return mapping; } + // TODO(b/356412421): deprecate old path related files. + private static TypedXmlPullParser readCustomizationFile(Resources res) + throws XmlPullParserException { + String customizationFile = res.getString( + com.android.internal.R.string.config_hapticFeedbackCustomizationFile); + if (TextUtils.isEmpty(customizationFile)) { + return null; + } + + final Reader customizationReader; + try { + customizationReader = new FileReader(customizationFile); + } catch (FileNotFoundException e) { + Slog.e(TAG, "Specified customization file not found.", e); + return null; + } + + final TypedXmlPullParser parser; + parser = Xml.newFastPullParser(); + parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); + parser.setInput(customizationReader); + Slog.d(TAG, "Successfully opened customization file."); + return parser; + } + + private static TypedXmlPullParser readCustomizationResources(Resources res) { + if (!Flags.loadHapticFeedbackVibrationCustomizationFromResources()) { + return null; + } + final XmlResourceParser resParser; + try { + resParser = res.getXml(com.android.internal.R.xml.haptic_feedback_customization); + } catch (Resources.NotFoundException e) { + Slog.e(TAG, "Haptic customization resource not found.", e); + return null; + } + Slog.d(TAG, "Successfully opened customization resource."); + return XmlUtils.makeTyped(resParser); + } + /** * Represents an error while parsing a haptic feedback customization XML. */ diff --git a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java index 3f9da82e3d2e..eccbffb53529 100644 --- a/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java +++ b/services/core/java/com/android/server/vibrator/HapticFeedbackVibrationProvider.java @@ -22,7 +22,6 @@ import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.VibratorInfo; -import android.os.vibrator.Flags; import android.util.Slog; import android.util.SparseArray; import android.view.HapticFeedbackConstants; @@ -348,7 +347,7 @@ public final class HapticFeedbackVibrationProvider { predefinedEffectId = VibrationEffect.EFFECT_CLICK; predefinedEffectFallback = true; } - if (Flags.keyboardCategoryEnabled() && mKeyboardVibrationFixedAmplitude > 0) { + if (mKeyboardVibrationFixedAmplitude > 0) { if (mVibratorInfo.isPrimitiveSupported(primitiveId)) { return VibrationEffect.startComposition() .addPrimitive(primitiveId, mKeyboardVibrationFixedAmplitude) @@ -361,10 +360,6 @@ public final class HapticFeedbackVibrationProvider { private VibrationAttributes createKeyboardVibrationAttributes( @HapticFeedbackConstants.PrivateFlags int privFlags) { - // Use touch attribute when the keyboard category is disable. - if (!Flags.keyboardCategoryEnabled()) { - return TOUCH_VIBRATION_ATTRIBUTES; - } // Use touch attribute when the haptic is not apply to IME. if ((privFlags & HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS) == 0) { return TOUCH_VIBRATION_ATTRIBUTES; diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java index fb92d609f1cf..f2f5eda7c05a 100644 --- a/services/core/java/com/android/server/vibrator/VibrationSettings.java +++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java @@ -55,7 +55,6 @@ import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.Vibrator.VibrationIntensity; -import android.os.vibrator.Flags; import android.os.vibrator.VibrationConfig; import android.provider.Settings; import android.util.IndentingPrintWriter; @@ -533,8 +532,7 @@ final class VibrationSettings { return false; } - if (Flags.keyboardCategoryEnabled() - && mVibrationConfig.isKeyboardVibrationSettingsSupported()) { + if (mVibrationConfig.isKeyboardVibrationSettingsSupported()) { int category = callerInfo.attrs.getCategory(); if (usage == USAGE_TOUCH && category == CATEGORY_KEYBOARD) { // Keyboard touch has a different user setting. diff --git a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java index 4bea95f61c1f..7933f7ab06cd 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java @@ -18,8 +18,8 @@ package com.android.server.notification; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_NIGHT; import static android.app.UiModeManager.MODE_ATTENTION_THEME_OVERLAY_OFF; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_APP; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; import static com.google.common.truth.Truth.assertThat; @@ -48,7 +48,6 @@ import android.hardware.display.ColorDisplayManager; import android.os.PowerManager; import android.platform.test.flag.junit.SetFlagsRule; import android.service.notification.ZenDeviceEffects; -import android.service.notification.ZenModeConfig; import android.testing.TestableContext; import androidx.test.InstrumentationRegistry; @@ -78,27 +77,6 @@ public class DefaultDeviceEffectsApplierTest { @Mock UiModeManager mUiModeManager; @Mock WallpaperManager mWallpaperManager; - private enum ChangeOrigin { - ORIGIN_UNKNOWN(ZenModeConfig.UPDATE_ORIGIN_UNKNOWN), - ORIGIN_INIT(ZenModeConfig.UPDATE_ORIGIN_INIT), - ORIGIN_INIT_USER(ZenModeConfig.UPDATE_ORIGIN_INIT_USER), - ORIGIN_USER(ZenModeConfig.UPDATE_ORIGIN_USER), - ORIGIN_APP(ZenModeConfig.UPDATE_ORIGIN_APP), - ORIGIN_SYSTEM_OR_SYSTEMUI(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), - ORIGIN_RESTORE_BACKUP(ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP); - - private final int mValue; - - ChangeOrigin(@ZenModeConfig.ConfigChangeOrigin int value) { - mValue = value; - } - - @ZenModeConfig.ConfigChangeOrigin - public int value() { - return mValue; - } - } - @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -123,7 +101,7 @@ public class DefaultDeviceEffectsApplierTest { .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); - mApplier.apply(effects, UPDATE_ORIGIN_USER); + mApplier.apply(effects, ORIGIN_USER_IN_SYSTEMUI); verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true)); verify(mColorDisplayManager).setSaturationLevel(eq(0)); @@ -141,14 +119,14 @@ public class DefaultDeviceEffectsApplierTest { .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); - mApplier.apply(previousEffects, UPDATE_ORIGIN_USER); + mApplier.apply(previousEffects, ORIGIN_USER_IN_SYSTEMUI); verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true)); verify(mColorDisplayManager).setSaturationLevel(eq(0)); verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f)); verify(mUiModeManager).setAttentionModeThemeOverlay(eq(MODE_ATTENTION_THEME_OVERLAY_NIGHT)); ZenDeviceEffects noEffects = new ZenDeviceEffects.Builder().build(); - mApplier.apply(noEffects, UPDATE_ORIGIN_USER); + mApplier.apply(noEffects, ORIGIN_USER_IN_SYSTEMUI); verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(false)); verify(mColorDisplayManager).setSaturationLevel(eq(100)); @@ -163,11 +141,11 @@ public class DefaultDeviceEffectsApplierTest { ZenDeviceEffects previousEffects = new ZenDeviceEffects.Builder() .setShouldSuppressAmbientDisplay(true) .build(); - mApplier.apply(previousEffects, UPDATE_ORIGIN_USER); + mApplier.apply(previousEffects, ORIGIN_USER_IN_SYSTEMUI); verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true)); ZenDeviceEffects noEffects = new ZenDeviceEffects.Builder().build(); - mApplier.apply(noEffects, UPDATE_ORIGIN_USER); + mApplier.apply(noEffects, ORIGIN_USER_IN_SYSTEMUI); verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(false)); verifyZeroInteractions(mColorDisplayManager, mWallpaperManager, mUiModeManager); @@ -186,7 +164,7 @@ public class DefaultDeviceEffectsApplierTest { .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); - mApplier.apply(effects, UPDATE_ORIGIN_USER); + mApplier.apply(effects, ORIGIN_USER_IN_SYSTEMUI); verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true)); // (And no crash from missing services). @@ -207,7 +185,7 @@ public class DefaultDeviceEffectsApplierTest { .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); - mApplier.apply(effects, UPDATE_ORIGIN_USER); + mApplier.apply(effects, ORIGIN_USER_IN_SYSTEMUI); verifyNoMoreInteractions(mWallpaperManager); } @@ -220,7 +198,7 @@ public class DefaultDeviceEffectsApplierTest { .setShouldDimWallpaper(true) .setShouldDisplayGrayscale(true) .build(); - mApplier.apply(effects, UPDATE_ORIGIN_USER); + mApplier.apply(effects, ORIGIN_USER_IN_SYSTEMUI); verify(mColorDisplayManager).setSaturationLevel(eq(0)); verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f)); @@ -234,12 +212,12 @@ public class DefaultDeviceEffectsApplierTest { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); mApplier.apply(new ZenDeviceEffects.Builder().setShouldDimWallpaper(true).build(), - UPDATE_ORIGIN_USER); + ORIGIN_USER_IN_SYSTEMUI); verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f)); // Apply a second effect and remove the first one. mApplier.apply(new ZenDeviceEffects.Builder().setShouldDisplayGrayscale(true).build(), - UPDATE_ORIGIN_USER); + ORIGIN_USER_IN_SYSTEMUI); // Wallpaper dimming was undone, Grayscale was applied, nothing else was touched. verify(mWallpaperManager).setWallpaperDimAmount(eq(0.0f)); @@ -259,7 +237,7 @@ public class DefaultDeviceEffectsApplierTest { when(mPowerManager.isInteractive()).thenReturn(true); mApplier.apply(new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build(), - UPDATE_ORIGIN_APP); + ORIGIN_APP); // Effect was not yet applied, but a broadcast receiver was registered. verifyZeroInteractions(mUiModeManager); @@ -278,7 +256,7 @@ public class DefaultDeviceEffectsApplierTest { @Test public void apply_nightModeWithScreenOff_appliedImmediately( - @TestParameter ChangeOrigin origin) { + @TestParameter ZenChangeOrigin origin) { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); when(mPowerManager.isInteractive()).thenReturn(false); @@ -292,9 +270,10 @@ public class DefaultDeviceEffectsApplierTest { } @Test - @TestParameters({"{origin: ORIGIN_USER}", "{origin: ORIGIN_INIT}", - "{origin: ORIGIN_INIT_USER}"}) - public void apply_nightModeWithScreenOn_appliedImmediatelyBasedOnOrigin(ChangeOrigin origin) { + @TestParameters({"{origin: ORIGIN_USER_IN_SYSTEMUI}", "{origin: ORIGIN_USER_IN_APP}", + "{origin: ORIGIN_INIT}", "{origin: ORIGIN_INIT_USER}"}) + public void apply_nightModeWithScreenOn_appliedImmediatelyBasedOnOrigin( + ZenChangeOrigin origin) { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); when(mPowerManager.isInteractive()).thenReturn(true); @@ -309,8 +288,9 @@ public class DefaultDeviceEffectsApplierTest { @Test @TestParameters({"{origin: ORIGIN_APP}", "{origin: ORIGIN_RESTORE_BACKUP}", - "{origin: ORIGIN_SYSTEM_OR_SYSTEMUI}", "{origin: ORIGIN_UNKNOWN}"}) - public void apply_nightModeWithScreenOn_willBeAppliedLaterBasedOnOrigin(ChangeOrigin origin) { + "{origin: ORIGIN_SYSTEM}", "{origin: ORIGIN_UNKNOWN}"}) + public void apply_nightModeWithScreenOn_willBeAppliedLaterBasedOnOrigin( + ZenChangeOrigin origin) { mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API); when(mPowerManager.isInteractive()).thenReturn(true); @@ -342,7 +322,7 @@ public class DefaultDeviceEffectsApplierTest { .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) .build(); - mApplier.apply(effects, UPDATE_ORIGIN_USER); + mApplier.apply(effects, ORIGIN_USER_IN_SYSTEMUI); // No crashes } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index 1b999e49d21b..4bb80170f9fa 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -10064,7 +10064,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // verify that zen mode helper gets passed in a package name of "android" verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), - eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_SYSTEM), anyString(), anyInt()); } @Test @@ -10086,7 +10086,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // verify that zen mode helper gets passed in a package name of "android" verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), - eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_SYSTEM), anyString(), anyInt()); } @Test @@ -10106,7 +10106,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { // verify that zen mode helper gets passed in the package name from the arg, not the owner verify(mockZenModeHelper).addAutomaticZenRule( - eq("another.package"), eq(rule), eq(ZenModeConfig.UPDATE_ORIGIN_APP), + eq("another.package"), eq(rule), eq(ZenModeConfig.ORIGIN_APP), anyString(), anyInt()); // doesn't count as a system/systemui call } @@ -10221,7 +10221,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.addAutomaticZenRule(SOME_ZEN_RULE, "pkg", /* fromUser= */ true); verify(zenModeHelper).addAutomaticZenRule(eq("pkg"), eq(SOME_ZEN_RULE), - eq(ZenModeConfig.UPDATE_ORIGIN_USER), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI), anyString(), anyInt()); } @Test @@ -10233,7 +10233,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.addAutomaticZenRule(SOME_ZEN_RULE, "pkg", /* fromUser= */ false); verify(zenModeHelper).addAutomaticZenRule(eq("pkg"), eq(SOME_ZEN_RULE), - eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_SYSTEM), anyString(), anyInt()); } @Test @@ -10245,7 +10245,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.addAutomaticZenRule(SOME_ZEN_RULE, "pkg", /* fromUser= */ false); verify(zenModeHelper).addAutomaticZenRule(eq("pkg"), eq(SOME_ZEN_RULE), - eq(ZenModeConfig.UPDATE_ORIGIN_APP), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_APP), anyString(), anyInt()); } @Test @@ -10267,7 +10267,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.updateAutomaticZenRule("id", SOME_ZEN_RULE, /* fromUser= */ true); verify(zenModeHelper).updateAutomaticZenRule(eq("id"), eq(SOME_ZEN_RULE), - eq(ZenModeConfig.UPDATE_ORIGIN_USER), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI), anyString(), anyInt()); } @Test @@ -10289,7 +10289,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.removeAutomaticZenRule("id", /* fromUser= */ true); verify(zenModeHelper).removeAutomaticZenRule(eq("id"), - eq(ZenModeConfig.UPDATE_ORIGIN_USER), anyString(), anyInt()); + eq(ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI), anyString(), anyInt()); } @Test @@ -10304,7 +10304,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) - public void setAutomaticZenRuleState_conditionFromUser_mappedToOriginUser() throws Exception { + public void setAutomaticZenRuleState_fromAppWithConditionFromUser_originUserInApp() + throws Exception { ZenModeHelper zenModeHelper = setUpMockZenTest(); mService.setCallerIsNormalPackage(); @@ -10313,12 +10314,12 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.setAutomaticZenRuleState("id", withSourceUser); verify(zenModeHelper).setAutomaticZenRuleState(eq("id"), eq(withSourceUser), - eq(ZenModeConfig.UPDATE_ORIGIN_USER), anyInt()); + eq(ZenModeConfig.ORIGIN_USER_IN_APP), anyInt()); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) - public void setAutomaticZenRuleState_fromAppWithConditionNotFromUser_mappedToOriginApp() + public void setAutomaticZenRuleState_fromAppWithConditionNotFromUser_originApp() throws Exception { ZenModeHelper zenModeHelper = setUpMockZenTest(); mService.setCallerIsNormalPackage(); @@ -10328,12 +10329,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.setAutomaticZenRuleState("id", withSourceContext); verify(zenModeHelper).setAutomaticZenRuleState(eq("id"), eq(withSourceContext), - eq(ZenModeConfig.UPDATE_ORIGIN_APP), anyInt()); + eq(ZenModeConfig.ORIGIN_APP), anyInt()); } @Test @EnableFlags(android.app.Flags.FLAG_MODES_API) - public void setAutomaticZenRuleState_fromSystemWithConditionNotFromUser_mappedToOriginSystem() + public void setAutomaticZenRuleState_fromSystemWithConditionFromUser_originUserInSystemUi() + throws Exception { + ZenModeHelper zenModeHelper = setUpMockZenTest(); + mService.isSystemUid = true; + + Condition withSourceContext = new Condition(Uri.parse("uri"), "summary", STATE_TRUE, + SOURCE_USER_ACTION); + mBinderService.setAutomaticZenRuleState("id", withSourceContext); + + verify(zenModeHelper).setAutomaticZenRuleState(eq("id"), eq(withSourceContext), + eq(ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI), anyInt()); + } + @Test + @EnableFlags(android.app.Flags.FLAG_MODES_API) + public void setAutomaticZenRuleState_fromSystemWithConditionNotFromUser_originSystem() throws Exception { ZenModeHelper zenModeHelper = setUpMockZenTest(); mService.isSystemUid = true; @@ -10343,7 +10358,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.setAutomaticZenRuleState("id", withSourceContext); verify(zenModeHelper).setAutomaticZenRuleState(eq("id"), eq(withSourceContext), - eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyInt()); + eq(ZenModeConfig.ORIGIN_SYSTEM), anyInt()); } /** Prepares for a zen-related test that uses a mocked {@link ZenModeHelper}. */ @@ -15508,7 +15523,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.setInterruptionFilter("package", INTERRUPTION_FILTER_PRIORITY, false); verify(zenModeHelper).setManualZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), eq(null), - eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), eq("package"), + eq(ZenModeConfig.ORIGIN_SYSTEM), anyString(), eq("package"), anyInt()); } @@ -15554,7 +15569,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { if (canSetGlobalPolicy) { verify(zenModeHelper).setManualZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), eq(null), - eq(ZenModeConfig.UPDATE_ORIGIN_APP), anyString(), eq("package"), anyInt()); + eq(ZenModeConfig.ORIGIN_APP), anyString(), eq("package"), anyInt()); } else { verify(zenModeHelper).applyGlobalZenModeAsImplicitZenRule(anyString(), anyInt(), eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS)); @@ -15594,7 +15609,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { INTERRUPTION_FILTER_PRIORITY); verify(mService.mZenModeHelper).setManualZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), - eq(null), eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), + eq(null), eq(ZenModeConfig.ORIGIN_SYSTEM), anyString(), eq("pkg"), eq(mUid)); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenChangeOrigin.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenChangeOrigin.java new file mode 100644 index 000000000000..572878857286 --- /dev/null +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenChangeOrigin.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.notification; + +import android.service.notification.ZenModeConfig; + +/** Enum version of {@link ZenModeConfig.ConfigOrigin}, for test parameterization. */ +public enum ZenChangeOrigin { + ORIGIN_UNKNOWN(ZenModeConfig.ORIGIN_UNKNOWN), + ORIGIN_INIT(ZenModeConfig.ORIGIN_INIT), + ORIGIN_INIT_USER(ZenModeConfig.ORIGIN_INIT_USER), + ORIGIN_APP(ZenModeConfig.ORIGIN_APP), + ORIGIN_USER_IN_APP(ZenModeConfig.ORIGIN_USER_IN_APP), + ORIGIN_SYSTEM(ZenModeConfig.ORIGIN_SYSTEM), + ORIGIN_USER_IN_SYSTEMUI(ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI), + ORIGIN_RESTORE_BACKUP(ZenModeConfig.ORIGIN_RESTORE_BACKUP); + + private final int mValue; + + ZenChangeOrigin(@ZenModeConfig.ConfigOrigin int value) { + mValue = value; + } + + /** Gets the {@link ZenModeConfig.ConfigOrigin} int value corresponding to the enum. */ + @ZenModeConfig.ConfigOrigin + public int value() { + return mValue; + } +} diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenEnumTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenEnumTest.java index 8add2f957a07..cdceb1f0d86b 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenEnumTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenEnumTest.java @@ -20,12 +20,14 @@ import static com.google.common.truth.Truth.assertThat; import android.app.AutomaticZenRule; import android.provider.Settings; +import android.service.notification.ZenModeConfig; import android.service.notification.ZenPolicy; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.os.dnd.ActiveRuleType; +import com.android.os.dnd.ChangeOrigin; import com.android.os.dnd.ChannelPolicy; import com.android.os.dnd.ConversationType; import com.android.os.dnd.PeopleType; @@ -78,6 +80,11 @@ public class ZenEnumTest { testEnum(ZenPolicy.class, "PEOPLE_TYPE", PeopleType.class, "PEOPLE"); } + @Test + public void testEnum_changeOrigin() { + testEnum(ZenModeConfig.class, "ORIGIN", ChangeOrigin.class, "ORIGIN"); + } + /** * Verifies that any constants (i.e. {@code public static final int} fields) named {@code * <apiPrefix>_SOMETHING} in {@code apiClass} are present and have the same numerical value diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java index 3c3c2f34490a..b955a795e94a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeConfigTest.java @@ -535,7 +535,7 @@ public class ZenModeConfigTest extends UiServiceTestCase { rule.triggerDescription = TRIGGER_DESC; rule.deletionInstant = Instant.ofEpochMilli(1701790147000L); if (Flags.modesUi()) { - rule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_USER; + rule.disabledOrigin = ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; } Parcel parcel = Parcel.obtain(); @@ -650,7 +650,7 @@ public class ZenModeConfigTest extends UiServiceTestCase { rule.triggerDescription = TRIGGER_DESC; rule.deletionInstant = Instant.ofEpochMilli(1701790147000L); if (Flags.modesUi()) { - rule.disabledOrigin = ZenModeConfig.UPDATE_ORIGIN_APP; + rule.disabledOrigin = ZenModeConfig.ORIGIN_APP; } ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index d7bae457c70a..63cf1068f51e 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -46,6 +46,7 @@ import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_STARRED; import static android.app.NotificationManager.Policy.STATE_PRIORITY_CHANNELS_BLOCKED; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE; import static android.content.pm.PackageManager.PERMISSION_GRANTED; +import static android.os.Process.SYSTEM_UID; import static android.provider.Settings.Global.ZEN_MODE_ALARMS; import static android.provider.Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; import static android.provider.Settings.Global.ZEN_MODE_NO_INTERRUPTIONS; @@ -54,12 +55,12 @@ import static android.service.notification.Condition.SOURCE_SCHEDULE; import static android.service.notification.Condition.SOURCE_USER_ACTION; import static android.service.notification.Condition.STATE_FALSE; import static android.service.notification.Condition.STATE_TRUE; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT_USER; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_UNKNOWN; -import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_APP; +import static android.service.notification.ZenModeConfig.ORIGIN_INIT; +import static android.service.notification.ZenModeConfig.ORIGIN_INIT_USER; +import static android.service.notification.ZenModeConfig.ORIGIN_UNKNOWN; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_APP; +import static android.service.notification.ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_NONE; import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED; @@ -131,7 +132,6 @@ import android.media.AudioSystem; import android.media.VolumePolicy; import android.net.Uri; import android.os.Parcel; -import android.os.Process; import android.os.SimpleClock; import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; @@ -186,9 +186,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.xmlpull.v1.XmlPullParserException; -import platform.test.runner.parameterized.ParameterizedAndroidJunit4; -import platform.test.runner.parameterized.Parameters; - import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; @@ -208,6 +205,9 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; +import platform.test.runner.parameterized.ParameterizedAndroidJunit4; +import platform.test.runner.parameterized.Parameters; + @SmallTest @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service. @RunWith(ParameterizedAndroidJunit4.class) @@ -338,27 +338,6 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeEventLogger.reset(); } - private enum ChangeOrigin { - ORIGIN_UNKNOWN(ZenModeConfig.UPDATE_ORIGIN_UNKNOWN), - ORIGIN_INIT(ZenModeConfig.UPDATE_ORIGIN_INIT), - ORIGIN_INIT_USER(ZenModeConfig.UPDATE_ORIGIN_INIT_USER), - ORIGIN_USER(ZenModeConfig.UPDATE_ORIGIN_USER), - ORIGIN_APP(ZenModeConfig.UPDATE_ORIGIN_APP), - ORIGIN_SYSTEM_OR_SYSTEMUI(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), - ORIGIN_RESTORE_BACKUP(ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP); - - private final int mValue; - - ChangeOrigin(@ZenModeConfig.ConfigChangeOrigin int value) { - mValue = value; - } - - @ZenModeConfig.ConfigChangeOrigin - public int value() { - return mValue; - } - } - private XmlResourceParser getDefaultConfigParser() throws IOException, XmlPullParserException { String xml = "<zen version=\"10\">\n" + "<allow alarms=\"true\" media=\"true\" system=\"false\" calls=\"true\" " @@ -395,8 +374,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL); serializer.endDocument(); serializer.flush(); - mZenModeHelper.setConfig(new ZenModeConfig(), null, UPDATE_ORIGIN_INIT, "writing xml", - Process.SYSTEM_UID); + mZenModeHelper.setConfig(new ZenModeConfig(), null, ORIGIN_INIT, "writing xml", + SYSTEM_UID); return baos; } @@ -411,8 +390,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { serializer.flush(); ZenModeConfig newConfig = new ZenModeConfig(); newConfig.user = userId; - mZenModeHelper.setConfig(newConfig, null, UPDATE_ORIGIN_INIT, "writing xml", - Process.SYSTEM_UID); + mZenModeHelper.setConfig(newConfig, null, ORIGIN_INIT, "writing xml", + SYSTEM_UID); return baos; } @@ -705,13 +684,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_NONE) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azr, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reason", Process.SYSTEM_UID); + azr, ZenModeConfig.ORIGIN_SYSTEM, "reason", SYSTEM_UID); // Enable rule mZenModeHelper.setAutomaticZenRuleState(ruleId, new Condition(azr.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, + SYSTEM_UID); // Confirm that the consolidated policy doesn't allow anything NotificationManager.Policy policy = mZenModeHelper.getConsolidatedNotificationPolicy(); @@ -739,13 +718,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azr, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reason", Process.SYSTEM_UID); + azr, ZenModeConfig.ORIGIN_SYSTEM, "reason", SYSTEM_UID); // Enable rule mZenModeHelper.setAutomaticZenRuleState(ruleId, new Condition(azr.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, + SYSTEM_UID); // Confirm that the consolidated policy allows only alarms and media and nothing else NotificationManager.Policy policy = mZenModeHelper.getConsolidatedNotificationPolicy(); @@ -819,7 +798,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL); // Set zen to priority-only with all notification sounds muted (so ringer will be muted) Policy totalSilence = new Policy(0, 0, 0); - mZenModeHelper.setNotificationPolicy(totalSilence, UPDATE_ORIGIN_APP, 1); + mZenModeHelper.setNotificationPolicy(totalSilence, ORIGIN_APP, 1); mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; // 2. verify ringer is unchanged @@ -857,7 +836,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // in priority only mode: // ringtone, notification and system streams are affected by ringer mode mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, Uri.EMPTY, - UPDATE_ORIGIN_APP, "test", "caller", 1); + ORIGIN_APP, "test", "caller", 1); ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerMuted = mZenModeHelper.new RingerModeDelegate(); @@ -873,9 +852,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { // even when ringer is muted (since all ringer sounds cannot bypass DND), // system stream is still affected by ringer mode - mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0), UPDATE_ORIGIN_APP, 1); + mZenModeHelper.setNotificationPolicy(new Policy(0, 0, 0), ORIGIN_APP, 1); mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, Uri.EMPTY, - UPDATE_ORIGIN_APP, "test", "caller", 1); + ORIGIN_APP, "test", "caller", 1); ZenModeHelper.RingerModeDelegate ringerModeDelegateRingerNotMuted = mZenModeHelper.new RingerModeDelegate(); @@ -983,7 +962,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_SILENT); for (int i = 0; i < 3; i++) { mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, Uri.EMPTY, - UPDATE_ORIGIN_APP, "test", "caller", 1); + ORIGIN_APP, "test", "caller", 1); } verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL, mZenModeHelper.TAG); @@ -1008,7 +987,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { for (int i = 0; i < 3; i++) { // if zen doesn't change, zen should not reapply itself to the ringer mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, Uri.EMPTY, - UPDATE_ORIGIN_APP, "test", "caller", 1); + ORIGIN_APP, "test", "caller", 1); } verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL, mZenModeHelper.TAG); @@ -1033,7 +1012,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { for (int i = 0; i < 3; i++) { // if zen doesn't change, zen should not reapply itself to the ringer mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, Uri.EMPTY, - UPDATE_ORIGIN_APP, "test", "caller", 1); + ORIGIN_APP, "test", "caller", 1); } verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL, mZenModeHelper.TAG); @@ -1048,7 +1027,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { reset(mAudioManager); // Turn manual zen mode on - mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP, + mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, + ORIGIN_APP, null, "test", CUSTOM_PKG_UID); // audio manager shouldn't do anything until the handler processes its messages @@ -1076,14 +1056,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setManualZenMode( ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_APP, + ORIGIN_APP, null, "test", CUSTOM_PKG_UID); mZenModeHelper.setManualZenMode( ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_APP, + ORIGIN_APP, null, "test", CUSTOM_PKG_UID); @@ -1108,15 +1088,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { | PRIORITY_CATEGORY_MESSAGES | PRIORITY_CATEGORY_REPEAT_CALLERS | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED, PRIORITY_SENDERS_STARRED, 0, CONVERSATION_SENDERS_ANYONE), - UPDATE_ORIGIN_UNKNOWN, + ORIGIN_UNKNOWN, 1); mZenModeHelper.setManualZenRuleDeviceEffects(new ZenDeviceEffects.Builder() .setShouldDimWallpaper(true) .setShouldDisplayGrayscale(true) .setShouldUseNightMode(true) - .build(), UPDATE_ORIGIN_UNKNOWN, "test", 1); + .build(), ORIGIN_UNKNOWN, "test", 1); mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, Uri.EMPTY, - UPDATE_ORIGIN_UNKNOWN, "test", "me", 1); + ORIGIN_UNKNOWN, "test", "me", 1); ZenModeConfig actual = mZenModeHelper.mConfig.copy(); @@ -1130,13 +1110,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { | PRIORITY_CATEGORY_CONVERSATIONS, PRIORITY_SENDERS_STARRED, PRIORITY_SENDERS_STARRED, SUPPRESSED_EFFECT_BADGE, CONVERSATION_SENDERS_ANYONE), - UPDATE_ORIGIN_UNKNOWN, 1); + ORIGIN_UNKNOWN, 1); mZenModeHelper.setManualZenRuleDeviceEffects(new ZenDeviceEffects.Builder() .setShouldDimWallpaper(true) .setShouldDisplayGrayscale(true) - .build(), UPDATE_ORIGIN_UNKNOWN, "test", 1); + .build(), ORIGIN_UNKNOWN, "test", 1); mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, Uri.EMPTY, - UPDATE_ORIGIN_UNKNOWN, "test", "me", 1); + ORIGIN_UNKNOWN, "test", "me", 1); ZenModeConfig expected = mZenModeHelper.mConfig.copy(); if (Flags.modesUi()) { @@ -1157,7 +1137,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test public void testProto() throws InvalidProtocolBufferException { mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, + Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ZenModeConfig.ORIGIN_SYSTEM, null, "test", CUSTOM_PKG_UID); mZenModeHelper.mConfig.automaticRules = new ArrayMap<>(); // no automatic rules @@ -1381,7 +1361,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { List<StatsEvent> events = new LinkedList<>(); mZenModeHelper.pullRules(events); - mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, UPDATE_ORIGIN_APP, "test", + mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertTrue(-1 == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1)); @@ -1410,7 +1390,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { public void testProtoWithManualRule() throws Exception { setupZenConfig(); mZenModeHelper.mConfig.automaticRules = getCustomAutomaticRules(); - mZenModeHelper.setManualZenMode(INTERRUPTION_FILTER_PRIORITY, Uri.EMPTY, UPDATE_ORIGIN_APP, + mZenModeHelper.setManualZenMode(INTERRUPTION_FILTER_PRIORITY, Uri.EMPTY, + ORIGIN_APP, "test", "me", 1); List<StatsEvent> events = new LinkedList<>(); @@ -1437,14 +1418,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { Policy policy = new Policy(PRIORITY_CATEGORY_MEDIA | PRIORITY_CATEGORY_ALARMS, 0, 0); config10.applyNotificationPolicy(policy); config10.user = 10; - mZenModeHelper.setConfig(config10, null, UPDATE_ORIGIN_INIT, "writeXml", - Process.SYSTEM_UID); + mZenModeHelper.setConfig(config10, null, ORIGIN_INIT, "writeXml", + SYSTEM_UID); ZenModeConfig config11 = mZenModeHelper.mConfig.copy(); config11.user = 11; policy = new Policy(0, 0, 0); config11.applyNotificationPolicy(policy); - mZenModeHelper.setConfig(config11, null, UPDATE_ORIGIN_INIT, "writeXml", - Process.SYSTEM_UID); + mZenModeHelper.setConfig(config11, null, ORIGIN_INIT, "writeXml", + SYSTEM_UID); // Backup user 10 and reset values. ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10); @@ -2307,7 +2288,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); // We need the package name to be something that's not "android" so there aren't any // existing rules under that package. - String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP, + String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertNotNull(id); } @@ -2318,7 +2299,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP, + String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { @@ -2339,7 +2320,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(si), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP, + String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertNotNull(id); } @@ -2350,7 +2331,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP, + String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { @@ -2371,7 +2352,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(si), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP, + String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertNotNull(id); } @@ -2382,7 +2363,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP, + String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); fail("allowed too many rules to be created"); } catch (IllegalArgumentException e) { @@ -2399,7 +2380,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); assertTrue(id != null); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -2420,7 +2401,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); assertTrue(id != null); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -2446,7 +2427,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id1 = mZenModeHelper.addAutomaticZenRule("android", zenRule1, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // Zen rule with partially-filled policy: should get all of the filled fields set, and the // rest filled with default state @@ -2461,7 +2442,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // rule 1 should exist assertThat(id1).isNotNull(); @@ -2506,11 +2487,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test", + String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(), new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_APP, + ORIGIN_APP, CUSTOM_PKG_UID); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); @@ -2526,7 +2507,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test", + String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW", @@ -2536,7 +2517,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - mZenModeHelper.updateAutomaticZenRule(id, zenRule2, UPDATE_ORIGIN_APP, "", CUSTOM_PKG_UID); + mZenModeHelper.updateAutomaticZenRule(id, zenRule2, ORIGIN_APP, "", CUSTOM_PKG_UID); ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id); assertEquals("NEW", ruleInConfig.name); @@ -2551,7 +2532,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test", + String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertTrue(id != null); @@ -2559,7 +2540,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue(ruleInConfig != null); assertEquals(zenRule.getName(), ruleInConfig.name); - mZenModeHelper.removeAutomaticZenRule(id, UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertNull(mZenModeHelper.mConfig.automaticRules.get(id)); } @@ -2571,7 +2552,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenModeConfig.toScheduleConditionId(new ScheduleInfo()), new ZenPolicy.Builder().build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); - String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test", + String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, ORIGIN_APP, "test", CUSTOM_PKG_UID); assertTrue(id != null); @@ -2579,7 +2560,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue(ruleInConfig != null); assertEquals(zenRule.getName(), ruleInConfig.name); - mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), UPDATE_ORIGIN_APP, "test", + mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), ORIGIN_APP, "test", CUSTOM_PKG_UID); assertNull(mZenModeHelper.mConfig.automaticRules.get(id)); } @@ -2596,17 +2577,17 @@ public class ZenModeHelperTest extends UiServiceTestCase { sharedUri, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mPkg, zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); AutomaticZenRule zenRule2 = new AutomaticZenRule("name2", new ComponentName(mPkg, "ScheduleConditionProvider"), sharedUri, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mPkg, zenRule2, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); Condition condition = new Condition(sharedUri, "", STATE_TRUE); mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) { if (rule.id.equals(id)) { @@ -2621,7 +2602,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { condition = new Condition(sharedUri, "", STATE_FALSE); mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) { if (rule.id.equals(id)) { @@ -2656,7 +2637,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(zde) .build(), - UPDATE_ORIGIN_APP, "reasons", 0); + ORIGIN_APP, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(savedRule.getDeviceEffects()).isEqualTo( @@ -2689,7 +2670,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(zde) .build(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(savedRule.getDeviceEffects()).isEqualTo(zde); @@ -2716,7 +2697,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(zde) .build(), - UPDATE_ORIGIN_USER, + ORIGIN_USER_IN_SYSTEMUI, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); @@ -2736,7 +2717,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(original) .build(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", 0); ZenDeviceEffects updateFromApp = new ZenDeviceEffects.Builder() .setShouldUseNightMode(true) // Good @@ -2748,7 +2729,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(updateFromApp) .build(), - UPDATE_ORIGIN_APP, "reasons", 0); + ORIGIN_APP, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(savedRule.getDeviceEffects()).isEqualTo( @@ -2770,7 +2751,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(original) .build(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", 0); ZenDeviceEffects updateFromSystem = new ZenDeviceEffects.Builder() .setShouldUseNightMode(true) // Good @@ -2780,7 +2761,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new AutomaticZenRule.Builder("Rule", CONDITION_ID) .setDeviceEffects(updateFromSystem) .build(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromSystem); @@ -2797,7 +2778,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setDeviceEffects(original) .build(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", 0); ZenDeviceEffects updateFromUser = new ZenDeviceEffects.Builder() .setShouldUseNightMode(true) @@ -2810,7 +2791,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { new AutomaticZenRule.Builder("Rule", CONDITION_ID) .setDeviceEffects(updateFromUser) .build(), - UPDATE_ORIGIN_USER, "reasons", 0); + ORIGIN_USER_IN_SYSTEMUI, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); @@ -2829,13 +2810,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowCalls(ZenPolicy.PEOPLE_TYPE_NONE) // default is stars .build()) .build(), - UPDATE_ORIGIN_APP, "reasons", 0); + ORIGIN_APP, "reasons", 0); mZenModeHelper.updateAutomaticZenRule(ruleId, new AutomaticZenRule.Builder("Rule", CONDITION_ID) // no zen policy .build(), - UPDATE_ORIGIN_APP, "reasons", 0); + ORIGIN_APP, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(savedRule.getZenPolicy().getPriorityCategoryCalls()) @@ -2857,7 +2838,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowReminders(true) .build()) .build(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", 0); mZenModeHelper.updateAutomaticZenRule(ruleId, new AutomaticZenRule.Builder("Rule", CONDITION_ID) @@ -2865,7 +2846,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .allowCalls(ZenPolicy.PEOPLE_TYPE_CONTACTS) .build()) .build(), - UPDATE_ORIGIN_APP, "reasons", 0); + ORIGIN_APP, "reasons", 0); AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(savedRule.getZenPolicy().getPriorityCategoryCalls()) @@ -2893,7 +2874,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID) .setType(TYPE_BEDTIME) .build(); - String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule("pkg", bedtime, UPDATE_ORIGIN_APP, + String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule("pkg", bedtime, + ORIGIN_APP, "reason", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(bedtimeRuleId); @@ -2913,7 +2895,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID) .setType(TYPE_BEDTIME) .build(); - String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule("pkg", bedtime, UPDATE_ORIGIN_APP, + String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule("pkg", bedtime, + ORIGIN_APP, "reason", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly( @@ -2934,7 +2917,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule bedtime = new AutomaticZenRule.Builder("Bedtime Mode (TM)", CONDITION_ID) .setType(TYPE_BEDTIME) .build(); - String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule("pkg", bedtime, UPDATE_ORIGIN_APP, + String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule("pkg", bedtime, + ORIGIN_APP, "reason", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly( @@ -2948,15 +2932,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { // note that caller=null because that's how it comes in from NMS.setZenMode mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "", null, SYSTEM_UID); // confirm that setting zen mode via setManualZenMode changed the zen mode correctly assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode); assertEquals(true, mZenModeHelper.mConfig.manualRule.allowManualInvocation); // and also that it works to turn it back off again - mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "", null, Process.SYSTEM_UID); + mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, ZenModeConfig.ORIGIN_SYSTEM, + "", null, SYSTEM_UID); assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode); } @@ -2965,28 +2949,29 @@ public class ZenModeHelperTest extends UiServiceTestCase { @EnableFlags(FLAG_MODES_API) @DisableFlags(FLAG_MODES_UI) public void setManualZenMode_off_snoozesActiveRules() { - for (ChangeOrigin origin : ChangeOrigin.values()) { + for (ZenChangeOrigin origin : ZenChangeOrigin.values()) { // Start with an active rule and an inactive rule. mZenModeHelper.mConfig.automaticRules.clear(); AutomaticZenRule activeRule = new AutomaticZenRule.Builder("Test", CONDITION_ID) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String activeRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - activeRule, UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); - mZenModeHelper.setAutomaticZenRuleState(activeRuleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + activeRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID); + mZenModeHelper.setAutomaticZenRuleState(activeRuleId, CONDITION_TRUE, + ORIGIN_APP, CUSTOM_PKG_UID); AutomaticZenRule inactiveRule = new AutomaticZenRule.Builder("Test", CONDITION_ID) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String inactiveRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - inactiveRule, UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + inactiveRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID); assertWithMessage("Failure for origin " + origin.name()) .that(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); // User turns DND off. mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, origin.value(), - "snoozing", "systemui", Process.SYSTEM_UID); + "snoozing", "systemui", SYSTEM_UID); assertWithMessage("Failure for origin " + origin.name()) .that(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF); assertWithMessage("Failure for origin " + origin.name()) @@ -3000,30 +2985,31 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI}) - public void setManualZenMode_off_doesNotSnoozeRulesIfFromUser() { - for (ChangeOrigin origin : ChangeOrigin.values()) { + public void setManualZenMode_off_doesNotSnoozeRulesIfFromUserInSystemUi() { + for (ZenChangeOrigin origin : ZenChangeOrigin.values()) { // Start with an active rule and an inactive rule mZenModeHelper.mConfig.automaticRules.clear(); AutomaticZenRule activeRule = new AutomaticZenRule.Builder("Test", CONDITION_ID) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String activeRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - activeRule, UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); - mZenModeHelper.setAutomaticZenRuleState(activeRuleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + activeRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID); + mZenModeHelper.setAutomaticZenRuleState(activeRuleId, CONDITION_TRUE, + ORIGIN_APP, CUSTOM_PKG_UID); AutomaticZenRule inactiveRule = new AutomaticZenRule.Builder("Test", CONDITION_ID) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String inactiveRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - inactiveRule, UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + inactiveRule, ORIGIN_APP, "add it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); // User turns DND off. mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, origin.value(), - "snoozing", "systemui", Process.SYSTEM_UID); + "snoozing", "systemui", SYSTEM_UID); ZenModeConfig config = mZenModeHelper.mConfig; - if (origin == ChangeOrigin.ORIGIN_USER) { + if (origin == ZenChangeOrigin.ORIGIN_USER_IN_SYSTEMUI) { // Other rule was unaffected. assertWithMessage("Failure for origin " + origin.name()).that( mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); @@ -3048,14 +3034,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { // note that caller=null because that's how it comes in from NMS.setZenMode mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "", null, SYSTEM_UID); // confirm that setting zen mode via setManualZenMode changed the zen mode correctly assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode); // and also that it works to turn it back off again - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", - null, Process.SYSTEM_UID); + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ZenModeConfig.ORIGIN_SYSTEM, "", + null, SYSTEM_UID); assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode); } @@ -3069,12 +3055,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Turn zen mode on (to important_interruptions) // Need to additionally call the looper in order to finish the post-apply-config process mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, - Process.SYSTEM_UID); + Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ZenModeConfig.ORIGIN_SYSTEM, "", + null, SYSTEM_UID); // Now turn zen mode off, but via a different package UID -- this should get registered as // "not an action by the user" because some other app is changing zen mode - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "", null, + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ORIGIN_APP, "", null, CUSTOM_PKG_UID); // In total, this should be 2 loggable changes @@ -3100,11 +3086,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(mZenModeEventLogger.getFromSystemOrSystemUi(0)).isEqualTo( !(Flags.modesUi() || Flags.modesApi())); assertTrue(mZenModeEventLogger.getIsUserAction(0)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(0)); checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0)); // change origin should be populated only under modes_ui assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo( - (Flags.modesApi() && Flags.modesUi()) ? UPDATE_ORIGIN_USER : 0); + (Flags.modesApi() && Flags.modesUi()) ? ORIGIN_USER_IN_SYSTEMUI : 0); // and from turning zen mode off: // - event ID: DND_TURNED_OFF @@ -3128,7 +3114,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1)); } assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_APP : 0); + Flags.modesUi() ? ORIGIN_APP : 0); } @Test @@ -3145,7 +3131,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID); + ORIGIN_APP, "test", CUSTOM_PKG_UID); // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE // Note that pre-modes_ui, this event serves as a test that automatic changes to an app's @@ -3153,14 +3139,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { // modes_ui is true, we opt to trust the provided change origin. mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - Flags.modesUi() ? UPDATE_ORIGIN_APP : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, + Flags.modesUi() ? ORIGIN_APP : ZenModeConfig.ORIGIN_SYSTEM, CUSTOM_PKG_UID); // Event 2: "User" turns off the automatic rule (sets it to not enabled) zenRule.setEnabled(false); mZenModeHelper.updateAutomaticZenRule(id, zenRule, - Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", - Process.SYSTEM_UID); + Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ZenModeConfig.ORIGIN_SYSTEM, "", + SYSTEM_UID); AutomaticZenRule systemRule = new AutomaticZenRule("systemRule", null, @@ -3169,18 +3155,18 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule, - Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", - Process.SYSTEM_UID); + Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ZenModeConfig.ORIGIN_SYSTEM, "test", + SYSTEM_UID); // Event 3: turn on the system rule mZenModeHelper.setAutomaticZenRuleState(systemId, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Event 4: "User" deletes the rule mZenModeHelper.removeAutomaticZenRule(systemId, - Flags.modesApi() ? UPDATE_ORIGIN_USER : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", - Process.SYSTEM_UID); + Flags.modesApi() ? ORIGIN_USER_IN_SYSTEMUI : ZenModeConfig.ORIGIN_SYSTEM, "", + SYSTEM_UID); // In total, this represents 4 events assertEquals(4, mZenModeEventLogger.numLoggedChanges()); @@ -3203,7 +3189,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0)); checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(0)); assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_APP : 0); + Flags.modesUi() ? ORIGIN_APP : 0); // When the automatic rule is disabled, this should turn off zen mode and also count as a // user action. We don't care what the consolidated policy is when DND turns off. @@ -3217,14 +3203,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(0, mZenModeEventLogger.getNumRulesActive(1)); assertTrue(mZenModeEventLogger.getIsUserAction(1)); assertThat(mZenModeEventLogger.getPackageUid(1)).isEqualTo( - Flags.modesUi() ? CUSTOM_PKG_UID : Process.SYSTEM_UID); + Flags.modesUi() ? CUSTOM_PKG_UID : SYSTEM_UID); if (Flags.modesApi()) { assertThat(mZenModeEventLogger.getPolicyProto(1)).isNull(); } else { checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(1)); } assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_USER : 0); + Flags.modesUi() ? ORIGIN_USER_IN_SYSTEMUI : 0); // When the system rule is enabled, this counts as an automatic action that comes from the // system and turns on DND @@ -3233,9 +3219,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2)); assertEquals(1, mZenModeEventLogger.getNumRulesActive(2)); assertFalse(mZenModeEventLogger.getIsUserAction(2)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(2)); assertThat(mZenModeEventLogger.getChangeOrigin(2)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI : 0); + Flags.modesUi() ? ZenModeConfig.ORIGIN_SYSTEM : 0); // When the system rule is deleted, we consider this a user action that turns DND off // (again) @@ -3244,9 +3230,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(3)); assertEquals(0, mZenModeEventLogger.getNumRulesActive(3)); assertTrue(mZenModeEventLogger.getIsUserAction(3)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(3)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(3)); assertThat(mZenModeEventLogger.getChangeOrigin(3)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_USER : 0); + Flags.modesUi() ? ORIGIN_USER_IN_SYSTEMUI : 0); } @Test @@ -3264,28 +3250,28 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID); + ORIGIN_APP, "test", CUSTOM_PKG_UID); // Event 1: Mimic the rule coming on manually when the user turns it on in the app // ("Turn on bedtime now" because user goes to bed earlier). mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_USER_ACTION), - UPDATE_ORIGIN_USER, CUSTOM_PKG_UID); + ORIGIN_USER_IN_APP, CUSTOM_PKG_UID); // Event 2: App deactivates the rule automatically (it's 8 AM, bedtime schedule ends) mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Event 3: App activates the rule automatically (it's now 11 PM, bedtime schedule starts) mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Event 4: User deactivates the rule manually (they get up before 8 AM on the next day) mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_USER_ACTION), - UPDATE_ORIGIN_USER, CUSTOM_PKG_UID); + ORIGIN_USER_IN_APP, CUSTOM_PKG_UID); // In total, this represents 4 events assertEquals(4, mZenModeEventLogger.numLoggedChanges()); @@ -3301,7 +3287,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue(mZenModeEventLogger.getIsUserAction(0)); assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(0)); assertThat(mZenModeEventLogger.getChangeOrigin(0)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_USER : 0); + Flags.modesUi() ? ORIGIN_USER_IN_APP : 0); // Automatic rule turned off automatically by app: // - event ID: DND_TURNED_OFF @@ -3314,7 +3300,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertFalse(mZenModeEventLogger.getIsUserAction(1)); assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(1)); assertThat(mZenModeEventLogger.getChangeOrigin(1)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_APP : 0); + Flags.modesUi() ? ORIGIN_APP : 0); // Automatic rule turned on automatically by app: // - event ID: DND_TURNED_ON @@ -3328,7 +3314,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertFalse(mZenModeEventLogger.getIsUserAction(2)); assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(2)); assertThat(mZenModeEventLogger.getChangeOrigin(2)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_APP : 0); + Flags.modesUi() ? ORIGIN_APP : 0); // Automatic rule turned off automatically by the user: // - event ID: DND_TURNED_ON @@ -3341,7 +3327,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertTrue(mZenModeEventLogger.getIsUserAction(3)); assertEquals(CUSTOM_PKG_UID, mZenModeEventLogger.getPackageUid(3)); assertThat(mZenModeEventLogger.getChangeOrigin(3)).isEqualTo( - Flags.modesUi() ? UPDATE_ORIGIN_USER : 0); + Flags.modesUi() ? ORIGIN_USER_IN_APP : 0); } @Test @@ -3352,21 +3338,21 @@ public class ZenModeHelperTest extends UiServiceTestCase { // First just turn zen mode on mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_USER, "", null, Process.SYSTEM_UID); + ORIGIN_USER_IN_SYSTEMUI, "", null, SYSTEM_UID); // Now change the policy slightly; want to confirm that this'll be reflected in the logs ZenModeConfig newConfig = mZenModeHelper.mConfig.copy(); mZenModeHelper.setNotificationPolicy(new Policy(PRIORITY_CATEGORY_ALARMS, 0, 0), - UPDATE_ORIGIN_USER, Process.SYSTEM_UID); + ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID); // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode // is off. - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", - null, Process.SYSTEM_UID); + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ZenModeConfig.ORIGIN_SYSTEM, "", + null, SYSTEM_UID); // Change the policy again mZenModeHelper.setNotificationPolicy(new Policy(PRIORITY_CATEGORY_REPEAT_CALLERS, 0, 0), - UPDATE_ORIGIN_USER, Process.SYSTEM_UID); + ORIGIN_USER_IN_SYSTEMUI, SYSTEM_UID); // Total events: we only expect ones for turning on, changing policy, and turning off assertEquals(3, mZenModeEventLogger.numLoggedChanges()); @@ -3386,7 +3372,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeEventLogger.getEventId(1)); assertEquals(DNDProtoEnums.UNKNOWN_RULE, mZenModeEventLogger.getChangedRuleType(1)); assertTrue(mZenModeEventLogger.getIsUserAction(1)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(1)); DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(1); assertEquals(STATE_ALLOW, dndProto.getAlarms().getNumber()); assertEquals(STATE_DISALLOW, dndProto.getRepeatCallers().getNumber()); @@ -3410,7 +3396,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // Rule 2, same as rule 1 AutomaticZenRule zenRule2 = new AutomaticZenRule("name2", @@ -3420,7 +3406,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // Rule 3, has stricter settings than the default settings ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy(); @@ -3432,27 +3418,27 @@ public class ZenModeHelperTest extends UiServiceTestCase { ruleConfig.getZenPolicy(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // First: turn on rule 1 mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Second: turn on rule 2 mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Third: turn on rule 3 mZenModeHelper.setAutomaticZenRuleState(id3, new Condition(zenRule3.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Fourth: Turn *off* rule 2 mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_FALSE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // This should result in a total of four events assertEquals(4, mZenModeEventLogger.numLoggedChanges()); @@ -3465,7 +3451,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeEventLogger.getNewZenMode(0)); assertEquals(1, mZenModeEventLogger.getNumRulesActive(0)); assertFalse(mZenModeEventLogger.getIsUserAction(0)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(0)); checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(0)); // Event 2: rule 2 turns on. This should not change anything about the policy, so the only @@ -3474,7 +3460,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeEventLogger.getEventId(1)); assertEquals(2, mZenModeEventLogger.getNumRulesActive(1)); assertFalse(mZenModeEventLogger.getIsUserAction(1)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(1)); checkDndProtoMatchesDefaultZenConfig(mZenModeEventLogger.getPolicyProto(1)); // Event 3: rule 3 turns on. This should trigger a policy change, and be classified as such, @@ -3484,7 +3470,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeEventLogger.getEventId(2)); assertEquals(3, mZenModeEventLogger.getNumRulesActive(2)); assertFalse(mZenModeEventLogger.getIsUserAction(2)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(2)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(2)); DNDPolicyProto dndProto = mZenModeEventLogger.getPolicyProto(2); assertEquals(STATE_DISALLOW, dndProto.getReminders().getNumber()); assertEquals(STATE_DISALLOW, dndProto.getCalls().getNumber()); @@ -3508,7 +3494,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Artificially turn zen mode "on". Re-evaluating zen mode should cause it to turn back off // given that we don't have any zen rules active. mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS; - mZenModeHelper.evaluateZenModeLocked(UPDATE_ORIGIN_UNKNOWN, "test", true); + mZenModeHelper.evaluateZenModeLocked(ORIGIN_UNKNOWN, "test", true); // Check that the change actually took: zen mode should be off now assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode); @@ -3537,7 +3523,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { manualRulePolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_APP, "test", Process.SYSTEM_UID); + ORIGIN_APP, "test", SYSTEM_UID); // Rule 2, same as rule 1 but owned by the system AutomaticZenRule zenRule2 = new AutomaticZenRule("name2", @@ -3547,7 +3533,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { manualRulePolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - UPDATE_ORIGIN_USER, "test", Process.SYSTEM_UID); + ORIGIN_USER_IN_SYSTEMUI, "test", SYSTEM_UID); // Turn on rule 1; call looks like it's from the system. Because setting a condition is // typically an automatic (non-user-initiated) action, expect the calling UID to be @@ -3555,23 +3541,24 @@ public class ZenModeHelperTest extends UiServiceTestCase { // When modes_ui is true: we expect the change origin to be the source of truth. mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - Flags.modesUi() ? UPDATE_ORIGIN_APP : UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - Process.SYSTEM_UID); + Flags.modesUi() ? ORIGIN_APP : ZenModeConfig.ORIGIN_SYSTEM, + SYSTEM_UID); // Second: turn on rule 2. This is a system-owned rule and the UID should not be modified // (nor even looked up; the mock PackageManager won't handle "android" as input). mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Disable rule 1. Because this looks like a user action, the UID should not be modified // from the system-provided one unless modes_ui is true. zenRule.setEnabled(false); mZenModeHelper.updateAutomaticZenRule(id, zenRule, - UPDATE_ORIGIN_USER, "", Process.SYSTEM_UID); + ORIGIN_USER_IN_SYSTEMUI, "", SYSTEM_UID); // Add a manual rule. Any manual rule changes should not get calling uids reassigned. - mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP, + mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, + ORIGIN_APP, "", null, CUSTOM_PKG_UID); // Change rule 2's condition, but from some other UID. Since it doesn't look like it's from @@ -3579,7 +3566,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Note that this probably shouldn't be able to occur in real scenarios. mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_FALSE), - UPDATE_ORIGIN_APP, 12345); + ORIGIN_APP, 12345); // That was 5 events total assertEquals(5, mZenModeEventLogger.numLoggedChanges()); @@ -3598,7 +3585,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeEventLogger.getEventId(1)); assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(1)); assertFalse(mZenModeEventLogger.getIsUserAction(1)); - assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(1)); + assertEquals(SYSTEM_UID, mZenModeEventLogger.getPackageUid(1)); // Third event: disable rule 1. This looks like a user action so UID should be left alone. // When modes_ui is true, we assign log this user action with the app that owns the rule. @@ -3607,7 +3594,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertEquals(DNDProtoEnums.AUTOMATIC_RULE, mZenModeEventLogger.getChangedRuleType(2)); assertTrue(mZenModeEventLogger.getIsUserAction(2)); assertThat(mZenModeEventLogger.getPackageUid(2)).isEqualTo( - Flags.modesUi() ? CUSTOM_PKG_UID : Process.SYSTEM_UID); + Flags.modesUi() ? CUSTOM_PKG_UID : SYSTEM_UID); // Fourth event: turns on manual mode. Doesn't change effective policy so this is just a // change in active rules. Confirm that the package UID is left unchanged. @@ -3636,29 +3623,30 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Turn on zen mode with a manual rule with an enabler set. This should *not* count // as a user action, and *should* get its UID reassigned. mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", CUSTOM_PKG_NAME, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "", CUSTOM_PKG_NAME, SYSTEM_UID); assertEquals(1, mZenModeEventLogger.numLoggedChanges()); // Now change apps bypassing to true ZenModeConfig newConfig = mZenModeHelper.mConfig.copy(); newConfig.areChannelsBypassingDnd = true; mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); assertEquals(2, mZenModeEventLogger.numLoggedChanges()); // and then back to false, all without changing anything else newConfig.areChannelsBypassingDnd = false; mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); assertEquals(3, mZenModeEventLogger.numLoggedChanges()); // Turn off manual mode, call from a package: don't reset UID even though enabler is set - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "", + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ORIGIN_APP, "", CUSTOM_PKG_NAME, 12345); assertEquals(4, mZenModeEventLogger.numLoggedChanges()); // And likewise when turning it back on again - mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP, + mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, + ORIGIN_APP, "", CUSTOM_PKG_NAME, 12345); // These are 5 events in total. @@ -3705,7 +3693,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // First just turn zen mode on mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "", null, SYSTEM_UID); // Now change only the channels part of the policy; want to confirm that this'll be // reflected in the logs @@ -3716,7 +3704,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { STATE_PRIORITY_CHANNELS_BLOCKED, oldPolicy.priorityConversationSenders); mZenModeHelper.setNotificationPolicy(newPolicy, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Total events: one for turning on, one for changing policy assertThat(mZenModeEventLogger.numLoggedChanges()).isEqualTo(2); @@ -3757,17 +3745,17 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_ALL, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID); + ORIGIN_APP, "test", CUSTOM_PKG_UID); // Event 1: App activates the rule automatically. mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Event 2: App deactivates the rule automatically. mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // In total, this represents 2 events. assertEquals(2, mZenModeEventLogger.numLoggedChanges()); @@ -3798,7 +3786,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_ALL) .setType(TYPE_BEDTIME) .build(); - String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(mPkg, bedtime, UPDATE_ORIGIN_APP, + String bedtimeRuleId = mZenModeHelper.addAutomaticZenRule(mPkg, bedtime, + ORIGIN_APP, "reason", CUSTOM_PKG_UID); // Create immersive rule @@ -3806,27 +3795,28 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setType(TYPE_IMMERSIVE) .setZenPolicy(mZenModeHelper.mConfig.getZenPolicy()) // same as the manual rule .build(); - String immersiveId = mZenModeHelper.addAutomaticZenRule(mPkg, immersive, UPDATE_ORIGIN_APP, + String immersiveId = mZenModeHelper.addAutomaticZenRule(mPkg, immersive, + ORIGIN_APP, "reason", CUSTOM_PKG_UID); // Event 1: Activate bedtime rule. This doesn't turn on notification filtering mZenModeHelper.setAutomaticZenRuleState(bedtimeRuleId, new Condition(bedtime.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Event 2: turn on manual zen mode. Manual rule will have ACTIVE_RULE_TYPE_MANUAL mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "", null, SYSTEM_UID); // Event 3: Turn immersive on mZenModeHelper.setAutomaticZenRuleState(immersiveId, new Condition(immersive.getConditionId(), "", STATE_TRUE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Event 4: Turn off bedtime mode, leaving just manual + immersive mZenModeHelper.setAutomaticZenRuleState(bedtimeRuleId, new Condition(bedtime.getConditionId(), "", STATE_FALSE, SOURCE_SCHEDULE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Total of 4 events assertEquals(4, mZenModeEventLogger.numLoggedChanges()); @@ -3887,12 +3877,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable the rule mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); assertEquals(mZenModeHelper.getNotificationPolicy(), mZenModeHelper.getConsolidatedNotificationPolicy()); @@ -3923,12 +3913,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, // null policy NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable the rule mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // inspect the consolidated policy, which should match the device default settings. assertThat(ZenAdapters.notificationPolicyToZenPolicy(mZenModeHelper.mConsolidatedPolicy)) @@ -3961,12 +3951,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable the rule; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // since this is the only active rule, the consolidated policy should match the custom // policy for every field specified, and take default values (from device default or @@ -4006,12 +3996,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable the rule; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // since this is the only active rule, the consolidated policy should match the custom // policy for every field specified, and take default values (from either device default @@ -4046,12 +4036,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable rule 1 mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // custom policy for rule 2 ZenPolicy customPolicy = new ZenPolicy.Builder() @@ -4070,12 +4060,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable rule 2; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // now both rules should be on, and the consolidated policy should reflect the most // restrictive option of each of the two @@ -4107,12 +4097,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable rule 1 mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // custom policy for rule 2 ZenPolicy customPolicy = new ZenPolicy.Builder() @@ -4131,12 +4121,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable rule 2; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // now both rules should be on, and the consolidated policy should reflect the most // restrictive option of each of the two @@ -4173,12 +4163,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { customPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable the rule; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // confirm that channels make it through assertTrue(mZenModeHelper.mConsolidatedPolicy.allowPriorityChannels()); @@ -4195,12 +4185,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { strictPolicy, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // enable rule 2; this will update the consolidated policy mZenModeHelper.setAutomaticZenRuleState(id2, new Condition(zenRule2.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // rule 2 should override rule 1 assertFalse(mZenModeHelper.mConsolidatedPolicy.allowPriorityChannels()); @@ -4226,10 +4216,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(), NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); String rule1Id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRuleWithPriority, UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID); + zenRuleWithPriority, ORIGIN_APP, "test", CUSTOM_PKG_UID); mZenModeHelper.setAutomaticZenRuleState(rule1Id, new Condition(zenRuleWithPriority.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Rule 2: ALL, but somehow with a super strict ZenPolicy. AutomaticZenRule zenRuleWithAll = new AutomaticZenRule("All", @@ -4239,10 +4229,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { new ZenPolicy.Builder().disallowAllSounds().build(), NotificationManager.INTERRUPTION_FILTER_ALL, true); String rule2Id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRuleWithAll, UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID); + zenRuleWithAll, ORIGIN_APP, "test", CUSTOM_PKG_UID); mZenModeHelper.setAutomaticZenRuleState(rule2Id, new Condition(zenRuleWithPriority.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); // Consolidated Policy should be default + rule1. assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isEqualTo( @@ -4321,7 +4311,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(OWNER.getPackageName(), azr, - UPDATE_ORIGIN_APP, "add", CUSTOM_PKG_UID); + ORIGIN_APP, "add", CUSTOM_PKG_UID); ZenModeConfig.ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); @@ -4351,15 +4341,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); // Checks the name can be changed by the app because the user has not modified it. AutomaticZenRule azrUpdate = new AutomaticZenRule.Builder(rule) .setName("NewName") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_APP, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_APP, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(rule.getName()).isEqualTo("NewName"); @@ -4368,16 +4358,16 @@ public class ZenModeHelperTest extends UiServiceTestCase { azrUpdate = new AutomaticZenRule.Builder(rule) .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); // ...but the app can still modify the name, because the name itself hasn't been modified // by the user. azrUpdate = new AutomaticZenRule.Builder(rule) .setName("NewAppName") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_APP, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_APP, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(rule.getName()).isEqualTo("NewAppName"); @@ -4385,8 +4375,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { azrUpdate = new AutomaticZenRule.Builder(rule) .setName("UserProvidedName") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(rule.getName()).isEqualTo("UserProvidedName"); @@ -4394,8 +4384,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { azrUpdate = new AutomaticZenRule.Builder(rule) .setName("NewAppName") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_APP, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_APP, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(rule.getName()).isEqualTo("UserProvidedName"); } @@ -4411,7 +4401,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); // Modifies the filter, icon, zen policy, and device effects @@ -4430,8 +4420,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Update the rule with the AZR from origin user. - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); // UPDATE_ORIGIN_USER should change the bitmask and change the values. @@ -4468,7 +4458,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); // Modifies the icon, zen policy and device effects @@ -4487,8 +4477,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Update the rule with the AZR from origin systemUI. - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "reason", Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ZenModeConfig.ORIGIN_SYSTEM, + "reason", SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); // UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI should change the value but NOT update the bitmask. @@ -4518,7 +4508,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); ZenPolicy policy = new ZenPolicy.Builder() @@ -4535,8 +4525,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Since the rule is not already user modified, UPDATE_ORIGIN_APP can modify the rule. // The bitmask is not modified. - mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, UPDATE_ORIGIN_APP, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azrUpdate, ORIGIN_APP, "reason", + SYSTEM_UID); ZenRule storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleId); assertThat(storedRule.userModifiedFields).isEqualTo(0); @@ -4551,7 +4541,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Creates another rule, this time from user. This will have user modified bits set. String ruleIdUser = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_USER, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_USER_IN_SYSTEMUI, "reason", SYSTEM_UID); storedRule = mZenModeHelper.mConfig.automaticRules.get(ruleIdUser); int ruleModifiedFields = storedRule.userModifiedFields; int rulePolicyModifiedFields = storedRule.zenPolicyUserModifiedFields; @@ -4559,8 +4549,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Zen rule update coming from the app again. This cannot fully update the rule, because // the rule is already considered user modified. - mZenModeHelper.updateAutomaticZenRule(ruleIdUser, azrUpdate, UPDATE_ORIGIN_APP, - "reason", Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleIdUser, azrUpdate, ORIGIN_APP, + "reason", SYSTEM_UID); AutomaticZenRule ruleUser = mZenModeHelper.getAutomaticZenRule(ruleIdUser); // The app can only change the value if the rule is not already user modified, @@ -4591,7 +4581,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build()) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); // The values are modified but the bitmask is not. @@ -4613,7 +4603,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule azr = new AutomaticZenRule.Builder(azrBase) // Sets Device Effects to null @@ -4622,8 +4612,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Zen rule update coming from app, but since the rule isn't already // user modified, it can be updated. - mZenModeHelper.updateAutomaticZenRule(ruleId, azr, UPDATE_ORIGIN_APP, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azr, ORIGIN_APP, "reason", + SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); // When AZR's ZenDeviceEffects is null, the updated rule's device effects are kept. @@ -4639,7 +4629,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); AutomaticZenRule azr = new AutomaticZenRule.Builder(azrBase) @@ -4649,8 +4639,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Zen rule update coming from app, but since the rule isn't already // user modified, it can be updated. - mZenModeHelper.updateAutomaticZenRule(ruleId, azr, UPDATE_ORIGIN_APP, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azr, ORIGIN_APP, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); // When AZR's ZenPolicy is null, we expect the updated rule's policy to be unchanged @@ -4671,7 +4661,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); // Create a fully populated ZenPolicy. @@ -4700,8 +4690,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Applies the update to the rule. // Default config defined in getDefaultConfigParser() is used as the original rule. - mZenModeHelper.updateAutomaticZenRule(ruleId, azr, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azr, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); // New ZenPolicy differs from the default config @@ -4732,7 +4722,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Adds the rule using the app, to avoid having any user modified bits set. String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - azrBase, UPDATE_ORIGIN_APP, "reason", Process.SYSTEM_UID); + azrBase, ORIGIN_APP, "reason", SYSTEM_UID); AutomaticZenRule rule = mZenModeHelper.getAutomaticZenRule(ruleId); ZenDeviceEffects deviceEffects = new ZenDeviceEffects.Builder() @@ -4743,8 +4733,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); // Applies the update to the rule. - mZenModeHelper.updateAutomaticZenRule(ruleId, azr, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, azr, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); rule = mZenModeHelper.getAutomaticZenRule(ruleId); // New ZenDeviceEffects is used; all fields considered set, since previously were null. @@ -4769,7 +4759,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + zenRule, ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[1]; @@ -4785,8 +4775,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.addCallback(callback); zenRule.setEnabled(false); - mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "", Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, ZenModeConfig.ORIGIN_SYSTEM, + "", SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); assertEquals(AUTOMATIC_RULE_STATUS_DISABLED, actualStatus[0]); @@ -4804,7 +4794,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, false); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + zenRule, ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[1]; @@ -4820,8 +4810,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.addCallback(callback); zenRule.setEnabled(true); - mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "", Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, ZenModeConfig.ORIGIN_SYSTEM, + "", SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); assertEquals(AUTOMATIC_RULE_STATUS_ENABLED, actualStatus[0]); @@ -4840,7 +4830,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + zenRule, ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[1]; @@ -4857,7 +4847,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { @@ -4880,7 +4870,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + zenRule, ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[2]; @@ -4899,10 +4889,10 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); - mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - null, "", Process.SYSTEM_UID); + mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, ZenModeConfig.ORIGIN_SYSTEM, + null, "", SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { @@ -4925,7 +4915,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + zenRule, ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); CountDownLatch latch = new CountDownLatch(1); final int[] actualStatus = new int[2]; @@ -4944,11 +4934,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_FALSE), - UPDATE_ORIGIN_APP, Process.SYSTEM_UID); + ORIGIN_APP, SYSTEM_UID); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); if (CompatChanges.isChangeEnabled(ZenModeHelper.SEND_ACTIVATION_AZR_STATUSES)) { @@ -4970,21 +4960,21 @@ public class ZenModeHelperTest extends UiServiceTestCase { null, NotificationManager.INTERRUPTION_FILTER_PRIORITY, true); final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID); + zenRule, ZenModeConfig.ORIGIN_SYSTEM, "test", SYSTEM_UID); // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE mZenModeHelper.setAutomaticZenRuleState(createdId, new Condition(zenRule.getConditionId(), "", STATE_TRUE), - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, SYSTEM_UID); // Event 2: Snooze rule by turning off DND - mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "", null, Process.SYSTEM_UID); + mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, ZenModeConfig.ORIGIN_SYSTEM, + "", null, SYSTEM_UID); // Event 3: "User" turns off the automatic rule (sets it to not enabled) zenRule.setEnabled(false); - mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "", Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, ZenModeConfig.ORIGIN_SYSTEM, + "", SYSTEM_UID); assertEquals(false, mZenModeHelper.mConfig.automaticRules.get(createdId).snoozing); } @@ -4997,16 +4987,16 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setConfigurationActivity(new ComponentName(mPkg, "cls")) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, UPDATE_ORIGIN_APP, "reason", + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "reason", CUSTOM_PKG_UID); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); AutomaticZenRule updateWithDiff = new AutomaticZenRule.Builder(rule) .setTriggerDescription("Whenever") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, updateWithDiff, UPDATE_ORIGIN_APP, "reason", + mZenModeHelper.updateAutomaticZenRule(ruleId, updateWithDiff, ORIGIN_APP, "reason", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF); @@ -5021,14 +5011,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setConfigurationActivity(new ComponentName(mPkg, "cls")) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, UPDATE_ORIGIN_APP, "reason", + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "reason", CUSTOM_PKG_UID); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); AutomaticZenRule updateUnchanged = new AutomaticZenRule.Builder(rule).build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, updateUnchanged, UPDATE_ORIGIN_APP, "reason", + mZenModeHelper.updateAutomaticZenRule(ruleId, updateUnchanged, ORIGIN_APP, "reason", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); @@ -5044,17 +5034,17 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setConfigurationActivity(new ComponentName(mPkg, "cls")) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, UPDATE_ORIGIN_APP, "reason", + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "reason", CUSTOM_PKG_UID); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); AutomaticZenRule updateWithDiff = new AutomaticZenRule.Builder(rule) .setTriggerDescription("Whenever") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, updateWithDiff, UPDATE_ORIGIN_USER, "reason", - CUSTOM_PKG_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, updateWithDiff, ORIGIN_USER_IN_SYSTEMUI, + "reason", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isEqualTo( @@ -5074,15 +5064,15 @@ public class ZenModeHelperTest extends UiServiceTestCase { .build(); String ruleId = mZenModeHelper.addAutomaticZenRule( - mPkg, rule, UPDATE_ORIGIN_APP, "reason", CUSTOM_PKG_UID); + mPkg, rule, ORIGIN_APP, "reason", CUSTOM_PKG_UID); mZenModeHelper.setAutomaticZenRuleState( - ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); AutomaticZenRule updateWithDiff = new AutomaticZenRule.Builder(rule).setTriggerDescription("Whenever").build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, updateWithDiff, UPDATE_ORIGIN_USER, "reason", - CUSTOM_PKG_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, updateWithDiff, ORIGIN_USER_IN_SYSTEMUI, + "reason", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isEqualTo( @@ -5097,18 +5087,18 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setConfigurationActivity(new ComponentName(mPkg, "cls")) .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, UPDATE_ORIGIN_APP, "reason", + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, rule, ORIGIN_APP, "reason", CUSTOM_PKG_UID); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_IMPORTANT_INTERRUPTIONS); mZenModeHelper.updateAutomaticZenRule(ruleId, - new AutomaticZenRule.Builder(rule).setEnabled(false).build(), UPDATE_ORIGIN_USER, - "disable", CUSTOM_PKG_UID); + new AutomaticZenRule.Builder(rule).setEnabled(false).build(), + ORIGIN_USER_IN_SYSTEMUI, "disable", SYSTEM_UID); mZenModeHelper.updateAutomaticZenRule(ruleId, - new AutomaticZenRule.Builder(rule).setEnabled(true).build(), UPDATE_ORIGIN_USER, - "enable", CUSTOM_PKG_UID); + new AutomaticZenRule.Builder(rule).setEnabled(true).build(), + ORIGIN_USER_IN_SYSTEMUI, "enable", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).condition).isNull(); @@ -5123,13 +5113,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(new ComponentName("android", "some.old.cps")) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule("android", original, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reason", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "reason", SYSTEM_UID); AutomaticZenRule update = new AutomaticZenRule.Builder("Rule", Uri.EMPTY) .setOwner(new ComponentName("android", "brand.new.cps")) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, update, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, update, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); AutomaticZenRule result = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(result).isNotNull(); @@ -5143,13 +5133,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(new ComponentName(mContext.getPackageName(), "old.third.party.cps")) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), original, - UPDATE_ORIGIN_APP, "reason", CUSTOM_PKG_UID); + ORIGIN_APP, "reason", CUSTOM_PKG_UID); AutomaticZenRule update = new AutomaticZenRule.Builder("Rule", Uri.EMPTY) .setOwner(new ComponentName(mContext.getPackageName(), "new.third.party.cps")) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, update, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, update, ORIGIN_USER_IN_SYSTEMUI, "reason", + SYSTEM_UID); AutomaticZenRule result = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(result).isNotNull(); @@ -5166,24 +5156,24 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setShouldSuppressAmbientDisplay(true) .setShouldDimWallpaper(true) .build()); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); - verify(mDeviceEffectsApplier).apply(any(), eq(UPDATE_ORIGIN_APP)); + verify(mDeviceEffectsApplier).apply(any(), eq(ORIGIN_APP)); // Now delete the (currently active!) rule. For example, assume this is done from settings. - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_USER, "remove", - Process.SYSTEM_UID); + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_USER_IN_SYSTEMUI, "remove", + SYSTEM_UID); mTestableLooper.processAllMessages(); - verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_USER)); + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_USER_IN_SYSTEMUI)); } @Test @EnableFlags(FLAG_MODES_API) public void testDeviceEffects_applied() { mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); - verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT)); + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT)); ZenDeviceEffects effects = new ZenDeviceEffects.Builder() .setShouldSuppressAmbientDisplay(true) @@ -5192,11 +5182,11 @@ public class ZenModeHelperTest extends UiServiceTestCase { String ruleId = addRuleWithEffects(effects); verifyNoMoreInteractions(mDeviceEffectsApplier); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); - verify(mDeviceEffectsApplier).apply(eq(effects), eq(UPDATE_ORIGIN_APP)); + verify(mDeviceEffectsApplier).apply(eq(effects), eq(ORIGIN_APP)); } @Test @@ -5206,30 +5196,30 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build(); String ruleId = addRuleWithEffects(zde); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); - verify(mDeviceEffectsApplier).apply(eq(zde), eq(UPDATE_ORIGIN_APP)); + verify(mDeviceEffectsApplier).apply(eq(zde), eq(ORIGIN_APP)); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_FALSE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_FALSE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); - verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_APP)); + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_APP)); } @Test @EnableFlags(FLAG_MODES_API) public void testDeviceEffects_changeToConsolidatedEffects_applied() { mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); - verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT)); + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT)); String ruleId = addRuleWithEffects( new ZenDeviceEffects.Builder() .setShouldDisplayGrayscale(true) .addExtraEffect("ONE") .build()); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); verify(mDeviceEffectsApplier).apply( @@ -5237,7 +5227,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setShouldDisplayGrayscale(true) .addExtraEffect("ONE") .build()), - eq(UPDATE_ORIGIN_APP)); + eq(ORIGIN_APP)); // Now create and activate a second rule that adds more effects. String secondRuleId = addRuleWithEffects( @@ -5245,7 +5235,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setShouldDimWallpaper(true) .addExtraEffect("TWO") .build()); - mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); @@ -5255,28 +5245,28 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setShouldDimWallpaper(true) .setExtraEffects(ImmutableSet.of("ONE", "TWO")) .build()), - eq(UPDATE_ORIGIN_APP)); + eq(ORIGIN_APP)); } @Test @EnableFlags(FLAG_MODES_API) public void testDeviceEffects_noChangeToConsolidatedEffects_notApplied() { mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); - verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT)); + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT)); ZenDeviceEffects zde = new ZenDeviceEffects.Builder() .setShouldUseNightMode(true) .addExtraEffect("extra_effect") .build(); String ruleId = addRuleWithEffects(zde); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); - verify(mDeviceEffectsApplier).apply(eq(zde), eq(UPDATE_ORIGIN_APP)); + verify(mDeviceEffectsApplier).apply(eq(zde), eq(ORIGIN_APP)); // Now create and activate a second rule that doesn't add any more effects. String secondRuleId = addRuleWithEffects(zde); - mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); @@ -5290,20 +5280,20 @@ public class ZenModeHelperTest extends UiServiceTestCase { String ruleId = addRuleWithEffects(zde); verify(mDeviceEffectsApplier, never()).apply(any(), anyInt()); - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); mTestableLooper.processAllMessages(); verify(mDeviceEffectsApplier, never()).apply(any(), anyInt()); mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); - verify(mDeviceEffectsApplier).apply(eq(zde), eq(UPDATE_ORIGIN_INIT)); + verify(mDeviceEffectsApplier).apply(eq(zde), eq(ORIGIN_INIT)); } @Test @EnableFlags(FLAG_MODES_API) public void testDeviceEffects_onUserSwitch_appliedImmediately() { mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier); - verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT)); + verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(ORIGIN_INIT)); // Initialize default configurations (default rules) for both users. mZenModeHelper.onUserSwitched(1); @@ -5324,7 +5314,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mTestableLooper.processAllMessages(); verify(mDeviceEffectsApplier).apply(eq(user1Rule.zenDeviceEffects), - eq(UPDATE_ORIGIN_INIT_USER)); + eq(ORIGIN_INIT_USER)); } private String addRuleWithEffects(ZenDeviceEffects effects) { @@ -5332,7 +5322,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setDeviceEffects(effects) .build(); return mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "reasons", SYSTEM_UID); } @Test @@ -5346,7 +5336,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build()) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + ORIGIN_APP, "add it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRule(ruleId).getCreationTime()).isEqualTo(1000); // User customizes it. @@ -5354,12 +5344,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build()) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, UPDATE_ORIGIN_USER, "userUpdate", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, ORIGIN_USER_IN_SYSTEMUI, + "userUpdate", SYSTEM_UID); // App deletes it. mTestClock.advanceByMillis(1000); - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_APP, "delete it", + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_APP, "delete it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1); @@ -5367,7 +5357,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // App adds it again. mTestClock.advanceByMillis(1000); String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it again", CUSTOM_PKG_UID); + ORIGIN_APP, "add it again", CUSTOM_PKG_UID); // Verify that the rule was restored: // - id and creation time is the same as the original one. @@ -5401,12 +5391,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build()) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + ORIGIN_APP, "add it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRule(ruleId).getCreationTime()).isEqualTo(1000); // App deletes it. mTestClock.advanceByMillis(1000); - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_APP, "delete it", + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_APP, "delete it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0); @@ -5414,7 +5404,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // App adds it again. mTestClock.advanceByMillis(1000); String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it again", CUSTOM_PKG_UID); + ORIGIN_APP, "add it again", CUSTOM_PKG_UID); // Verify that the rule was recreated. This means id and creation time are new. AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(newRuleId); @@ -5433,7 +5423,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build()) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + ORIGIN_APP, "add it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRule(ruleId).getCreationTime()).isEqualTo(1000); // User customizes it. @@ -5442,12 +5432,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build()) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, UPDATE_ORIGIN_USER, "userUpdate", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, ORIGIN_USER_IN_SYSTEMUI, + "userUpdate", SYSTEM_UID); // App deletes it. mTestClock.advanceByMillis(1000); - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_APP, "delete it", + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_APP, "delete it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1); @@ -5455,7 +5445,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // User creates it again (unusual case, but ok). mTestClock.advanceByMillis(1000); String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_USER, "add it anew", CUSTOM_PKG_UID); + ORIGIN_USER_IN_SYSTEMUI, "add it anew", SYSTEM_UID); // Verify that the rule was recreated. This means id and creation time are new, and the rule // matches the latest data supplied to addAZR. @@ -5481,7 +5471,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(false).build()) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + ORIGIN_APP, "add it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRule(ruleId).getCreationTime()).isEqualTo(1000); // User customizes it. @@ -5490,20 +5480,20 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .setZenPolicy(new ZenPolicy.Builder().allowRepeatCallers(true).build()) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, UPDATE_ORIGIN_USER, "userUpdate", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, ORIGIN_USER_IN_SYSTEMUI, + "userUpdate", SYSTEM_UID); // User deletes it. mTestClock.advanceByMillis(1000); - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_USER, "delete it", - CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_USER_IN_SYSTEMUI, "delete it", + SYSTEM_UID); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(0); // App creates it again. mTestClock.advanceByMillis(1000); String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it again", CUSTOM_PKG_UID); + ORIGIN_APP, "add it again", CUSTOM_PKG_UID); // Verify that the rule was recreated. This means id and creation time are new. AutomaticZenRule finalRule = mZenModeHelper.getAutomaticZenRule(newRuleId); @@ -5520,29 +5510,34 @@ public class ZenModeHelperTest extends UiServiceTestCase { // Start with a bunch of customized rules where conditionUris are not unique. String id1 = mZenModeHelper.addAutomaticZenRule("pkg1", - new AutomaticZenRule.Builder("Test1", Uri.parse("uri1")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test1", Uri.parse("uri1")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); String id2 = mZenModeHelper.addAutomaticZenRule("pkg1", - new AutomaticZenRule.Builder("Test2", Uri.parse("uri2")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test2", Uri.parse("uri2")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); String id3 = mZenModeHelper.addAutomaticZenRule("pkg1", - new AutomaticZenRule.Builder("Test3", Uri.parse("uri2")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test3", Uri.parse("uri2")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); String id4 = mZenModeHelper.addAutomaticZenRule("pkg2", - new AutomaticZenRule.Builder("Test4", Uri.parse("uri1")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test4", Uri.parse("uri1")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); String id5 = mZenModeHelper.addAutomaticZenRule("pkg2", - new AutomaticZenRule.Builder("Test5", Uri.parse("uri1")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test5", Uri.parse("uri1")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); for (ZenRule zenRule : mZenModeHelper.mConfig.automaticRules.values()) { zenRule.userModifiedFields = AutomaticZenRule.FIELD_INTERRUPTION_FILTER; } - mZenModeHelper.removeAutomaticZenRule(id1, UPDATE_ORIGIN_APP, "begone", CUSTOM_PKG_UID); - mZenModeHelper.removeAutomaticZenRule(id2, UPDATE_ORIGIN_APP, "begone", CUSTOM_PKG_UID); - mZenModeHelper.removeAutomaticZenRule(id3, UPDATE_ORIGIN_APP, "begone", CUSTOM_PKG_UID); - mZenModeHelper.removeAutomaticZenRule(id4, UPDATE_ORIGIN_APP, "begone", CUSTOM_PKG_UID); - mZenModeHelper.removeAutomaticZenRule(id5, UPDATE_ORIGIN_APP, "begone", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id1, ORIGIN_APP, "begone", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id2, ORIGIN_APP, "begone", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id3, ORIGIN_APP, "begone", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id4, ORIGIN_APP, "begone", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id5, ORIGIN_APP, "begone", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.deletedRules.keySet()) .containsExactly("pkg1|uri1", "pkg1|uri2", "pkg2|uri1"); @@ -5557,17 +5552,19 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.mConfig.automaticRules.clear(); mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - new AutomaticZenRule.Builder("Test1", Uri.parse("uri1")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test1", Uri.parse("uri1")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), - new AutomaticZenRule.Builder("Test2", Uri.parse("uri2")).build(), UPDATE_ORIGIN_APP, + new AutomaticZenRule.Builder("Test2", Uri.parse("uri2")).build(), + ORIGIN_APP, "add it", CUSTOM_PKG_UID); for (ZenRule zenRule : mZenModeHelper.mConfig.automaticRules.values()) { zenRule.userModifiedFields = AutomaticZenRule.FIELD_INTERRUPTION_FILTER; } - mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), UPDATE_ORIGIN_APP, + mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), ORIGIN_APP, "begone", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(2); @@ -5586,7 +5583,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.mConfig.deletedRules.put(ZenModeConfig.deletedRuleKey(pkg2Rule), pkg2Rule); mZenModeHelper.removeAutomaticZenRules("pkg1", - UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "goodbye pkg1", Process.SYSTEM_UID); + ZenModeConfig.ORIGIN_SYSTEM, "goodbye pkg1", SYSTEM_UID); // Preserved rules from pkg1 are gone; those from pkg2 are still there. assertThat(mZenModeHelper.mConfig.deletedRules.values().stream().map(r -> r.pkg) @@ -5603,23 +5600,23 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + ORIGIN_APP, "add it", CUSTOM_PKG_UID); // User customizes it. AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule) .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, UPDATE_ORIGIN_USER, "userUpdate", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, ORIGIN_USER_IN_SYSTEMUI, + "userUpdate", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF); // App activates it. - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); // App deletes it. - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_APP, "delete it", + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_APP, "delete it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1); @@ -5627,7 +5624,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // App adds it again. String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it again", CUSTOM_PKG_UID); + ORIGIN_APP, "add it again", CUSTOM_PKG_UID); // The rule is restored... assertThat(newRuleId).isEqualTo(ruleId); @@ -5652,35 +5649,35 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setInterruptionFilter(INTERRUPTION_FILTER_PRIORITY) .build(); String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it", CUSTOM_PKG_UID); + ORIGIN_APP, "add it", CUSTOM_PKG_UID); // User customizes it. AutomaticZenRule userUpdate = new AutomaticZenRule.Builder(rule) .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, UPDATE_ORIGIN_USER, "userUpdate", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdate, ORIGIN_USER_IN_SYSTEMUI, + "userUpdate", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF); // App activates it. - mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); // User snoozes it. - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, - "snoozing", "systemui", Process.SYSTEM_UID); + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ZenModeConfig.ORIGIN_SYSTEM, + "snoozing", "systemui", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_OFF); // App deletes it. - mZenModeHelper.removeAutomaticZenRule(ruleId, UPDATE_ORIGIN_APP, "delete it", + mZenModeHelper.removeAutomaticZenRule(ruleId, ORIGIN_APP, "delete it", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(0); assertThat(mZenModeHelper.mConfig.deletedRules).hasSize(1); // App adds it again. String newRuleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), rule, - UPDATE_ORIGIN_APP, "add it again", CUSTOM_PKG_UID); + ORIGIN_APP, "add it again", CUSTOM_PKG_UID); // The rule is restored... assertThat(newRuleId).isEqualTo(ruleId); @@ -5762,20 +5759,20 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setConfigurationActivity( new ComponentName(mContext.getPackageName(), "Blah")) .build(), - UPDATE_ORIGIN_APP, "reasons", CUSTOM_PKG_UID); + ORIGIN_APP, "reasons", CUSTOM_PKG_UID); // Null condition -> STATE_FALSE assertThat(mZenModeHelper.getAutomaticZenRuleState(id)).isEqualTo(Condition.STATE_FALSE); - mZenModeHelper.setAutomaticZenRuleState(id, CONDITION_TRUE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(id, CONDITION_TRUE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRuleState(id)).isEqualTo(Condition.STATE_TRUE); - mZenModeHelper.setAutomaticZenRuleState(id, CONDITION_FALSE, UPDATE_ORIGIN_APP, + mZenModeHelper.setAutomaticZenRuleState(id, CONDITION_FALSE, ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRuleState(id)).isEqualTo(Condition.STATE_FALSE); - mZenModeHelper.removeAutomaticZenRule(id, UPDATE_ORIGIN_APP, "", CUSTOM_PKG_UID); + mZenModeHelper.removeAutomaticZenRule(id, ORIGIN_APP, "", CUSTOM_PKG_UID); assertThat(mZenModeHelper.getAutomaticZenRuleState(id)).isEqualTo(Condition.STATE_UNKNOWN); } @@ -5788,7 +5785,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { systemRule.condition = new Condition(systemRule.conditionId, "on", Condition.STATE_TRUE); ZenModeConfig config = mZenModeHelper.mConfig.copy(); config.automaticRules.put("systemRule", systemRule); - mZenModeHelper.setConfig(config, null, UPDATE_ORIGIN_INIT, "", Process.SYSTEM_UID); + mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); assertThat(mZenModeHelper.getAutomaticZenRuleState("systemRule")).isEqualTo( @@ -5805,13 +5802,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { otherRule.condition = new Condition(otherRule.conditionId, "on", Condition.STATE_TRUE); ZenModeConfig config = mZenModeHelper.mConfig.copy(); config.automaticRules.put("otherRule", otherRule); - mZenModeHelper.setConfig(config, null, UPDATE_ORIGIN_INIT, "", Process.SYSTEM_UID); + mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); // Should be ignored. mZenModeHelper.setAutomaticZenRuleState("otherRule", new Condition(otherRule.conditionId, "off", Condition.STATE_FALSE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); } @@ -5826,13 +5823,13 @@ public class ZenModeHelperTest extends UiServiceTestCase { otherRule.condition = new Condition(otherRule.conditionId, "on", Condition.STATE_TRUE); ZenModeConfig config = mZenModeHelper.mConfig.copy(); config.automaticRules.put("otherRule", otherRule); - mZenModeHelper.setConfig(config, null, UPDATE_ORIGIN_INIT, "", Process.SYSTEM_UID); + mZenModeHelper.setConfig(config, null, ORIGIN_INIT, "", SYSTEM_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); // Should be ignored. mZenModeHelper.setAutomaticZenRuleState(otherRule.conditionId, new Condition(otherRule.conditionId, "off", Condition.STATE_FALSE), - UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + ORIGIN_APP, CUSTOM_PKG_UID); assertThat(mZenModeHelper.getZenMode()).isEqualTo(ZEN_MODE_ALARMS); } @@ -5851,7 +5848,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { }); Policy totalSilencePolicy = new Policy(0, 0, 0); - mZenModeHelper.setNotificationPolicy(totalSilencePolicy, UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + mZenModeHelper.setNotificationPolicy(totalSilencePolicy, ORIGIN_APP, CUSTOM_PKG_UID); Policy callbackPolicy = futurePolicy.get(1, TimeUnit.SECONDS); assertThat(callbackPolicy.allowReminders()).isFalse(); @@ -5874,9 +5871,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(OWNER) .setInterruptionFilter(INTERRUPTION_FILTER_NONE) .build(), - UPDATE_ORIGIN_APP, "reasons", 0); + ORIGIN_APP, "reasons", 0); mZenModeHelper.setAutomaticZenRuleState(totalSilenceRuleId, - new Condition(CONDITION_ID, "", STATE_TRUE), UPDATE_ORIGIN_APP, CUSTOM_PKG_UID); + new Condition(CONDITION_ID, "", STATE_TRUE), ORIGIN_APP, CUSTOM_PKG_UID); Policy callbackPolicy = futureConsolidatedPolicy.get(1, TimeUnit.SECONDS); assertThat(callbackPolicy.allowMedia()).isFalse(); @@ -5905,7 +5902,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, ZEN_MODE_IMPORTANT_INTERRUPTIONS); - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "test", "test", 0); + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ORIGIN_APP, "test", "test", 0); assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1); mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, @@ -5937,8 +5934,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setInterruptionFilter(INTERRUPTION_FILTER_ALARMS) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, ORIGIN_USER_IN_SYSTEMUI, + "reason", SYSTEM_UID); // From app, call "setInterruptionFilter" again. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, @@ -5969,8 +5966,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setName("Renamed") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, ORIGIN_USER_IN_SYSTEMUI, + "reason", SYSTEM_UID); // From app, call "setInterruptionFilter" again. mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(pkg, CUSTOM_PKG_UID, @@ -6020,7 +6017,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1); assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).snoozing).isFalse(); - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "test", "test", 0); + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, ORIGIN_APP, "test", "test", 0); assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).snoozing).isTrue(); mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID, @@ -6121,8 +6118,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setZenPolicy(userUpdateZenPolicy) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, ORIGIN_USER_IN_SYSTEMUI, + "reason", SYSTEM_UID); // From app, call "setNotificationPolicy" again. Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0); @@ -6159,8 +6156,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { AutomaticZenRule userUpdateRule = new AutomaticZenRule.Builder(rule) .setName("Rule renamed, not touching policy") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, UPDATE_ORIGIN_USER, "reason", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, userUpdateRule, ORIGIN_USER_IN_SYSTEMUI, + "reason", SYSTEM_UID); // From app, call "setNotificationPolicy" again. Policy appUpdatePolicy = new Policy(PRIORITY_CATEGORY_SYSTEM, 0, 0); @@ -6215,7 +6212,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { // If the policy then changes afterwards, it should inherit updates because user cannot // edit the policy in the UI. mZenModeHelper.setNotificationPolicy(new Policy(PRIORITY_CATEGORY_ALARMS, 0, 0), - UPDATE_ORIGIN_APP, 1); + ORIGIN_APP, 1); Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule( CUSTOM_PKG_NAME); @@ -6228,7 +6225,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { @EnableFlags(FLAG_MODES_API) public void getNotificationPolicyFromImplicitZenRule_noImplicitRule_returnsGlobalPolicy() { Policy policy = new Policy(PRIORITY_CATEGORY_CALLS, PRIORITY_SENDERS_STARRED, 0); - mZenModeHelper.setNotificationPolicy(policy, UPDATE_ORIGIN_USER, 1); + mZenModeHelper.setNotificationPolicy(policy, ORIGIN_APP, CUSTOM_PKG_UID); Policy readPolicy = mZenModeHelper.getNotificationPolicyFromImplicitZenRule( CUSTOM_PKG_NAME); @@ -6264,7 +6261,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZEN_MODE_IMPORTANT_INTERRUPTIONS, previousManualZenPolicy); Policy newManualPolicy = new Policy(PRIORITY_CATEGORY_EVENTS, 0, 0); - mZenModeHelper.setNotificationPolicy(newManualPolicy, UPDATE_ORIGIN_USER, 0); + mZenModeHelper.setNotificationPolicy(newManualPolicy, ORIGIN_APP, CUSTOM_PKG_UID); ZenPolicy newManualZenPolicy = ZenAdapters.notificationPolicyToZenPolicy(newManualPolicy); // Only app rules with default or same-as-manual policies were updated. @@ -6294,7 +6291,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { String ruleId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), new AutomaticZenRule.Builder("Rule", CONDITION_ID).setIconResId(resourceId).build(), - UPDATE_ORIGIN_APP, "reason", CUSTOM_PKG_UID); + ORIGIN_APP, "reason", CUSTOM_PKG_UID); AutomaticZenRule storedRule = mZenModeHelper.getAutomaticZenRule(ruleId); assertThat(storedRule.getIconResId()).isEqualTo(0); @@ -6306,7 +6303,8 @@ public class ZenModeHelperTest extends UiServiceTestCase { ZenDeviceEffects effects = new ZenDeviceEffects.Builder() .setShouldDimWallpaper(true) .build(); - mZenModeHelper.setManualZenRuleDeviceEffects(effects, UPDATE_ORIGIN_USER, "settings", 1000); + mZenModeHelper.setManualZenRuleDeviceEffects(effects, ORIGIN_USER_IN_SYSTEMUI, "settings", + SYSTEM_UID); assertThat(mZenModeHelper.getConfig().manualRule).isNotNull(); assertThat(mZenModeHelper.getConfig().isManualActive()).isFalse(); @@ -6316,13 +6314,14 @@ public class ZenModeHelperTest extends UiServiceTestCase { @Test @EnableFlags({FLAG_MODES_API, FLAG_MODES_UI}) public void setManualZenRuleDeviceEffects_preexistingMode() { - mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, Uri.EMPTY, UPDATE_ORIGIN_USER, - "create manual rule", "settings", 1000); + mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, Uri.EMPTY, ORIGIN_USER_IN_SYSTEMUI, + "create manual rule", "settings", SYSTEM_UID); ZenDeviceEffects effects = new ZenDeviceEffects.Builder() .setShouldDimWallpaper(true) .build(); - mZenModeHelper.setManualZenRuleDeviceEffects(effects, UPDATE_ORIGIN_USER, "settings", 1000); + mZenModeHelper.setManualZenRuleDeviceEffects(effects, ORIGIN_USER_IN_SYSTEMUI, "settings", + SYSTEM_UID); assertThat(mZenModeHelper.getConfig().manualRule).isNotNull(); assertThat(mZenModeHelper.getConfig().isManualActive()).isFalse(); @@ -6337,11 +6336,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setEnabled(false) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsDisabled, UPDATE_ORIGIN_APP, + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsDisabled, + ORIGIN_APP, "new", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_APP); + ORIGIN_APP); } @Test @@ -6351,19 +6351,20 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(new ComponentName(mPkg, "SomeProvider")) .setEnabled(true) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, UPDATE_ORIGIN_APP, + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, + ORIGIN_APP, "new", CUSTOM_PKG_UID); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_UNKNOWN); + ORIGIN_UNKNOWN); AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled) .setEnabled(false) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, UPDATE_ORIGIN_USER, "off", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, ORIGIN_USER_IN_SYSTEMUI, "off", + SYSTEM_UID); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_USER); + ORIGIN_USER_IN_SYSTEMUI); } @Test @@ -6373,26 +6374,27 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(new ComponentName(mPkg, "SomeProvider")) .setEnabled(true) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, UPDATE_ORIGIN_APP, + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, + ORIGIN_APP, "new", CUSTOM_PKG_UID); AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled) .setEnabled(false) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, UPDATE_ORIGIN_USER, "off", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, ORIGIN_USER_IN_SYSTEMUI, "off", + SYSTEM_UID); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_USER); + ORIGIN_USER_IN_SYSTEMUI); // Now update it again, for an unrelated reason with a different origin. AutomaticZenRule nowRenamed = new AutomaticZenRule.Builder(nowDisabled) .setName("Fancy pants rule") .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, nowRenamed, UPDATE_ORIGIN_APP, "update", + mZenModeHelper.updateAutomaticZenRule(ruleId, nowRenamed, ORIGIN_APP, "update", CUSTOM_PKG_UID); // Identity of the disabler is preserved. assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_USER); + ORIGIN_USER_IN_SYSTEMUI); } @Test @@ -6402,26 +6404,27 @@ public class ZenModeHelperTest extends UiServiceTestCase { .setOwner(new ComponentName(mPkg, "SomeProvider")) .setEnabled(true) .build(); - String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, UPDATE_ORIGIN_APP, + String ruleId = mZenModeHelper.addAutomaticZenRule(mPkg, startsEnabled, + ORIGIN_APP, "new", CUSTOM_PKG_UID); AutomaticZenRule nowDisabled = new AutomaticZenRule.Builder(startsEnabled) .setEnabled(false) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, UPDATE_ORIGIN_USER, "off", - Process.SYSTEM_UID); + mZenModeHelper.updateAutomaticZenRule(ruleId, nowDisabled, ORIGIN_USER_IN_SYSTEMUI, "off", + SYSTEM_UID); assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_USER); + ORIGIN_USER_IN_SYSTEMUI); // Now enable it again AutomaticZenRule nowEnabled = new AutomaticZenRule.Builder(nowDisabled) .setEnabled(true) .build(); - mZenModeHelper.updateAutomaticZenRule(ruleId, nowEnabled, UPDATE_ORIGIN_APP, "on", + mZenModeHelper.updateAutomaticZenRule(ruleId, nowEnabled, ORIGIN_APP, "on", CUSTOM_PKG_UID); // Identity of the disabler was cleared. assertThat(mZenModeHelper.mConfig.automaticRules.get(ruleId).disabledOrigin).isEqualTo( - UPDATE_ORIGIN_UNKNOWN); + ORIGIN_UNKNOWN); } private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode, @@ -6494,7 +6497,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { SUPPRESSED_EFFECT_BADGE, 0, CONVERSATION_SENDERS_IMPORTANT); - mZenModeHelper.setNotificationPolicy(customPolicy, UPDATE_ORIGIN_UNKNOWN, 1); + mZenModeHelper.setNotificationPolicy(customPolicy, ORIGIN_UNKNOWN, 1); if (!Flags.modesUi()) { mZenModeHelper.mConfig.manualRule = null; } diff --git a/services/tests/vibrator/Android.bp b/services/tests/vibrator/Android.bp index 757bcd8e2193..43ad44f057cc 100644 --- a/services/tests/vibrator/Android.bp +++ b/services/tests/vibrator/Android.bp @@ -32,6 +32,7 @@ android_test { "frameworks-base-testutils", "frameworks-services-vibrator-testutils", "junit", + "junit-params", "mockito-target-inline-minus-junit4", "platform-test-annotations", "service-permission.stubs.system_server", diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java index 2b23b1897f59..e0d05df1de80 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackCustomizationTest.java @@ -16,16 +16,17 @@ package com.android.server.vibrator; - import static android.os.VibrationEffect.Composition.PRIMITIVE_TICK; import static android.os.VibrationEffect.EFFECT_CLICK; +import static com.android.internal.R.xml.haptic_feedback_customization; import static com.android.server.vibrator.HapticFeedbackCustomization.CustomizationParserException; import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertThrows; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.when; import android.content.res.Resources; @@ -39,10 +40,15 @@ import android.util.SparseArray; import androidx.test.InstrumentationRegistry; import com.android.internal.R; +import com.android.internal.annotations.Keep; + +import junitparams.JUnitParamsRunner; +import junitparams.Parameters; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; @@ -50,6 +56,7 @@ import org.mockito.junit.MockitoRule; import java.io.File; import java.io.FileOutputStream; +@RunWith(JUnitParamsRunner.class) public class HapticFeedbackCustomizationTest { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -78,21 +85,35 @@ public class HapticFeedbackCustomizationTest { @Mock private Resources mResourcesMock; @Mock private VibratorInfo mVibratorInfoMock; + @Keep + private static Object[][] hapticFeedbackCustomizationTestArguments() { + // (boolean hasConfigFile, boolean hasRes). + return new Object[][] {{true, true}, {true, false}, {false, true}}; + } + @Before public void setUp() { when(mVibratorInfoMock.areVibrationFeaturesSupported(any())).thenReturn(true); mSetFlagsRule.enableFlags(Flags.FLAG_HAPTIC_FEEDBACK_VIBRATION_OEM_CUSTOMIZATION_ENABLED); + mSetFlagsRule.disableFlags( + Flags.FLAG_LOAD_HAPTIC_FEEDBACK_VIBRATION_CUSTOMIZATION_FROM_RESOURCES); } @Test - public void testParseCustomizations_noCustomization_success() throws Exception { - assertParseCustomizationsSucceeds( - /* xml= */ "<haptic-feedback-constants></haptic-feedback-constants>", - /* expectedCustomizations= */ new SparseArray<>()); + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_noCustomization_success( + boolean hasConfigFile, boolean hasRes) throws Exception { + String xml = "<haptic-feedback-constants></haptic-feedback-constants>"; + SparseArray<VibrationEffect> expectedMapping = new SparseArray<>(); + setupParseCustomizations(xml, hasConfigFile, hasRes); + + assertParseCustomizationsSucceeds(xml, expectedMapping, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_featureFlagDisabled_returnsNull() throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_featureFlagDisabled_returnsNull( + boolean hasConfigFile, boolean hasRes) throws Exception { mSetFlagsRule.disableFlags(Flags.FLAG_HAPTIC_FEEDBACK_VIBRATION_OEM_CUSTOMIZATION_ENABLED); // Valid customization XML. String xml = "<haptic-feedback-constants>" @@ -100,14 +121,16 @@ public class HapticFeedbackCustomizationTest { + COMPOSITION_VIBRATION_XML + "</constant>" + "</haptic-feedback-constants>"; - setupCustomizationFile(xml); + setupParseCustomizations(xml, hasConfigFile, hasRes); assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock)) .isNull(); } @Test - public void testParseCustomizations_oneVibrationCustomization_success() throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_oneVibrationCustomization_success( + boolean hasConfigFile, boolean hasRes) throws Exception { String xml = "<haptic-feedback-constants>" + "<constant id=\"10\">" + COMPOSITION_VIBRATION_XML @@ -116,11 +139,13 @@ public class HapticFeedbackCustomizationTest { SparseArray<VibrationEffect> expectedMapping = new SparseArray<>(); expectedMapping.put(10, COMPOSITION_VIBRATION); - assertParseCustomizationsSucceeds(xml, expectedMapping); + assertParseCustomizationsSucceeds(xml, expectedMapping, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_oneVibrationSelectCustomization_success() throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_oneVibrationSelectCustomization_success( + boolean hasConfigFile, boolean hasRes) throws Exception { String xml = "<haptic-feedback-constants>" + "<constant id=\"10\">" + "<vibration-select>" @@ -131,11 +156,13 @@ public class HapticFeedbackCustomizationTest { SparseArray<VibrationEffect> expectedMapping = new SparseArray<>(); expectedMapping.put(10, COMPOSITION_VIBRATION); - assertParseCustomizationsSucceeds(xml, expectedMapping); + assertParseCustomizationsSucceeds(xml, expectedMapping, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_multipleCustomizations_success() throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_multipleCustomizations_success( + boolean hasConfigFile, boolean hasRes) throws Exception { String xml = "<haptic-feedback-constants>" + "<constant id=\"1\">" + COMPOSITION_VIBRATION_XML @@ -162,11 +189,13 @@ public class HapticFeedbackCustomizationTest { expectedMapping.put(150, PREDEFINED_VIBRATION); expectedMapping.put(10, WAVEFORM_VIBARTION); - assertParseCustomizationsSucceeds(xml, expectedMapping); + assertParseCustomizationsSucceeds(xml, expectedMapping, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_multipleCustomizations_noSupportedVibration_success() + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_multipleCustomizations_noSupportedVibration_success( + boolean hasConfigFile, boolean hasRes) throws Exception { makeUnsupported(COMPOSITION_VIBRATION, PREDEFINED_VIBRATION, WAVEFORM_VIBARTION); String xml = "<haptic-feedback-constants>" @@ -189,13 +218,16 @@ public class HapticFeedbackCustomizationTest { + "</vibration-select>" + "</constant>" + "</haptic-feedback-constants>"; + SparseArray<VibrationEffect> expectedMapping = new SparseArray<>(); - assertParseCustomizationsSucceeds(xml, new SparseArray<>()); + assertParseCustomizationsSucceeds(xml, expectedMapping, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_multipleCustomizations_someUnsupportedVibration_success() - throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_multipleCustomizations_someUnsupportedVibration_success( + boolean hasConfigFile, boolean hasRes) + throws Exception { makeSupported(PREDEFINED_VIBRATION, WAVEFORM_VIBARTION); makeUnsupported(COMPOSITION_VIBRATION); String xml = "<haptic-feedback-constants>" @@ -230,7 +262,7 @@ public class HapticFeedbackCustomizationTest { expectedMapping.put(150, PREDEFINED_VIBRATION); expectedMapping.put(10, PREDEFINED_VIBRATION); - assertParseCustomizationsSucceeds(xml, expectedMapping); + assertParseCustomizationsSucceeds(xml, expectedMapping, hasConfigFile, hasRes); } @Test @@ -252,12 +284,23 @@ public class HapticFeedbackCustomizationTest { } @Test - public void testParseCustomizations_disallowedVibrationForHapticFeedback_throwsException() - throws Exception { + public void testParseCustomizations_noCustomizationResource_returnsNull() throws Exception { + mSetFlagsRule.enableFlags( + Flags.FLAG_LOAD_HAPTIC_FEEDBACK_VIBRATION_CUSTOMIZATION_FROM_RESOURCES); + doThrow(new Resources.NotFoundException()) + .when(mResourcesMock).getXml(haptic_feedback_customization); + + assertThat(HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock)) + .isNull(); + } + + @Test + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_disallowedVibrationForHapticFeedback_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { // The XML content is good, but the serialized vibration is not supported for haptic // feedback usage (i.e. repeating vibration). - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + String xml = "<haptic-feedback-constants>" + "<constant id=\"10\">" + "<vibration-effect>" + "<waveform-effect>" @@ -267,127 +310,139 @@ public class HapticFeedbackCustomizationTest { + "</waveform-effect>" + "</vibration-effect>" + "</constant>" - + "</haptic-feedback-constants>"); + + "</haptic-feedback-constants>"; + + assertParseCustomizationsFails(xml, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_emptyXml_throwsException() throws Exception { - assertParseCustomizationsFails(""); + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_emptyXml_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { + assertParseCustomizationsFails("", hasConfigFile, hasRes); } @Test - public void testParseCustomizations_noVibrationXml_throwsException() throws Exception { - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_noVibrationXml_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { + String xml = "<haptic-feedback-constants>" + "<constant id=\"1\">" + "</constant>" - + "</haptic-feedback-constants>"); + + "</haptic-feedback-constants>"; + + assertParseCustomizationsFails(xml, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_badEffectId_throwsException() throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_badEffectId_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { // Negative id - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + String xmlNegativeId = "<haptic-feedback-constants>" + "<constant id=\"-10\">" + COMPOSITION_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); - + + "</haptic-feedback-constants>"; // Non-numeral id - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + String xmlNonNumericalId = "<haptic-feedback-constants>" + "<constant id=\"xyz\">" + COMPOSITION_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); + + "</haptic-feedback-constants>"; + + assertParseCustomizationsFails(xmlNegativeId, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlNonNumericalId, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_malformedXml_throwsException() throws Exception { + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_malformedXml_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { // No start "<constant>" tag - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + String xmlNoStartConstantTag = "<haptic-feedback-constants>" + COMPOSITION_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); - + + "</haptic-feedback-constants>"; // No end "<constant>" tag - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + String xmlNoEndConstantTag = "<haptic-feedback-constants>" + "<constant id=\"10\">" + COMPOSITION_VIBRATION_XML - + "</haptic-feedback-constants>"); - + + "</haptic-feedback-constants>"; // No start "<haptic-feedback-constants>" tag - assertParseCustomizationsFails( - "<constant id=\"10\">" + String xmlNoStartCustomizationTag = "<constant id=\"10\">" + COMPOSITION_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); - + + "</haptic-feedback-constants>"; // No end "<haptic-feedback-constants>" tag - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + String xmlNoEndCustomizationTag = "<haptic-feedback-constants>" + "<constant id=\"10\">" + COMPOSITION_VIBRATION_XML - + "</constant>"); + + "</constant>"; + + assertParseCustomizationsFails(xmlNoStartConstantTag, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlNoEndConstantTag, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlNoStartCustomizationTag, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlNoEndCustomizationTag, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_badVibrationXml_throwsException() throws Exception { - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_badVibrationXml_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { + String xmlBad1 = "<haptic-feedback-constants>" + "<constant id=\"10\">" + "<bad-vibration-effect></bad-vibration-effect>" + "</constant>" - + "</haptic-feedback-constants>"); - - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + + "</haptic-feedback-constants>"; + String xmlBad2 = "<haptic-feedback-constants>" + "<constant id=\"10\">" + "<vibration-effect><predefined-effect name=\"bad-effect\"/></vibration-effect>" + "</constant>" - + "</haptic-feedback-constants>"); - - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + + "</haptic-feedback-constants>"; + String xmlBad3 = "<haptic-feedback-constants>" + "<constant id=\"10\">" + "<vibration-select>" + "<vibration-effect><predefined-effect name=\"bad-effect\"/></vibration-effect>" + "</constant>" - + "</haptic-feedback-constants>"); - - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + + "</haptic-feedback-constants>"; + String xmlBad4 = "<haptic-feedback-constants>" + "<constant id=\"10\">" + "<vibration-effect><predefined-effect name=\"bad-effect\"/></vibration-effect>" + "</vibration-select>" + "</constant>" - + "</haptic-feedback-constants>"); + + "</haptic-feedback-constants>"; + + assertParseCustomizationsFails(xmlBad1, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlBad2, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlBad3, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlBad4, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_badConstantAttribute_throwsException() throws Exception { - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_badConstantAttribute_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { + String xmlBadConstantAttribute1 = "<haptic-feedback-constants>" + "<constant iddddd=\"10\">" + COMPOSITION_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); - - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + + "</haptic-feedback-constants>"; + String xmlBadConstantAttribute2 = "<haptic-feedback-constants>" + "<constant id=\"10\" unwanted-attr=\"1\">" + COMPOSITION_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); + + "</haptic-feedback-constants>"; + + assertParseCustomizationsFails(xmlBadConstantAttribute1, hasConfigFile, hasRes); + assertParseCustomizationsFails(xmlBadConstantAttribute2, hasConfigFile, hasRes); } @Test - public void testParseCustomizations_duplicateEffects_throwsException() throws Exception { - assertParseCustomizationsFails( - "<haptic-feedback-constants>" + @Parameters(method = "hapticFeedbackCustomizationTestArguments") + public void testParseCustomizations_duplicateEffects_throwsException( + boolean hasConfigFile, boolean hasRes) throws Exception { + String xmlDuplicateEffect = "<haptic-feedback-constants>" + "<constant id=\"10\">" + COMPOSITION_VIBRATION_XML + "</constant>" @@ -397,30 +452,44 @@ public class HapticFeedbackCustomizationTest { + "<constant id=\"11\">" + PREDEFINED_VIBRATION_XML + "</constant>" - + "</haptic-feedback-constants>"); + + "</haptic-feedback-constants>"; + + assertParseCustomizationsFails(xmlDuplicateEffect, hasConfigFile, hasRes); } - private void assertParseCustomizationsSucceeds( - String xml, SparseArray<VibrationEffect> expectedCustomizations) throws Exception { - setupCustomizationFile(xml); + private void assertParseCustomizationsSucceeds(String xml, + SparseArray<VibrationEffect> expectedCustomizations, boolean hasConfigFile, + boolean hasRes) throws Exception { + setupParseCustomizations(xml, hasConfigFile, hasRes); assertThat(expectedCustomizations.contentEquals( HapticFeedbackCustomization.loadVibrations(mResourcesMock, mVibratorInfoMock))) - .isTrue(); + .isTrue(); } - private void assertParseCustomizationsFails(String xml) throws Exception { - setupCustomizationFile(xml); - assertThrows("Expected haptic feedback customization to fail for " + xml, + private void assertParseCustomizationsFails(String xml, boolean hasConfigFile, boolean hasRes) + throws Exception { + setupParseCustomizations(xml, hasConfigFile, hasRes); + assertThrows("Expected haptic feedback customization to fail", CustomizationParserException.class, () -> HapticFeedbackCustomization.loadVibrations( mResourcesMock, mVibratorInfoMock)); } - private void assertParseCustomizationsFails() throws Exception { - assertThrows("Expected haptic feedback customization to fail", - CustomizationParserException.class, - () -> HapticFeedbackCustomization.loadVibrations( - mResourcesMock, mVibratorInfoMock)); + private void setupParseCustomizations(String xml, boolean hasConfigFile, boolean hasRes) + throws Exception { + clearFileAndResourceSetup(); + if (hasConfigFile) { + setupCustomizationFile(xml); + } + if (hasRes) { + setupCustomizationResource(xml); + } + } + + private void clearFileAndResourceSetup() { + when(mResourcesMock.getString(R.string.config_hapticFeedbackCustomizationFile)) + .thenReturn(null); + when(mResourcesMock.getXml(haptic_feedback_customization)).thenReturn(null); } private void setupCustomizationFile(String xml) throws Exception { @@ -433,6 +502,13 @@ public class HapticFeedbackCustomizationTest { .thenReturn(path); } + private void setupCustomizationResource(String xml) throws Exception { + mSetFlagsRule.enableFlags( + Flags.FLAG_LOAD_HAPTIC_FEEDBACK_VIBRATION_CUSTOMIZATION_FROM_RESOURCES); + when(mResourcesMock.getXml(haptic_feedback_customization)) + .thenReturn(FakeXmlResourceParser.fromXml(xml)); + } + private void makeSupported(VibrationEffect... effects) { for (VibrationEffect effect : effects) { when(mVibratorInfoMock.areVibrationFeaturesSupported(effect)).thenReturn(true); diff --git a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java index 4f7593184d83..240bd1ec56e3 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/HapticFeedbackVibrationProviderTest.java @@ -50,7 +50,6 @@ import android.hardware.vibrator.IVibrator; import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.VibratorInfo; -import android.os.vibrator.Flags; import android.platform.test.flag.junit.SetFlagsRule; import android.util.AtomicFile; import android.util.SparseArray; @@ -256,22 +255,7 @@ public class HapticFeedbackVibrationProviderTest { } @Test - public void testKeyboardHaptic_fixAmplitude_keyboardCategoryOff_defaultVibrationReturned() { - mSetFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); - mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK); - mockKeyboardVibrationFixedAmplitude(KEYBOARD_VIBRATION_FIXED_AMPLITUDE); - - HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); - - assertThat(hapticProvider.getVibrationForHapticFeedback(KEYBOARD_TAP)) - .isEqualTo(VibrationEffect.get(EFFECT_CLICK, true /* fallback */)); - assertThat(hapticProvider.getVibrationForHapticFeedback(KEYBOARD_RELEASE)) - .isEqualTo(VibrationEffect.get(EFFECT_TICK, false /* fallback */)); - } - - @Test public void testKeyboardHaptic_fixAmplitude_keyboardCategoryOn_keyboardVibrationReturned() { - mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); mockVibratorPrimitiveSupport(PRIMITIVE_CLICK, PRIMITIVE_TICK); mockKeyboardVibrationFixedAmplitude(KEYBOARD_VIBRATION_FIXED_AMPLITUDE); @@ -346,24 +330,7 @@ public class HapticFeedbackVibrationProviderTest { } @Test - public void testVibrationAttribute_keyboardCategoryOff_isIme_useTouchUsage() { - mSetFlagsRule.disableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); - HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); - - for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { - VibrationAttributes attrs = hapticProvider.getVibrationAttributesForHapticFeedback( - effectId, /* flags */ 0, - HapticFeedbackConstants.PRIVATE_FLAG_APPLY_INPUT_METHOD_SETTINGS); - assertWithMessage("Expected USAGE_TOUCH for effect " + effectId) - .that(attrs.getUsage()).isEqualTo(USAGE_TOUCH); - assertWithMessage("Expected no CATEGORY_KEYBOARD for effect " + effectId) - .that(attrs.getCategory()).isEqualTo(CATEGORY_UNKNOWN); - } - } - - @Test public void testVibrationAttribute_keyboardCategoryOn_notIme_useTouchUsage() { - mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { @@ -378,7 +345,6 @@ public class HapticFeedbackVibrationProviderTest { @Test public void testVibrationAttribute_keyboardCategoryOn_isIme_useImeFeedbackUsage() { - mSetFlagsRule.enableFlags(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED); HapticFeedbackVibrationProvider hapticProvider = createProviderWithDefaultCustomizations(); for (int effectId : KEYBOARD_FEEDBACK_CONSTANTS) { diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java index 8d4a6aa5ba29..72ef888aa061 100644 --- a/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java +++ b/services/tests/vibrator/src/com/android/server/vibrator/VibrationSettingsTest.java @@ -70,9 +70,7 @@ import android.os.VibrationAttributes; import android.os.VibrationEffect; import android.os.Vibrator; import android.os.test.TestLooper; -import android.os.vibrator.Flags; import android.os.vibrator.VibrationConfig; -import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.provider.Settings; @@ -602,7 +600,6 @@ public class VibrationSettingsTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED) public void shouldIgnoreVibration_withKeyboardSettingsOff_shouldIgnoreKeyboardVibration() { setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_MEDIUM); setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 0 /* OFF*/); @@ -627,7 +624,6 @@ public class VibrationSettingsTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED) public void shouldIgnoreVibration_withKeyboardSettingsOn_shouldNotIgnoreKeyboardVibration() { setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF); setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 1 /* ON */); @@ -645,7 +641,6 @@ public class VibrationSettingsTest { } @Test - @RequiresFlagsEnabled(Flags.FLAG_KEYBOARD_CATEGORY_ENABLED) public void shouldIgnoreVibration_notSupportKeyboardVibration_ignoresKeyboardTouchVibration() { setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY, VIBRATION_INTENSITY_OFF); setUserSetting(Settings.System.KEYBOARD_VIBRATION_ENABLED, 1 /* ON */); diff --git a/services/tests/vibrator/utils/com/android/server/vibrator/FakeXmlResourceParser.java b/services/tests/vibrator/utils/com/android/server/vibrator/FakeXmlResourceParser.java new file mode 100644 index 000000000000..ab7d43c66765 --- /dev/null +++ b/services/tests/vibrator/utils/com/android/server/vibrator/FakeXmlResourceParser.java @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.vibrator; + +import android.content.res.XmlResourceParser; +import android.util.Xml; + +import com.android.modules.utils.TypedXmlPullParser; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; + +/** + * Wrapper to use TypedXmlPullParser as XmlResourceParser for Resources.getXml(). This is borrowed + * from {@code ZenModeHelperTest}. + */ +public final class FakeXmlResourceParser implements XmlResourceParser { + private final TypedXmlPullParser mParser; + + public FakeXmlResourceParser(TypedXmlPullParser parser) { + this.mParser = parser; + } + + /** Create a {@link FakeXmlResourceParser} given a xml {@link String}. */ + public static XmlResourceParser fromXml(String xml) throws XmlPullParserException { + TypedXmlPullParser parser = Xml.newFastPullParser(); + parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())), null); + return new FakeXmlResourceParser(parser); + } + + @Override + public int getEventType() throws XmlPullParserException { + return mParser.getEventType(); + } + + @Override + public void setFeature(String name, boolean state) throws XmlPullParserException { + mParser.setFeature(name, state); + } + + @Override + public boolean getFeature(String name) { + return false; + } + + @Override + public void setProperty(String name, Object value) throws XmlPullParserException { + mParser.setProperty(name, value); + } + + @Override + public Object getProperty(String name) { + return mParser.getProperty(name); + } + + @Override + public void setInput(Reader in) throws XmlPullParserException { + mParser.setInput(in); + } + + @Override + public void setInput(InputStream inputStream, String inputEncoding) + throws XmlPullParserException { + mParser.setInput(inputStream, inputEncoding); + } + + @Override + public String getInputEncoding() { + return mParser.getInputEncoding(); + } + + @Override + public void defineEntityReplacementText(String entityName, String replacementText) + throws XmlPullParserException { + mParser.defineEntityReplacementText(entityName, replacementText); + } + + @Override + public int getNamespaceCount(int depth) throws XmlPullParserException { + return mParser.getNamespaceCount(depth); + } + + @Override + public String getNamespacePrefix(int pos) throws XmlPullParserException { + return mParser.getNamespacePrefix(pos); + } + + @Override + public String getNamespaceUri(int pos) throws XmlPullParserException { + return mParser.getNamespaceUri(pos); + } + + @Override + public String getNamespace(String prefix) { + return mParser.getNamespace(prefix); + } + + @Override + public int getDepth() { + return mParser.getDepth(); + } + + @Override + public String getPositionDescription() { + return mParser.getPositionDescription(); + } + + @Override + public int getLineNumber() { + return mParser.getLineNumber(); + } + + @Override + public int getColumnNumber() { + return mParser.getColumnNumber(); + } + + @Override + public boolean isWhitespace() throws XmlPullParserException { + return mParser.isWhitespace(); + } + + @Override + public String getText() { + return mParser.getText(); + } + + @Override + public char[] getTextCharacters(int[] holderForStartAndLength) { + return mParser.getTextCharacters(holderForStartAndLength); + } + + @Override + public String getNamespace() { + return mParser.getNamespace(); + } + + @Override + public String getName() { + return mParser.getName(); + } + + @Override + public String getPrefix() { + return mParser.getPrefix(); + } + + @Override + public boolean isEmptyElementTag() throws XmlPullParserException { + return false; + } + + @Override + public int getAttributeCount() { + return mParser.getAttributeCount(); + } + + @Override + public int next() throws IOException, XmlPullParserException { + return mParser.next(); + } + + @Override + public int nextToken() throws XmlPullParserException, IOException { + return mParser.next(); + } + + @Override + public void require(int type, String namespace, String name) + throws XmlPullParserException, IOException { + mParser.require(type, namespace, name); + } + + @Override + public String nextText() throws XmlPullParserException, IOException { + return mParser.nextText(); + } + + @Override + public String getAttributeNamespace(int index) { + return ""; + } + + @Override + public String getAttributeName(int index) { + return mParser.getAttributeName(index); + } + + @Override + public String getAttributePrefix(int index) { + return mParser.getAttributePrefix(index); + } + + @Override + public String getAttributeType(int index) { + return mParser.getAttributeType(index); + } + + @Override + public boolean isAttributeDefault(int index) { + return mParser.isAttributeDefault(index); + } + + @Override + public String getAttributeValue(int index) { + return mParser.getAttributeValue(index); + } + + @Override + public String getAttributeValue(String namespace, String name) { + return mParser.getAttributeValue(namespace, name); + } + + @Override + public int getAttributeNameResource(int index) { + return 0; + } + + @Override + public int getAttributeListValue(String namespace, String attribute, String[] options, + int defaultValue) { + return 0; + } + + @Override + public boolean getAttributeBooleanValue(String namespace, String attribute, + boolean defaultValue) { + return false; + } + + @Override + public int getAttributeResourceValue(String namespace, String attribute, int defaultValue) { + return 0; + } + + @Override + public int getAttributeIntValue(String namespace, String attribute, int defaultValue) { + return 0; + } + + @Override + public int getAttributeUnsignedIntValue(String namespace, String attribute, + int defaultValue) { + return 0; + } + + @Override + public float getAttributeFloatValue(String namespace, String attribute, + float defaultValue) { + return 0; + } + + @Override + public int getAttributeListValue(int index, String[] options, int defaultValue) { + return 0; + } + + @Override + public boolean getAttributeBooleanValue(int index, boolean defaultValue) { + return false; + } + + @Override + public int getAttributeResourceValue(int index, int defaultValue) { + return 0; + } + + @Override + public int getAttributeIntValue(int index, int defaultValue) { + return 0; + } + + @Override + public int getAttributeUnsignedIntValue(int index, int defaultValue) { + return 0; + } + + @Override + public float getAttributeFloatValue(int index, float defaultValue) { + return 0; + } + + @Override + public String getIdAttribute() { + return null; + } + + @Override + public String getClassAttribute() { + return null; + } + + @Override + public int getIdAttributeResourceValue(int defaultValue) { + return 0; + } + + @Override + public int getStyleAttribute() { + return 0; + } + + @Override + public void close() { + } + + @Override + public int nextTag() throws IOException, XmlPullParserException { + return mParser.nextTag(); + } +} diff --git a/telephony/java/android/service/euicc/EuiccService.java b/telephony/java/android/service/euicc/EuiccService.java index 55245419c570..a01a72003570 100644 --- a/telephony/java/android/service/euicc/EuiccService.java +++ b/telephony/java/android/service/euicc/EuiccService.java @@ -267,6 +267,17 @@ public abstract class EuiccService extends Service { "android.service.euicc.extra.RESOLUTION_CONFIRMATION_CODE_RETRIED"; /** + * Bundle key for the {@code resolvedBundle} passed to {@link #onDownloadSubscription( + * int, int, DownloadableSubscription, boolean, boolean, Bundle)}. The value is a + * {@link String} for the package name of the app calling the + * {@link EuiccManager#downloadSubscription(int, DownloadableSubscription, PendingIntent)} API. + * This is to be used by LPA to determine the app that is requesting the download. + * + * @hide + */ + public static final String EXTRA_PACKAGE_NAME = "android.service.euicc.extra.PACKAGE_NAME"; + + /** * Intent extra set for resolution requests containing an int indicating the current card Id. */ public static final String EXTRA_RESOLUTION_CARD_ID = |