diff options
31 files changed, 532 insertions, 166 deletions
diff --git a/core/api/current.txt b/core/api/current.txt index f640ea25a22b..c9f06397abbf 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -6749,7 +6749,6 @@ package android.app { method public android.app.Notification.WearableExtender clone(); method public android.app.Notification.Builder extend(android.app.Notification.Builder); method public java.util.List<android.app.Notification.Action> getActions(); - method @Deprecated public android.graphics.Bitmap getBackground(); method public String getBridgeTag(); method public int getContentAction(); method @Deprecated public int getContentIcon(); @@ -6768,7 +6767,6 @@ package android.app { method @Deprecated public boolean getHintShowBackgroundOnly(); method @Deprecated public java.util.List<android.app.Notification> getPages(); method public boolean getStartScrollBottom(); - method @Deprecated public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap); method public android.app.Notification.WearableExtender setBridgeTag(String); method public android.app.Notification.WearableExtender setContentAction(int); method @Deprecated public android.app.Notification.WearableExtender setContentIcon(int); @@ -9682,6 +9680,7 @@ package android.companion.virtual { method public int describeContents(); method public int getDeviceId(); method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @NonNull public int[] getDisplayIds(); + method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") @Nullable public CharSequence getDisplayName(); method @Nullable public String getName(); method @Nullable public String getPersistentDeviceId(); method @FlaggedApi("android.companion.virtual.flags.vdm_public_apis") public boolean hasCustomSensorSupport(); diff --git a/core/api/removed.txt b/core/api/removed.txt index 8b3696a1e6d9..57e2e73854c1 100644 --- a/core/api/removed.txt +++ b/core/api/removed.txt @@ -23,6 +23,11 @@ package android.app { method @Deprecated public android.app.Notification.Builder setTimeout(long); } + public static final class Notification.WearableExtender implements android.app.Notification.Extender { + method @Deprecated public android.graphics.Bitmap getBackground(); + method @Deprecated public android.app.Notification.WearableExtender setBackground(android.graphics.Bitmap); + } + } package android.app.slice { diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 2c42df3c8819..93c2b5ad4d86 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -44,6 +44,9 @@ import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.admin.DevicePolicyManager; +import android.app.compat.CompatChanges; +import android.compat.annotation.ChangeId; +import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Intent; @@ -296,6 +299,15 @@ public class Notification implements Parcelable public static final String EXTRA_REMOTE_INPUT_DRAFT = "android.remoteInputDraft"; /** + * The call to WearableExtender#setBackground(Bitmap) will have no effect and the passed + * Bitmap will not be retained in memory. + */ + @ChangeId + @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM) + @VisibleForTesting + static final long WEARABLE_EXTENDER_BACKGROUND_BLOCKED = 270551184L; + + /** * A timestamp related to this notification, in milliseconds since the epoch. * * Default value: {@link System#currentTimeMillis() Now}. @@ -11148,9 +11160,20 @@ public class Notification implements Parcelable wearableBundle.putParcelableArray(KEY_PAGES, mPages.toArray( new Notification[mPages.size()])); } + if (mBackground != null) { - wearableBundle.putParcelable(KEY_BACKGROUND, mBackground); + // Keeping WearableExtender backgrounds in memory despite them being deprecated has + // added noticeable increase in system server and system ui memory usage. After + // target VERSION_CODE#VANILLA_ICE_CREAM the background will not be populated + // anymore. + if (CompatChanges.isChangeEnabled(WEARABLE_EXTENDER_BACKGROUND_BLOCKED)) { + Log.d(TAG, "Use of background in WearableExtenders has been deprecated and " + + "will not be populated anymore."); + } else { + wearableBundle.putParcelable(KEY_BACKGROUND, mBackground); + } } + if (mContentIcon != 0) { wearableBundle.putInt(KEY_CONTENT_ICON, mContentIcon); } @@ -11369,12 +11392,21 @@ public class Notification implements Parcelable * * @param background the background bitmap * @return this object for method chaining - * @see android.app.Notification.WearableExtender#getBackground - * @deprecated Background images are no longer supported. + * @removed Not functional since {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. + * The wearable background is not used by wearables anymore and uses up + * unnecessary memory. */ @Deprecated public WearableExtender setBackground(Bitmap background) { - mBackground = background; + // Keeping WearableExtender backgrounds in memory despite them being deprecated has + // added noticeable increase in system server and system ui memory usage. After + // target VERSION_CODE#VANILLA_ICE_CREAM the background will not be populated anymore. + if (CompatChanges.isChangeEnabled(WEARABLE_EXTENDER_BACKGROUND_BLOCKED)) { + Log.d(TAG, "Use of background in WearableExtenders has been deprecated and " + + "will not be populated anymore."); + } else { + mBackground = background; + } return this; } @@ -11384,11 +11416,13 @@ public class Notification implements Parcelable * will work with any notification style. * * @return the background image - * @see android.app.Notification.WearableExtender#setBackground - * @deprecated Background images are no longer supported. + * @removed Not functional since {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}. The + * wearable background is not used by wearables anymore and uses up + * unnecessary memory. */ @Deprecated public Bitmap getBackground() { + Log.w(TAG, "Use of background in WearableExtender has been removed, returning null."); return mBackground; } diff --git a/core/java/android/companion/virtual/VirtualDevice.java b/core/java/android/companion/virtual/VirtualDevice.java index 4692f921beb2..ce883cddc952 100644 --- a/core/java/android/companion/virtual/VirtualDevice.java +++ b/core/java/android/companion/virtual/VirtualDevice.java @@ -44,6 +44,7 @@ public final class VirtualDevice implements Parcelable { private final int mId; private final @Nullable String mPersistentId; private final @Nullable String mName; + private final @Nullable CharSequence mDisplayName; /** * Creates a new instance of {@link VirtualDevice}. @@ -53,6 +54,18 @@ public final class VirtualDevice implements Parcelable { */ public VirtualDevice(@NonNull IVirtualDevice virtualDevice, int id, @Nullable String persistentId, @Nullable String name) { + this(virtualDevice, id, persistentId, name, null); + } + + /** + * Creates a new instance of {@link VirtualDevice}. Only to be used by the + * VirtualDeviceManagerService. + * + * @hide + */ + public VirtualDevice(@NonNull IVirtualDevice virtualDevice, int id, + @Nullable String persistentId, @Nullable String name, + @Nullable CharSequence displayName) { if (id <= Context.DEVICE_ID_DEFAULT) { throw new IllegalArgumentException("VirtualDevice ID must be greater than " + Context.DEVICE_ID_DEFAULT); @@ -61,6 +74,7 @@ public final class VirtualDevice implements Parcelable { mId = id; mPersistentId = persistentId; mName = name; + mDisplayName = displayName; } private VirtualDevice(@NonNull Parcel parcel) { @@ -68,6 +82,7 @@ public final class VirtualDevice implements Parcelable { mId = parcel.readInt(); mPersistentId = parcel.readString8(); mName = parcel.readString8(); + mDisplayName = parcel.readCharSequence(); } /** @@ -112,6 +127,15 @@ public final class VirtualDevice implements Parcelable { } /** + * Returns the human-readable name of the virtual device, if defined, which is suitable to be + * shown in UI. + */ + @FlaggedApi(Flags.FLAG_VDM_PUBLIC_APIS) + public @Nullable CharSequence getDisplayName() { + return mDisplayName; + } + + /** * Returns the IDs of all virtual displays that belong to this device, if any. * * <p>The actual {@link android.view.Display} objects can be obtained by passing the returned @@ -156,6 +180,7 @@ public final class VirtualDevice implements Parcelable { dest.writeInt(mId); dest.writeString8(mPersistentId); dest.writeString8(mName); + dest.writeCharSequence(mDisplayName); } @Override @@ -165,6 +190,7 @@ public final class VirtualDevice implements Parcelable { + " mId=" + mId + " mPersistentId=" + mPersistentId + " mName=" + mName + + " mDisplayName=" + mDisplayName + ")"; } diff --git a/core/java/android/companion/virtual/flags.aconfig b/core/java/android/companion/virtual/flags.aconfig index 3e96c96d8d17..d0e13cd977ef 100644 --- a/core/java/android/companion/virtual/flags.aconfig +++ b/core/java/android/companion/virtual/flags.aconfig @@ -34,3 +34,10 @@ flag { description: "Enable Virtual Camera" bug: "270352264" } + +flag { + name: "stream_permissions" + namespace: "virtual_devices" + description: "Enable streaming permission dialogs to Virtual Devices" + bug: "291737919" +} diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java index 94d851603064..6a82f6da67b3 100644 --- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java +++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java @@ -959,8 +959,8 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { mKeyphraseMetadata = new KeyphraseMetadata(1, mText, fakeSupportedLocales, AlwaysOnHotwordDetector.RECOGNITION_MODE_VOICE_TRIGGER); } - notifyStateChangedLocked(); } + notifyStateChanged(availability); } /** @@ -1370,8 +1370,8 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { mAvailability = STATE_INVALID; mIsAvailabilityOverriddenByTestApi = false; - notifyStateChangedLocked(); } + notifyStateChanged(STATE_INVALID); super.destroy(); } @@ -1401,6 +1401,8 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { */ // TODO(b/281608561): remove the enrollment flow from AlwaysOnHotwordDetector void onSoundModelsChanged() { + boolean notifyError = false; + synchronized (mLock) { if (mAvailability == STATE_INVALID || mAvailability == STATE_HARDWARE_UNAVAILABLE @@ -1441,6 +1443,9 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { // calling stopRecognition where there is no started session. Log.w(TAG, "Failed to stop recognition after enrollment update: code=" + result); + + // Execute a refresh availability task - which should then notify of a change. + new RefreshAvailabilityTask().execute(); } catch (Exception e) { Slog.w(TAG, "Failed to stop recognition after enrollment update", e); if (CompatChanges.isChangeEnabled(SEND_ON_FAILURE_FOR_ASYNC_EXCEPTIONS)) { @@ -1449,14 +1454,14 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { + Log.getStackTraceString(e), FailureSuggestedAction.RECREATE_DETECTOR)); } else { - updateAndNotifyStateChangedLocked(STATE_ERROR); + notifyError = true; } - return; } } + } - // Execute a refresh availability task - which should then notify of a change. - new RefreshAvailabilityTask().execute(); + if (notifyError) { + updateAndNotifyStateChanged(STATE_ERROR); } } @@ -1572,10 +1577,11 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { } } - @GuardedBy("mLock") - private void updateAndNotifyStateChangedLocked(int availability) { - updateAvailabilityLocked(availability); - notifyStateChangedLocked(); + private void updateAndNotifyStateChanged(int availability) { + synchronized (mLock) { + updateAvailabilityLocked(availability); + } + notifyStateChanged(availability); } @GuardedBy("mLock") @@ -1589,17 +1595,17 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { } } - @GuardedBy("mLock") - private void notifyStateChangedLocked() { + private void notifyStateChanged(int newAvailability) { Message message = Message.obtain(mHandler, MSG_AVAILABILITY_CHANGED); - message.arg1 = mAvailability; + message.arg1 = newAvailability; message.sendToTarget(); } - @GuardedBy("mLock") private void sendUnknownFailure(String failureMessage) { - // update but do not call onAvailabilityChanged callback for STATE_ERROR - updateAvailabilityLocked(STATE_ERROR); + synchronized (mLock) { + // update but do not call onAvailabilityChanged callback for STATE_ERROR + updateAvailabilityLocked(STATE_ERROR); + } Message.obtain(mHandler, MSG_DETECTION_UNKNOWN_FAILURE, failureMessage).sendToTarget(); } @@ -1802,19 +1808,17 @@ public class AlwaysOnHotwordDetector extends AbstractDetector { availability = STATE_KEYPHRASE_UNENROLLED; } } - updateAndNotifyStateChangedLocked(availability); } + updateAndNotifyStateChanged(availability); } catch (Exception e) { // Any exception here not caught will crash the process because AsyncTask does not // bubble up the exceptions to the client app, so we must propagate it to the app. Slog.w(TAG, "Failed to refresh availability", e); - synchronized (mLock) { - if (CompatChanges.isChangeEnabled(SEND_ON_FAILURE_FOR_ASYNC_EXCEPTIONS)) { - sendUnknownFailure( - "Failed to refresh availability: " + Log.getStackTraceString(e)); - } else { - updateAndNotifyStateChangedLocked(STATE_ERROR); - } + if (CompatChanges.isChangeEnabled(SEND_ON_FAILURE_FOR_ASYNC_EXCEPTIONS)) { + sendUnknownFailure( + "Failed to refresh availability: " + Log.getStackTraceString(e)); + } else { + updateAndNotifyStateChanged(STATE_ERROR); } } diff --git a/core/java/android/view/TextureView.java b/core/java/android/view/TextureView.java index bdd0a9cf653a..969b6a5125d0 100644 --- a/core/java/android/view/TextureView.java +++ b/core/java/android/view/TextureView.java @@ -16,6 +16,7 @@ package android.view; +import android.annotation.FloatRange; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; @@ -30,8 +31,10 @@ import android.graphics.SurfaceTexture; import android.graphics.TextureLayer; import android.graphics.drawable.Drawable; import android.os.Build; +import android.os.Trace; import android.util.AttributeSet; import android.util.Log; +import android.view.flags.Flags; /** * <p>A TextureView can be used to display a content stream, such as that @@ -194,6 +197,9 @@ public class TextureView extends View { private Canvas mCanvas; private int mSaveCount; + @FloatRange(from = 0.0) float mFrameRate; + @Surface.FrameRateCompatibility int mFrameRateCompatibility; + private final Object[] mNativeWindowLock = new Object[0]; // Set by native code, do not write! @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -465,6 +471,16 @@ public class TextureView extends View { mLayer.setSurfaceTexture(mSurface); mSurface.setDefaultBufferSize(getWidth(), getHeight()); mSurface.setOnFrameAvailableListener(mUpdateListener, mAttachInfo.mHandler); + if (Flags.toolkitSetFrameRate()) { + mSurface.setOnSetFrameRateListener( + (surfaceTexture, frameRate, compatibility, strategy) -> { + if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { + Trace.instant(Trace.TRACE_TAG_VIEW, "setFrameRate: " + frameRate); + } + mFrameRate = frameRate; + mFrameRateCompatibility = compatibility; + }, mAttachInfo.mHandler); + } if (mListener != null && createNewSurface) { mListener.onSurfaceTextureAvailable(mSurface, getWidth(), getHeight()); diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 55374b994cd4..5eaded218a0b 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -8562,6 +8562,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * announcements every time a View is updated. * * <p> + * For notifying users about errors, such as in a login screen with text that displays an + * "incorrect password" notification, that view should send an AccessibilityEvent of type + * {@link AccessibilityEvent#CONTENT_CHANGE_TYPE_ERROR} and set + * {@link AccessibilityNodeInfo#setError(CharSequence)} instead. Custom widgets should expose + * error-setting methods that support accessibility automatically. For example, instead of + * explicitly sending this event when using a TextView, use + * {@link android.widget.TextView#setError(CharSequence)}. + * + * <p> * Use {@link #setStateDescription(CharSequence)} to convey state changes to views within the * user interface. While a live region may send different types of events generated by the view, * state description will send {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED} events of diff --git a/core/java/android/window/StartingWindowInfo.java b/core/java/android/window/StartingWindowInfo.java index a88e394c0985..451acbe84a60 100644 --- a/core/java/android/window/StartingWindowInfo.java +++ b/core/java/android/window/StartingWindowInfo.java @@ -122,7 +122,7 @@ public final class StartingWindowInfo implements Parcelable { TYPE_PARAMETER_PROCESS_RUNNING, TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT, TYPE_PARAMETER_ACTIVITY_CREATED, - TYPE_PARAMETER_ALLOW_ICON, + TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN, TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN, TYPE_PARAMETER_WINDOWLESS, TYPE_PARAMETER_LEGACY_SPLASH_SCREEN @@ -143,7 +143,7 @@ public final class StartingWindowInfo implements Parcelable { /** @hide */ public static final int TYPE_PARAMETER_ACTIVITY_CREATED = 0x00000010; /** @hide */ - public static final int TYPE_PARAMETER_ALLOW_ICON = 0x00000020; + public static final int TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN = 0x00000020; /** * The parameter which indicates if the activity has finished drawing. * @hide diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 9ed41553a4b4..3795fc8594ae 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -102,6 +102,7 @@ cc_library_shared_for_libandroid_runtime { static_libs: [ "libnativehelper_lazy", "libziparchive_for_incfs", + "libguiflags", ], export_include_dirs: [ diff --git a/core/jni/android_graphics_SurfaceTexture.cpp b/core/jni/android_graphics_SurfaceTexture.cpp index 21487abadbae..50832a5c256a 100644 --- a/core/jni/android_graphics_SurfaceTexture.cpp +++ b/core/jni/android_graphics_SurfaceTexture.cpp @@ -17,27 +17,24 @@ #undef LOG_TAG #define LOG_TAG "SurfaceTexture" -#include <stdio.h> - #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES2/gl2.h> #include <GLES2/gl2ext.h> - +#include <com_android_graphics_libgui_flags.h> +#include <cutils/atomic.h> #include <gui/BufferQueue.h> #include <gui/Surface.h> +#include <nativehelper/JNIHelp.h> +#include <nativehelper/ScopedLocalRef.h> +#include <stdio.h> #include <surfacetexture/SurfaceTexture.h> #include <surfacetexture/surface_texture_platform.h> - -#include "core_jni_helpers.h" - -#include <cutils/atomic.h> #include <utils/Log.h> #include <utils/misc.h> +#include "core_jni_helpers.h" #include "jni.h" -#include <nativehelper/JNIHelp.h> -#include <nativehelper/ScopedLocalRef.h> // ---------------------------------------------------------------------------- @@ -55,6 +52,7 @@ struct fields_t { jfieldID producer; jfieldID frameAvailableListener; jmethodID postEvent; + jmethodID postOnSetFrameRateEvent; }; static fields_t fields; @@ -139,61 +137,81 @@ bool android_SurfaceTexture_isInstanceOf(JNIEnv* env, jobject thiz) { // ---------------------------------------------------------------------------- -class JNISurfaceTextureContext : public SurfaceTexture::FrameAvailableListener -{ +class JNISurfaceTextureContextCommon { public: - JNISurfaceTextureContext(JNIEnv* env, jobject weakThiz, jclass clazz); - virtual ~JNISurfaceTextureContext(); - virtual void onFrameAvailable(const BufferItem& item); + JNISurfaceTextureContextCommon(JNIEnv* env, jobject weakThiz, jclass clazz) + : mWeakThiz(env->NewGlobalRef(weakThiz)), mClazz((jclass)env->NewGlobalRef(clazz)) {} + + virtual ~JNISurfaceTextureContextCommon() { + JNIEnv* env = getJNIEnv(); + if (env != NULL) { + env->DeleteGlobalRef(mWeakThiz); + env->DeleteGlobalRef(mClazz); + } else { + ALOGW("leaking JNI object references"); + } + } -private: - static JNIEnv* getJNIEnv(); + void onFrameAvailable(const BufferItem& item) { + JNIEnv* env = getJNIEnv(); + if (env != NULL) { + env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); + } else { + ALOGW("onFrameAvailable event will not posted"); + } + } + +protected: + static JNIEnv* getJNIEnv() { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + JavaVMAttachArgs args = {JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL}; + JavaVM* vm = AndroidRuntime::getJavaVM(); + int result = vm->AttachCurrentThreadAsDaemon(&env, (void*)&args); + if (result != JNI_OK) { + ALOGE("thread attach failed: %#x", result); + return NULL; + } + } + return env; + } jobject mWeakThiz; jclass mClazz; }; -JNISurfaceTextureContext::JNISurfaceTextureContext(JNIEnv* env, - jobject weakThiz, jclass clazz) : - mWeakThiz(env->NewGlobalRef(weakThiz)), - mClazz((jclass)env->NewGlobalRef(clazz)) -{} - -JNIEnv* JNISurfaceTextureContext::getJNIEnv() { - JNIEnv* env = AndroidRuntime::getJNIEnv(); - if (env == NULL) { - JavaVMAttachArgs args = { - JNI_VERSION_1_4, "JNISurfaceTextureContext", NULL }; - JavaVM* vm = AndroidRuntime::getJavaVM(); - int result = vm->AttachCurrentThreadAsDaemon(&env, (void*)&args); - if (result != JNI_OK) { - ALOGE("thread attach failed: %#x", result); - return NULL; - } +class JNISurfaceTextureContextFrameAvailableListener + : public JNISurfaceTextureContextCommon, + public SurfaceTexture::FrameAvailableListener { +public: + JNISurfaceTextureContextFrameAvailableListener(JNIEnv* env, jobject weakThiz, jclass clazz) + : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} + void onFrameAvailable(const BufferItem& item) override { + JNISurfaceTextureContextCommon::onFrameAvailable(item); } - return env; -} +}; -JNISurfaceTextureContext::~JNISurfaceTextureContext() -{ - JNIEnv* env = getJNIEnv(); - if (env != NULL) { - env->DeleteGlobalRef(mWeakThiz); - env->DeleteGlobalRef(mClazz); - } else { - ALOGW("leaking JNI object references"); +class JNISurfaceTextureContextListener : public JNISurfaceTextureContextCommon, + public SurfaceTexture::SurfaceTextureListener { +public: + JNISurfaceTextureContextListener(JNIEnv* env, jobject weakThiz, jclass clazz) + : JNISurfaceTextureContextCommon(env, weakThiz, clazz) {} + + void onFrameAvailable(const BufferItem& item) override { + JNISurfaceTextureContextCommon::onFrameAvailable(item); } -} -void JNISurfaceTextureContext::onFrameAvailable(const BufferItem& /* item */) -{ - JNIEnv* env = getJNIEnv(); - if (env != NULL) { - env->CallStaticVoidMethod(mClazz, fields.postEvent, mWeakThiz); - } else { - ALOGW("onFrameAvailable event will not posted"); + void onSetFrameRate(float frameRate, int8_t compatibility, + int8_t changeFrameRateStrategy) override { + JNIEnv* env = getJNIEnv(); + if (env != NULL) { + env->CallStaticVoidMethod(mClazz, fields.postOnSetFrameRateEvent, mWeakThiz, frameRate, + compatibility, changeFrameRateStrategy); + } else { + ALOGW("onSetFrameRate event will not posted"); + } } -} +}; // ---------------------------------------------------------------------------- @@ -229,6 +247,13 @@ static void SurfaceTexture_classInit(JNIEnv* env, jclass clazz) if (fields.postEvent == NULL) { ALOGE("can't find android/graphics/SurfaceTexture.postEventFromNative"); } + + fields.postOnSetFrameRateEvent = + env->GetStaticMethodID(clazz, "postOnSetFrameRateEventFromNative", + "(Ljava/lang/ref/WeakReference;FII)V"); + if (fields.postOnSetFrameRateEvent == NULL) { + ALOGE("can't find android/graphics/SurfaceTexture.postOnSetFrameRateEventFromNative"); + } } static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached, @@ -274,17 +299,27 @@ static void SurfaceTexture_init(JNIEnv* env, jobject thiz, jboolean isDetached, return; } - sp<JNISurfaceTextureContext> ctx(new JNISurfaceTextureContext(env, weakThiz, - clazz)); - surfaceTexture->setFrameAvailableListener(ctx); - SurfaceTexture_setFrameAvailableListener(env, thiz, ctx); + if (com::android::graphics::libgui::flags::bq_setframerate()) { + sp<JNISurfaceTextureContextListener> ctx( + new JNISurfaceTextureContextListener(env, weakThiz, clazz)); + surfaceTexture->setSurfaceTextureListener(ctx); + } else { + sp<JNISurfaceTextureContextFrameAvailableListener> ctx( + new JNISurfaceTextureContextFrameAvailableListener(env, weakThiz, clazz)); + surfaceTexture->setFrameAvailableListener(ctx); + SurfaceTexture_setFrameAvailableListener(env, thiz, ctx); + } } static void SurfaceTexture_finalize(JNIEnv* env, jobject thiz) { sp<SurfaceTexture> surfaceTexture(SurfaceTexture_getSurfaceTexture(env, thiz)); - surfaceTexture->setFrameAvailableListener(0); - SurfaceTexture_setFrameAvailableListener(env, thiz, 0); + if (com::android::graphics::libgui::flags::bq_setframerate()) { + surfaceTexture->setSurfaceTextureListener(0); + } else { + surfaceTexture->setFrameAvailableListener(0); + SurfaceTexture_setFrameAvailableListener(env, thiz, 0); + } SurfaceTexture_setSurfaceTexture(env, thiz, 0); SurfaceTexture_setProducer(env, thiz, 0); } diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java index 48dc167438da..7f3e01432dd9 100644 --- a/core/tests/coretests/src/android/app/NotificationTest.java +++ b/core/tests/coretests/src/android/app/NotificationTest.java @@ -69,6 +69,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.annotation.Nullable; +import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.Intent; import android.content.LocusId; @@ -95,16 +96,20 @@ import android.util.Pair; import android.widget.RemoteViews; import androidx.test.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; -import androidx.test.runner.AndroidJUnit4; import com.android.internal.R; import com.android.internal.util.ContrastColorUtil; import junit.framework.Assert; +import libcore.junit.util.compat.CoreCompatChangeRule; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestRule; import org.junit.runner.RunWith; import java.util.List; @@ -116,6 +121,9 @@ public class NotificationTest { private Context mContext; + @Rule + public TestRule compatChangeRule = new PlatformCompatChangeRule(); + @Before public void setUp() { mContext = InstrumentationRegistry.getContext(); @@ -1777,6 +1785,42 @@ public class NotificationTest { assertThat(recoveredExtender.getColor()).isEqualTo(1234); } + @Test + @CoreCompatChangeRule.EnableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED}) + public void wearableBackgroundBlockEnabled_wearableBackgroundSet_valueRemainsNull() { + Notification.WearableExtender extender = new Notification.WearableExtender(); + Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888); + extender.setBackground(bitmap); + Notification notif = + new Notification.Builder(mContext, "test id") + .setSmallIcon(1) + .setContentTitle("test_title") + .extend(extender) + .build(); + + Notification.WearableExtender result = new Notification.WearableExtender(notif); + Assert.assertNull(result.getBackground()); + } + + @Test + @CoreCompatChangeRule.DisableCompatChanges({Notification.WEARABLE_EXTENDER_BACKGROUND_BLOCKED}) + public void wearableBackgroundBlockDisabled_wearableBackgroundSet_valueKeepsBitmap() { + Notification.WearableExtender extender = new Notification.WearableExtender(); + Bitmap bitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888); + extender.setBackground(bitmap); + Notification notif = + new Notification.Builder(mContext, "test id") + .setSmallIcon(1) + .setContentTitle("test_title") + .extend(extender) + .build(); + + Notification.WearableExtender result = new Notification.WearableExtender(notif); + Bitmap resultBitmap = result.getBackground(); + assertNotNull(resultBitmap); + Assert.assertEquals(bitmap, resultBitmap); + } + private void assertValid(Notification.Colors c) { // Assert that all colors are populated assertThat(c.getBackgroundColor()).isNotEqualTo(Notification.COLOR_INVALID); diff --git a/graphics/java/android/graphics/SurfaceTexture.java b/graphics/java/android/graphics/SurfaceTexture.java index dfe5012a2b4d..dd82fed03087 100644 --- a/graphics/java/android/graphics/SurfaceTexture.java +++ b/graphics/java/android/graphics/SurfaceTexture.java @@ -16,6 +16,7 @@ package android.graphics; +import android.annotation.FloatRange; import android.annotation.Nullable; import android.annotation.SuppressLint; import android.compat.annotation.UnsupportedAppUsage; @@ -24,8 +25,10 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.Trace; import android.view.Surface; import android.view.TextureView; +import android.view.flags.Flags; import java.lang.ref.WeakReference; @@ -79,6 +82,7 @@ public class SurfaceTexture { private final Looper mCreatorLooper; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private Handler mOnFrameAvailableHandler; + private Handler mOnSetFrameRateHandler; /** * These fields are used by native code, do not access or modify. @@ -100,6 +104,21 @@ public class SurfaceTexture { } /** + * Callback interface for being notified that a producer set a frame rate + * @hide + */ + public interface OnSetFrameRateListener { + /** + * Called when the producer sets a frame rate + * @hide + */ + void onSetFrameRate(SurfaceTexture surfaceTexture, + @FloatRange(from = 0.0) float frameRate, + @Surface.FrameRateCompatibility int compatibility, + @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy); + } + + /** * Exception thrown when a SurfaceTexture couldn't be created or resized. * * @deprecated No longer thrown. {@link android.view.Surface.OutOfResourcesException} @@ -224,6 +243,48 @@ public class SurfaceTexture { } } + private static class SetFrameRateArgs { + SetFrameRateArgs(@FloatRange(from = 0.0) float frameRate, + @Surface.FrameRateCompatibility int compatibility, + @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) { + this.mFrameRate = frameRate; + this.mCompatibility = compatibility; + this.mChangeFrameRateStrategy = changeFrameRateStrategy; + } + final float mFrameRate; + final int mCompatibility; + final int mChangeFrameRateStrategy; + } + + /** + * Register a callback to be invoked when the producer sets a frame rate using + * Surface.setFrameRate. + * @hide + */ + public void setOnSetFrameRateListener(@Nullable final OnSetFrameRateListener listener, + @Nullable Handler handler) { + if (listener != null) { + Looper looper = handler != null ? handler.getLooper() : + mCreatorLooper != null ? mCreatorLooper : Looper.getMainLooper(); + mOnSetFrameRateHandler = new Handler(looper, null, true /*async*/) { + @Override + public void handleMessage(Message msg) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "onSetFrameRateHandler"); + try { + SetFrameRateArgs args = (SetFrameRateArgs) msg.obj; + listener.onSetFrameRate(SurfaceTexture.this, + args.mFrameRate, args.mCompatibility, + args.mChangeFrameRateStrategy); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + } + }; + } else { + mOnSetFrameRateHandler = null; + } + } + /** * Set the default size of the image buffers. The image producer may override the buffer size, * in which case the producer-set buffer size will be used, not the default size set by this @@ -418,6 +479,35 @@ public class SurfaceTexture { } /** + * This method is invoked from native code only. + * @hide + */ + @SuppressWarnings({"UnusedDeclaration"}) + private static void postOnSetFrameRateEventFromNative(WeakReference<SurfaceTexture> weakSelf, + @FloatRange(from = 0.0) float frameRate, + @Surface.FrameRateCompatibility int compatibility, + @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) { + Trace.traceBegin(Trace.TRACE_TAG_VIEW, "postOnSetFrameRateEventFromNative"); + try { + if (Flags.toolkitSetFrameRate()) { + SurfaceTexture st = weakSelf.get(); + if (st != null) { + Handler handler = st.mOnSetFrameRateHandler; + if (handler != null) { + Message msg = new Message(); + msg.obj = new SetFrameRateArgs(frameRate, compatibility, + changeFrameRateStrategy); + handler.sendMessage(msg); + } + } + } + } finally { + Trace.traceEnd(Trace.TRACE_TAG_VIEW); + } + + } + + /** * Returns {@code true} if the SurfaceTexture is single-buffered. * @hide */ diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java index 6ea6516a96f5..72fc8686f648 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/startingsurface/phone/PhoneStartingWindowTypeAlgorithm.java @@ -30,7 +30,7 @@ import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCR import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK; import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING; import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_ICON; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN; import static android.window.StartingWindowInfo.TYPE_PARAMETER_WINDOWLESS; import android.window.StartingWindowInfo; @@ -52,7 +52,8 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor final boolean processRunning = (parameter & TYPE_PARAMETER_PROCESS_RUNNING) != 0; final boolean allowTaskSnapshot = (parameter & TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT) != 0; final boolean activityCreated = (parameter & TYPE_PARAMETER_ACTIVITY_CREATED) != 0; - final boolean allowIcon = (parameter & TYPE_PARAMETER_ALLOW_ICON) != 0; + final boolean isSolidColorSplashScreen = + (parameter & TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN) != 0; final boolean legacySplashScreen = ((parameter & TYPE_PARAMETER_LEGACY_SPLASH_SCREEN) != 0); final boolean activityDrawn = (parameter & TYPE_PARAMETER_ACTIVITY_DRAWN) != 0; @@ -66,13 +67,13 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor + "processRunning=%b, " + "allowTaskSnapshot=%b, " + "activityCreated=%b, " - + "allowIcon=%b, " + + "isSolidColorSplashScreen=%b, " + "legacySplashScreen=%b, " + "activityDrawn=%b, " + "windowless=%b, " + "topIsHome=%b", newTask, taskSwitch, processRunning, allowTaskSnapshot, activityCreated, - allowIcon, legacySplashScreen, activityDrawn, windowlessSurface, + isSolidColorSplashScreen, legacySplashScreen, activityDrawn, windowlessSurface, topIsHome); if (windowlessSurface) { @@ -80,7 +81,7 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor } if (!topIsHome) { if (!processRunning || newTask || (taskSwitch && !activityCreated)) { - return getSplashscreenType(allowIcon, legacySplashScreen); + return getSplashscreenType(isSolidColorSplashScreen, legacySplashScreen); } } @@ -94,18 +95,18 @@ public class PhoneStartingWindowTypeAlgorithm implements StartingWindowTypeAlgor } } if (!activityDrawn && !topIsHome) { - return getSplashscreenType(allowIcon, legacySplashScreen); + return getSplashscreenType(isSolidColorSplashScreen, legacySplashScreen); } } return STARTING_WINDOW_TYPE_NONE; } - private static int getSplashscreenType(boolean allowIcon, boolean legacySplashScreen) { - if (allowIcon) { - return legacySplashScreen ? STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN + private static int getSplashscreenType(boolean solidColorSplashScreen, + boolean legacySplashScreen) { + return solidColorSplashScreen + ? STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN + : legacySplashScreen + ? STARTING_WINDOW_TYPE_LEGACY_SPLASH_SCREEN : STARTING_WINDOW_TYPE_SPLASH_SCREEN; - } else { - return STARTING_WINDOW_TYPE_SOLID_COLOR_SPLASH_SCREEN; - } } } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt index 664fbb22b13b..f2c29f4a623e 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt @@ -180,7 +180,8 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) + val wct = + getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) @@ -198,7 +199,8 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) + val wct = + getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) @@ -216,7 +218,8 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) + val wct = + getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(3) // Expect order to be from bottom: home, task1, task2 wct.assertReorderAt(index = 0, homeTask) @@ -230,7 +233,8 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) + val wct = + getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(1) wct.assertReorderAt(index = 0, homeTask) } @@ -246,7 +250,8 @@ class DesktopTasksControllerTest : ShellTestCase() { controller.showDesktopApps(DEFAULT_DISPLAY, RemoteTransition(TestRemoteTransition())) - val wct = getLatestWct(type = TRANSIT_OPEN, handlerClass = OneShotRemoteHandler::class.java) + val wct = + getLatestWct(type = TRANSIT_TO_FRONT, handlerClass = OneShotRemoteHandler::class.java) assertThat(wct.hierarchyOps).hasSize(2) // Expect order to be from bottom: home, task wct.assertReorderAt(index = 0, homeTaskDefaultDisplay) diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp index 94ed06c806e5..f76ea063842f 100644 --- a/libs/hwui/renderthread/RenderThread.cpp +++ b/libs/hwui/renderthread/RenderThread.cpp @@ -17,6 +17,7 @@ #include "RenderThread.h" #include <GrContextOptions.h> +#include <include/gpu/ganesh/gl/GrGLDirectContext.h> #include <android-base/properties.h> #include <dlfcn.h> #include <gl/GrGLInterface.h> @@ -286,7 +287,7 @@ void RenderThread::requireGlContext() { auto glesVersion = reinterpret_cast<const char*>(glGetString(GL_VERSION)); auto size = glesVersion ? strlen(glesVersion) : -1; cacheManager().configureContext(&options, glesVersion, size); - sk_sp<GrDirectContext> grContext(GrDirectContext::MakeGL(std::move(glInterface), options)); + sk_sp<GrDirectContext> grContext(GrDirectContexts::MakeGL(std::move(glInterface), options)); LOG_ALWAYS_FATAL_IF(!grContext.get()); setGrContext(grContext); } diff --git a/packages/SettingsLib/tests/integ/AndroidManifest.xml b/packages/SettingsLib/tests/integ/AndroidManifest.xml index a95da3033eae..32048ca6344c 100644 --- a/packages/SettingsLib/tests/integ/AndroidManifest.xml +++ b/packages/SettingsLib/tests/integ/AndroidManifest.xml @@ -41,7 +41,7 @@ </application> <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner" - android:targetPackage="com.android.settingslib" + android:targetPackage="com.android.settingslib.tests.integ" android:label="Tests for SettingsLib"> </instrumentation> </manifest> diff --git a/packages/SettingsLib/tests/integ/AndroidTest.xml b/packages/SettingsLib/tests/integ/AndroidTest.xml index b5d09475269e..d0aee8822a72 100644 --- a/packages/SettingsLib/tests/integ/AndroidTest.xml +++ b/packages/SettingsLib/tests/integ/AndroidTest.xml @@ -21,7 +21,7 @@ <option name="test-suite-tag" value="apct" /> <option name="test-tag" value="SettingsLibTests" /> <test class="com.android.tradefed.testtype.AndroidJUnitTest" > - <option name="package" value="com.android.settingslib" /> + <option name="package" value="com.android.settingslib.tests.integ" /> <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" /> <option name="hidden-api-checks" value="false"/> </test> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index 625c1de0134d..b2287d876a48 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -163,7 +163,10 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard } mCurrentUser = KeyguardUpdateMonitor.getCurrentUser(); showPrimarySecurityScreen(false); - reinflateViewFlipper((l) -> {}); + if (mCurrentSecurityMode != SecurityMode.SimPin + && mCurrentSecurityMode != SecurityMode.SimPuk) { + reinflateViewFlipper((l) -> {}); + } } }; diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 954129ef78c8..22bd20767e14 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -18,8 +18,8 @@ package com.android.systemui; import static androidx.dynamicanimation.animation.DynamicAnimation.TRANSLATION_X; import static androidx.dynamicanimation.animation.FloatPropertyCompat.createFloatPropertyCompat; - import static com.android.systemui.classifier.Classifier.NOTIFICATION_DISMISS; +import static com.android.systemui.flags.Flags.SWIPE_UNCLEARED_TRANSIENT_VIEW_FIX; import static com.android.systemui.statusbar.notification.NotificationUtils.logKey; import android.animation.Animator; @@ -482,7 +482,14 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { boolean wasRemoved = false; if (animView instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) animView; - wasRemoved = row.isRemoved(); + if (mFeatureFlags.isEnabled(SWIPE_UNCLEARED_TRANSIENT_VIEW_FIX)) { + // If the view is already removed from its parent and added as Transient, + // we need to clean the transient view upon animation end + wasRemoved = row.getTransientContainer() != null + || row.getParent() == null || row.isRemoved(); + } else { + wasRemoved = row.isRemoved(); + } } if (!mCancelled || wasRemoved) { mCallback.onChildDismissed(animView); diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java index e8be40eaf3fe..9b74ac4afed4 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java @@ -791,7 +791,8 @@ public class QuickSettingsController implements Dumpable { /** update Qs height state */ public void setExpansionHeight(float height) { // TODO(b/277909752): remove below log when bug is fixed - if (mSplitShadeEnabled && mShadeExpandedFraction == 1.0f && height == 0) { + if (mSplitShadeEnabled && mShadeExpandedFraction == 1.0f && height == 0 + && mBarState == SHADE) { Log.wtf(TAG, "setting QS height to 0 in split shade while shade is open(ing). " + "Value of mExpandImmediate = " + mExpandImmediate); diff --git a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java index a3ccb168aa4e..b56b47f9c727 100644 --- a/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java +++ b/services/companion/java/com/android/server/companion/virtual/GenericWindowPolicyController.java @@ -113,6 +113,8 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController private final boolean mCrossTaskNavigationAllowedByDefault; @NonNull private final ArraySet<ComponentName> mCrossTaskNavigationExemptions; + @Nullable + private final ComponentName mPermissionDialogComponent; private final Object mGenericWindowPolicyControllerLock = new Object(); @Nullable private final ActivityBlockedCallback mActivityBlockedCallback; private int mDisplayId = Display.INVALID_DISPLAY; @@ -171,6 +173,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController @NonNull Set<ComponentName> activityPolicyExemptions, boolean crossTaskNavigationAllowedByDefault, @NonNull Set<ComponentName> crossTaskNavigationExemptions, + @Nullable ComponentName permissionDialogComponent, @Nullable ActivityListener activityListener, @Nullable PipBlockedCallback pipBlockedCallback, @Nullable ActivityBlockedCallback activityBlockedCallback, @@ -185,6 +188,7 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController mActivityPolicyExemptions = activityPolicyExemptions; mCrossTaskNavigationAllowedByDefault = crossTaskNavigationAllowedByDefault; mCrossTaskNavigationExemptions = new ArraySet<>(crossTaskNavigationExemptions); + mPermissionDialogComponent = permissionDialogComponent; mActivityBlockedCallback = activityBlockedCallback; setInterestedWindowFlags(windowFlags, systemWindowFlags); mActivityListener = activityListener; @@ -309,6 +313,13 @@ public class GenericWindowPolicyController extends DisplayWindowPolicyController return false; } + // mPermissionDialogComponent being null means we don't want to block permission Dialogs + // based on FLAG_STREAM_PERMISSIONS + if (mPermissionDialogComponent != null + && mPermissionDialogComponent.equals(activityComponent)) { + return false; + } + return true; } diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java index 203a152ccc73..a2e4d2cc6929 100644 --- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java +++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java @@ -24,6 +24,7 @@ import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAUL import static android.companion.virtual.VirtualDeviceParams.NAVIGATION_POLICY_DEFAULT_ALLOWED; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_ACTIVITY; import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_RECENTS; +import static android.content.pm.PackageManager.ACTION_REQUEST_PERMISSIONS; import static android.view.WindowManager.LayoutParams.FLAG_SECURE; import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS; @@ -204,6 +205,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub @GuardedBy("mVirtualDeviceLock") @NonNull private final Set<ComponentName> mActivityPolicyExemptions; + private final ComponentName mPermissionDialogComponent; private ActivityListener createListenerAdapter() { return new ActivityListener() { @@ -317,6 +319,11 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub mParams.getVirtualSensorCallback(), mParams.getVirtualSensorConfigs()); mCameraAccessController = cameraAccessController; mCameraAccessController.startObservingIfNeeded(); + if (!Flags.streamPermissions()) { + mPermissionDialogComponent = getPermissionDialogComponent(); + } else { + mPermissionDialogComponent = null; + } try { token.linkToDeath(this, 0); } catch (RemoteException e) { @@ -324,8 +331,14 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub } mVirtualDeviceLog.logCreated(deviceId, mOwnerUid); - mPublicVirtualDeviceObject = new VirtualDevice( - this, getDeviceId(), getPersistentDeviceId(), mParams.getName()); + if (Flags.vdmPublicApis()) { + mPublicVirtualDeviceObject = new VirtualDevice( + this, getDeviceId(), getPersistentDeviceId(), mParams.getName(), + getDisplayName()); + } else { + mPublicVirtualDeviceObject = new VirtualDevice( + this, getDeviceId(), getPersistentDeviceId(), mParams.getName()); + } if (Flags.dynamicPolicy()) { mActivityPolicyExemptions = new ArraySet<>( @@ -951,6 +964,7 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub /*crossTaskNavigationExemptions=*/crossTaskNavigationAllowedByDefault ? mParams.getBlockedCrossTaskNavigations() : mParams.getAllowedCrossTaskNavigations(), + mPermissionDialogComponent, createListenerAdapter(), this::onEnteringPipBlocked, this::onActivityBlocked, @@ -963,6 +977,13 @@ final class VirtualDeviceImpl extends IVirtualDevice.Stub return gwpc; } + private ComponentName getPermissionDialogComponent() { + Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS); + PackageManager packageManager = mContext.getPackageManager(); + intent.setPackage(packageManager.getPermissionControllerPackageName()); + return intent.resolveActivity(packageManager); + } + int createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig, @NonNull IVirtualDisplayCallback callback, String packageName) { GenericWindowPolicyController gwpc; diff --git a/services/core/java/com/android/server/pm/PackageManagerException.java b/services/core/java/com/android/server/pm/PackageManagerException.java index 881cbe806c66..d69737aef98f 100644 --- a/services/core/java/com/android/server/pm/PackageManagerException.java +++ b/services/core/java/com/android/server/pm/PackageManagerException.java @@ -102,7 +102,8 @@ public class PackageManagerException extends Exception { INTERNAL_ERROR_STATIC_SHARED_LIB_PROTECTED_BROADCAST, INTERNAL_ERROR_STATIC_SHARED_LIB_OVERLAY_TARGETS, INTERNAL_ERROR_APEX_NOT_DIRECTORY, - INTERNAL_ERROR_APEX_MORE_THAN_ONE_FILE + INTERNAL_ERROR_APEX_MORE_THAN_ONE_FILE, + INTERNAL_ERROR_MISSING_USER }) @Retention(RetentionPolicy.SOURCE) public @interface InternalErrorCode {} diff --git a/services/core/java/com/android/server/pm/RemovePackageHelper.java b/services/core/java/com/android/server/pm/RemovePackageHelper.java index 3d61f3eea393..b055a3ffd688 100644 --- a/services/core/java/com/android/server/pm/RemovePackageHelper.java +++ b/services/core/java/com/android/server/pm/RemovePackageHelper.java @@ -402,7 +402,7 @@ final class RemovePackageHelper { mBroadcastHelper.sendPreferredActivityChangedBroadcast(UserHandle.USER_ALL); } } else if (!deletedPs.isSystem() && outInfo != null && !outInfo.mIsUpdate - && outInfo.mRemovedUsers != null) { + && outInfo.mRemovedUsers != null && !outInfo.mIsExternal) { // For non-system uninstalls with DELETE_KEEP_DATA, set the installed state to false // for affected users. This does not apply to app updates where the old apk is replaced // but the old data remains. diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index a0c78702fec5..16847243b6e1 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -580,7 +580,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A IBinder mRequestedLaunchingTaskFragmentToken; // Tracking splash screen status from previous activity - boolean mAllowIconSplashScreen = true; + boolean mSplashScreenStyleSolidColor = false; boolean mPauseSchedulePendingForPip = false; @@ -2408,7 +2408,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A @VisibleForTesting boolean addStartingWindow(String pkg, int resolvedTheme, ActivityRecord from, boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot, - boolean activityCreated, boolean allowIcon, boolean activityAllDrawn) { + boolean activityCreated, boolean isSimple, + boolean activityAllDrawn) { // If the display is frozen, we won't do anything until the actual window is // displayed so there is no reason to put in the starting window. if (!okToDisplay()) { @@ -2443,8 +2444,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int typeParameter = StartingSurfaceController .makeStartingWindowTypeParameter(newTask, taskSwitch, processRunning, - allowTaskSnapshot, activityCreated, allowIcon, useLegacy, - activityAllDrawn, type, packageName, mUserId); + allowTaskSnapshot, activityCreated, isSimple, useLegacy, activityAllDrawn, + type, packageName, mUserId); if (type == STARTING_WINDOW_TYPE_SNAPSHOT) { if (isActivityTypeHome()) { @@ -6746,7 +6747,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void onFirstWindowDrawn(WindowState win) { firstWindowDrawn = true; // stop tracking - mAllowIconSplashScreen = false; + mSplashScreenStyleSolidColor = true; if (mStartingWindow != null) { ProtoLog.v(WM_DEBUG_STARTING_WINDOW, "Finish starting %s" @@ -6795,7 +6796,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A void onStartingWindowDrawn() { boolean wasTaskVisible = false; if (task != null) { - mAllowIconSplashScreen = false; + mSplashScreenStyleSolidColor = true; wasTaskVisible = !setTaskHasBeenVisible(); } @@ -7320,32 +7321,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A } /** - * Checks whether an icon splash screen can be used in the starting window based on the - * preference in the {@code options} and this activity's theme, giving higher priority to the - * {@code options}'s preference. - * - * When no preference is specified, a default behaviour is defined: - * - if the activity is started from the home or shell app, an icon can be used - * - if the activity is started from SystemUI, an icon should not be used - * - if there is a launching activity, use its preference - * - if none of the above is met, only use an icon when the activity is started for the first - * time from a System app - * - * The returned value is sent to WmShell, which will make the final decision on what splash - * screen type will be used. - * - * @return true if an icon can be used in the splash screen - * false when an icon should not be used in the splash screen + * @return true if a solid color splash screen must be used + * false when an icon splash screen can be used, but the final decision for whether to + * use an icon or solid color splash screen will be made by WmShell. */ - private boolean canUseIconSplashScreen(ActivityRecord sourceRecord, + private boolean shouldUseSolidColorSplashScreen(ActivityRecord sourceRecord, boolean startActivity, ActivityOptions options, int resolvedTheme) { if (sourceRecord == null && !startActivity) { - // Shouldn't use an icon if this activity is not top activity. This could happen when - // adding a splash screen window to the warm start activity which is re-create because - // top is finishing. + // Use simple style if this activity is not top activity. This could happen when adding + // a splash screen window to the warm start activity which is re-create because top is + // finishing. final ActivityRecord above = task.getActivityAbove(this); if (above != null) { - return false; + return true; } } @@ -7353,33 +7341,32 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int optionsStyle = options != null ? options.getSplashScreenStyle() : SplashScreen.SPLASH_SCREEN_STYLE_UNDEFINED; if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR) { - return false; + return true; } else if (optionsStyle == SplashScreen.SPLASH_SCREEN_STYLE_ICON || isIconStylePreferred(resolvedTheme)) { - return true; + return false; } // Choose the default behavior when neither the ActivityRecord nor the activity theme have // specified a splash screen style. if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_HOME || launchedFromUid == Process.SHELL_UID) { - return true; - } else if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI) { return false; + } else if (mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEMUI) { + return true; } else { - // Need to check sourceRecord in case this activity is launched from a service or a - // trampoline activity. + // Need to check sourceRecord in case this activity is launched from a service. if (sourceRecord == null) { sourceRecord = searchCandidateLaunchingActivity(); } if (sourceRecord != null) { - return sourceRecord.mAllowIconSplashScreen; + return sourceRecord.mSplashScreenStyleSolidColor; } // Use an icon if the activity was launched from System for the first start. - // Otherwise, can't use an icon splash screen. - return mLaunchSourceType == LAUNCH_SOURCE_TYPE_SYSTEM && startActivity; + // Otherwise, must use solid color splash screen. + return mLaunchSourceType != LAUNCH_SOURCE_TYPE_SYSTEM || !startActivity; } } @@ -7443,7 +7430,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final int resolvedTheme = evaluateStartingWindowTheme(prev, packageName, theme, splashScreenTheme); - mAllowIconSplashScreen = canUseIconSplashScreen(sourceRecord, startActivity, + mSplashScreenStyleSolidColor = shouldUseSolidColorSplashScreen(sourceRecord, startActivity, startOptions, resolvedTheme); final boolean activityCreated = @@ -7455,7 +7442,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A final boolean scheduled = addStartingWindow(packageName, resolvedTheme, prev, newTask || newSingleActivity, taskSwitch, processRunning, - allowTaskSnapshot(), activityCreated, mAllowIconSplashScreen, allDrawn); + allowTaskSnapshot(), activityCreated, mSplashScreenStyleSolidColor, allDrawn); if (DEBUG_STARTING_WINDOW_VERBOSE && scheduled) { Slog.d(TAG, "Scheduled starting window for " + this); } diff --git a/services/core/java/com/android/server/wm/StartingSurfaceController.java b/services/core/java/com/android/server/wm/StartingSurfaceController.java index a0517bebca6d..a55c232990cf 100644 --- a/services/core/java/com/android/server/wm/StartingSurfaceController.java +++ b/services/core/java/com/android/server/wm/StartingSurfaceController.java @@ -19,12 +19,12 @@ package com.android.server.wm; import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_CREATED; import static android.window.StartingWindowInfo.TYPE_PARAMETER_ACTIVITY_DRAWN; import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_HANDLE_SOLID_COLOR_SCREEN; -import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_ICON; import static android.window.StartingWindowInfo.TYPE_PARAMETER_ALLOW_TASK_SNAPSHOT; import static android.window.StartingWindowInfo.TYPE_PARAMETER_LEGACY_SPLASH_SCREEN; import static android.window.StartingWindowInfo.TYPE_PARAMETER_NEW_TASK; import static android.window.StartingWindowInfo.TYPE_PARAMETER_PROCESS_RUNNING; import static android.window.StartingWindowInfo.TYPE_PARAMETER_TASK_SWITCH; +import static android.window.StartingWindowInfo.TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN; import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_TYPE_SNAPSHOT; import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_TYPE_SPLASH_SCREEN; @@ -102,7 +102,7 @@ public class StartingSurfaceController { static int makeStartingWindowTypeParameter(boolean newTask, boolean taskSwitch, boolean processRunning, boolean allowTaskSnapshot, boolean activityCreated, - boolean allowIcon, boolean useLegacy, boolean activityDrawn, int startingWindowType, + boolean isSolidColor, boolean useLegacy, boolean activityDrawn, int startingWindowType, String packageName, int userId) { int parameter = 0; if (newTask) { @@ -120,8 +120,8 @@ public class StartingSurfaceController { if (activityCreated || startingWindowType == STARTING_WINDOW_TYPE_SNAPSHOT) { parameter |= TYPE_PARAMETER_ACTIVITY_CREATED; } - if (allowIcon) { - parameter |= TYPE_PARAMETER_ALLOW_ICON; + if (isSolidColor) { + parameter |= TYPE_PARAMETER_USE_SOLID_COLOR_SPLASH_SCREEN; } if (useLegacy) { parameter |= TYPE_PARAMETER_LEGACY_SPLASH_SCREEN; diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java index 41af9e31dbdd..1e6306cb4071 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java @@ -57,6 +57,7 @@ import android.companion.virtual.IVirtualDeviceSoundEffectListener; import android.companion.virtual.VirtualDeviceParams; import android.companion.virtual.audio.IAudioConfigChangedCallback; import android.companion.virtual.audio.IAudioRoutingCallback; +import android.companion.virtual.flags.Flags; import android.companion.virtual.sensor.IVirtualSensorCallback; import android.companion.virtual.sensor.VirtualSensor; import android.companion.virtual.sensor.VirtualSensorCallback; @@ -100,6 +101,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.WorkSource; import android.platform.test.annotations.Presubmit; +import android.platform.test.flag.junit.SetFlagsRule; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.ArraySet; @@ -211,6 +213,9 @@ public class VirtualDeviceManagerServiceTest { private static final String TEST_SITE = "http://test"; @Rule + public SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + @Rule public AdoptShellPermissionsRule mAdoptShellPermissionsRule = new AdoptShellPermissionsRule( InstrumentationRegistry.getInstrumentation().getUiAutomation(), Manifest.permission.CREATE_VIRTUAL_DEVICE); @@ -328,6 +333,11 @@ public class VirtualDeviceManagerServiceTest { LocalServices.removeServiceForTest(DisplayManagerInternal.class); LocalServices.addService(DisplayManagerInternal.class, mDisplayManagerInternalMock); + mSetFlagsRule.disableFlags(Flags.FLAG_VDM_PUBLIC_APIS); + mSetFlagsRule.disableFlags(Flags.FLAG_DYNAMIC_POLICY); + mSetFlagsRule.disableFlags(Flags.FLAG_STREAM_PERMISSIONS); + mSetFlagsRule.disableFlags(Flags.FLAG_VDM_CUSTOM_HOME); + doReturn(true).when(mInputManagerInternalMock).setVirtualMousePointerDisplayId(anyInt()); doNothing().when(mInputManagerInternalMock).setPointerAcceleration(anyFloat(), anyInt()); doNothing().when(mInputManagerInternalMock).setPointerIconVisible(anyBoolean(), anyInt()); @@ -1450,6 +1460,50 @@ public class VirtualDeviceManagerServiceTest { } @Test + public void openPermissionControllerOnVirtualDisplay_displayOnRemoteDevices_startsWhenFlagIsEnabled() { + mSetFlagsRule.enableFlags(Flags.FLAG_STREAM_PERMISSIONS); + addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); + GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( + DISPLAY_ID_1); + doNothing().when(mContext).startActivityAsUser(any(), any(), any()); + + ActivityInfo activityInfo = getActivityInfo( + PERMISSION_CONTROLLER_PACKAGE_NAME, + PERMISSION_CONTROLLER_PACKAGE_NAME, + /* displayOnRemoveDevices */ true, + /* targetDisplayCategory */ null); + Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + + verify(mContext, never()).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + } + + @Test + public void openPermissionControllerOnVirtualDisplay_dontDisplayOnRemoteDevices_startsWhenFlagIsEnabled() { + mSetFlagsRule.enableFlags(Flags.FLAG_STREAM_PERMISSIONS); + addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); + GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( + DISPLAY_ID_1); + doNothing().when(mContext).startActivityAsUser(any(), any(), any()); + + ActivityInfo activityInfo = getActivityInfo( + PERMISSION_CONTROLLER_PACKAGE_NAME, + PERMISSION_CONTROLLER_PACKAGE_NAME, + /* displayOnRemoveDevices */ false, + /* targetDisplayCategory */ null); + Intent blockedAppIntent = BlockedAppStreamingActivity.createIntent( + activityInfo, mAssociationInfo.getDisplayName()); + gwpc.canActivityBeLaunched(activityInfo, blockedAppIntent, + WindowConfiguration.WINDOWING_MODE_FULLSCREEN, DISPLAY_ID_1, /*isNewTask=*/false); + + verify(mContext).startActivityAsUser(argThat(intent -> + intent.filterEquals(blockedAppIntent)), any(), any()); + } + + @Test public void openSettingsOnVirtualDisplay_startBlockedAlertActivity() { addVirtualDisplay(mDeviceImpl, DISPLAY_ID_1); GenericWindowPolicyController gwpc = mDeviceImpl.getDisplayWindowPolicyControllerForTest( diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java index c65452aa2fa1..90d9452fb9c3 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceTest.java @@ -49,6 +49,7 @@ public class VirtualDeviceTest { private static final int VIRTUAL_DEVICE_ID = 42; private static final String PERSISTENT_ID = "persistentId"; private static final String DEVICE_NAME = "VirtualDeviceName"; + private static final String DISPLAY_NAME = "DisplayName"; @Mock private IVirtualDevice mVirtualDevice; @@ -87,7 +88,8 @@ public class VirtualDeviceTest { @Test public void parcelable_shouldRecreateSuccessfully() { VirtualDevice originalDevice = - new VirtualDevice(mVirtualDevice, VIRTUAL_DEVICE_ID, PERSISTENT_ID, DEVICE_NAME); + new VirtualDevice(mVirtualDevice, VIRTUAL_DEVICE_ID, PERSISTENT_ID, DEVICE_NAME, + DISPLAY_NAME); Parcel parcel = Parcel.obtain(); originalDevice.writeToParcel(parcel, 0); parcel.setDataPosition(0); @@ -96,6 +98,7 @@ public class VirtualDeviceTest { assertThat(device.getDeviceId()).isEqualTo(VIRTUAL_DEVICE_ID); assertThat(device.getPersistentDeviceId()).isEqualTo(PERSISTENT_ID); assertThat(device.getName()).isEqualTo(DEVICE_NAME); + assertThat(device.getDisplayName().toString()).isEqualTo(DISPLAY_NAME); } @RequiresFlagsEnabled(Flags.FLAG_VDM_PUBLIC_APIS) diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java index 1c48b8aa79f9..ef5270e8f003 100644 --- a/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/companion/virtual/audio/VirtualAudioControllerTest.java @@ -82,6 +82,7 @@ public class VirtualAudioControllerTest { /* activityPolicyExemptions= */ new ArraySet<>(), /* crossTaskNavigationAllowedByDefault= */ true, /* crossTaskNavigationExemptions= */ new ArraySet<>(), + /* permissionDialogComponent */ null, /* activityListener= */ null, /* pipBlockedCallback= */ null, /* activityBlockedCallback= */ null, 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 f65cb93258bc..40ac7b1ccdca 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -2855,14 +2855,14 @@ public class ActivityRecordTests extends WindowTestsBase { .setTask(sourceRecord.getTask()).build(); secondRecord.showStartingWindow(null /* prev */, true /* newTask */, false, true /* startActivity */, sourceRecord); - assertTrue(secondRecord.mAllowIconSplashScreen); + assertFalse(secondRecord.mSplashScreenStyleSolidColor); secondRecord.onStartingWindowDrawn(); final ActivityRecord finalRecord = new ActivityBuilder(mAtm) .setTask(sourceRecord.getTask()).build(); finalRecord.showStartingWindow(null /* prev */, true /* newTask */, false, true /* startActivity */, secondRecord); - assertFalse(finalRecord.mAllowIconSplashScreen); + assertTrue(finalRecord.mSplashScreenStyleSolidColor); } @Test |