diff options
102 files changed, 1093 insertions, 613 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt index ef8ae7095d65..a87f2e2bdaee 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -6134,6 +6134,11 @@ package android.media { field public static final int ROLE_OUTPUT = 2; // 0x2 } + public class AudioDeviceVolumeManager { + ctor public AudioDeviceVolumeManager(@NonNull android.content.Context); + method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes); + } + public final class AudioFocusInfo implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.media.AudioAttributes getAttributes(); @@ -6453,6 +6458,33 @@ package android.media { method public void onSpatializerOutputChanged(@NonNull android.media.Spatializer, @IntRange(from=0) int); } + public final class VolumeInfo implements android.os.Parcelable { + method public int describeContents(); + method @NonNull public static android.media.VolumeInfo getDefaultVolumeInfo(); + method public int getMaxVolumeIndex(); + method public int getMinVolumeIndex(); + method public int getStreamType(); + method @Nullable public android.media.audiopolicy.AudioVolumeGroup getVolumeGroup(); + method public int getVolumeIndex(); + method public boolean hasStreamType(); + method public boolean hasVolumeGroup(); + method public boolean isMuted(); + method public void writeToParcel(@NonNull android.os.Parcel, int); + field @NonNull public static final android.os.Parcelable.Creator<android.media.VolumeInfo> CREATOR; + field public static final int INDEX_NOT_SET = -100; // 0xffffff9c + } + + public static final class VolumeInfo.Builder { + ctor public VolumeInfo.Builder(int); + ctor public VolumeInfo.Builder(@NonNull android.media.audiopolicy.AudioVolumeGroup); + ctor public VolumeInfo.Builder(@NonNull android.media.VolumeInfo); + method @NonNull public android.media.VolumeInfo build(); + method @NonNull public android.media.VolumeInfo.Builder setMaxVolumeIndex(int); + method @NonNull public android.media.VolumeInfo.Builder setMinVolumeIndex(int); + method @NonNull public android.media.VolumeInfo.Builder setMuted(boolean); + method @NonNull public android.media.VolumeInfo.Builder setVolumeIndex(int); + } + } package android.media.audiofx { diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index ceaf337b2122..aefa5f827f4a 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -182,7 +182,7 @@ public class Handler { * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to - * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. + * the synchronization barriers introduced by {@link MessageQueue#postSyncBarrier()}. * * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for * each {@link Message} that is sent to it or {@link Runnable} that is posted to it. @@ -203,7 +203,7 @@ public class Handler { * * Asynchronous messages represent interrupts or events that do not require global ordering * with respect to synchronous messages. Asynchronous messages are not subject to - * the synchronization barriers introduced by {@link MessageQueue#enqueueSyncBarrier(long)}. + * the synchronization barriers introduced by {@link MessageQueue#postSyncBarrier()}. * * @param callback The callback interface in which to handle messages, or null. * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for @@ -212,25 +212,17 @@ public class Handler { * @hide */ public Handler(@Nullable Callback callback, boolean async) { - if (FIND_POTENTIAL_LEAKS) { - final Class<? extends Handler> klass = getClass(); - if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) && - (klass.getModifiers() & Modifier.STATIC) == 0) { - Log.w(TAG, "The following Handler class should be static or leaks might occur: " + - klass.getCanonicalName()); - } - } + this(getThreadLooper(), callback, async); + } - mLooper = Looper.myLooper(); - if (mLooper == null) { + private static Looper getThreadLooper() { + final Looper looper = Looper.myLooper(); + if (looper == null) { throw new RuntimeException( - "Can't create handler inside thread " + Thread.currentThread() - + " that has not called Looper.prepare()"); + "Can't create handler inside thread " + Thread.currentThread() + + " that has not called Looper.prepare()"); } - mQueue = mLooper.mQueue; - mCallback = callback; - mAsynchronous = async; - mIsShared = false; + return looper; } /** @@ -257,14 +249,44 @@ public class Handler { this(looper, callback, async, /* shared= */ false); } - /** @hide */ + /** + * Use the provided {@link Looper} instead of the default one and take a callback + * interface in which to handle messages. Also set whether the handler + * should be asynchronous. + * + * Handlers are synchronous by default unless this constructor is used to make + * one that is strictly asynchronous. + * + * Asynchronous messages represent interrupts or events that do not require global ordering + * with respect to synchronous messages. Asynchronous messages are not subject to + * the synchronization barriers introduced by conditions such as display vsync. + * + * @param looper The looper, must not be null. + * @param callback The callback interface in which to handle messages, or null. + * @param async If true, the handler calls {@link Message#setAsynchronous(boolean)} for + * each {@link Message} that is sent to it or {@link Runnable} that is posted to + * it. + * @param shared Whether this Handler might be used by more than one client. A shared Handler + * applies some extra policy, such as disallowing the removal of all messages, + * in order to avoid one client affecting another's messages. + * @hide + */ public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async, boolean shared) { + if (FIND_POTENTIAL_LEAKS) { + final Class<? extends Handler> klass = getClass(); + if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) + && (klass.getModifiers() & Modifier.STATIC) == 0) { + Log.w(TAG, "The following Handler class should be static or leaks might occur: " + + klass.getCanonicalName()); + } + } mLooper = looper; mQueue = looper.mQueue; mCallback = callback; mAsynchronous = async; mIsShared = shared; + mClock = looper.getClock(); } /** @@ -702,7 +724,14 @@ public class Handler { if (delayMillis < 0) { delayMillis = 0; } - return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis); + // mClock should theoretically never be null, but some tests create a mock handler that + // instantiates an instance where all members are null. Ideally we'd fix these tests to + // not rely on this but there are quite a lot at this point, so it's easier to just keep + // the existing behavior. + if (mClock == null) { + return false; + } + return sendMessageAtTime(msg, mClock.uptimeMillis() + delayMillis); } /** @@ -895,7 +924,7 @@ public class Handler { } public final void dump(@NonNull Printer pw, @NonNull String prefix) { - pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); + pw.println(prefix + this + " @ " + mClock.uptimeMillis()); if (mLooper == null) { pw.println(prefix + "looper uninitialized"); } else { @@ -907,7 +936,7 @@ public class Handler { * @hide */ public final void dumpMine(@NonNull Printer pw, @NonNull String prefix) { - pw.println(prefix + this + " @ " + SystemClock.uptimeMillis()); + pw.println(prefix + this + " @ " + mClock.uptimeMillis()); if (mLooper == null) { pw.println(prefix + "looper uninitialized"); } else { @@ -964,6 +993,7 @@ public class Handler { @UnsupportedAppUsage final Callback mCallback; final boolean mAsynchronous; + final MessageQueue.Clock mClock; @UnsupportedAppUsage IMessenger mMessenger; @@ -997,9 +1027,9 @@ public class Handler { synchronized (this) { if (timeout > 0) { - final long expirationTime = SystemClock.uptimeMillis() + timeout; + final long expirationTime = handler.mClock.uptimeMillis() + timeout; while (!mDone) { - long delay = expirationTime - SystemClock.uptimeMillis(); + long delay = expirationTime - handler.mClock.uptimeMillis(); if (delay <= 0) { return false; // timeout } diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index a529ac6569bd..f0fda15f6e90 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -24,6 +24,8 @@ import android.util.Printer; import android.util.Slog; import android.util.proto.ProtoOutputStream; +import java.util.Objects; + /** * Class used to run a message loop for a thread. Threads by default do * not have a message loop associated with them; to create one, call @@ -69,7 +71,7 @@ public final class Looper { // sThreadLocal.get() will return null unless you've called prepare(). @UnsupportedAppUsage - static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); + static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<>(); @UnsupportedAppUsage private static Looper sMainLooper; // guarded by Looper.class private static Observer sObserver; @@ -77,6 +79,7 @@ public final class Looper { @UnsupportedAppUsage final MessageQueue mQueue; final Thread mThread; + final MessageQueue.Clock mClock; private boolean mInLoop; @UnsupportedAppUsage @@ -191,7 +194,7 @@ public final class Looper { Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); } - final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0; + final long dispatchStart = needStartTime ? me.mClock.uptimeMillis() : 0; final long dispatchEnd; Object token = null; if (observer != null) { @@ -203,7 +206,7 @@ public final class Looper { if (observer != null) { observer.messageDispatched(token, msg); } - dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; + dispatchEnd = needEndTime ? me.mClock.uptimeMillis() : 0; } catch (Exception exception) { if (observer != null) { observer.dispatchingThrewException(token, msg, exception); @@ -325,8 +328,13 @@ public final class Looper { } private Looper(boolean quitAllowed) { - mQueue = new MessageQueue(quitAllowed); + this(quitAllowed, SystemClock::uptimeMillis); + } + + private Looper(boolean quitAllowed, @NonNull MessageQueue.Clock clock) { + mQueue = new MessageQueue(quitAllowed, Objects.requireNonNull(clock)); mThread = Thread.currentThread(); + mClock = clock; } /** @@ -419,6 +427,16 @@ public final class Looper { } /** + * Gets the looper's clock. + * + * @return The looper's clock + * @hide + */ + public @NonNull MessageQueue.Clock getClock() { + return mClock; + } + + /** * Dumps the state of the looper for debugging purposes. * * @param pw A printer to receive the contents of the dump. diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java index 87c4f331e93f..a8ed5ba99489 100644 --- a/core/java/android/os/MessageQueue.java +++ b/core/java/android/os/MessageQueue.java @@ -19,6 +19,7 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; +import android.annotation.UptimeMillisLong; import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; @@ -29,6 +30,7 @@ import java.io.FileDescriptor; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; +import java.util.Objects; /** * Low-level class holding the list of messages to be dispatched by a @@ -54,6 +56,7 @@ public final class MessageQueue { Message mMessages; @UnsupportedAppUsage private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>(); + private final Clock mClock; private SparseArray<FileDescriptorRecord> mFileDescriptorRecords; private IdleHandler[] mPendingIdleHandlers; private boolean mQuitting; @@ -74,9 +77,10 @@ public final class MessageQueue { private native static boolean nativeIsPolling(long ptr); private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); - MessageQueue(boolean quitAllowed) { + MessageQueue(boolean quitAllowed, @NonNull Clock clock) { mQuitAllowed = quitAllowed; mPtr = nativeInit(); + mClock = Objects.requireNonNull(clock); } @Override @@ -106,7 +110,7 @@ public final class MessageQueue { */ public boolean isIdle() { synchronized (this) { - final long now = SystemClock.uptimeMillis(); + final long now = mClock.uptimeMillis(); return mMessages == null || now < mMessages.when; } } @@ -336,7 +340,7 @@ public final class MessageQueue { synchronized (this) { // Try to retrieve the next message. Return if found. - final long now = SystemClock.uptimeMillis(); + final long now = mClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; if (msg != null && msg.target == null) { @@ -470,7 +474,7 @@ public final class MessageQueue { @UnsupportedAppUsage @TestApi public int postSyncBarrier() { - return postSyncBarrier(SystemClock.uptimeMillis()); + return postSyncBarrier(mClock.uptimeMillis()); } private int postSyncBarrier(long when) { @@ -772,41 +776,6 @@ public final class MessageQueue { } } - void removeEqualMessages(Handler h, Runnable r, Object object) { - if (h == null || r == null) { - return; - } - - synchronized (this) { - Message p = mMessages; - - // Remove all messages at front. - while (p != null && p.target == h && p.callback == r - && (object == null || object.equals(p.obj))) { - Message n = p.next; - mMessages = n; - p.recycleUnchecked(); - p = n; - } - - // Remove all messages after front. - while (p != null) { - Message n = p.next; - if (n != null) { - if (n.target == h && n.callback == r - && (object == null || object.equals(n.obj))) { - Message nn = n.next; - n.recycleUnchecked(); - p.next = nn; - continue; - } - } - p = n; - } - } - } - - void removeCallbacksAndMessages(Handler h, Object object) { if (h == null) { return; @@ -884,7 +853,7 @@ public final class MessageQueue { } private void removeAllFutureMessagesLocked() { - final long now = SystemClock.uptimeMillis(); + final long now = mClock.uptimeMillis(); Message p = mMessages; if (p != null) { if (p.when > now) { @@ -913,7 +882,7 @@ public final class MessageQueue { void dump(Printer pw, String prefix, Handler h) { synchronized (this) { - long now = SystemClock.uptimeMillis(); + long now = mClock.uptimeMillis(); int n = 0; for (Message msg = mMessages; msg != null; msg = msg.next) { if (h == null || h == msg.target) { @@ -942,7 +911,7 @@ public final class MessageQueue { * Callback interface for discovering when a thread is going to block * waiting for more messages. */ - public static interface IdleHandler { + public interface IdleHandler { /** * Called when the message queue has run out of messages and will now * wait for more. Return true to keep your idle handler active, false @@ -1041,4 +1010,17 @@ public final class MessageQueue { mListener = listener; } } + + /** + * Time supplier for MessageQueue and the things that interact with it (e.g. {@link Looper}). + * + * Intentionally replaceable for testing. + * + * @hide + */ + public interface Clock { + /** @see SystemClock#uptimeMillis */ + @UptimeMillisLong + long uptimeMillis(); + } } diff --git a/core/java/com/android/internal/widget/LocalImageResolver.java b/core/java/com/android/internal/widget/LocalImageResolver.java index b11ea2961c17..9ef7ce38fc09 100644 --- a/core/java/com/android/internal/widget/LocalImageResolver.java +++ b/core/java/com/android/internal/widget/LocalImageResolver.java @@ -19,6 +19,8 @@ package com.android.internal.widget; import android.annotation.DrawableRes; import android.annotation.Nullable; import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.ImageDecoder; @@ -109,13 +111,13 @@ public class LocalImageResolver { } break; case Icon.TYPE_RESOURCE: - if (!(TextUtils.isEmpty(icon.getResPackage()) - || context.getPackageName().equals(icon.getResPackage()))) { - // We can't properly resolve icons from other packages here, so fall back. + Resources res = resolveResourcesForIcon(context, icon); + if (res == null) { + // We couldn't resolve resources properly, fall back to icon loading. return icon.loadDrawable(context); } - Drawable result = resolveImage(icon.getResId(), context, maxWidth, maxHeight); + Drawable result = resolveImage(res, icon.getResId(), maxWidth, maxHeight); if (result != null) { return tintDrawable(icon, result); } @@ -159,6 +161,13 @@ public class LocalImageResolver { } @Nullable + private static Drawable resolveImage(Resources res, @DrawableRes int resId, int maxWidth, + int maxHeight) { + final ImageDecoder.Source source = ImageDecoder.createSource(res, resId); + return resolveImage(source, maxWidth, maxHeight); + } + + @Nullable private static Drawable resolveBitmapImage(Icon icon, Context context, int maxWidth, int maxHeight) { @@ -259,4 +268,52 @@ public class LocalImageResolver { } return icon.getUri(); } + + /** + * Resolves the correct resources package for a given Icon - it may come from another + * package. + * + * @see Icon#loadDrawableInner(Context) + * @hide + * + * @return resources instance if the operation succeeded, null otherwise + */ + @Nullable + @VisibleForTesting + public static Resources resolveResourcesForIcon(Context context, Icon icon) { + if (icon.getType() != Icon.TYPE_RESOURCE) { + return null; + } + + // Icons cache resolved resources, use cache if available. + Resources res = icon.getResources(); + if (res != null) { + return res; + } + + String resPackage = icon.getResPackage(); + // No package means we try to use current context. + if (TextUtils.isEmpty(resPackage) || context.getPackageName().equals(resPackage)) { + return context.getResources(); + } + + if ("android".equals(resPackage)) { + return Resources.getSystem(); + } + + final PackageManager pm = context.getPackageManager(); + try { + ApplicationInfo ai = pm.getApplicationInfo(resPackage, + PackageManager.MATCH_UNINSTALLED_PACKAGES + | PackageManager.GET_SHARED_LIBRARY_FILES); + if (ai != null) { + return pm.getResourcesForApplication(ai); + } + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, String.format("Unable to resolve package %s for icon %s", resPackage, icon)); + return null; + } + + return null; + } } diff --git a/core/jni/OWNERS b/core/jni/OWNERS index 7f50204fb842..14699e7097f4 100644 --- a/core/jni/OWNERS +++ b/core/jni/OWNERS @@ -95,3 +95,7 @@ per-file android_os_VintfRuntimeInfo* = file:platform/system/libvintf:/OWNERS # Battery per-file com_android_internal_os_Kernel* = file:/BATTERY_STATS_OWNERS per-file com_android_internal_os_*MultiStateCounter* = file:/BATTERY_STATS_OWNERS + +# PM +per-file com_android_internal_content_* = file:/PACKAGE_MANAGER_OWNERS + diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 6a52ec91fa32..e7cae76c60fc 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -1565,7 +1565,8 @@ <bool name="config_enableIdleScreenBrightnessMode">false</bool> <!-- Array of desired screen brightness in nits corresponding to the lux values - in the config_autoBrightnessLevels array. The display brightness is defined as the measured + in the config_autoBrightnessLevels array. As with config_screenBrightnessMinimumNits and + config_screenBrightnessMaximumNits, the display brightness is defined as the measured brightness of an all-white image. If this is defined then: @@ -1586,7 +1587,7 @@ <array name="config_autoBrightnessDisplayValuesNitsIdle"> </array> - <!-- Array of output values for button backlight corresponding to the lux values + <!-- Array of output values for button backlight corresponding to the luX values in the config_autoBrightnessLevels array. This array should have size one greater than the size of the config_autoBrightnessLevels array. The brightness values must be between 0 and 255 and be non-decreasing. diff --git a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java index 0cee526651a6..271a20b71106 100644 --- a/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java +++ b/core/tests/coretests/src/com/android/internal/widget/LocalImageResolverTest.java @@ -17,6 +17,8 @@ package com.android.internal.widget; import android.content.Context; +import android.content.pm.PackageManager; +import android.content.res.Resources; import android.graphics.BitmapFactory; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.BitmapDrawable; @@ -279,4 +281,49 @@ public class LocalImageResolverTest { // This drawable must not be loaded - if it was, the code ignored the package specification. assertThat(d).isNull(); } + + @Test + public void resolveResourcesForIcon_notAResourceIcon_returnsNull() { + Icon icon = Icon.createWithContentUri(Uri.parse("some_uri")); + assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isNull(); + } + + @Test + public void resolveResourcesForIcon_localPackageIcon_returnsPackageResources() { + Icon icon = Icon.createWithResource(mContext, R.drawable.test32x24); + assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)) + .isSameInstanceAs(mContext.getResources()); + } + + @Test + public void resolveResourcesForIcon_iconWithoutPackageSpecificed_returnsPackageResources() { + Icon icon = Icon.createWithResource("", R.drawable.test32x24); + assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)) + .isSameInstanceAs(mContext.getResources()); + } + + @Test + public void resolveResourcesForIcon_systemPackageSpecified_returnsSystemPackage() { + Icon icon = Icon.createWithResource("android", R.drawable.test32x24); + assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isSameInstanceAs( + Resources.getSystem()); + } + + @Test + public void resolveResourcesForIcon_differentPackageSpecified_returnsPackageResources() throws + PackageManager.NameNotFoundException { + String pkg = "com.android.settings"; + Resources res = mContext.getPackageManager().getResourcesForApplication(pkg); + int resId = res.getIdentifier("ic_android", "drawable", pkg); + Icon icon = Icon.createWithResource(pkg, resId); + + assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon).getDrawable(resId, + mContext.getTheme())).isNotNull(); + } + + @Test + public void resolveResourcesForIcon_invalidPackageSpecified_returnsNull() { + Icon icon = Icon.createWithResource("invalid.package", R.drawable.test32x24); + assertThat(LocalImageResolver.resolveResourcesForIcon(mContext, icon)).isNull(); + } } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java index 0d75bc451b72..f1465f421c5b 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java @@ -105,8 +105,8 @@ public class FullscreenTaskListener<T extends AutoCloseable> state.mTaskInfo = taskInfo; mTasks.put(taskInfo.taskId, state); - updateRecentsForVisibleFullscreenTask(taskInfo); if (Transitions.ENABLE_SHELL_TRANSITIONS) return; + updateRecentsForVisibleFullscreenTask(taskInfo); if (shouldShowWindowDecor(taskInfo) && mWindowDecorViewModelOptional.isPresent()) { SurfaceControl.Transaction t = new SurfaceControl.Transaction(); state.mWindowDecoration = @@ -135,8 +135,8 @@ public class FullscreenTaskListener<T extends AutoCloseable> mWindowDecorViewModelOptional.get().onTaskInfoChanged( state.mTaskInfo, state.mWindowDecoration); } - updateRecentsForVisibleFullscreenTask(taskInfo); if (Transitions.ENABLE_SHELL_TRANSITIONS) return; + updateRecentsForVisibleFullscreenTask(taskInfo); final Point positionInParent = state.mTaskInfo.positionInParent; if (!oldPositionInParent.equals(state.mTaskInfo.positionInParent)) { diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt index 67d7aca8db8c..298bf68c41a7 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/BaseBubbleScreen.kt @@ -86,8 +86,7 @@ abstract class BaseBubbleScreen( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } const val FIND_OBJECT_TIMEOUT = 2000L diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt index 293eb7cd5581..47557bcead2f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/bubble/LaunchBubbleFromLockScreen.kt @@ -18,7 +18,6 @@ package com.android.wm.shell.flicker.bubble import android.platform.test.annotations.FlakyTest import android.platform.test.annotations.Postsubmit -import android.platform.test.annotations.Presubmit import android.view.WindowInsets import android.view.WindowManager import androidx.test.filters.RequiresDevice @@ -92,7 +91,7 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr } } - @Presubmit + @FlakyTest(bugId = 242088970) @Test fun testAppIsVisibleAtEnd() { testSpec.assertLayersEnd { @@ -125,7 +124,7 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr super.navBarWindowIsAlwaysVisible() /** {@inheritDoc} */ - @Postsubmit + @FlakyTest(bugId = 242088970) @Test override fun taskBarLayerIsVisibleAtStartAndEnd() = super.taskBarLayerIsVisibleAtStartAndEnd() @@ -135,4 +134,28 @@ class LaunchBubbleFromLockScreen(testSpec: FlickerTestParameter) : BaseBubbleScr @Test override fun taskBarWindowIsAlwaysVisible() = super.taskBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun statusBarLayerIsVisibleAtStartAndEnd() = + super.statusBarLayerIsVisibleAtStartAndEnd() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun statusBarLayerPositionAtStartAndEnd() = + super.statusBarLayerPositionAtStartAndEnd() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun statusBarWindowIsAlwaysVisible() = + super.statusBarWindowIsAlwaysVisible() + + /** {@inheritDoc} */ + @FlakyTest(bugId = 242088970) + @Test + override fun visibleWindowsShownMoreThanOneConsecutiveEntry() = + super.visibleWindowsShownMoreThanOneConsecutiveEntry() } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt index d194472b9000..6fcd17ae5f8a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTest.kt @@ -185,8 +185,7 @@ open class EnterPipTest(testSpec: FlickerTestParameter) : PipTransition(testSpec fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt index 507562b00f4f..a99439e35291 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipToOtherOrientationTest.kt @@ -246,8 +246,7 @@ class EnterPipToOtherOrientationTest( fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt index b5a3c78b67a7..39a7017a16d0 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaExpandButtonClickTest.kt @@ -100,7 +100,7 @@ class ExitPipViaExpandButtonClickTest( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3) + supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt index 1d266140f2e6..421a6fc38e4c 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipViaIntentTest.kt @@ -125,7 +125,7 @@ class ExitPipViaIntentTest(testSpec: FlickerTestParameter) : ExitPipToAppTransit @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3) + supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt index b71a9d85d8cc..3bffef0ca793 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithDismissButtonTest.kt @@ -86,8 +86,7 @@ class ExitPipWithDismissButtonTest(testSpec: FlickerTestParameter) : ExitPipTran @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt index 31a39c190dd6..75d25e6ef67e 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExitPipWithSwipeDownTest.kt @@ -105,8 +105,7 @@ class ExitPipWithSwipeDownTest(testSpec: FlickerTestParameter) : ExitPipTransiti @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt index fd661cfc3ee1..825aca3aaa16 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/ExpandPipOnDoubleClickTest.kt @@ -178,8 +178,7 @@ class ExpandPipOnDoubleClickTest(testSpec: FlickerTestParameter) : PipTransition fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt index b3f0fb91ab73..d3e2ce1571b4 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipDownShelfHeightChangeTest.kt @@ -89,7 +89,7 @@ open class MovePipDownShelfHeightChangeTest( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt index 8bd5c548f6bd..3d64bbeb720b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/MovePipUpShelfHeightChangeTest.kt @@ -105,7 +105,7 @@ class MovePipUpShelfHeightChangeTest( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - supportedRotations = listOf(Surface.ROTATION_0), repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt index 454927e57aa2..be39faeff321 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipKeyboardTest.kt @@ -116,8 +116,7 @@ open class PipKeyboardTest(testSpec: FlickerTestParameter) : PipTransition(testS @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 3) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt index 09248a167308..4dc98588217a 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/PipRotationTest.kt @@ -264,8 +264,7 @@ open class PipRotationTest(testSpec: FlickerTestParameter) : PipTransition(testS @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigRotationTests( - supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90), - repetitions = 3 + supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90) ) } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt index 6d64cb9e0dee..d5de22fb49c0 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/SetRequestedOrientationWhilePinnedTest.kt @@ -224,8 +224,7 @@ open class SetRequestedOrientationWhilePinnedTest( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0), - repetitions = 1) + .getConfigNonRotationTests(supportedRotations = listOf(Surface.ROTATION_0)) } } } diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt index d23881475ad6..6cbb685850fa 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/CopyContentInSplit.kt @@ -178,7 +178,6 @@ class CopyContentInSplit(testSpec: FlickerTestParameter) : SplitScreenBase(testS @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt index ba40c2740bb1..581826ef889f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByDivider.kt @@ -195,7 +195,6 @@ class DismissSplitScreenByDivider (testSpec: FlickerTestParameter) : SplitScreen @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt index 6828589656d6..5c051e859d59 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DismissSplitScreenByGoHome.kt @@ -182,7 +182,6 @@ class DismissSplitScreenByGoHome( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt index 9ac7c230096b..9ca9ab01fd7b 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/DragDividerToResize.kt @@ -186,7 +186,6 @@ class DragDividerToResize (testSpec: FlickerTestParameter) : SplitScreenBase(tes @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, supportedRotations = listOf(Surface.ROTATION_0), // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt index 8401c1a910b8..8e2769fb75bd 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt @@ -180,7 +180,6 @@ class EnterSplitScreenByDragFromAllApps( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt index 168afda119a9..531d376e3588 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt @@ -195,7 +195,6 @@ class EnterSplitScreenByDragFromNotification( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt index c1fce5f40b57..ea43c7ea0ddf 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromTaskbar.kt @@ -183,7 +183,6 @@ class EnterSplitScreenByDragFromTaskbar( @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY) ) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt index 153056188d24..525e09a19d2f 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchAppByDoubleTapDivider.kt @@ -180,7 +180,6 @@ class SwitchAppByDoubleTapDivider (testSpec: FlickerTestParameter) : SplitScreen @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt index 20544bd2fc2f..c030603a6b55 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromAnotherApp.kt @@ -184,7 +184,6 @@ class SwitchBackToSplitFromAnotherApp(testSpec: FlickerTestParameter) : SplitScr @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt index 5a8604f2dccc..b8565f3e89b2 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromHome.kt @@ -183,7 +183,6 @@ class SwitchBackToSplitFromHome(testSpec: FlickerTestParameter) : SplitScreenBas @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt index adea66a49c46..20d7f2cf57e8 100644 --- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt +++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/SwitchBackToSplitFromRecent.kt @@ -185,7 +185,6 @@ class SwitchBackToSplitFromRecent(testSpec: FlickerTestParameter) : SplitScreenB @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance().getConfigNonRotationTests( - repetitions = SplitScreenHelper.TEST_REPETITIONS, // TODO(b/176061063):The 3 buttons of nav bar do not exist in the hierarchy. supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY)) diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java index c70887672f9e..40f6dc541f86 100644 --- a/media/java/android/media/AudioDeviceVolumeManager.java +++ b/media/java/android/media/AudioDeviceVolumeManager.java @@ -21,6 +21,8 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; import android.content.Context; import android.os.IBinder; import android.os.RemoteException; @@ -39,23 +41,29 @@ import java.util.concurrent.Executor; * @hide * AudioDeviceVolumeManager provides access to audio device volume control. */ +@SystemApi public class AudioDeviceVolumeManager { // define when using Log.* //private static final String TAG = "AudioDeviceVolumeManager"; - /** Indicates no special treatment in the handling of the volume adjustment */ + /** @hide + * Indicates no special treatment in the handling of the volume adjustment */ public static final int ADJUST_MODE_NORMAL = 0; - /** Indicates the start of a volume adjustment */ + /** @hide + * Indicates the start of a volume adjustment */ public static final int ADJUST_MODE_START = 1; - /** Indicates the end of a volume adjustment */ + /** @hide + * Indicates the end of a volume adjustment */ public static final int ADJUST_MODE_END = 2; + /** @hide */ @IntDef(flag = false, prefix = "ADJUST_MODE", value = { ADJUST_MODE_NORMAL, ADJUST_MODE_START, ADJUST_MODE_END} ) + /** @hide */ @Retention(RetentionPolicy.SOURCE) public @interface VolumeAdjustmentMode {} @@ -64,7 +72,16 @@ public class AudioDeviceVolumeManager { private final @NonNull String mPackageName; private final @Nullable String mAttributionTag; - public AudioDeviceVolumeManager(Context context) { + /** + * Constructor + * @param context the Context for the device volume operations + */ + @SuppressLint("ManagerConstructor") + // reason for suppression: even though the functionality handled by this class is implemented in + // AudioService, we want to avoid bloating android.media.AudioManager + // with @SystemApi functionality + public AudioDeviceVolumeManager(@NonNull Context context) { + Objects.requireNonNull(context); mPackageName = context.getApplicationContext().getOpPackageName(); mAttributionTag = context.getApplicationContext().getAttributionTag(); } @@ -101,6 +118,7 @@ public class AudioDeviceVolumeManager { @VolumeAdjustmentMode int mode); } + /** @hide */ static class ListenerInfo { final @NonNull OnAudioDeviceVolumeChangedListener mListener; final @NonNull Executor mExecutor; @@ -127,6 +145,7 @@ public class AudioDeviceVolumeManager { @GuardedBy("mDeviceVolumeListenerLock") private DeviceVolumeDispatcherStub mDeviceVolumeDispatcherStub; + /** @hide */ final class DeviceVolumeDispatcherStub extends IAudioDeviceVolumeDispatcher.Stub { /** * Register / unregister the stub @@ -305,6 +324,7 @@ public class AudioDeviceVolumeManager { * @param vi the volume information, only stream-based volumes are supported * @param ada the device for which volume is to be modified */ + @SystemApi @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setDeviceVolume(@NonNull VolumeInfo vi, @NonNull AudioDeviceAttributes ada) { try { @@ -315,6 +335,7 @@ public class AudioDeviceVolumeManager { } /** + * @hide * Return human-readable name for volume behavior * @param behavior one of the volume behaviors defined in AudioManager * @return a string for the given behavior diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 650f36059495..72190e370129 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -65,8 +65,6 @@ public class AudioSystem private static final String TAG = "AudioSystem"; - private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U - // private constructor to prevent instantiating AudioSystem private AudioSystem() { throw new UnsupportedOperationException("Trying to instantiate AudioSystem"); @@ -293,7 +291,7 @@ public class AudioSystem case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD; case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC; case AUDIO_FORMAT_LC3: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3; - case AUDIO_FORMAT_OPUS: return SOURCE_CODEC_TYPE_OPUS; // TODO update in U + case AUDIO_FORMAT_OPUS: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS; default: Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat) + " for conversion to BT codec"); @@ -336,7 +334,7 @@ public class AudioSystem return AudioSystem.AUDIO_FORMAT_LDAC; case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3: return AudioSystem.AUDIO_FORMAT_LC3; - case SOURCE_CODEC_TYPE_OPUS: // TODO update in U + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: return AudioSystem.AUDIO_FORMAT_OPUS; default: Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec) diff --git a/media/java/android/media/VolumeInfo.java b/media/java/android/media/VolumeInfo.java index c61b0e57db1a..6b4f604025e2 100644 --- a/media/java/android/media/VolumeInfo.java +++ b/media/java/android/media/VolumeInfo.java @@ -18,6 +18,7 @@ package android.media; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.content.Context; import android.media.audiopolicy.AudioVolumeGroup; import android.os.IBinder; @@ -32,16 +33,13 @@ import java.util.Objects; /** * @hide - * A class to represent type of volume information. + * A class to represent volume information. * Can be used to represent volume associated with a stream type or {@link AudioVolumeGroup}. * Volume index is optional when used to represent a category of volume. * Index ranges are supported too, making the representation of volume changes agnostic to the * range (e.g. can be used to map BT A2DP absolute volume range to internal range). - * - * Note: this class is not yet part of the SystemApi but is intended to be gradually introduced - * particularly in parts of the audio framework that suffer from code ambiguity when - * dealing with different volume ranges / units. */ +@SystemApi public final class VolumeInfo implements Parcelable { private static final String TAG = "VolumeInfo"; diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl index 31fb8d03c4a0..9bf126b7a875 100644 --- a/media/java/android/media/session/ISession.aidl +++ b/media/java/android/media/session/ISession.aidl @@ -35,7 +35,7 @@ interface ISession { ISessionController getController(); void setFlags(int flags); void setActive(boolean active); - void setMediaButtonReceiver(in PendingIntent mbr); + void setMediaButtonReceiver(in PendingIntent mbr, String sessionPackageName); void setMediaButtonBroadcastReceiver(in ComponentName broadcastReceiver); void setLaunchPendingIntent(in PendingIntent pi); void destroySession(); diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java index 1bd12afdc026..9e265d8339dd 100644 --- a/media/java/android/media/session/MediaSession.java +++ b/media/java/android/media/session/MediaSession.java @@ -286,7 +286,7 @@ public final class MediaSession { @Deprecated public void setMediaButtonReceiver(@Nullable PendingIntent mbr) { try { - mBinder.setMediaButtonReceiver(mbr); + mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName()); } catch (RemoteException e) { Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e); } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java index 19409865284c..b64dcca63ac9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/A2dpProfile.java @@ -43,8 +43,6 @@ import java.util.List; public class A2dpProfile implements LocalBluetoothProfile { private static final String TAG = "A2dpProfile"; - private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U - private Context mContext; private BluetoothA2dp mService; @@ -333,7 +331,7 @@ public class A2dpProfile implements LocalBluetoothProfile { case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3: index = 6; break; - case SOURCE_CODEC_TYPE_OPUS: // TODO update in U + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: index = 7; break; } diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 62def4875594..abcd65b5071a 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -85,7 +85,6 @@ <uses-permission android:name="android.permission.CONTROL_VPN" /> <uses-permission android:name="android.permission.PEERS_MAC_ADDRESS"/> <uses-permission android:name="android.permission.READ_WIFI_CREDENTIAL"/> - <uses-permission android:name="android.permission.NETWORK_STACK"/> <!-- Physical hardware --> <uses-permission android:name="android.permission.MANAGE_USB" /> <uses-permission android:name="android.permission.CONTROL_DISPLAY_BRIGHTNESS" /> diff --git a/packages/SystemUI/res/layout/media_ttt_chip.xml b/packages/SystemUI/res/layout/media_ttt_chip.xml index d88680669fe0..ae8e38e2634b 100644 --- a/packages/SystemUI/res/layout/media_ttt_chip.xml +++ b/packages/SystemUI/res/layout/media_ttt_chip.xml @@ -16,7 +16,7 @@ <!-- Wrap in a frame layout so that we can update the margins on the inner layout. (Since this view is the root view of a window, we cannot change the root view's margins.) --> <!-- Alphas start as 0 because the view will be animated in. --> -<FrameLayout +<com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" android:id="@+id/media_ttt_sender_chip" @@ -97,4 +97,4 @@ /> </LinearLayout> -</FrameLayout> +</com.android.systemui.media.taptotransfer.sender.MediaTttChipRootView> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index e1957c09fef5..93175e19a287 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -418,6 +418,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state); getCurrentSecurityController().onResume(reason); + updateSideFpsVisibility(); } mView.onResume( mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()), diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 7b497ade683c..c48271e0348a 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -518,9 +518,20 @@ class MediaDataManager( } val actions = createActionsFromState(it.packageName, mediaControllerFactory.create(it.token), UserHandle(it.userId)) - val data = it.copy( - semanticActions = actions, - isPlaying = isPlayingState(state.state)) + + // Control buttons + // If flag is enabled and controller has a PlaybackState, + // create actions from session info + // otherwise, no need to update semantic actions. + val data = if (actions != null) { + it.copy( + semanticActions = actions, + isPlaying = isPlayingState(state.state)) + } else { + it.copy( + isPlaying = isPlayingState(state.state) + ) + } if (DEBUG) Log.d(TAG, "State updated outside of notification") onMediaDataLoaded(key, key, data) } diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt index a153cb6c0d31..f93c671f6740 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt @@ -26,6 +26,7 @@ import com.android.internal.logging.UiEventLogger import com.android.internal.statusbar.IUndoMediaTransferCallback import com.android.systemui.R import com.android.systemui.media.taptotransfer.common.DEFAULT_TIMEOUT_MILLIS +import com.android.systemui.plugins.FalsingManager /** * A class enumerating all the possible states of the media tap-to-transfer chip on the sender @@ -106,12 +107,15 @@ enum class ChipStateSender( controllerSender: MediaTttChipControllerSender, routeInfo: MediaRoute2Info, undoCallback: IUndoMediaTransferCallback?, - uiEventLogger: MediaTttSenderUiEventLogger + uiEventLogger: MediaTttSenderUiEventLogger, + falsingManager: FalsingManager, ): View.OnClickListener? { if (undoCallback == null) { return null } return View.OnClickListener { + if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener + uiEventLogger.logUndoClicked( MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_RECEIVER_CLICKED ) @@ -141,12 +145,15 @@ enum class ChipStateSender( controllerSender: MediaTttChipControllerSender, routeInfo: MediaRoute2Info, undoCallback: IUndoMediaTransferCallback?, - uiEventLogger: MediaTttSenderUiEventLogger + uiEventLogger: MediaTttSenderUiEventLogger, + falsingManager: FalsingManager, ): View.OnClickListener? { if (undoCallback == null) { return null } return View.OnClickListener { + if (falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) return@OnClickListener + uiEventLogger.logUndoClicked( MediaTttSenderUiEvents.MEDIA_TTT_SENDER_UNDO_TRANSFER_TO_THIS_DEVICE_CLICKED ) @@ -212,7 +219,8 @@ enum class ChipStateSender( controllerSender: MediaTttChipControllerSender, routeInfo: MediaRoute2Info, undoCallback: IUndoMediaTransferCallback?, - uiEventLogger: MediaTttSenderUiEventLogger + uiEventLogger: MediaTttSenderUiEventLogger, + falsingManager: FalsingManager, ): View.OnClickListener? = null companion object { diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt index 933548963390..5ad82fd9fd8f 100644 --- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt @@ -22,21 +22,25 @@ import android.media.MediaRoute2Info import android.os.PowerManager import android.util.Log import android.view.Gravity +import android.view.MotionEvent import android.view.View import android.view.ViewGroup import android.view.WindowManager import android.view.accessibility.AccessibilityManager import android.widget.TextView import com.android.internal.statusbar.IUndoMediaTransferCallback +import com.android.systemui.Gefingerpoken import com.android.systemui.R import com.android.systemui.animation.Interpolators import com.android.systemui.animation.ViewHierarchyAnimator +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.common.ChipInfoCommon import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCommon import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttRemovalReason +import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.DelayableExecutor @@ -58,7 +62,9 @@ class MediaTttChipControllerSender @Inject constructor( accessibilityManager: AccessibilityManager, configurationController: ConfigurationController, powerManager: PowerManager, - private val uiEventLogger: MediaTttSenderUiEventLogger + private val uiEventLogger: MediaTttSenderUiEventLogger, + private val falsingManager: FalsingManager, + private val falsingCollector: FalsingCollector, ) : MediaTttChipControllerCommon<ChipSenderInfo>( context, logger, @@ -70,6 +76,9 @@ class MediaTttChipControllerSender @Inject constructor( powerManager, R.layout.media_ttt_chip, ) { + + private lateinit var parent: MediaTttChipRootView + override val windowLayoutParams = commonWindowLayoutParams.apply { gravity = Gravity.TOP.or(Gravity.CENTER_HORIZONTAL) } @@ -121,6 +130,15 @@ class MediaTttChipControllerSender @Inject constructor( val chipState = newChipInfo.state + // Detect falsing touches on the chip. + parent = currentChipView as MediaTttChipRootView + parent.touchHandler = object : Gefingerpoken { + override fun onTouchEvent(ev: MotionEvent?): Boolean { + falsingCollector.onTouchEvent(ev) + return false + } + } + // App icon val iconName = setIcon(currentChipView, newChipInfo.routeInfo.clientPackageName) @@ -136,7 +154,11 @@ class MediaTttChipControllerSender @Inject constructor( // Undo val undoView = currentChipView.requireViewById<View>(R.id.undo) val undoClickListener = chipState.undoClickListener( - this, newChipInfo.routeInfo, newChipInfo.undoCallback, uiEventLogger + this, + newChipInfo.routeInfo, + newChipInfo.undoCallback, + uiEventLogger, + falsingManager, ) undoView.setOnClickListener(undoClickListener) undoView.visibility = (undoClickListener != null).visibleIfTrue() diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt new file mode 100644 index 000000000000..3373159fba4e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipRootView.kt @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2022 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.media.taptotransfer.sender + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import android.widget.FrameLayout +import com.android.systemui.Gefingerpoken + +/** A simple subclass that allows for observing touch events on chip. */ +class MediaTttChipRootView( + context: Context, + attrs: AttributeSet? +) : FrameLayout(context, attrs) { + + /** Assign this field to observe touch events. */ + var touchHandler: Gefingerpoken? = null + + override fun dispatchTouchEvent(ev: MotionEvent): Boolean { + touchHandler?.onTouchEvent(ev) + return super.dispatchTouchEvent(ev) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java index 3f931088ec83..5da480968b89 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileRevealController.java @@ -17,7 +17,14 @@ import java.util.Set; import javax.inject.Inject; -/** */ +/** + * Plays a animation to reveal newly added QS tiles. + * + * The aniumation is played when the user fully opens Quick Settings, and is only shown for + * <li> tiles added automatically (not through user customization) + * <li> tiles not have been revealed before (memoized via {@code QS_TILE_SPECS_REVEALED} + * preference) + */ public class QSTileRevealController { private static final long QS_REVEAL_TILES_DELAY = 500L; @@ -39,6 +46,7 @@ public class QSTileRevealController { }); } }; + QSTileRevealController(Context context, QSPanelController qsPanelController, PagedTileLayout pagedTileLayout, QSCustomizerController qsCustomizerController) { mContext = context; diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt index a918e5d9e106..309059fdb9ad 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt @@ -17,6 +17,7 @@ package com.android.systemui.screenshot import android.graphics.Insets +import android.util.Log import android.view.WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE import com.android.internal.util.ScreenshotHelper.HardwareBitmapBundler import com.android.internal.util.ScreenshotHelper.ScreenshotRequest @@ -61,8 +62,9 @@ class RequestProcessor @Inject constructor( ) { val info = policy.findPrimaryContent(policy.getDefaultDisplayId()) + Log.d(TAG, "findPrimaryContent: $info") - result = if (policy.isManagedProfile(info.userId)) { + result = if (policy.isManagedProfile(info.user.identifier)) { val image = capture.captureTask(info.taskId) ?: error("Task snapshot returned a null Bitmap!") @@ -70,7 +72,7 @@ class RequestProcessor @Inject constructor( ScreenshotRequest( TAKE_SCREENSHOT_PROVIDED_IMAGE, request.source, HardwareBitmapBundler.hardwareBitmapToBundle(image), - info.bounds, Insets.NONE, info.taskId, info.userId, info.component + info.bounds, Insets.NONE, info.taskId, info.user.identifier, info.component ) } else { // Create a new request of the same type which includes the top component diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt index 3580010cc1e8..f73d2041af95 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt @@ -19,6 +19,7 @@ package com.android.systemui.screenshot import android.annotation.UserIdInt import android.content.ComponentName import android.graphics.Rect +import android.os.UserHandle import android.view.Display /** @@ -42,7 +43,7 @@ interface ScreenshotPolicy { data class DisplayContentInfo( val component: ComponentName, val bounds: Rect, - @UserIdInt val userId: Int, + val user: UserHandle, val taskId: Int, ) diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt index ba809f676f1e..c2a50609b6a5 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt @@ -29,9 +29,11 @@ import android.content.Intent import android.graphics.Rect import android.os.Process import android.os.RemoteException +import android.os.UserHandle import android.os.UserManager import android.util.Log import android.view.Display.DEFAULT_DISPLAY +import com.android.internal.annotations.VisibleForTesting import com.android.internal.infra.ServiceConnector import com.android.systemui.SystemUIService import com.android.systemui.dagger.SysUISingleton @@ -45,21 +47,13 @@ import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.withContext @SysUISingleton -internal class ScreenshotPolicyImpl @Inject constructor( +internal open class ScreenshotPolicyImpl @Inject constructor( context: Context, private val userMgr: UserManager, private val atmService: IActivityTaskManager, @Background val bgDispatcher: CoroutineDispatcher, ) : ScreenshotPolicy { - private val systemUiContent = - DisplayContentInfo( - ComponentName(context, SystemUIService::class.java), - Rect(), - ActivityTaskManager.INVALID_TASK_ID, - Process.myUserHandle().identifier, - ) - private val proxyConnector: ServiceConnector<IScreenshotProxy> = ServiceConnector.Impl( context, @@ -78,6 +72,9 @@ internal class ScreenshotPolicyImpl @Inject constructor( } private fun nonPipVisibleTask(info: RootTaskInfo): Boolean { + if (DEBUG) { + debugLogRootTaskInfo(info) + } return info.windowingMode != WindowConfiguration.WINDOWING_MODE_PINNED && info.isVisible && info.isRunning && @@ -99,58 +96,46 @@ internal class ScreenshotPolicyImpl @Inject constructor( } val taskInfoList = getAllRootTaskInfosOnDisplay(displayId) - if (DEBUG) { - debugLogRootTaskInfos(taskInfoList) - } // If no visible task is located, then report SystemUI as the foreground content val target = taskInfoList.firstOrNull(::nonPipVisibleTask) ?: return systemUiContent - - val topActivity: ComponentName = target.topActivity ?: error("should not be null") - val topChildTask = target.childTaskIds.size - 1 - val childTaskId = target.childTaskIds[topChildTask] - val childTaskUserId = target.childTaskUserIds[topChildTask] - val childTaskBounds = target.childTaskBounds[topChildTask] - - return DisplayContentInfo(topActivity, childTaskBounds, childTaskId, childTaskUserId) + return target.toDisplayContentInfo() } - private fun debugLogRootTaskInfos(taskInfoList: List<RootTaskInfo>) { - for (info in taskInfoList) { - Log.d( - TAG, - "[root task info] " + - "taskId=${info.taskId} " + - "parentTaskId=${info.parentTaskId} " + - "position=${info.position} " + - "positionInParent=${info.positionInParent} " + - "isVisible=${info.isVisible()} " + - "visible=${info.visible} " + - "isFocused=${info.isFocused} " + - "isSleeping=${info.isSleeping} " + - "isRunning=${info.isRunning} " + - "windowMode=${windowingModeToString(info.windowingMode)} " + - "activityType=${activityTypeToString(info.activityType)} " + - "topActivity=${info.topActivity} " + - "topActivityInfo=${info.topActivityInfo} " + - "numActivities=${info.numActivities} " + - "childTaskIds=${Arrays.toString(info.childTaskIds)} " + - "childUserIds=${Arrays.toString(info.childTaskUserIds)} " + - "childTaskBounds=${Arrays.toString(info.childTaskBounds)} " + - "childTaskNames=${Arrays.toString(info.childTaskNames)}" - ) - - for (j in 0 until info.childTaskIds.size) { - Log.d(TAG, " *** [$j] ******") - Log.d(TAG, " *** childTaskIds[$j]: ${info.childTaskIds[j]}") - Log.d(TAG, " *** childTaskUserIds[$j]: ${info.childTaskUserIds[j]}") - Log.d(TAG, " *** childTaskBounds[$j]: ${info.childTaskBounds[j]}") - Log.d(TAG, " *** childTaskNames[$j]: ${info.childTaskNames[j]}") - } + private fun debugLogRootTaskInfo(info: RootTaskInfo) { + Log.d(TAG, "RootTaskInfo={" + + "taskId=${info.taskId} " + + "parentTaskId=${info.parentTaskId} " + + "position=${info.position} " + + "positionInParent=${info.positionInParent} " + + "isVisible=${info.isVisible()} " + + "visible=${info.visible} " + + "isFocused=${info.isFocused} " + + "isSleeping=${info.isSleeping} " + + "isRunning=${info.isRunning} " + + "windowMode=${windowingModeToString(info.windowingMode)} " + + "activityType=${activityTypeToString(info.activityType)} " + + "topActivity=${info.topActivity} " + + "topActivityInfo=${info.topActivityInfo} " + + "numActivities=${info.numActivities} " + + "childTaskIds=${Arrays.toString(info.childTaskIds)} " + + "childUserIds=${Arrays.toString(info.childTaskUserIds)} " + + "childTaskBounds=${Arrays.toString(info.childTaskBounds)} " + + "childTaskNames=${Arrays.toString(info.childTaskNames)}" + + "}" + ) + + for (j in 0 until info.childTaskIds.size) { + Log.d(TAG, " *** [$j] ******") + Log.d(TAG, " *** childTaskIds[$j]: ${info.childTaskIds[j]}") + Log.d(TAG, " *** childTaskUserIds[$j]: ${info.childTaskUserIds[j]}") + Log.d(TAG, " *** childTaskBounds[$j]: ${info.childTaskBounds[j]}") + Log.d(TAG, " *** childTaskNames[$j]: ${info.childTaskNames[j]}") } } - private suspend fun getAllRootTaskInfosOnDisplay(displayId: Int): List<RootTaskInfo> = + @VisibleForTesting + open suspend fun getAllRootTaskInfosOnDisplay(displayId: Int): List<RootTaskInfo> = withContext(bgDispatcher) { try { atmService.getAllRootTaskInfosOnDisplay(displayId) @@ -160,7 +145,8 @@ internal class ScreenshotPolicyImpl @Inject constructor( } } - private suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k -> + @VisibleForTesting + open suspend fun isNotificationShadeExpanded(): Boolean = suspendCoroutine { k -> proxyConnector .postForResult { it.isNotificationShadeExpanded } .whenComplete { expanded, error -> @@ -171,8 +157,30 @@ internal class ScreenshotPolicyImpl @Inject constructor( } } - companion object { - const val TAG: String = "ScreenshotPolicyImpl" - const val DEBUG: Boolean = false - } + @VisibleForTesting + internal val systemUiContent = + DisplayContentInfo( + ComponentName(context, SystemUIService::class.java), + Rect(), + Process.myUserHandle(), + ActivityTaskManager.INVALID_TASK_ID + ) +} + +private const val TAG: String = "ScreenshotPolicyImpl" +private const val DEBUG: Boolean = false + +@VisibleForTesting +internal fun RootTaskInfo.toDisplayContentInfo(): DisplayContentInfo { + val topActivity: ComponentName = topActivity ?: error("should not be null") + val topChildTask = childTaskIds.size - 1 + val childTaskId = childTaskIds[topChildTask] + val childTaskUserId = childTaskUserIds[topChildTask] + val childTaskBounds = childTaskBounds[topChildTask] + + return DisplayContentInfo( + topActivity, + childTaskBounds, + UserHandle.of(childTaskUserId), + childTaskId) } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java index aecec9d100cc..d68e8bd36c40 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java @@ -387,6 +387,33 @@ public class KeyguardSecurityContainerControllerTest extends SysuiTestCase { } @Test + public void onResume_sideFpsHintShouldBeShown_sideFpsHintShown() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onResume(0); + + verify(mSidefpsController).show(); + verify(mSidefpsController, never()).hide(); + } + + @Test + public void onResume_sideFpsHintShouldNotBeShown_sideFpsHintHidden() { + setupGetSecurityView(); + setupConditionsToEnableSideFpsHint(); + setSideFpsHintEnabledFromResources(false); + mKeyguardSecurityContainerController.onBouncerVisibilityChanged(View.VISIBLE); + reset(mSidefpsController); + + mKeyguardSecurityContainerController.onResume(0); + + verify(mSidefpsController).hide(); + verify(mSidefpsController, never()).show(); + } + + @Test public void showNextSecurityScreenOrFinish_setsSecurityScreenToPinAfterSimPinUnlock() { // GIVEN the current security method is SimPin when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(false); diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt index d1ed8e983cdd..f9c7d2d5cb41 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -31,7 +31,6 @@ import com.android.systemui.statusbar.SbnBuilder import com.android.systemui.tuner.TunerService import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.mockito.any -import com.android.systemui.util.mockito.argumentCaptor import com.android.systemui.util.mockito.capture import com.android.systemui.util.mockito.eq import com.android.systemui.util.time.FakeSystemClock @@ -108,6 +107,7 @@ class MediaDataManagerTest : SysuiTestCase() { private val clock = FakeSystemClock() @Mock private lateinit var tunerService: TunerService @Captor lateinit var tunableCaptor: ArgumentCaptor<TunerService.Tunable> + @Captor lateinit var callbackCaptor: ArgumentCaptor<(String, PlaybackState) -> Unit> private val instanceIdSequence = InstanceIdSequenceFake(1 shl 20) @@ -974,7 +974,6 @@ class MediaDataManagerTest : SysuiTestCase() { fun testPlaybackStateChange_keyExists_callsListener() { // Notification has been added addNotificationAndLoad() - val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>() verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor) // Callback gets an updated state @@ -992,7 +991,6 @@ class MediaDataManagerTest : SysuiTestCase() { @Test fun testPlaybackStateChange_keyDoesNotExist_doesNothing() { val state = PlaybackState.Builder().build() - val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>() verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor) // No media added with this key @@ -1013,7 +1011,6 @@ class MediaDataManagerTest : SysuiTestCase() { // And then get a state update val state = PlaybackState.Builder().build() - val callbackCaptor = argumentCaptor<(String, PlaybackState) -> Unit>() verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor) // Then no changes are made @@ -1022,6 +1019,83 @@ class MediaDataManagerTest : SysuiTestCase() { anyBoolean()) } + @Test + fun testPlaybackState_PauseWhenFlagTrue_keyExists_callsListener() { + whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(true) + val state = PlaybackState.Builder() + .setState(PlaybackState.STATE_PAUSED, 0L, 1f) + .build() + whenever(controller.playbackState).thenReturn(state) + + addNotificationAndLoad() + verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor) + callbackCaptor.value.invoke(KEY, state) + + verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), + capture(mediaDataCaptor), eq(true), eq(0), eq(false)) + assertThat(mediaDataCaptor.value.isPlaying).isFalse() + assertThat(mediaDataCaptor.value.semanticActions).isNotNull() + } + + @Test + fun testPlaybackState_PauseStateAfterAddingResumption_keyExists_callsListener() { + val desc = MediaDescription.Builder().run { + setTitle(SESSION_TITLE) + build() + } + val state = PlaybackState.Builder() + .setState(PlaybackState.STATE_PAUSED, 0L, 1f) + .setActions(PlaybackState.ACTION_PLAY_PAUSE) + .build() + + // Add resumption controls in order to have semantic actions. + // To make sure that they are not null after changing state. + mediaDataManager.addResumptionControls( + USER_ID, + desc, + Runnable {}, + session.sessionToken, + APP_NAME, + pendingIntent, + PACKAGE_NAME + ) + backgroundExecutor.runAllReady() + foregroundExecutor.runAllReady() + + verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor) + callbackCaptor.value.invoke(PACKAGE_NAME, state) + + verify(listener) + .onMediaDataLoaded( + eq(PACKAGE_NAME), + eq(PACKAGE_NAME), + capture(mediaDataCaptor), + eq(true), + eq(0), + eq(false) + ) + assertThat(mediaDataCaptor.value.isPlaying).isFalse() + assertThat(mediaDataCaptor.value.semanticActions).isNotNull() + } + + @Test + fun testPlaybackStateNull_Pause_keyExists_callsListener() { + whenever(controller.playbackState).thenReturn(null) + val state = PlaybackState.Builder() + .setState(PlaybackState.STATE_PAUSED, 0L, 1f) + .setActions(PlaybackState.ACTION_PLAY_PAUSE) + .build() + + addNotificationAndLoad() + verify(mediaTimeoutListener).stateCallback = capture(callbackCaptor) + callbackCaptor.value.invoke(KEY, state) + + verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), + capture(mediaDataCaptor), eq(true), eq(0), eq(false)) + assertThat(mediaDataCaptor.value.isPlaying).isFalse() + assertThat(mediaDataCaptor.value.semanticActions).isNull() + } + /** * Helper function to add a media notification and capture the resulting MediaData */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt index 1061e3c6b0d5..fa47a746f8ba 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt @@ -35,7 +35,9 @@ import com.android.internal.logging.testing.UiEventLoggerFake import com.android.internal.statusbar.IUndoMediaTransferCallback import com.android.systemui.R import com.android.systemui.SysuiTestCase +import com.android.systemui.classifier.FalsingCollector import com.android.systemui.media.taptotransfer.common.MediaTttLogger +import com.android.systemui.plugins.FalsingManager import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.util.concurrency.FakeExecutor @@ -48,11 +50,12 @@ import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor +import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mock import org.mockito.Mockito.never import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations @SmallTest @RunWith(AndroidTestingRunner::class) @@ -78,6 +81,10 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { private lateinit var viewUtil: ViewUtil @Mock private lateinit var commandQueue: CommandQueue + @Mock + private lateinit var falsingManager: FalsingManager + @Mock + private lateinit var falsingCollector: FalsingCollector private lateinit var commandQueueCallback: CommandQueue.Callbacks private lateinit var fakeAppIconDrawable: Drawable private lateinit var fakeClock: FakeSystemClock @@ -115,7 +122,9 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { accessibilityManager, configurationController, powerManager, - senderUiEventLogger + senderUiEventLogger, + falsingManager, + falsingCollector ) val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java) @@ -421,6 +430,38 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() { } @Test + fun transferToReceiverSucceeded_withUndoRunnable_falseTap_callbackNotRun() { + whenever(falsingManager.isFalseTap(anyInt())).thenReturn(true) + var undoCallbackCalled = false + val undoCallback = object : IUndoMediaTransferCallback.Stub() { + override fun onUndoTriggered() { + undoCallbackCalled = true + } + } + + controllerSender.displayChip(transferToReceiverSucceeded(undoCallback)) + getChipView().getUndoButton().performClick() + + assertThat(undoCallbackCalled).isFalse() + } + + @Test + fun transferToReceiverSucceeded_withUndoRunnable_realTap_callbackRun() { + whenever(falsingManager.isFalseTap(anyInt())).thenReturn(false) + var undoCallbackCalled = false + val undoCallback = object : IUndoMediaTransferCallback.Stub() { + override fun onUndoTriggered() { + undoCallbackCalled = true + } + } + + controllerSender.displayChip(transferToReceiverSucceeded(undoCallback)) + getChipView().getUndoButton().performClick() + + assertThat(undoCallbackCalled).isTrue() + } + + @Test fun transferToReceiverSucceeded_undoButtonClick_switchesToTransferToThisDeviceTriggered() { val undoCallback = object : IUndoMediaTransferCallback.Stub() { override fun onUndoTriggered() {} diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt index 48fbd354b98d..073c23cec569 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt @@ -23,6 +23,7 @@ import android.graphics.Insets import android.graphics.Rect import android.hardware.HardwareBuffer import android.os.Bundle +import android.os.UserHandle import android.view.WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD import android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER import android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN @@ -97,7 +98,7 @@ class RequestProcessorTest { policy.setManagedProfile(USER_ID, false) policy.setDisplayContentInfo( policy.getDefaultDisplayId(), - DisplayContentInfo(component, bounds, USER_ID, TASK_ID)) + DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)) val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD) val processor = RequestProcessor(imageCapture, policy, flags, scope) @@ -120,7 +121,7 @@ class RequestProcessorTest { // Indicate that the primary content belongs to a manged profile policy.setManagedProfile(USER_ID, true) policy.setDisplayContentInfo(policy.getDefaultDisplayId(), - DisplayContentInfo(component, bounds, USER_ID, TASK_ID)) + DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)) val request = ScreenshotRequest(TAKE_SCREENSHOT_FULLSCREEN, SCREENSHOT_KEY_CHORD) val processor = RequestProcessor(imageCapture, policy, flags, scope) @@ -160,7 +161,7 @@ class RequestProcessorTest { policy.setManagedProfile(USER_ID, false) policy.setDisplayContentInfo(policy.getDefaultDisplayId(), - DisplayContentInfo(component, bounds, USER_ID, TASK_ID)) + DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)) val processedRequest = processor.process(request) @@ -183,7 +184,7 @@ class RequestProcessorTest { // Indicate that the primary content belongs to a manged profile policy.setManagedProfile(USER_ID, true) policy.setDisplayContentInfo(policy.getDefaultDisplayId(), - DisplayContentInfo(component, bounds, USER_ID, TASK_ID)) + DisplayContentInfo(component, bounds, UserHandle.of(USER_ID), TASK_ID)) val processedRequest = processor.process(request) diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt new file mode 100644 index 000000000000..17396b13036c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotPolicyImplTest.kt @@ -0,0 +1,227 @@ +/* + * Copyright (C) 2022 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.screenshot + +import android.app.ActivityTaskManager.RootTaskInfo +import android.app.IActivityTaskManager +import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME +import android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD +import android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED +import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN +import android.app.WindowConfiguration.WINDOWING_MODE_PINNED +import android.content.ComponentName +import android.content.Context +import android.graphics.Rect +import android.os.UserHandle +import android.os.UserManager +import android.testing.AndroidTestingRunner +import com.android.systemui.SysuiTestCase +import com.android.systemui.screenshot.ScreenshotPolicy.DisplayContentInfo +import com.android.systemui.util.mockito.mock +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.runBlocking +import org.junit.Test +import org.junit.runner.RunWith + +// The following values are chosen to be distinct from commonly seen real values +private const val DISPLAY_ID = 100 +private const val PRIMARY_USER = 2000 +private const val MANAGED_PROFILE_USER = 3000 + +@RunWith(AndroidTestingRunner::class) +class ScreenshotPolicyImplTest : SysuiTestCase() { + + @Test + fun testToDisplayContentInfo() { + assertThat(fullScreenWorkProfileTask.toDisplayContentInfo()) + .isEqualTo( + DisplayContentInfo( + ComponentName( + "com.google.android.apps.nbu.files", + "com.google.android.apps.nbu.files.home.HomeActivity" + ), + Rect(0, 0, 1080, 2400), + UserHandle.of(MANAGED_PROFILE_USER), + 65)) + } + + @Test + fun findPrimaryContent_ignoresPipTask() = runBlocking { + val policy = fakeTasksPolicyImpl( + mContext, + shadeExpanded = false, + tasks = listOf( + pipTask, + fullScreenWorkProfileTask, + launcherTask, + emptyTask) + ) + + val info = policy.findPrimaryContent(DISPLAY_ID) + assertThat(info).isEqualTo(fullScreenWorkProfileTask.toDisplayContentInfo()) + } + + @Test + fun findPrimaryContent_shadeExpanded_ignoresTopTask() = runBlocking { + val policy = fakeTasksPolicyImpl( + mContext, + shadeExpanded = true, + tasks = listOf( + fullScreenWorkProfileTask, + launcherTask, + emptyTask) + ) + + val info = policy.findPrimaryContent(DISPLAY_ID) + assertThat(info).isEqualTo(policy.systemUiContent) + } + + @Test + fun findPrimaryContent_emptyTaskList() = runBlocking { + val policy = fakeTasksPolicyImpl( + mContext, + shadeExpanded = false, + tasks = listOf() + ) + + val info = policy.findPrimaryContent(DISPLAY_ID) + assertThat(info).isEqualTo(policy.systemUiContent) + } + + @Test + fun findPrimaryContent_workProfileNotOnTop() = runBlocking { + val policy = fakeTasksPolicyImpl( + mContext, + shadeExpanded = false, + tasks = listOf( + launcherTask, + fullScreenWorkProfileTask, + emptyTask) + ) + + val info = policy.findPrimaryContent(DISPLAY_ID) + assertThat(info).isEqualTo(launcherTask.toDisplayContentInfo()) + } + + private fun fakeTasksPolicyImpl( + context: Context, + shadeExpanded: Boolean, + tasks: List<RootTaskInfo> + ): ScreenshotPolicyImpl { + val userManager = mock<UserManager>() + val atmService = mock<IActivityTaskManager>() + val dispatcher = Dispatchers.Unconfined + + return object : ScreenshotPolicyImpl(context, userManager, atmService, dispatcher) { + override suspend fun isManagedProfile(userId: Int) = (userId == MANAGED_PROFILE_USER) + override suspend fun getAllRootTaskInfosOnDisplay(displayId: Int) = tasks + override suspend fun isNotificationShadeExpanded() = shadeExpanded + } + } + + private val pipTask = RootTaskInfo().apply { + configuration.windowConfiguration.apply { + windowingMode = WINDOWING_MODE_PINNED + bounds = Rect(628, 1885, 1038, 2295) + activityType = ACTIVITY_TYPE_STANDARD + } + displayId = DISPLAY_ID + userId = PRIMARY_USER + taskId = 66 + visible = true + isVisible = true + isRunning = true + numActivities = 1 + topActivity = ComponentName( + "com.google.android.youtube", + "com.google.android.apps.youtube.app.watchwhile.WatchWhileActivity" + ) + childTaskIds = intArrayOf(66) + childTaskNames = arrayOf("com.google.android.youtube/" + + "com.google.android.youtube.app.honeycomb.Shell\$HomeActivity") + childTaskUserIds = intArrayOf(0) + childTaskBounds = arrayOf(Rect(628, 1885, 1038, 2295)) + } + + private val fullScreenWorkProfileTask = RootTaskInfo().apply { + configuration.windowConfiguration.apply { + windowingMode = WINDOWING_MODE_FULLSCREEN + bounds = Rect(0, 0, 1080, 2400) + activityType = ACTIVITY_TYPE_STANDARD + } + displayId = DISPLAY_ID + userId = MANAGED_PROFILE_USER + taskId = 65 + visible = true + isVisible = true + isRunning = true + numActivities = 1 + topActivity = ComponentName( + "com.google.android.apps.nbu.files", + "com.google.android.apps.nbu.files.home.HomeActivity" + ) + childTaskIds = intArrayOf(65) + childTaskNames = arrayOf("com.google.android.apps.nbu.files/" + + "com.google.android.apps.nbu.files.home.HomeActivity") + childTaskUserIds = intArrayOf(MANAGED_PROFILE_USER) + childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400)) + } + + private val launcherTask = RootTaskInfo().apply { + configuration.windowConfiguration.apply { + windowingMode = WINDOWING_MODE_FULLSCREEN + bounds = Rect(0, 0, 1080, 2400) + activityType = ACTIVITY_TYPE_HOME + } + displayId = DISPLAY_ID + taskId = 1 + userId = PRIMARY_USER + visible = true + isVisible = true + isRunning = true + numActivities = 1 + topActivity = ComponentName( + "com.google.android.apps.nexuslauncher", + "com.google.android.apps.nexuslauncher.NexusLauncherActivity", + ) + childTaskIds = intArrayOf(1) + childTaskNames = arrayOf("com.google.android.apps.nexuslauncher/" + + "com.google.android.apps.nexuslauncher.NexusLauncherActivity") + childTaskUserIds = intArrayOf(0) + childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400)) + } + + private val emptyTask = RootTaskInfo().apply { + configuration.windowConfiguration.apply { + windowingMode = WINDOWING_MODE_FULLSCREEN + bounds = Rect(0, 0, 1080, 2400) + activityType = ACTIVITY_TYPE_UNDEFINED + } + displayId = DISPLAY_ID + taskId = 2 + userId = PRIMARY_USER + visible = false + isVisible = false + isRunning = false + numActivities = 0 + childTaskIds = intArrayOf(3, 4) + childTaskNames = arrayOf("", "") + childTaskUserIds = intArrayOf(0, 0) + childTaskBounds = arrayOf(Rect(0, 0, 1080, 2400), Rect(0, 2400, 1080, 4800)) + } +} diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java index 66a4527bc2cb..4adbfaa79c69 100644 --- a/services/core/java/com/android/server/audio/BtHelper.java +++ b/services/core/java/com/android/server/audio/BtHelper.java @@ -53,8 +53,6 @@ public class BtHelper { private static final String TAG = "AS.BtHelper"; - private static final int SOURCE_CODEC_TYPE_OPUS = 6; // TODO remove in U - private final @NonNull AudioDeviceBroker mDeviceBroker; BtHelper(@NonNull AudioDeviceBroker broker) { @@ -913,7 +911,7 @@ public class BtHelper { return "ENCODING_APTX_HD"; case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC: return "ENCODING_LDAC"; - case SOURCE_CODEC_TYPE_OPUS: // TODO update in U + case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS: return "ENCODING_OPUS"; default: return "ENCODING_BT_CODEC_TYPE(" + btCodecType + ")"; diff --git a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java index 25d0752844fd..c835d2fe1bbd 100644 --- a/services/core/java/com/android/server/display/BrightnessMappingStrategy.java +++ b/services/core/java/com/android/server/display/BrightnessMappingStrategy.java @@ -116,8 +116,10 @@ public abstract class BrightnessMappingStrategy { luxLevels = getLuxLevels(resources.getIntArray( com.android.internal.R.array.config_autoBrightnessLevelsIdle)); } else { - brightnessLevelsNits = displayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(); - luxLevels = displayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(); + brightnessLevelsNits = getFloatArray(resources.obtainTypedArray( + com.android.internal.R.array.config_autoBrightnessDisplayValuesNits)); + luxLevels = getLuxLevels(resources.getIntArray( + com.android.internal.R.array.config_autoBrightnessLevels)); } // Display independent, mode independent values diff --git a/services/core/java/com/android/server/display/DisplayDeviceConfig.java b/services/core/java/com/android/server/display/DisplayDeviceConfig.java index 3b627ef6a786..4f3fd6409cd8 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceConfig.java +++ b/services/core/java/com/android/server/display/DisplayDeviceConfig.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.content.res.TypedArray; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation; import android.os.Environment; @@ -150,22 +149,12 @@ import javax.xml.datatype.DatatypeConfigurationException; * </quirks> * * <autoBrightness> - * <brighteningLightDebounceMillis> + * <brighteningLightDebounceMillis> * 2000 - * </brighteningLightDebounceMillis> + * </brighteningLightDebounceMillis> * <darkeningLightDebounceMillis> * 1000 * </darkeningLightDebounceMillis> - * <displayBrightnessMapping> - * <displayBrightnessPoint> - * <lux>50</lux> - * <nits>45</nits> - * </displayBrightnessPoint> - * <displayBrightnessPoint> - * <lux>80</lux> - * <nits>75</nits> - * </displayBrightnessPoint> - * </displayBrightnessMapping> * </autoBrightness> * * <screenBrightnessRampFastDecrease>0.01</screenBrightnessRampFastDecrease> @@ -279,39 +268,6 @@ public class DisplayDeviceConfig { // for the corresponding values above private float[] mBrightness; - - /** - * Array of desired screen brightness in nits corresponding to the lux values - * in the mBrightnessLevelsLux array. The display brightness is defined as the - * measured brightness of an all-white image. The brightness values must be non-negative and - * non-decreasing. This must be overridden in platform specific overlays - */ - private float[] mBrightnessLevelsNits; - - /** - * Array of light sensor lux values to define our levels for auto backlight - * brightness support. - * The N entries of this array define N + 1 control points as follows: - * (1-based arrays) - * - * Point 1: (0, value[1]): lux <= 0 - * Point 2: (level[1], value[2]): 0 < lux <= level[1] - * Point 3: (level[2], value[3]): level[2] < lux <= level[3] - * ... - * Point N+1: (level[N], value[N+1]): level[N] < lux - * - * The control points must be strictly increasing. Each control point - * corresponds to an entry in the brightness backlight values arrays. - * For example, if lux == level[1] (first element of the levels array) - * then the brightness will be determined by value[2] (second element - * of the brightness values array). - * - * Spline interpolation is used to determine the auto-brightness - * backlight values for lux levels between these control points. - * - */ - private float[] mBrightnessLevelsLux; - private float mBacklightMinimum = Float.NaN; private float mBacklightMaximum = Float.NaN; private float mBrightnessDefault = Float.NaN; @@ -705,20 +661,6 @@ public class DisplayDeviceConfig { return mAutoBrightnessBrighteningLightDebounce; } - /** - * @return Auto brightness brightening ambient lux levels - */ - public float[] getAutoBrightnessBrighteningLevelsLux() { - return mBrightnessLevelsLux; - } - - /** - * @return Auto brightness brightening nits levels - */ - public float[] getAutoBrightnessBrighteningLevelsNits() { - return mBrightnessLevelsNits; - } - @Override public String toString() { return "DisplayDeviceConfig{" @@ -761,8 +703,6 @@ public class DisplayDeviceConfig { + mAutoBrightnessBrighteningLightDebounce + ", mAutoBrightnessDarkeningLightDebounce= " + mAutoBrightnessDarkeningLightDebounce - + ", mBrightnessLevelsLux= " + Arrays.toString(mBrightnessLevelsLux) - + ", mBrightnessLevelsNits= " + Arrays.toString(mBrightnessLevelsNits) + "}"; } @@ -839,7 +779,6 @@ public class DisplayDeviceConfig { loadBrightnessRampsFromConfigXml(); loadAmbientLightSensorFromConfigXml(); setProxSensorUnspecified(); - loadAutoBrightnessConfigsFromConfigXml(); mLoadedFrom = "<config.xml>"; } @@ -1052,7 +991,6 @@ public class DisplayDeviceConfig { private void loadAutoBrightnessConfigValues(DisplayConfiguration config) { loadAutoBrightnessBrighteningLightDebounce(config.getAutoBrightness()); loadAutoBrightnessDarkeningLightDebounce(config.getAutoBrightness()); - loadAutoBrightnessDisplayBrightnessMapping(config.getAutoBrightness()); } /** @@ -1085,33 +1023,6 @@ public class DisplayDeviceConfig { } } - /** - * Loads the auto-brightness display brightness mappings. Internally, this takes care of - * loading the value from the display config, and if not present, falls back to config.xml. - */ - private void loadAutoBrightnessDisplayBrightnessMapping(AutoBrightness autoBrightnessConfig) { - if (autoBrightnessConfig == null - || autoBrightnessConfig.getDisplayBrightnessMapping() == null) { - mBrightnessLevelsNits = getFloatArray(mContext.getResources() - .obtainTypedArray(com.android.internal.R.array - .config_autoBrightnessDisplayValuesNits)); - mBrightnessLevelsLux = getFloatArray(mContext.getResources() - .obtainTypedArray(com.android.internal.R.array - .config_autoBrightnessLevels)); - } else { - final int size = autoBrightnessConfig.getDisplayBrightnessMapping() - .getDisplayBrightnessPoint().size(); - mBrightnessLevelsNits = new float[size]; - mBrightnessLevelsLux = new float[size]; - for (int i = 0; i < size; i++) { - mBrightnessLevelsNits[i] = autoBrightnessConfig.getDisplayBrightnessMapping() - .getDisplayBrightnessPoint().get(i).getNits().floatValue(); - mBrightnessLevelsLux[i] = autoBrightnessConfig.getDisplayBrightnessMapping() - .getDisplayBrightnessPoint().get(i).getLux().floatValue(); - } - } - } - private void loadBrightnessMapFromConfigXml() { // Use the config.xml mapping final Resources res = mContext.getResources(); @@ -1337,10 +1248,6 @@ public class DisplayDeviceConfig { com.android.internal.R.string.config_displayLightSensorType); } - private void loadAutoBrightnessConfigsFromConfigXml() { - loadAutoBrightnessDisplayBrightnessMapping(null /*AutoBrightnessConfig*/); - } - private void loadAmbientLightSensorFromDdc(DisplayConfiguration config) { final SensorDetails sensorDetails = config.getLightSensor(); if (sensorDetails != null) { @@ -1483,22 +1390,6 @@ public class DisplayDeviceConfig { } } - /** - * Extracts a float array from the specified {@link TypedArray}. - * - * @param array The array to convert. - * @return the given array as a float array. - */ - public static float[] getFloatArray(TypedArray array) { - final int n = array.length(); - float[] vals = new float[n]; - for (int i = 0; i < n; i++) { - vals[i] = array.getFloat(i, PowerManager.BRIGHTNESS_OFF_FLOAT); - } - array.recycle(); - return vals; - } - static class SensorData { public String type; public String name; diff --git a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java index c12dc8e9e92e..a5c762a1df0b 100644 --- a/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java +++ b/services/core/java/com/android/server/media/MediaButtonReceiverHolder.java @@ -119,7 +119,7 @@ final class MediaButtonReceiverHolder { ComponentName componentName = getComponentName(pendingIntent, componentType); if (componentName != null) { if (!TextUtils.equals(componentName.getPackageName(), sessionPackageName)) { - EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet Logging. + EventLog.writeEvent(0x534e4554, "238177121", -1, ""); throw new IllegalArgumentException("ComponentName does not belong to " + "sessionPackageName. sessionPackageName = " + sessionPackageName + ", ComponentName pkg = " + componentName.getPackageName()); diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java index 4f8771a3ddef..1ee9a873fff9 100644 --- a/services/core/java/com/android/server/media/MediaSessionRecord.java +++ b/services/core/java/com/android/server/media/MediaSessionRecord.java @@ -914,7 +914,16 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR } @Override - public void setMediaButtonReceiver(PendingIntent pi) throws RemoteException { + public void setMediaButtonReceiver(PendingIntent pi, String sessionPackageName) + throws RemoteException { + //mPackageName has been verified in MediaSessionService.enforcePackageName(). + if (!TextUtils.equals(sessionPackageName, mPackageName)) { + EventLog.writeEvent(0x534e4554, "238177121", -1, ""); + throw new IllegalArgumentException("sessionPackageName name does not match " + + "package name provided to MediaSessionRecord. sessionPackageName = " + + sessionPackageName + ", pkg = " + + mPackageName); + } final long token = Binder.clearCallingIdentity(); try { if ((mPolicies & MediaSessionPolicyProvider.SESSION_POLICY_IGNORE_BUTTON_RECEIVER) @@ -922,7 +931,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR return; } mMediaButtonReceiverHolder = - MediaButtonReceiverHolder.create(mContext, mUserId, pi, mPackageName); + MediaButtonReceiverHolder.create(mContext, mUserId, pi, sessionPackageName); mService.onMediaButtonReceiverChanged(MediaSessionRecord.this); } finally { Binder.restoreCallingIdentity(token); @@ -936,7 +945,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR //mPackageName has been verified in MediaSessionService.enforcePackageName(). if (receiver != null && !TextUtils.equals( mPackageName, receiver.getPackageName())) { - EventLog.writeEvent(0x534e4554, "238177121", -1, ""); // SafetyNet Logging. + EventLog.writeEvent(0x534e4554, "238177121", -1, ""); throw new IllegalArgumentException("receiver does not belong to " + "package name provided to MediaSessionRecord. Pkg = " + mPackageName + ", Receiver Pkg = " + receiver.getPackageName()); diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f8f94f655a16..58e1d053d433 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -1582,13 +1582,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A if (newParent != null && isState(RESUMED)) { newParent.setResumedActivity(this, "onParentChanged"); - if (mStartingWindow != null && mStartingData != null - && mStartingData.mAssociatedTask == null && newParent.isEmbedded()) { - // The starting window should keep covering its task when the activity is - // reparented to a task fragment that may not fill the task bounds. - associateStartingDataWithTask(); - attachStartingSurfaceToAssociatedTask(); - } mImeInsetsFrozenUntilStartInput = false; } @@ -2679,14 +2672,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } } + /** Called when the starting window is added to this activity. */ void attachStartingWindow(@NonNull WindowState startingWindow) { startingWindow.mStartingData = mStartingData; mStartingWindow = startingWindow; + // The snapshot type may have called associateStartingDataWithTask(). if (mStartingData != null && mStartingData.mAssociatedTask != null) { attachStartingSurfaceToAssociatedTask(); } } + /** Makes starting window always fill the associated task. */ private void attachStartingSurfaceToAssociatedTask() { // Associate the configuration of starting window with the task. overrideConfigurationPropagation(mStartingWindow, mStartingData.mAssociatedTask); @@ -2694,6 +2690,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A mStartingData.mAssociatedTask.mSurfaceControl); } + /** Called when the starting window is not added yet but its data is known to fill the task. */ private void associateStartingDataWithTask() { mStartingData.mAssociatedTask = task; task.forAllActivities(r -> { @@ -2703,6 +2700,16 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A }); } + /** Associates and attaches an added starting window to the current task. */ + void associateStartingWindowWithTaskIfNeeded() { + if (mStartingWindow == null || mStartingData == null + || mStartingData.mAssociatedTask != null) { + return; + } + associateStartingDataWithTask(); + attachStartingSurfaceToAssociatedTask(); + } + void removeStartingWindow() { boolean prevEligibleForLetterboxEducation = isEligibleForLetterboxEducation(); diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index e38f5fe61888..de135a34c3df 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -1436,6 +1436,13 @@ class Task extends TaskFragment { final TaskFragment childTaskFrag = child.asTaskFragment(); if (childTaskFrag != null && childTaskFrag.asTask() == null) { childTaskFrag.setMinDimensions(mMinWidth, mMinHeight); + + // The starting window should keep covering its task when a pure TaskFragment is added + // because its bounds may not fill the task. + final ActivityRecord top = getTopMostActivity(); + if (top != null) { + top.associateStartingWindowWithTaskIfNeeded(); + } } } diff --git a/services/core/xsd/display-device-config/autobrightness.xsd b/services/core/xsd/display-device-config/autobrightness.xsd new file mode 100644 index 000000000000..477625a36cbd --- /dev/null +++ b/services/core/xsd/display-device-config/autobrightness.xsd @@ -0,0 +1,33 @@ +<!-- + Copyright (C) 2022 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. +--> +<xs:schema version="2.0" + elementFormDefault="qualified" + xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:complexType name="autoBrightness"> + <xs:sequence> + <!-- Sets the debounce for autoBrightness brightening in millis--> + <xs:element name="brighteningLightDebounceMillis" type="xs:nonNegativeInteger" + minOccurs="0" maxOccurs="1"> + <xs:annotation name="final"/> + </xs:element> + <!-- Sets the debounce for autoBrightness darkening in millis--> + <xs:element name="darkeningLightDebounceMillis" type="xs:nonNegativeInteger" + minOccurs="0" maxOccurs="1"> + <xs:annotation name="final"/> + </xs:element> + </xs:sequence> + </xs:complexType> +</xs:schema>
\ No newline at end of file diff --git a/services/core/xsd/display-device-config/display-device-config.xsd b/services/core/xsd/display-device-config/display-device-config.xsd index 98f83d8c0d09..bea5e2c2de74 100644 --- a/services/core/xsd/display-device-config/display-device-config.xsd +++ b/services/core/xsd/display-device-config/display-device-config.xsd @@ -23,6 +23,7 @@ <xs:schema version="2.0" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> + <xs:include schemaLocation="autobrightness.xsd" /> <xs:element name="displayConfiguration"> <xs:complexType> <xs:sequence> @@ -342,74 +343,4 @@ <xs:annotation name="final"/> </xs:element> </xs:complexType> - - <xs:complexType name="autoBrightness"> - <xs:sequence> - <!-- Sets the debounce for autoBrightness brightening in millis--> - <xs:element name="brighteningLightDebounceMillis" type="xs:nonNegativeInteger" - minOccurs="0" maxOccurs="1"> - <xs:annotation name="final"/> - </xs:element> - <!-- Sets the debounce for autoBrightness darkening in millis--> - <xs:element name="darkeningLightDebounceMillis" type="xs:nonNegativeInteger" - minOccurs="0" maxOccurs="1"> - <xs:annotation name="final"/> - </xs:element> - <!-- Sets the brightness mapping of the desired screen brightness in nits to the - corresponding lux for the current display --> - <xs:element name="displayBrightnessMapping" type="displayBrightnessMapping" - minOccurs="0" maxOccurs="1"> - <xs:annotation name="final"/> - </xs:element> - </xs:sequence> - </xs:complexType> - - <!-- Represents the brightness mapping of the desired screen brightness in nits to the - corresponding lux for the current display --> - <xs:complexType name="displayBrightnessMapping"> - <xs:sequence> - <!-- Sets the list of display brightness points, each representing the desired screen - brightness in nits to the corresponding lux for the current display - - The N entries of this array define N + 1 control points as follows: - (1-based arrays) - - Point 1: (0, nits[1]): currentLux <= 0 - Point 2: (lux[1], nits[2]): 0 < currentLux <= lux[1] - Point 3: (lux[2], nits[3]): lux[2] < currentLux <= lux[3] - ... - Point N+1: (lux[N], nits[N+1]): lux[N] < currentLux - - The control points must be strictly increasing. Each control point - corresponds to an entry in the brightness backlight values arrays. - For example, if currentLux == lux[1] (first element of the levels array) - then the brightness will be determined by nits[2] (second element - of the brightness values array). - --> - <xs:element name="displayBrightnessPoint" type="displayBrightnessPoint" - minOccurs="1" maxOccurs="unbounded"> - <xs:annotation name="final"/> - </xs:element> - </xs:sequence> - </xs:complexType> - - <!-- Represents a point in the display brightness mapping, representing the lux level from the - light sensor to the desired screen brightness in nits at this level --> - <xs:complexType name="displayBrightnessPoint"> - <xs:sequence> - <!-- The lux level from the light sensor. This must be a non-negative integer --> - <xs:element name="lux" type="xs:nonNegativeInteger" - minOccurs="1" maxOccurs="1"> - <xs:annotation name="final"/> - </xs:element> - - <!-- Desired screen brightness in nits corresponding to the suggested lux values. - The display brightness is defined as the measured brightness of an all-white image. - This must be a non-negative integer --> - <xs:element name="nits" type="xs:nonNegativeInteger" - minOccurs="1" maxOccurs="1"> - <xs:annotation name="final"/> - </xs:element> - </xs:sequence> - </xs:complexType> </xs:schema> diff --git a/services/core/xsd/display-device-config/schema/current.txt b/services/core/xsd/display-device-config/schema/current.txt index e5d26177b725..e9a926946764 100644 --- a/services/core/xsd/display-device-config/schema/current.txt +++ b/services/core/xsd/display-device-config/schema/current.txt @@ -5,10 +5,8 @@ package com.android.server.display.config { ctor public AutoBrightness(); method public final java.math.BigInteger getBrighteningLightDebounceMillis(); method public final java.math.BigInteger getDarkeningLightDebounceMillis(); - method public final com.android.server.display.config.DisplayBrightnessMapping getDisplayBrightnessMapping(); method public final void setBrighteningLightDebounceMillis(java.math.BigInteger); method public final void setDarkeningLightDebounceMillis(java.math.BigInteger); - method public final void setDisplayBrightnessMapping(com.android.server.display.config.DisplayBrightnessMapping); } public class BrightnessThresholds { @@ -45,19 +43,6 @@ package com.android.server.display.config { method public java.util.List<com.android.server.display.config.Density> getDensity(); } - public class DisplayBrightnessMapping { - ctor public DisplayBrightnessMapping(); - method public final java.util.List<com.android.server.display.config.DisplayBrightnessPoint> getDisplayBrightnessPoint(); - } - - public class DisplayBrightnessPoint { - ctor public DisplayBrightnessPoint(); - method public final java.math.BigInteger getLux(); - method public final java.math.BigInteger getNits(); - method public final void setLux(java.math.BigInteger); - method public final void setNits(java.math.BigInteger); - } - public class DisplayConfiguration { ctor public DisplayConfiguration(); method @NonNull public final com.android.server.display.config.Thresholds getAmbientBrightnessChangeThresholds(); diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java index 60ddeeb497a8..7755552bcad2 100644 --- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java @@ -149,12 +149,6 @@ public class LocalDisplayAdapterTest { .thenReturn(mockArray); when(mMockedResources.obtainTypedArray(R.array.config_roundedCornerBottomRadiusArray)) .thenReturn(mockArray); - when(mMockedResources.obtainTypedArray( - com.android.internal.R.array.config_autoBrightnessDisplayValuesNits)) - .thenReturn(mockArray); - when(mMockedResources.obtainTypedArray( - com.android.internal.R.array.config_autoBrightnessLevels)) - .thenReturn(mockArray); } @After diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java index 261b882319d8..03ea6137074d 100644 --- a/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java +++ b/services/tests/servicestests/src/com/android/server/display/DisplayDeviceConfigTest.java @@ -19,19 +19,16 @@ package com.android.server.display; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; -import static org.mockito.ArgumentMatchers.anyFloat; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; -import android.content.res.TypedArray; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,16 +52,22 @@ public final class DisplayDeviceConfigTest { private Resources mResources; @Before - public void setUp() { + public void setUp() throws IOException { MockitoAnnotations.initMocks(this); when(mContext.getResources()).thenReturn(mResources); mockDeviceConfigs(); + try { + Path tempFile = Files.createTempFile("display_config", ".tmp"); + Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8)); + mDisplayDeviceConfig = new DisplayDeviceConfig(mContext); + mDisplayDeviceConfig.initFromFile(tempFile.toFile()); + } catch (IOException e) { + throw new IOException("Failed to setup the display device config.", e); + } } @Test - public void testConfigValuesFromDisplayConfig() throws IOException { - setupDisplayDeviceConfigFromDisplayConfigFile(); - + public void testConfigValues() { assertEquals(mDisplayDeviceConfig.getAmbientHorizonLong(), 5000); assertEquals(mDisplayDeviceConfig.getAmbientHorizonShort(), 50); assertEquals(mDisplayDeviceConfig.getBrightnessRampDecreaseMaxMillis(), 3000); @@ -85,24 +88,10 @@ public final class DisplayDeviceConfigTest { assertEquals(mDisplayDeviceConfig.getScreenDarkeningMinThreshold(), 0.002, 0.000001f); assertEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLightDebounce(), 2000); assertEquals(mDisplayDeviceConfig.getAutoBrightnessDarkeningLightDebounce(), 1000); - assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new - float[]{50.0f, 80.0f}, 0.0f); - assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new - float[]{45.0f, 75.0f}, 0.0f); - // Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping, - // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor. - } - @Test - public void testConfigValuesFromDeviceConfig() { - setupDisplayDeviceConfigFromDeviceConfigFile(); - assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsLux(), new - float[]{0.0f, 110.0f, 500.0f}, 0.0f); - assertArrayEquals(mDisplayDeviceConfig.getAutoBrightnessBrighteningLevelsNits(), new - float[]{2.0f, 200.0f, 600.0f}, 0.0f); // Todo(brup): Add asserts for BrightnessThrottlingData, DensityMapping, // HighBrightnessModeData AmbientLightSensor, RefreshRateLimitations and ProximitySensor. - + // Also add test for the case where optional display configs are null } private String getContent() { @@ -125,16 +114,6 @@ public final class DisplayDeviceConfigTest { + "<autoBrightness>\n" + "<brighteningLightDebounceMillis>2000</brighteningLightDebounceMillis>\n" + "<darkeningLightDebounceMillis>1000</darkeningLightDebounceMillis>\n" - + "<displayBrightnessMapping>\n" - + "<displayBrightnessPoint>\n" - + "<lux>50</lux>\n" - + "<nits>45</nits>\n" - + "</displayBrightnessPoint>\n" - + "<displayBrightnessPoint>\n" - + "<lux>80</lux>\n" - + "<nits>75</nits>\n" - + "</displayBrightnessPoint>\n" - + "</displayBrightnessMapping>\n" + "</autoBrightness>\n" + "<highBrightnessMode enabled=\"true\">\n" + "<transitionPoint>0.62</transitionPoint>\n" @@ -206,64 +185,4 @@ public final class DisplayDeviceConfigTest { when(mResources.getFloat(com.android.internal.R.dimen .config_screenBrightnessSettingMaximumFloat)).thenReturn(1.0f); } - - private void setupDisplayDeviceConfigFromDisplayConfigFile() throws IOException { - Path tempFile = Files.createTempFile("display_config", ".tmp"); - Files.write(tempFile, getContent().getBytes(StandardCharsets.UTF_8)); - mDisplayDeviceConfig = new DisplayDeviceConfig(mContext); - mDisplayDeviceConfig.initFromFile(tempFile.toFile()); - } - - private void setupDisplayDeviceConfigFromDeviceConfigFile() { - TypedArray screenBrightnessNits = createFloatTypedArray(new float[]{2.0f, 250.0f, 650.0f}); - when(mResources.obtainTypedArray( - com.android.internal.R.array.config_screenBrightnessNits)) - .thenReturn(screenBrightnessNits); - TypedArray screenBrightnessBacklight = createFloatTypedArray(new - float[]{0.0f, 120.0f, 255.0f}); - when(mResources.obtainTypedArray( - com.android.internal.R.array.config_screenBrightnessBacklight)) - .thenReturn(screenBrightnessBacklight); - when(mResources.getIntArray(com.android.internal.R.array - .config_screenBrightnessBacklight)).thenReturn(new int[]{0, 120, 255}); - - when(mResources.getIntArray(com.android.internal.R.array - .config_autoBrightnessLevels)).thenReturn(new int[]{30, 80}); - when(mResources.getIntArray(com.android.internal.R.array - .config_autoBrightnessDisplayValuesNits)).thenReturn(new int[]{25, 55}); - - TypedArray screenBrightnessLevelNits = createFloatTypedArray(new - float[]{2.0f, 200.0f, 600.0f}); - when(mResources.obtainTypedArray( - com.android.internal.R.array.config_autoBrightnessDisplayValuesNits)) - .thenReturn(screenBrightnessLevelNits); - TypedArray screenBrightnessLevelLux = createFloatTypedArray(new - float[]{0.0f, 110.0f, 500.0f}); - when(mResources.obtainTypedArray( - com.android.internal.R.array.config_autoBrightnessLevels)) - .thenReturn(screenBrightnessLevelLux); - - mDisplayDeviceConfig = DisplayDeviceConfig.create(mContext, true); - - } - - private TypedArray createFloatTypedArray(float[] vals) { - TypedArray mockArray = mock(TypedArray.class); - when(mockArray.length()).thenAnswer(invocation -> { - return vals.length; - }); - when(mockArray.getFloat(anyInt(), anyFloat())).thenAnswer(invocation -> { - final float def = (float) invocation.getArguments()[1]; - if (vals == null) { - return def; - } - int idx = (int) invocation.getArguments()[0]; - if (idx >= 0 && idx < vals.length) { - return vals[idx]; - } else { - return def; - } - }); - return mockArray; - } } diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java index 44494831eb68..25c8f145bd62 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -2869,6 +2869,7 @@ public class ActivityRecordTests extends WindowTestsBase { mAtm, null /* fragmentToken */, false /* createdByOrganizer */); fragmentSetup.accept(taskFragment1, new Rect(0, 0, width / 2, height)); task.addChild(taskFragment1, POSITION_TOP); + assertEquals(task, activity1.mStartingData.mAssociatedTask); final TaskFragment taskFragment2 = new TaskFragment( mAtm, null /* fragmentToken */, false /* createdByOrganizer */); @@ -2890,7 +2891,6 @@ public class ActivityRecordTests extends WindowTestsBase { eq(task.mSurfaceControl)); assertEquals(activity1.mStartingData, startingWindow.mStartingData); assertEquals(task.mSurfaceControl, startingWindow.getAnimationLeashParent()); - assertEquals(task, activity1.mStartingData.mAssociatedTask); assertEquals(taskFragment1.getBounds(), activity1.getBounds()); // The activity was resized by task fragment, but starting window must still cover the task. assertEquals(taskBounds, activity1.mStartingWindow.getBounds()); @@ -2898,7 +2898,6 @@ public class ActivityRecordTests extends WindowTestsBase { // The starting window is only removed when all embedded activities are drawn. final WindowState activityWindow = mock(WindowState.class); activity1.onFirstWindowDrawn(activityWindow); - assertNotNull(activity1.mStartingWindow); activity2.onFirstWindowDrawn(activityWindow); assertNull(activity1.mStartingWindow); } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt index 3853af2f609e..1a40f82654ff 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/activityembedding/OpenActivityEmbeddingPlaceholderSplit.kt @@ -164,7 +164,6 @@ class OpenActivityEmbeddingPlaceholderSplit( fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 1, supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt index 9cc1bfe81c8c..ec2b4fa35c41 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt @@ -95,7 +95,7 @@ class CloseAppBackButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio @JvmStatic fun getParams(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt index 58a80112c85e..55d412927ba6 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt @@ -103,7 +103,7 @@ class CloseAppHomeButtonTest(testSpec: FlickerTestParameter) : CloseAppTransitio @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt index f6f3f58f29cb..725c10a8ada0 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToAppTest.kt @@ -113,8 +113,7 @@ class CloseImeAutoOpenWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - // b/190352379 (IME doesn't show on app launch in 90 degrees) + // b/190352379 (IME doesn't show on app launch in 90 degrees) supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt index 52f561ec4497..8832686b43aa 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeAutoOpenWindowToHomeTest.kt @@ -123,7 +123,7 @@ class CloseImeAutoOpenWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTes @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3, + .getConfigNonRotationTests( // b/190352379 (IME doesn't show on app launch in 90 degrees) supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt index c6e25d3de4cd..71e0aa1f9628 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeEditorPopupDialogTest.kt @@ -141,7 +141,6 @@ class CloseImeEditorPopupDialogTest(testSpec: FlickerTestParameter) : BaseTest(t fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 2, supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt index 23bd2200397a..0f91fd58abb7 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToAppTest.kt @@ -121,7 +121,7 @@ class CloseImeWindowToAppTest(testSpec: FlickerTestParameter) : BaseTest(testSpe @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt index 8ce184072d32..007a4f1835d7 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/CloseImeWindowToHomeTest.kt @@ -134,8 +134,7 @@ class CloseImeWindowToHomeTest(testSpec: FlickerTestParameter) : BaseTest(testSp fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_0), + supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt index a04a50f02c26..216e0edaf451 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeAndDialogThemeAppTest.kt @@ -127,14 +127,13 @@ class LaunchAppShowImeAndDialogThemeAppTest( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_0), - supportedNavigationModes = listOf( - WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, - WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY - ) + .getConfigNonRotationTests( + supportedRotations = listOf(Surface.ROTATION_0), + supportedNavigationModes = listOf( + WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, + WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY ) + ) } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt index 04e4bc94de9c..868290ec7585 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/LaunchAppShowImeOnStartTest.kt @@ -141,8 +141,7 @@ class LaunchAppShowImeOnStartTest(testSpec: FlickerTestParameter) : BaseTest(tes fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_0), + supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt index b10aed30e39e..16c23b93a5de 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowAndCloseTest.kt @@ -82,8 +82,7 @@ class OpenImeWindowAndCloseTest(testSpec: FlickerTestParameter) : BaseTest(testS fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_0), + supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt index d9008158ffaf..e5874921ddfa 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowFromFixedOrientationAppTest.kt @@ -117,8 +117,7 @@ class OpenImeWindowFromFixedOrientationAppTest( fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_90), + supportedRotations = listOf(Surface.ROTATION_90), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY ) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt index fdc2193b7eb8..c1f17f3deb2e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowTest.kt @@ -95,8 +95,7 @@ class OpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) { fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_0), + supportedRotations = listOf(Surface.ROTATION_0), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt index 9475734ef3f5..5fd94427dc82 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/OpenImeWindowToOverViewTest.kt @@ -265,7 +265,6 @@ class OpenImeWindowToOverViewTest(testSpec: FlickerTestParameter) : BaseTest(tes fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 1, supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90), supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY, diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt index 2e22e6224813..0281a60bbc3b 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/ReOpenImeWindowTest.kt @@ -192,8 +192,7 @@ open class ReOpenImeWindowTest(testSpec: FlickerTestParameter) : BaseTest(testSp fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedRotations = listOf(Surface.ROTATION_0) + supportedRotations = listOf(Surface.ROTATION_0) ) } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt index 4f47ec439da8..85bf6d752bf5 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ime/SwitchImeWindowsFromGestureNavTest.kt @@ -200,8 +200,7 @@ open class SwitchImeWindowsFromGestureNavTest( fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedNavigationModes = listOf( + supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY ), supportedRotations = listOf(Surface.ROTATION_0) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt index 33c280ea78bb..eb9acc4b8e4e 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/ActivitiesTransitionTest.kt @@ -142,7 +142,7 @@ class ActivitiesTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSp @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt index bfc7b39f9d9f..b3db5b70fafa 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationCold.kt @@ -171,7 +171,7 @@ open class OpenAppFromLockNotificationCold(testSpec: FlickerTestParameter) : @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt index f93d7a0b09e3..8c1d244b69e0 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWarm.kt @@ -221,7 +221,7 @@ open class OpenAppFromLockNotificationWarm(testSpec: FlickerTestParameter) : @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt index 75311eaf5c66..caf2e2dbadc6 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromLockNotificationWithLockOverlayApp.kt @@ -127,7 +127,7 @@ class OpenAppFromLockNotificationWithLockOverlayApp(testSpec: FlickerTestParamet @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt index dbe541882fa8..e744d44bc542 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationCold.kt @@ -157,7 +157,7 @@ open class OpenAppFromNotificationCold( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt index 915b70289055..4ea42433e054 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarm.kt @@ -284,7 +284,7 @@ open class OpenAppFromNotificationWarm( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt index 7c07ace06b82..a3dd0cbcf64f 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt @@ -130,7 +130,7 @@ open class OpenAppFromOverviewTest( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt index 53be7d43cce8..82e30accb341 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt @@ -233,8 +233,7 @@ open class OpenAppNonResizeableTest(testSpec: FlickerTestParameter) : fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedNavigationModes = + supportedNavigationModes = listOf(WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY), supportedRotations = listOf(Surface.ROTATION_0) ) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt index fe5e74b87f93..5f342a00bf8c 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/TaskTransitionTest.kt @@ -263,7 +263,7 @@ class TaskTransitionTest(testSpec: FlickerTestParameter) : BaseTest(testSpec) { @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigNonRotationTests(repetitions = 3) + .getConfigNonRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt index 181767b3448d..f85bad33c4fd 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsBackTest.kt @@ -278,8 +278,7 @@ open class QuickSwitchBetweenTwoAppsBackTest( fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedNavigationModes = listOf( + supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY ), supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt index 0f05622c81bc..f6392cab4a35 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchBetweenTwoAppsForwardTest.kt @@ -298,8 +298,7 @@ open class QuickSwitchBetweenTwoAppsForwardTest( fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedNavigationModes = listOf( + supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY ), supportedRotations = listOf(Surface.ROTATION_0, Surface.ROTATION_90) diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt index d1f356c830eb..a714111fae21 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/quickswitch/QuickSwitchFromLauncherTest.kt @@ -324,8 +324,7 @@ class QuickSwitchFromLauncherTest(testSpec: FlickerTestParameter) : BaseTest(tes fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() .getConfigNonRotationTests( - repetitions = 3, - supportedNavigationModes = listOf( + supportedNavigationModes = listOf( WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY ), // TODO: Test with 90 rotation diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt index 4be8963bf7b7..e6c1eaca9380 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/ChangeAppRotationTest.kt @@ -146,7 +146,7 @@ class ChangeAppRotationTest( @JvmStatic fun getParams(): Collection<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigRotationTests(repetitions = 3) + .getConfigRotationTests() } } } diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt index 0912812afef9..07c213034642 100644 --- a/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt +++ b/tests/FlickerTests/src/com/android/server/wm/flicker/rotation/SeamlessAppRotationTest.kt @@ -241,7 +241,7 @@ open class SeamlessAppRotationTest( @JvmStatic private fun getConfigurations(): List<FlickerTestParameter> { return FlickerTestParameterFactory.getInstance() - .getConfigRotationTests(repetitions = 2) + .getConfigRotationTests() .flatMap { sourceConfig -> val defaultRun = createConfig(sourceConfig, starveUiThread = false) val busyUiRun = createConfig(sourceConfig, starveUiThread = true) diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java index 8b69db707d41..dc34cb6d6a53 100644 --- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java +++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/HandwritingIme.java @@ -15,21 +15,25 @@ */ package com.google.android.test.handwritingime; +import android.R; import android.annotation.Nullable; import android.graphics.PointF; import android.graphics.RectF; import android.inputmethodservice.InputMethodService; -import android.os.Bundle; import android.util.Log; -import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.Window; -import android.view.inputmethod.CursorAnchorInfo; +import android.view.inputmethod.DeleteGesture; +import android.view.inputmethod.HandwritingGesture; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InsertGesture; +import android.view.inputmethod.SelectGesture; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.FrameLayout; +import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.Toast; @@ -39,19 +43,19 @@ public class HandwritingIme extends InputMethodService { public static final int HEIGHT_DP = 100; - private static final int OP_NONE = 0; private static final int OP_SELECT = 1; private static final int OP_DELETE = 2; - private static final int OP_DELETE_SPACE = 3; - private static final int OP_INSERT = 4; + private static final int OP_INSERT = 3; private Window mInkWindow; private InkView mInk; static final String TAG = "HandwritingIme"; private int mRichGestureMode = OP_NONE; + private int mRichGestureGranularity = -1; private Spinner mRichGestureModeSpinner; + private Spinner mRichGestureGranularitySpinner; private PointF mRichGestureStartPoint; @@ -86,13 +90,45 @@ public class HandwritingIme extends InputMethodService { switch (event.getAction()) { case MotionEvent.ACTION_UP: { if (areRichGesturesEnabled()) { - Bundle bundle = new Bundle(); - bundle.putInt("operation", mRichGestureMode); - bundle.putFloat("left", mRichGestureStartPoint.x); - bundle.putFloat("top", mRichGestureStartPoint.y); - bundle.putFloat("right", event.getX()); - bundle.putFloat("bottom", event.getY()); - performPrivateCommand("android.widget.RichGesture", bundle); + HandwritingGesture gesture = null; + switch(mRichGestureMode) { + case OP_SELECT: + SelectGesture.Builder builder = new SelectGesture.Builder(); + builder.setGranularity(mRichGestureGranularity) + .setSelectionArea(new RectF(mRichGestureStartPoint.x, + mRichGestureStartPoint.y, event.getX(), event.getY())) + .setFallbackText("fallback text"); + gesture = builder.build(); + break; + case OP_DELETE: + DeleteGesture.Builder builder1 = new DeleteGesture.Builder(); + builder1.setGranularity(mRichGestureGranularity) + .setDeletionArea(new RectF(mRichGestureStartPoint.x, + mRichGestureStartPoint.y, event.getX(), event.getY())) + .setFallbackText("fallback text"); + gesture = builder1.build(); + break; + case OP_INSERT: + InsertGesture.Builder builder2 = new InsertGesture.Builder(); + builder2.setInsertionPoint( + new PointF(mRichGestureStartPoint.x, mRichGestureStartPoint.y)) + .setTextToInsert(" ") + .setFallbackText("fallback text"); + gesture = builder2.build(); + + } + if (gesture == null) { + // This shouldn't happen + Log.e(TAG, "Unrecognized gesture mode: " + mRichGestureMode); + return; + } + InputConnection ic = getCurrentInputConnection(); + if (getCurrentInputStarted() && ic != null) { + ic.performHandwritingGesture(gesture, null, null); + } else { + // This shouldn't happen + Log.e(TAG, "No active InputConnection"); + } Log.d(TAG, "Sending RichGesture " + mRichGestureMode + " (Screen) Left: " + mRichGestureStartPoint.x + ", Top: " + mRichGestureStartPoint.y @@ -123,8 +159,15 @@ public class HandwritingIme extends InputMethodService { view.addView(inner, new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT, height)); - view.addView(getRichGestureActionsSpinner()); - inner.setBackgroundColor(getColor(R.color.abc_tint_spinner)); + LinearLayout layout = new LinearLayout(this); + layout.setLayoutParams(new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + layout.setOrientation(LinearLayout.VERTICAL); + layout.addView(getRichGestureActionsSpinner()); + layout.addView(getRichGestureGranularitySpinner()); + + view.addView(layout); + inner.setBackgroundColor(getColor(R.color.holo_green_light)); return view; } @@ -133,14 +176,12 @@ public class HandwritingIme extends InputMethodService { if (mRichGestureModeSpinner != null) { return mRichGestureModeSpinner; } - //get the spinner from the xml. mRichGestureModeSpinner = new Spinner(this); mRichGestureModeSpinner.setPadding(100, 0, 100, 0); mRichGestureModeSpinner.setTooltipText("Handwriting IME mode"); String[] items = new String[] { "Handwriting IME - Rich gesture disabled", "Rich gesture SELECT", - "Rich gesture DELETE", "Rich gesture DELETE SPACE", - "Rich gesture INSERT" }; + "Rich gesture DELETE", "Rich gesture INSERT" }; ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_dropdown_item, items); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -149,17 +190,52 @@ public class HandwritingIme extends InputMethodService { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { mRichGestureMode = position; + mRichGestureGranularitySpinner.setEnabled( + mRichGestureMode != OP_INSERT && mRichGestureMode != OP_NONE); Log.d(TAG, "Setting RichGesture Mode " + mRichGestureMode); } @Override public void onNothingSelected(AdapterView<?> parent) { mRichGestureMode = OP_NONE; + mRichGestureGranularitySpinner.setEnabled(false); } }); + mRichGestureModeSpinner.setSelection(0); // default disabled return mRichGestureModeSpinner; } + private View getRichGestureGranularitySpinner() { + if (mRichGestureGranularitySpinner != null) { + return mRichGestureGranularitySpinner; + } + mRichGestureGranularitySpinner = new Spinner(this); + mRichGestureGranularitySpinner.setPadding(100, 0, 100, 0); + mRichGestureGranularitySpinner.setTooltipText(" Granularity"); + String[] items = + new String[] { "Granularity - UNDEFINED", + "Granularity - WORD", "Granularity - CHARACTER"}; + ArrayAdapter<String> adapter = new ArrayAdapter<>(this, + android.R.layout.simple_spinner_dropdown_item, items); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mRichGestureGranularitySpinner.setAdapter(adapter); + mRichGestureGranularitySpinner.setOnItemSelectedListener( + new AdapterView.OnItemSelectedListener() { + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + mRichGestureGranularity = position; + Log.d(TAG, "Setting RichGesture Granularity " + mRichGestureGranularity); + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + mRichGestureGranularity = 0; + } + }); + mRichGestureGranularitySpinner.setSelection(1); + return mRichGestureGranularitySpinner; + } + public void onPrepareStylusHandwriting() { Log.d(TAG, "onPrepareStylusHandwriting "); if (mInk == null) { @@ -190,15 +266,6 @@ public class HandwritingIme extends InputMethodService { return false; } - boolean performPrivateCommand(String action, Bundle bundle) { - if (!getCurrentInputStarted()) { - Log.e(TAG, "Input hasnt started, can't performPrivateCommand"); - return false; - } - - return getCurrentInputConnection().performPrivateCommand(action, bundle); - } - private boolean areRichGesturesEnabled() { return mRichGestureMode != OP_NONE; } diff --git a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java index c9e429b6f4c8..94b1f863f197 100644 --- a/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java +++ b/tests/HandwritingIme/src/com/google/android/test/handwritingime/InkView.java @@ -30,7 +30,7 @@ import android.view.WindowManager; import android.view.WindowMetrics; class InkView extends View { - private static final long FINISH_TIMEOUT = 600; + private static final long FINISH_TIMEOUT = 1500; private final HandwritingIme.HandwritingFinisher mHwCanceller; private final HandwritingIme.StylusConsumer mConsumer; private final int mTopInset; diff --git a/tests/utils/testutils/java/android/os/test/TestLooper.java b/tests/utils/testutils/java/android/os/test/TestLooper.java index a826646f69f3..9ad6d53a3246 100644 --- a/tests/utils/testutils/java/android/os/test/TestLooper.java +++ b/tests/utils/testutils/java/android/os/test/TestLooper.java @@ -48,13 +48,14 @@ public class TestLooper { private static final Method MESSAGE_MARK_IN_USE_METHOD; private static final String TAG = "TestLooper"; - private final Clock mClock; + private final MessageQueue.Clock mClock; private AutoDispatchThread mAutoDispatchThread; static { try { - LOOPER_CONSTRUCTOR = Looper.class.getDeclaredConstructor(Boolean.TYPE); + LOOPER_CONSTRUCTOR = Looper.class.getDeclaredConstructor(Boolean.TYPE, + MessageQueue.Clock.class); LOOPER_CONSTRUCTOR.setAccessible(true); THREAD_LOCAL_LOOPER_FIELD = Looper.class.getDeclaredField("sThreadLocal"); THREAD_LOCAL_LOOPER_FIELD.setAccessible(true); @@ -83,15 +84,15 @@ public class TestLooper { * thread. * * Messages are dispatched when their {@link Message#when} is before or at {@link - * Clock#uptimeMillis()}. + * MessageQueue.Clock#uptimeMillis()}. * Use a custom clock with care. When using an offsettable clock like {@link * com.android.server.testutils.OffsettableClock} be sure not to double offset messages by * offsetting the clock and calling {@link #moveTimeForward(long)}. Instead, offset the clock * and call {@link #dispatchAll()}. */ - public TestLooper(Clock clock) { + public TestLooper(MessageQueue.Clock clock) { try { - mLooper = LOOPER_CONSTRUCTOR.newInstance(false); + mLooper = LOOPER_CONSTRUCTOR.newInstance(false, clock); ThreadLocal<Looper> threadLocalLooper = (ThreadLocal<Looper>) THREAD_LOCAL_LOOPER_FIELD .get(null); @@ -224,10 +225,6 @@ public class TestLooper { return count; } - public interface Clock { - long uptimeMillis(); - } - /** * Thread used to dispatch messages when the main thread is blocked waiting for a response. */ |