diff options
29 files changed, 291 insertions, 132 deletions
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index 57f91ed3c0ae..c098fae11b8c 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -893,12 +893,15 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } return; } - ViewRootImpl viewRoot = getViewRootImpl(); - if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) { - if (DEBUG) { - Log.d(TAG, System.identityHashCode(this) - + " updateSurface: no valid surface"); - } + final ViewRootImpl viewRoot = getViewRootImpl(); + + if (viewRoot == null) { + return; + } + + if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) { + notifySurfaceDestroyed(); + releaseSurfaces(); return; } @@ -1109,28 +1112,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall final boolean surfaceChanged = creating; if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) { mSurfaceCreated = false; - if (mSurface.isValid()) { - if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " - + "visibleChanged -- surfaceDestroyed"); - callbacks = getSurfaceCallbacks(); - for (SurfaceHolder.Callback c : callbacks) { - c.surfaceDestroyed(mSurfaceHolder); - } - // Since Android N the same surface may be reused and given to us - // again by the system server at a later point. However - // as we didn't do this in previous releases, clients weren't - // necessarily required to clean up properly in - // surfaceDestroyed. This leads to problems for example when - // clients don't destroy their EGL context, and try - // and create a new one on the same surface following reuse. - // Since there is no valid use of the surface in-between - // surfaceDestroyed and surfaceCreated, we force a disconnect, - // so the next connect will always work if we end up reusing - // the surface. - if (mSurface.isValid()) { - mSurface.forceScopedDisconnect(); - } - } + notifySurfaceDestroyed(); } if (creating) { @@ -1786,6 +1768,31 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall } } + private void notifySurfaceDestroyed() { + if (mSurface.isValid()) { + if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " " + + "surfaceDestroyed"); + SurfaceHolder.Callback[] callbacks = getSurfaceCallbacks(); + for (SurfaceHolder.Callback c : callbacks) { + c.surfaceDestroyed(mSurfaceHolder); + } + // Since Android N the same surface may be reused and given to us + // again by the system server at a later point. However + // as we didn't do this in previous releases, clients weren't + // necessarily required to clean up properly in + // surfaceDestroyed. This leads to problems for example when + // clients don't destroy their EGL context, and try + // and create a new one on the same surface following reuse. + // Since there is no valid use of the surface in-between + // surfaceDestroyed and surfaceCreated, we force a disconnect, + // so the next connect will always work if we end up reusing + // the surface. + if (mSurface.isValid()) { + mSurface.forceScopedDisconnect(); + } + } + } + /** * Wrapper of accessibility embedded connection for embedded view hierarchy. */ diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 5af9b81ac032..0a1e3a0caeff 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -3100,7 +3100,7 @@ public class ChooserActivity extends ResolverActivity implements setVerticalScrollEnabled(false); } } else if (state == ViewPager.SCROLL_STATE_IDLE) { - if (mScrollStatus == SCROLL_STATUS_SCROLLING_VERTICAL) { + if (mScrollStatus == SCROLL_STATUS_SCROLLING_HORIZONTAL) { mScrollStatus = SCROLL_STATUS_IDLE; setVerticalScrollEnabled(true); } diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml index d20ab49a22e6..ab9426593535 100644 --- a/packages/CarSystemUI/res/values/colors.xml +++ b/packages/CarSystemUI/res/values/colors.xml @@ -15,7 +15,6 @@ ~ limitations under the License --> <resources xmlns:android="http://schemas.android.com/apk/res/android"> - <color name="nav_bar_ripple_background_color">#40ffffff</color> <!-- colors for user switcher --> <color name="car_user_switcher_background_color">#000000</color> <color name="car_user_switcher_name_text_color">@*android:color/car_body1_light</color> diff --git a/packages/CarSystemUI/res/values/styles.xml b/packages/CarSystemUI/res/values/styles.xml index 7fc69e6d5d8f..e76373d4a4f7 100644 --- a/packages/CarSystemUI/res/values/styles.xml +++ b/packages/CarSystemUI/res/values/styles.xml @@ -37,13 +37,9 @@ <item name="android:textColor">@*android:color/car_grey_50</item> </style> - <style name="CarNavigationBarButtonTheme"> - <item name="android:colorControlHighlight">@color/nav_bar_ripple_background_color</item> - </style> - <style name="NavigationBarButton"> <item name="android:layout_height">96dp</item> <item name="android:layout_width">96dp</item> - <item name="android:background">@*android:drawable/item_background_material</item> + <item name="android:background">?android:attr/selectableItemBackground</item> </style> </resources>
\ No newline at end of file diff --git a/packages/OsuLogin/Android.bp b/packages/OsuLogin/Android.bp index d7e36b164811..445c81b89273 100644 --- a/packages/OsuLogin/Android.bp +++ b/packages/OsuLogin/Android.bp @@ -1,5 +1,6 @@ android_app { name: "OsuLogin", + defaults: ["wifi-module-sdk-version-defaults"], static_libs: ["androidx.legacy_legacy-support-v4"], resource_dirs: ["res"], srcs: ["src/**/*.java"], diff --git a/packages/SystemUI/docs/broadcasts.md b/packages/SystemUI/docs/broadcasts.md index 6c8488b332c2..8ec20f5689ff 100644 --- a/packages/SystemUI/docs/broadcasts.md +++ b/packages/SystemUI/docs/broadcasts.md @@ -62,7 +62,7 @@ Acquire the dispatcher by using `@Inject` to obtain a `BroadcastDispatcher`. The * @param executor An executor to dispatch [BroadcastReceiver.onReceive]. Pass null to use an * executor in the main thread (default). * @param user A user handle to determine which broadcast should be dispatched to this receiver. - * By default, it is the current user. + * By default, it is the user of the context (system user in SystemUI). * @throws IllegalArgumentException if the filter has other constraints that are not actions or * categories or the filter has no actions. */ diff --git a/packages/SystemUI/res/layout/global_screenshot.xml b/packages/SystemUI/res/layout/global_screenshot.xml index 6a235218b32f..ef7325ea8f38 100644 --- a/packages/SystemUI/res/layout/global_screenshot.xml +++ b/packages/SystemUI/res/layout/global_screenshot.xml @@ -48,4 +48,18 @@ android:visibility="gone" android:pointerIcon="crosshair"/> <include layout="@layout/global_screenshot_static"/> + <FrameLayout + android:id="@+id/global_screenshot_dismiss_button" + android:layout_width="@dimen/screenshot_dismiss_button_tappable_size" + android:layout_height="@dimen/screenshot_dismiss_button_tappable_size" + android:elevation="7dp" + android:visibility="gone" + android:contentDescription="@string/screenshot_dismiss_ui_description"> + <ImageView + android:id="@+id/global_screenshot_dismiss_image" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_margin="@dimen/screenshot_dismiss_button_margin" + android:src="@drawable/screenshot_cancel"/> + </FrameLayout> </FrameLayout> diff --git a/packages/SystemUI/res/layout/global_screenshot_static.xml b/packages/SystemUI/res/layout/global_screenshot_static.xml index da5277ce3876..9ec2f20597e7 100644 --- a/packages/SystemUI/res/layout/global_screenshot_static.xml +++ b/packages/SystemUI/res/layout/global_screenshot_static.xml @@ -54,22 +54,4 @@ android:layout_height="wrap_content"/> </HorizontalScrollView> <include layout="@layout/global_screenshot_preview"/> - <FrameLayout - android:id="@+id/global_screenshot_dismiss_button" - android:layout_width="@dimen/screenshot_dismiss_button_tappable_size" - android:layout_height="@dimen/screenshot_dismiss_button_tappable_size" - android:elevation="7dp" - android:visibility="gone" - android:contentDescription="@string/screenshot_dismiss_ui_description" - app:layout_constraintStart_toEndOf="@+id/global_screenshot_preview" - app:layout_constraintEnd_toEndOf="@+id/global_screenshot_preview" - app:layout_constraintTop_toTopOf="@+id/global_screenshot_preview" - app:layout_constraintBottom_toTopOf="@+id/global_screenshot_preview"> - <ImageView - android:id="@+id/global_screenshot_dismiss_image" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_margin="@dimen/screenshot_dismiss_button_margin" - android:src="@drawable/screenshot_cancel"/> - </FrameLayout> </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml index 21a671cf9d5a..214c44a41c5c 100644 --- a/packages/SystemUI/res/layout/hybrid_conversation_notification.xml +++ b/packages/SystemUI/res/layout/hybrid_conversation_notification.xml @@ -20,24 +20,26 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical|start" + android:paddingTop="1dp" + android:paddingBottom="1dp" android:paddingEnd="12dp"> <FrameLayout android:layout_width="@*android:dimen/conversation_content_start" - android:layout_height="36dp" + android:layout_height="25dp" > <ImageView android:id="@*android:id/conversation_icon" - android:layout_width="24dp" - android:layout_height="24dp" + android:layout_width="20dp" + android:layout_height="20dp" android:layout_gravity="center" /> <ViewStub android:id="@*android:id/conversation_face_pile" android:layout="@*android:layout/conversation_face_pile_layout" - android:layout_width="36dp" - android:layout_height="36dp" + android:layout_width="25dp" + android:layout_height="25dp" android:layout_gravity="center" /> </FrameLayout> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index abc560bed595..44d3b02f0db7 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -631,10 +631,10 @@ <dimen name="notification_section_divider_height">@dimen/notification_side_paddings</dimen> <!-- Size of the face pile shown on one-line (children of a group) conversation notifications --> - <dimen name="conversation_single_line_face_pile_size">36dp</dimen> + <dimen name="conversation_single_line_face_pile_size">25dp</dimen> <!-- Size of an avatar shown on one-line (children of a group) conversation notifications --> - <dimen name="conversation_single_line_avatar_size">24dp</dimen> + <dimen name="conversation_single_line_avatar_size">20dp</dimen> <!-- Border width for avatars in the face pile shown on one-line (children of a group) conversation notifications --> <dimen name="conversation_single_line_face_pile_protection_width">1dp</dimen> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index ee31706c0b94..34c85877577b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -1903,6 +1903,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private boolean shouldListenForFingerprint() { final boolean allowedOnBouncer = !(mFingerprintLockedOut && mBouncer && mCredentialAttempted); + final int user = getCurrentUser(); + final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user); + final boolean isLockDown = + containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) + || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + final boolean isEncrypted = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT); // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware. @@ -1911,7 +1917,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming)) && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser()) && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser - && allowedOnBouncer; + && allowedOnBouncer && !isLockDown && !isEncrypted; return shouldListen; } @@ -1928,9 +1934,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab final boolean isLockDown = containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); - final boolean isEncryptedOrTimedOut = - containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT) - || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT); + final boolean isEncrypted = + containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT); + final boolean isTimedOut = + containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT); boolean canBypass = mKeyguardBypassController != null && mKeyguardBypassController.canBypass(); @@ -1939,10 +1946,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab // TrustAgents or biometrics are keeping the device unlocked. boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass; - // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing. + // Scan even when timeout to show a preemptive bouncer when bypassing. // Lock-down mode shouldn't scan, since it is more explicit. - boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer) - && !isLockDown; + boolean strongAuthAllowsScanning = (!isTimedOut || canBypass && !mBouncer); // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware. @@ -1952,7 +1958,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed && strongAuthAllowsScanning && mIsPrimaryUser - && !mSecureCameraLaunched; + && !mSecureCameraLaunched && !isLockDown && !isEncrypted; // Aggregate relevant fields for debug logging. if (DEBUG_FACE || DEBUG_SPEW) { diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt index d61de0623fe8..67c0c620f136 100644 --- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt +++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt @@ -16,8 +16,10 @@ package com.android.systemui.broadcast +import android.app.ActivityManager import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent import android.content.IntentFilter import android.os.Handler import android.os.HandlerExecutor @@ -29,14 +31,10 @@ import android.util.SparseArray import com.android.internal.annotations.VisibleForTesting import com.android.systemui.Dumpable import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger -import com.android.systemui.dagger.qualifiers.Background -import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import java.io.FileDescriptor import java.io.PrintWriter import java.util.concurrent.Executor -import javax.inject.Inject -import javax.inject.Singleton data class ReceiverData( val receiver: BroadcastReceiver, @@ -48,6 +46,8 @@ data class ReceiverData( private const val MSG_ADD_RECEIVER = 0 private const val MSG_REMOVE_RECEIVER = 1 private const val MSG_REMOVE_RECEIVER_FOR_USER = 2 +private const val MSG_USER_SWITCH = 3 +private const val MSG_SET_STARTING_USER = 99 private const val TAG = "BroadcastDispatcher" private const val DEBUG = true @@ -62,21 +62,27 @@ private const val DEBUG = true * permissions, schemes, data types, data authorities or priority different than 0. * Cannot be used for getting sticky broadcasts (either as return of registering or as re-delivery). */ -@Singleton -open class BroadcastDispatcher @Inject constructor ( +open class BroadcastDispatcher constructor ( private val context: Context, - @Main private val mainHandler: Handler, - @Background private val bgLooper: Looper, - dumpManager: DumpManager, + private val bgLooper: Looper, + private val dumpManager: DumpManager, private val logger: BroadcastDispatcherLogger -) : Dumpable { +) : Dumpable, BroadcastReceiver() { // Only modify in BG thread private val receiversByUser = SparseArray<UserBroadcastDispatcher>(20) - init { - // TODO: Don't do this in the constructor + fun initialize() { dumpManager.registerDumpable(javaClass.name, this) + handler.sendEmptyMessage(MSG_SET_STARTING_USER) + registerReceiver(this, IntentFilter(Intent.ACTION_USER_SWITCHED), null, UserHandle.ALL) + } + + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == Intent.ACTION_USER_SWITCHED) { + val user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL) + handler.obtainMessage(MSG_USER_SWITCH, user, 0).sendToTarget() + } } /** @@ -88,7 +94,7 @@ open class BroadcastDispatcher @Inject constructor ( * have at least one action. * @param handler A handler to dispatch [BroadcastReceiver.onReceive]. * @param user A user handle to determine which broadcast should be dispatched to this receiver. - * By default, it is the current user. + * By default, it is the user of the context (system user in SystemUI). * @throws IllegalArgumentException if the filter has other constraints that are not actions or * categories or the filter has no actions. */ @@ -114,7 +120,7 @@ open class BroadcastDispatcher @Inject constructor ( * @param executor An executor to dispatch [BroadcastReceiver.onReceive]. Pass null to use an * executor in the main thread (default). * @param user A user handle to determine which broadcast should be dispatched to this receiver. - * By default, it is the current user. + * By default, it is the user of the context (system user in SystemUI). * @throws IllegalArgumentException if the filter has other constraints that are not actions or * categories or the filter has no actions. */ @@ -171,6 +177,7 @@ open class BroadcastDispatcher @Inject constructor ( override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) { pw.println("Broadcast dispatcher:") + pw.println(" Current user: ${handler.currentUser}") for (index in 0 until receiversByUser.size()) { pw.println(" User ${receiversByUser.keyAt(index)}") receiversByUser.valueAt(index).dump(fd, pw, args) @@ -178,6 +185,8 @@ open class BroadcastDispatcher @Inject constructor ( } private val handler = object : Handler(bgLooper) { + var currentUser = UserHandle.USER_SYSTEM + override fun handleMessage(msg: Message) { when (msg.what) { MSG_ADD_RECEIVER -> { @@ -185,7 +194,7 @@ open class BroadcastDispatcher @Inject constructor ( // If the receiver asked to be registered under the current user, we register // under the actual current user. val userId = if (data.user.identifier == UserHandle.USER_CURRENT) { - context.userId + currentUser } else { data.user.identifier } @@ -208,6 +217,13 @@ open class BroadcastDispatcher @Inject constructor ( receiversByUser.get(msg.arg1)?.unregisterReceiver(msg.obj as BroadcastReceiver) } + MSG_USER_SWITCH -> { + currentUser = msg.arg1 + } + MSG_SET_STARTING_USER -> { + currentUser = ActivityManager.getCurrentUser() + } + else -> super.handleMessage(msg) } } diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java index 163f7819750e..c4c5da42ec06 100644 --- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java +++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java @@ -913,7 +913,7 @@ public class BubbleController implements ConfigurationController.ConfigurationLi mLogger.log(bubble, BubbleLogger.Event.BUBBLE_OVERFLOW_REMOVE_BACK_TO_STACK); bubble.setInflateSynchronously(mInflateSynchronously); bubble.setShouldAutoExpand(true); - bubble.markUpdatedAt(System.currentTimeMillis()); + bubble.markAsAccessedAt(System.currentTimeMillis()); setIsBubble(bubble, true /* isBubble */); } diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java index 8368b2c1ae86..1f30305ab169 100644 --- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java +++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java @@ -25,6 +25,7 @@ import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.NightDisplayListener; import android.os.Handler; import android.os.HandlerThread; +import android.os.Looper; import android.os.ServiceManager; import android.util.DisplayMetrics; import android.view.Choreographer; @@ -39,9 +40,12 @@ import com.android.internal.util.NotificationMessagingUtil; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.Prefs; +import com.android.systemui.broadcast.BroadcastDispatcher; +import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger; import com.android.systemui.dagger.qualifiers.Background; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.AlwaysOnDisplayPolicy; +import com.android.systemui.dump.DumpManager; import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.plugins.PluginInitializerImpl; import com.android.systemui.shared.plugins.PluginManager; @@ -178,6 +182,21 @@ public class DependencyProvider { return ActivityManagerWrapper.getInstance(); } + /** Provides and initializes the {#link BroadcastDispatcher} for SystemUI */ + @Singleton + @Provides + public BroadcastDispatcher providesBroadcastDispatcher( + Context context, + @Background Looper backgroundLooper, + DumpManager dumpManager, + BroadcastDispatcherLogger logger + ) { + BroadcastDispatcher bD = + new BroadcastDispatcher(context, backgroundLooper, dumpManager, logger); + bD.initialize(); + return bD; + } + @Singleton @Provides public DevicePolicyManagerWrapper provideDevicePolicyManagerWrapper() { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index b26dc5f91245..53251ed4362d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -654,7 +654,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { @Override public void onBouncerVisiblityChanged(boolean shown) { synchronized (KeyguardViewMediator.this) { - adjustStatusBarLocked(shown); + adjustStatusBarLocked(shown, false); } } @@ -2003,10 +2003,12 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { } private void adjustStatusBarLocked() { - adjustStatusBarLocked(false /* forceHideHomeRecentsButtons */); + adjustStatusBarLocked(false /* forceHideHomeRecentsButtons */, + false /* forceClearFlags */); } - private void adjustStatusBarLocked(boolean forceHideHomeRecentsButtons) { + private void adjustStatusBarLocked(boolean forceHideHomeRecentsButtons, + boolean forceClearFlags) { if (mStatusBarManager == null) { mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE); @@ -2018,6 +2020,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { // Disable aspects of the system/status/navigation bars that must not be re-enabled by // windows that appear on top, ever int flags = StatusBarManager.DISABLE_NONE; + + // TODO (b/155663717) After restart, status bar will not properly hide home button + // unless disable is called to show un-hide it once first + if (forceClearFlags) { + mStatusBarManager.disable(flags); + } + if (forceHideHomeRecentsButtons || isShowingAndNotOccluded()) { if (!mShowHomeOverLockscreen || !mInGestureNavigationMode) { flags |= StatusBarManager.DISABLE_HOME; @@ -2141,6 +2150,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable { public void onBootCompleted() { synchronized (this) { mBootCompleted = true; + adjustStatusBarLocked(false, true); if (mBootSendUserPresent) { sendUserPresentBroadcast(); } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index d0ddf501dca4..7babe2f4f2db 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -173,6 +173,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset private static final long SCREENSHOT_FLASH_IN_DURATION_MS = 133; private static final long SCREENSHOT_FLASH_OUT_DURATION_MS = 217; + // delay before starting to fade in dismiss button + private static final long SCREENSHOT_TO_CORNER_DISMISS_DELAY_MS = 200; private static final long SCREENSHOT_TO_CORNER_X_DURATION_MS = 234; private static final long SCREENSHOT_TO_CORNER_Y_DURATION_MS = 500; private static final long SCREENSHOT_TO_CORNER_SCALE_DURATION_MS = 234; @@ -772,6 +774,9 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset mScreenshotAnimatedView.setScaleX(currentScale); mScreenshotAnimatedView.setScaleY(currentScale); + mDismissButton.setAlpha(0); + mDismissButton.setVisibility(View.VISIBLE); + AnimatorSet dropInAnimation = new AnimatorSet(); ValueAnimator flashInAnimator = ValueAnimator.ofFloat(0, 1); flashInAnimator.setDuration(SCREENSHOT_FLASH_IN_DURATION_MS); @@ -793,6 +798,8 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset toCorner.setDuration(SCREENSHOT_TO_CORNER_Y_DURATION_MS); float xPositionPct = SCREENSHOT_TO_CORNER_X_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; + float dismissPct = + SCREENSHOT_TO_CORNER_DISMISS_DELAY_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; float scalePct = SCREENSHOT_TO_CORNER_SCALE_DURATION_MS / (float) SCREENSHOT_TO_CORNER_Y_DURATION_MS; toCorner.addUpdateListener(animation -> { @@ -820,6 +827,19 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset float yCenter = MathUtils.lerp( startPos.y, finalPos.y, mFastOutSlowIn.getInterpolation(t)); mScreenshotAnimatedView.setY(yCenter - bounds.height() * currentScaleY / 2f); + + if (t >= dismissPct) { + mDismissButton.setAlpha((t - dismissPct) / (1 - dismissPct)); + float currentX = mScreenshotAnimatedView.getX(); + float currentY = mScreenshotAnimatedView.getY(); + mDismissButton.setY(currentY - mDismissButton.getHeight() / 2f); + if (mDirectionLTR) { + mDismissButton.setX(currentX + + bounds.width() * currentScaleX - mDismissButton.getWidth() / 2f); + } else { + mDismissButton.setX(currentX - mDismissButton.getWidth() / 2f); + } + } }); toCorner.addListener(new AnimatorListenerAdapter() { @@ -844,13 +864,20 @@ public class GlobalScreenshot implements ViewTreeObserver.OnComputeInternalInset @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); + mDismissButton.setAlpha(1); + float dismissOffset = mDismissButton.getWidth() / 2f; + float finalDismissX = mDirectionLTR + ? finalPos.x - dismissOffset + bounds.width() * cornerScale / 2f + : finalPos.x - dismissOffset - bounds.width() * cornerScale / 2f; + mDismissButton.setX(finalDismissX); + mDismissButton.setY( + finalPos.y - dismissOffset - bounds.height() * cornerScale / 2f); mScreenshotAnimatedView.setScaleX(1); mScreenshotAnimatedView.setScaleY(1); mScreenshotAnimatedView.setX(finalPos.x - bounds.width() * cornerScale / 2f); mScreenshotAnimatedView.setY(finalPos.y - bounds.height() * cornerScale / 2f); mScreenshotAnimatedView.setVisibility(View.GONE); mScreenshotPreview.setVisibility(View.VISIBLE); - mDismissButton.setVisibility(View.VISIBLE); mScreenshotLayout.forceLayout(); } }); diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java index 7bc453ac9aa1..023879926563 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java @@ -452,12 +452,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { } @Test - public void requiresAuthentication_whenEncryptedKeyguard_andBypass() { - testStrongAuthExceptOnBouncer( - KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT); - } - - @Test public void requiresAuthentication_whenTimeoutKeyguard_andBypass() { testStrongAuthExceptOnBouncer( KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT); @@ -513,10 +507,20 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase { @Test public void testIgnoresAuth_whenLockdown() { + testIgnoresAuth( + KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + } + + @Test + public void testIgnoresAuth_whenEncrypted() { + testIgnoresAuth( + KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT); + } + + private void testIgnoresAuth(int strongAuth) { mKeyguardUpdateMonitor.dispatchStartedWakingUp(); mTestableLooper.processAllMessages(); - when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn( - KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN); + when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth); mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true); verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt()); diff --git a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java index aa3f91a22208..713aef9e8a91 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java +++ b/packages/SystemUI/tests/src/com/android/systemui/SysuiTestCase.java @@ -73,8 +73,8 @@ public abstract class SysuiTestCase { public void SysuiSetup() throws Exception { SystemUIFactory.createFromConfig(mContext); mDependency = new TestableDependency(mContext); - mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Handler.class), - mock(Looper.class), mock(DumpManager.class), mock(BroadcastDispatcherLogger.class)); + mFakeBroadcastDispatcher = new FakeBroadcastDispatcher(mContext, mock(Looper.class), + mock(DumpManager.class), mock(BroadcastDispatcherLogger.class)); mRealInstrumentation = InstrumentationRegistry.getInstrumentation(); Instrumentation inst = spy(mRealInstrumentation); diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt index 86ddb209f321..4ed284ede634 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt @@ -18,6 +18,7 @@ package com.android.systemui.broadcast import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent import android.content.IntentFilter import android.os.Handler import android.os.Looper @@ -96,7 +97,6 @@ class BroadcastDispatcherTest : SysuiTestCase() { broadcastDispatcher = TestBroadcastDispatcher( mockContext, - Handler(testableLooper.looper), testableLooper.looper, mock(DumpManager::class.java), logger, @@ -177,7 +177,12 @@ class BroadcastDispatcherTest : SysuiTestCase() { @Test fun testRegisterCurrentAsActualUser() { - setUserMock(mockContext, user1) + val intent = Intent(Intent.ACTION_USER_SWITCHED).apply { + putExtra(Intent.EXTRA_USER_HANDLE, user1.identifier) + } + broadcastDispatcher.onReceive(mockContext, intent) + testableLooper.processAllMessages() + broadcastDispatcher.registerReceiverWithHandler(broadcastReceiver, intentFilter, mockHandler, UserHandle.CURRENT) @@ -240,12 +245,11 @@ class BroadcastDispatcherTest : SysuiTestCase() { private class TestBroadcastDispatcher( context: Context, - mainHandler: Handler, bgLooper: Looper, dumpManager: DumpManager, logger: BroadcastDispatcherLogger, var mockUBRMap: Map<Int, UserBroadcastDispatcher> - ) : BroadcastDispatcher(context, mainHandler, bgLooper, dumpManager, logger) { + ) : BroadcastDispatcher(context, bgLooper, dumpManager, logger) { override fun createUBRForUser(userId: Int): UserBroadcastDispatcher { return mockUBRMap.getOrDefault(userId, mock(UserBroadcastDispatcher::class.java)) } diff --git a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt index 6e982e26b8cb..09a091689a23 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt @@ -30,11 +30,10 @@ import java.util.concurrent.Executor class FakeBroadcastDispatcher( context: SysuiTestableContext, - handler: Handler, looper: Looper, dumpManager: DumpManager, logger: BroadcastDispatcherLogger -) : BroadcastDispatcher(context, handler, looper, dumpManager, logger) { +) : BroadcastDispatcher(context, looper, dumpManager, logger) { private val registeredReceivers = ArraySet<BroadcastReceiver>() diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java index e1f9a7a150d8..ef81d7159c42 100644 --- a/services/core/java/com/android/server/adb/AdbService.java +++ b/services/core/java/com/android/server/adb/AdbService.java @@ -241,12 +241,7 @@ public class AdbService extends IAdbManager.Stub { private AdbService(Context context) { mContext = context; mContentResolver = context.getContentResolver(); - - boolean secureAdbEnabled = AdbProperties.secure().orElse(false); - boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt")); - if (secureAdbEnabled && !dataEncrypted) { - mDebuggingManager = new AdbDebuggingManager(context); - } + mDebuggingManager = new AdbDebuggingManager(context); initAdbState(); LocalServices.addService(AdbManagerInternal.class, new AdbManagerInternalImpl()); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 026f147e955c..079512275797 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1671,6 +1671,12 @@ public class ActivityManagerService extends IActivityManager.Stub */ @Nullable ContentCaptureManagerInternal mContentCaptureService; + /** + * Set of {@link ProcessRecord} that have either {@link ProcessRecord#hasTopUi()} or + * {@link ProcessRecord#runningRemoteAnimation} set to {@code true}. + */ + final ArraySet<ProcessRecord> mTopUiOrRunningRemoteAnimApps = new ArraySet<>(); + final class UiHandler extends Handler { public UiHandler() { super(com.android.server.UiThread.get().getLooper(), null, true); @@ -14702,6 +14708,7 @@ public class ActivityManagerService extends IActivityManager.Stub mProcessesToGc.remove(app); mPendingPssProcesses.remove(app); + mTopUiOrRunningRemoteAnimApps.remove(app); ProcessList.abortNextPssTime(app.procStateMemTracker); // Dismiss any open dialogs. @@ -18490,6 +18497,22 @@ public class ActivityManagerService extends IActivityManager.Stub return proc; } + /** + * @return {@code true} if {@link #mTopUiOrRunningRemoteAnimApps} set contains {@code app} or when there are no apps + * in this list, an false otherwise. + */ + boolean containsTopUiOrRunningRemoteAnimOrEmptyLocked(ProcessRecord app) { + return mTopUiOrRunningRemoteAnimApps.isEmpty() || mTopUiOrRunningRemoteAnimApps.contains(app); + } + + void addTopUiOrRunningRemoteAnim(ProcessRecord app) { + mTopUiOrRunningRemoteAnimApps.add(app); + } + + void removeTopUiOrRunningRemoteAnim(ProcessRecord app) { + mTopUiOrRunningRemoteAnimApps.remove(app); + } + @Override public boolean dumpHeap(String process, int userId, boolean managed, boolean mallocInfo, boolean runGc, String path, ParcelFileDescriptor fd, RemoteCallback finishCallback) { diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index da5f48962130..58b0a157e2c2 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1151,8 +1151,17 @@ public final class OomAdjuster { // is currently showing UI. app.systemNoUi = true; if (app == topApp) { + // If specific system app has set ProcessRecord.mHasTopUi or is running a remote + // animation (ProcessRecord.runningRemoteAnimation), this will prevent topApp + // to use SCHED_GROUP_TOP_APP to ensure process with mHasTopUi will have exclusive + // access to configured cores. + if (mService.containsTopUiOrRunningRemoteAnimOrEmptyLocked(app)) { + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); + } else { + app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); + } app.systemNoUi = false; - app.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_TOP_APP); + app.adjType = "pers-top-activity"; } else if (app.hasTopUi()) { // sched group/proc state adjustment is below @@ -1193,10 +1202,20 @@ public final class OomAdjuster { boolean foregroundActivities = false; if (PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP && app == topApp) { - // The last app on the list is the foreground app. - adj = ProcessList.FOREGROUND_APP_ADJ; - schedGroup = ProcessList.SCHED_GROUP_TOP_APP; - app.adjType = "top-activity"; + + // If specific system app has set ProcessRecord.mHasTopUi or is running a remote + // animation (ProcessRecord.runningRemoteAnimation), this will prevent topApp + // to use SCHED_GROUP_TOP_APP to ensure process with mHasTopUi will have exclusive + // access to configured cores. + if (mService.containsTopUiOrRunningRemoteAnimOrEmptyLocked(app)) { + adj = ProcessList.FOREGROUND_APP_ADJ; + schedGroup = ProcessList.SCHED_GROUP_TOP_APP; + app.adjType = "top-activity"; + } else { + adj = ProcessList.FOREGROUND_APP_ADJ; + schedGroup = ProcessList.SCHED_GROUP_DEFAULT; + app.adjType = "top-activity-behind-topui"; + } foregroundActivities = true; procState = PROCESS_STATE_CUR_TOP; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index c5152c081e70..4c75ab21d6f2 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -1268,6 +1268,7 @@ class ProcessRecord implements WindowProcessListener { void setHasTopUi(boolean hasTopUi) { mHasTopUi = hasTopUi; mWindowProcessController.setHasTopUi(hasTopUi); + updateTopUiOrRunningRemoteAnim(); } boolean hasTopUi() { @@ -1518,10 +1519,19 @@ class ProcessRecord implements WindowProcessListener { Slog.i(TAG, "Setting runningRemoteAnimation=" + runningRemoteAnimation + " for pid=" + pid); } + updateTopUiOrRunningRemoteAnim(); mService.updateOomAdjLocked(this, true, OomAdjuster.OOM_ADJ_REASON_UI_VISIBILITY); } } + void updateTopUiOrRunningRemoteAnim() { + if (runningRemoteAnimation || hasTopUi()) { + mService.addTopUiOrRunningRemoteAnim(this); + } else { + mService.removeTopUiOrRunningRemoteAnim(this); + } + } + public long getInputDispatchingTimeout() { return mWindowProcessController.getInputDispatchingTimeout(); } diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index a498e3867c05..65a13016c9b6 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -2352,6 +2352,16 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mImeTargetWindowMap.put(startInputToken, mCurFocusedWindow); mStartInputHistory.addEntry(info); + // Seems that PackageManagerInternal#grantImplicitAccess() doesn't handle cross-user + // implicit visibility (e.g. IME[user=10] -> App[user=0]) thus we do this only for the + // same-user scenarios. + // That said ignoring cross-user scenario will never affect IMEs that do not have + // INTERACT_ACROSS_USERS(_FULL) permissions, which is actually almost always the case. + if (mSettings.getCurrentUserId() == UserHandle.getUserId(mCurClient.uid)) { + mPackageManagerInternal.grantImplicitAccess(mSettings.getCurrentUserId(), + null /* intent */, UserHandle.getAppId(mCurMethodUid), mCurClient.uid, true); + } + final SessionState session = mCurClient.curSession; executeOrSendMessage(session.method, mCaller.obtainMessageIIOOOO( MSG_START_INPUT, mCurInputContextMissingMethods, initial ? 0 : 1 /* restarting */, diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java index 7c89b9850c5d..492b84a0a84b 100644 --- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java +++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java @@ -363,7 +363,8 @@ class UserSystemPackageInstaller { pmInt.forEachPackage(pkg -> { if (!pkg.isSystem()) return; final String pkgName = pkg.getManifestPackageName(); - if (!allWhitelistedPackages.contains(pkgName)) { + if (!allWhitelistedPackages.contains(pkgName) + && !isAutoGeneratedRRO(pmInt.getPackage(pkgName))) { errors.add(String.format(logMessageFmt, pkgName)); } }); diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java index bfdb9d291f28..7fe21e32cbaf 100644 --- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java +++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java @@ -209,14 +209,6 @@ public class StatsPullAtomService extends SystemService { // Random seed stable for StatsPullAtomService life cycle - can be used for stable sampling private static final int RANDOM_SEED = new Random().nextInt(); - /** - * Lowest available uid for apps. - * - * <p>Used to quickly discard memory snapshots of the zygote forks from native process - * measurements. - */ - private static final int MIN_APP_UID = 10_000; - private static final int DIMENSION_KEY_SIZE_HARD_LIMIT = 800; private static final int DIMENSION_KEY_SIZE_SOFT_LIMIT = 500; private static final long APP_OPS_SAMPLING_INITIALIZATION_DELAY_MILLIS = 45000; @@ -1819,10 +1811,6 @@ public class StatsPullAtomService extends SystemService { return StatsManager.PULL_SUCCESS; } - private static boolean isAppUid(int uid) { - return uid >= MIN_APP_UID; - } - private void registerProcessMemoryHighWaterMark() { int tagId = FrameworkStatsLog.PROCESS_MEMORY_HIGH_WATER_MARK; mStatsManager.setPullAtomCallback( @@ -1859,7 +1847,7 @@ public class StatsPullAtomService extends SystemService { int size = processCmdlines.size(); for (int i = 0; i < size; ++i) { final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(processCmdlines.keyAt(i)); - if (snapshot == null || isAppUid(snapshot.uid)) { + if (snapshot == null) { continue; } StatsEvent e = StatsEvent.newBuilder() @@ -1920,7 +1908,7 @@ public class StatsPullAtomService extends SystemService { for (int i = 0; i < size; ++i) { int pid = processCmdlines.keyAt(i); final MemorySnapshot snapshot = readMemorySnapshotFromProcfs(pid); - if (snapshot == null || isAppUid(snapshot.uid)) { + if (snapshot == null) { continue; } StatsEvent e = StatsEvent.newBuilder() diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index fde40aa77a0e..cdafd32cbbb5 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -63,6 +63,7 @@ import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.AdditionalAnswers.answer; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyLong; @@ -170,6 +171,7 @@ public class MockingOomAdjusterTests { mock(OomAdjProfiler.class)); doReturn(new ActivityManagerService.ProcessChangeItem()).when(sService) .enqueueProcessChangeItemLocked(anyInt(), anyInt()); + doReturn(true).when(sService).containsTopUiOrRunningRemoteAnimOrEmptyLocked(any()); sService.mOomAdjuster = new OomAdjuster(sService, sService.mProcessList, mock(ActiveUids.class)); sService.mOomAdjuster.mAdjSeq = 10000; @@ -266,6 +268,21 @@ public class MockingOomAdjusterTests { @SuppressWarnings("GuardedBy") @Test + public void testUpdateOomAdj_DoOne_TopApp_PreemptedByTopUi() { + ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, + MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); + doReturn(PROCESS_STATE_TOP).when(sService.mAtmInternal).getTopProcessState(); + doReturn(app).when(sService).getTopAppLocked(); + doReturn(false).when(sService).containsTopUiOrRunningRemoteAnimOrEmptyLocked(eq(app)); + sService.mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE; + sService.mOomAdjuster.updateOomAdjLocked(app, false, OomAdjuster.OOM_ADJ_REASON_NONE); + doReturn(null).when(sService).getTopAppLocked(); + + assertProcStates(app, PROCESS_STATE_TOP, FOREGROUND_APP_ADJ, SCHED_GROUP_DEFAULT); + } + + @SuppressWarnings("GuardedBy") + @Test public void testUpdateOomAdj_DoOne_RunningInstrumentation() { ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); diff --git a/wifi/Android.bp b/wifi/Android.bp index 9c5b7b66f2a3..941ff61b3ba5 100644 --- a/wifi/Android.bp +++ b/wifi/Android.bp @@ -12,6 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +java_defaults { + name: "wifi-module-sdk-version-defaults", + min_sdk_version: "30", + target_sdk_version: "30", +} + filegroup { name: "framework-wifi-updatable-exported-aidl-sources", srcs: ["aidl-export/**/*.aidl"], @@ -73,6 +79,7 @@ test_access_hidden_api_whitelist = [ // classes before they are renamed. java_library { name: "framework-wifi-pre-jarjar", + defaults: ["wifi-module-sdk-version-defaults"], sdk_version: "module_current", static_libs: [ "framework-wifi-util-lib", @@ -98,7 +105,10 @@ java_library { // post-jarjar version of framework-wifi java_sdk_library { name: "framework-wifi", - defaults: ["framework-module-defaults"], + defaults: [ + "framework-module-defaults", + "wifi-module-sdk-version-defaults", + ], static_libs: [ "framework-wifi-util-lib", "android.hardware.wifi-V1.0-java-constants", |