From bcb4d3cf638599da7749c0e96195130313848a6f Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 2 Feb 2021 18:57:19 +0000 Subject: [PATCH 001/176] Revert "Make keyguard exit animation to remote animation." Revert "Make keyguard exit animation to remote animation." Revert submission 13354553-KeyguardRemoteAnimation Reason for revert: Bug: 179122467 Reverted Changes: I7a70add76:Make keyguard exit animation to remote animation. I1cd6a86c2:Make keyguard exit animation to remote animation. I1cd6a86c2:Make keyguard exit animation to remote animation. Change-Id: I3009b203c46fbf7f7d46fd66570680f266e3c064 (cherry picked from commit 7321b45093e1f8eee9ca799df185af6fe0dcbbb5) --- .../android/view/IRemoteAnimationRunner.aidl | 6 +- .../system/RemoteAnimationAdapterCompat.java | 20 +-- .../system/RemoteAnimationRunnerCompat.java | 7 +- .../systemui/keyguard/KeyguardService.java | 92 ------------- .../keyguard/KeyguardViewMediator.java | 128 +----------------- .../notification/ActivityLaunchAnimator.java | 5 +- .../server/policy/PhoneWindowManager.java | 6 +- .../server/policy/WindowManagerPolicy.java | 2 +- .../keyguard/KeyguardServiceDelegate.java | 3 +- .../com/android/server/wm/AppTransition.java | 9 +- .../server/wm/AppTransitionController.java | 11 +- .../server/wm/RemoteAnimationController.java | 12 +- .../android/server/wm/TaskDisplayArea.java | 8 -- .../com/android/server/wm/Transition.java | 2 + .../server/wm/WindowManagerInternal.java | 25 ---- .../server/wm/WindowManagerService.java | 25 +--- .../server/wm/ActivityRecordTests.java | 4 +- .../server/wm/AppChangeTransitionTests.java | 5 +- .../android/server/wm/AppTransitionTests.java | 4 +- .../wm/RemoteAnimationControllerTest.java | 57 +++----- .../server/wm/WindowContainerTests.java | 5 +- 21 files changed, 49 insertions(+), 387 deletions(-) diff --git a/core/java/android/view/IRemoteAnimationRunner.aidl b/core/java/android/view/IRemoteAnimationRunner.aidl index 1f64fb8ca2ec4..423e23d2bc081 100644 --- a/core/java/android/view/IRemoteAnimationRunner.aidl +++ b/core/java/android/view/IRemoteAnimationRunner.aidl @@ -30,15 +30,11 @@ oneway interface IRemoteAnimationRunner { /** * Called when the process needs to start the remote animation. * - * @param transition The old transition type. Must be one of WindowManager.TRANSIT_OLD_* values. * @param apps The list of apps to animate. - * @param wallpapers The list of wallpapers to animate. - * @param nonApps The list of non-app windows such as Bubbles to animate. * @param finishedCallback The callback to invoke when the animation is finished. */ @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) - void onAnimationStart(int transit, in RemoteAnimationTarget[] apps, - in RemoteAnimationTarget[] wallpapers, in RemoteAnimationTarget[] nonApps, + void onAnimationStart(in RemoteAnimationTarget[] apps, in RemoteAnimationTarget[] wallpapers, in IRemoteAnimationFinishedCallback finishedCallback); /** diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java index e6477f158c277..a56c6a1f084e5 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java @@ -18,11 +18,9 @@ package com.android.systemui.shared.system; import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.view.WindowManager.TRANSIT_CLOSE; -import static android.view.WindowManager.TRANSIT_OLD_NONE; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_BACK; import static android.view.WindowManager.TRANSIT_TO_FRONT; -import static android.view.WindowManager.TransitionOldType; import android.os.RemoteException; import android.util.Log; @@ -67,17 +65,13 @@ public class RemoteAnimationAdapterCompat { final RemoteAnimationRunnerCompat remoteAnimationAdapter) { return new IRemoteAnimationRunner.Stub() { @Override - public void onAnimationStart(@TransitionOldType int transit, - RemoteAnimationTarget[] apps, + public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, final IRemoteAnimationFinishedCallback finishedCallback) { final RemoteAnimationTargetCompat[] appsCompat = RemoteAnimationTargetCompat.wrap(apps); final RemoteAnimationTargetCompat[] wallpapersCompat = RemoteAnimationTargetCompat.wrap(wallpapers); - final RemoteAnimationTargetCompat[] nonAppsCompat = - RemoteAnimationTargetCompat.wrap(nonApps); final Runnable animationFinishedCallback = new Runnable() { @Override public void run() { @@ -89,8 +83,8 @@ public class RemoteAnimationAdapterCompat { } } }; - remoteAnimationAdapter.onAnimationStart(transit, appsCompat, wallpapersCompat, - nonAppsCompat, animationFinishedCallback); + remoteAnimationAdapter.onAnimationStart(appsCompat, wallpapersCompat, + animationFinishedCallback); } @Override @@ -110,9 +104,6 @@ public class RemoteAnimationAdapterCompat { RemoteAnimationTargetCompat.wrap(info, false /* wallpapers */); final RemoteAnimationTargetCompat[] wallpapersCompat = RemoteAnimationTargetCompat.wrap(info, true /* wallpapers */); - // TODO(bc-unlock): Build wrapped object for non-apps target. - final RemoteAnimationTargetCompat[] nonAppsCompat = - new RemoteAnimationTargetCompat[0]; final Runnable animationFinishedCallback = new Runnable() { @Override public void run() { @@ -156,10 +147,7 @@ public class RemoteAnimationAdapterCompat { } } t.apply(); - // TODO(bc-unlcok): Pass correct transit type. - remoteAnimationAdapter.onAnimationStart( - TRANSIT_OLD_NONE, - appsCompat, wallpapersCompat, nonAppsCompat, + remoteAnimationAdapter.onAnimationStart(appsCompat, wallpapersCompat, animationFinishedCallback); } }; diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java index 007629254c7ca..33372f6bd0b91 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationRunnerCompat.java @@ -16,11 +16,8 @@ package com.android.systemui.shared.system; -import android.view.WindowManager; - public interface RemoteAnimationRunnerCompat { - void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTargetCompat[] apps, RemoteAnimationTargetCompat[] wallpapers, - RemoteAnimationTargetCompat[] nonApps, Runnable finishedCallback); + void onAnimationStart(RemoteAnimationTargetCompat[] apps, + RemoteAnimationTargetCompat[] wallpapers, Runnable finishedCallback); void onAnimationCancelled(); } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 17f7ccf0d9672..1b033e91b76b7 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -17,13 +17,7 @@ package com.android.systemui.keyguard; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_OCCLUDE; -import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_UNOCCLUDE; -import android.app.ActivityTaskManager; import android.app.Service; import android.content.Intent; import android.os.Binder; @@ -32,17 +26,8 @@ import android.os.Debug; import android.os.IBinder; import android.os.PowerManager; import android.os.Process; -import android.os.RemoteException; -import android.os.SystemProperties; import android.os.Trace; import android.util.Log; -import android.util.Slog; -import android.view.IRemoteAnimationFinishedCallback; -import android.view.IRemoteAnimationRunner; -import android.view.RemoteAnimationAdapter; -import android.view.RemoteAnimationDefinition; -import android.view.RemoteAnimationTarget; -import android.view.WindowManager; import android.view.WindowManagerPolicyConstants; import com.android.internal.policy.IKeyguardDismissCallback; @@ -58,21 +43,6 @@ public class KeyguardService extends Service { static final String TAG = "KeyguardService"; static final String PERMISSION = android.Manifest.permission.CONTROL_KEYGUARD; - /** - * Run Keyguard animation as remote animation in System UI instead of local animation in - * the server process. - * - * Note: Must be consistent with WindowManagerService. - */ - private static final String ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY = - "persist.wm.enable_remote_keyguard_animation"; - - /** - * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY - */ - private static boolean sEnableRemoteKeyguardAnimation = - SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false); - private final KeyguardViewMediator mKeyguardViewMediator; private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher; @@ -82,21 +52,6 @@ public class KeyguardService extends Service { super(); mKeyguardViewMediator = keyguardViewMediator; mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; - - if (sEnableRemoteKeyguardAnimation) { - RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); - final RemoteAnimationAdapter exitAnimationAdapter = - new RemoteAnimationAdapter(mExitAnimationRunner, 0, 0); - definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, exitAnimationAdapter); - definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER, - exitAnimationAdapter); - final RemoteAnimationAdapter occludeAnimationAdapter = - new RemoteAnimationAdapter(mOccludeAnimationRunner, 0, 0); - definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE, occludeAnimationAdapter); - definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE, occludeAnimationAdapter); - ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay( - DEFAULT_DISPLAY, definition); - } } @Override @@ -121,48 +76,6 @@ public class KeyguardService extends Service { } } - private final IRemoteAnimationRunner.Stub mExitAnimationRunner = - new IRemoteAnimationRunner.Stub() { - @Override // Binder interface - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, - RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, - IRemoteAnimationFinishedCallback finishedCallback) { - Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation"); - checkPermission(); - mKeyguardViewMediator.startKeyguardExitAnimation(transit, apps, wallpapers, - null /* nonApps */, finishedCallback); - Trace.endSection(); - } - - @Override // Binder interface - public void onAnimationCancelled() { - } - }; - - private final IRemoteAnimationRunner.Stub mOccludeAnimationRunner = - new IRemoteAnimationRunner.Stub() { - @Override // Binder interface - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, - RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, - IRemoteAnimationFinishedCallback finishedCallback) { - // TODO(bc-unlock): Calls KeyguardViewMediator#setOccluded to update the state and - // run animation. - try { - finishedCallback.onAnimationFinished(); - } catch (RemoteException e) { - Slog.e(TAG, "RemoteException"); - } - } - - @Override // Binder interface - public void onAnimationCancelled() { - } - }; - private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() { @Override // Binder interface @@ -312,11 +225,6 @@ public class KeyguardService extends Service { mKeyguardViewMediator.onBootCompleted(); } - /** - * @deprecated When remote animation is enabled, this won't be called anymore. Use - * {@code IRemoteAnimationRunner#onAnimationStart} instead. - */ - @Deprecated @Override public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { Trace.beginSection("KeyguardService.mBinder#startKeyguardExitAnimation"); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 5a918d4808d66..e7326698e43ea 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -27,9 +27,6 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE; import static com.android.systemui.DejankUtils.whitelistIpcs; -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.ValueAnimator; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.app.AlarmManager; @@ -68,13 +65,8 @@ import android.util.EventLog; import android.util.Log; import android.util.Slog; import android.util.SparseIntArray; -import android.view.IRemoteAnimationFinishedCallback; -import android.view.RemoteAnimationTarget; -import android.view.SyncRtSurfaceTransactionApplier; -import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; import android.view.View; import android.view.ViewGroup; -import android.view.WindowManager; import android.view.WindowManagerPolicyConstants; import android.view.animation.Animation; import android.view.animation.AnimationUtils; @@ -93,7 +85,6 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardViewController; import com.android.keyguard.ViewMediatorCallback; import com.android.systemui.Dumpable; -import com.android.systemui.Interpolators; import com.android.systemui.SystemUI; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.classifier.FalsingCollector; @@ -1327,7 +1318,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, if (mHiding && isOccluded) { // We're in the process of going away but WindowManager wants to show a // SHOW_WHEN_LOCKED activity instead. - // TODO(bc-unlock): Migrate to remote animation. startKeyguardExitAnimation(0, 0); } @@ -1713,9 +1703,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, Trace.beginSection( "KeyguardViewMediator#handleMessage START_KEYGUARD_EXIT_ANIM"); StartKeyguardExitAnimParams params = (StartKeyguardExitAnimParams) msg.obj; - handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration, - params.mApps, params.mWallpapers, params.mNonApps, - params.mFinishedCallback); + handleStartKeyguardExitAnimation(params.startTime, params.fadeoutDuration); mFalsingCollector.onSuccessfulUnlock(); Trace.endSection(); break; @@ -2002,19 +1990,15 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, if (mShowing && !mOccluded) { mKeyguardGoingAwayRunnable.run(); } else { - // TODO(bc-unlock): Fill parameters handleStartKeyguardExitAnimation( SystemClock.uptimeMillis() + mHideAnimation.getStartOffset(), - mHideAnimation.getDuration(), null /* apps */, null /* wallpapers */, - null /* nonApps */, null /* finishedCallback */); + mHideAnimation.getDuration()); } } Trace.endSection(); } - private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration, - RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) { + private void handleStartKeyguardExitAnimation(long startTime, long fadeoutDuration) { Trace.beginSection("KeyguardViewMediator#handleStartKeyguardExitAnimation"); if (DEBUG) Log.d(TAG, "handleStartKeyguardExitAnimation startTime=" + startTime + " fadeoutDuration=" + fadeoutDuration); @@ -2047,49 +2031,6 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, mWakeAndUnlocking = false; mDismissCallbackRegistry.notifyDismissSucceeded(); mKeyguardViewControllerLazy.get().hide(startTime, fadeoutDuration); - - // TODO(bc-animation): When remote animation is enabled for keyguard exit animation, - // apps, wallpapers and finishedCallback are set to non-null. nonApps is not yet - // supported, so it's always null. - mContext.getMainExecutor().execute(() -> { - if (finishedCallback == null) { - return; - } - - // TODO(bc-unlock): Sample animation, just to apply alpha animation on the app. - final SyncRtSurfaceTransactionApplier applier = new SyncRtSurfaceTransactionApplier( - mKeyguardViewControllerLazy.get().getViewRootImpl().getView()); - final RemoteAnimationTarget primary = apps[0]; - ValueAnimator anim = ValueAnimator.ofFloat(0, 1); - anim.setDuration(400 /* duration */); - anim.setInterpolator(Interpolators.LINEAR); - anim.addUpdateListener((ValueAnimator animation) -> { - SurfaceParams params = new SurfaceParams.Builder(primary.leash) - .withAlpha(animation.getAnimatedFraction()) - .build(); - applier.scheduleApply(params); - }); - anim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - try { - finishedCallback.onAnimationFinished(); - } catch (RemoteException e) { - Slog.e(TAG, "RemoteException"); - } - } - - @Override - public void onAnimationCancel(Animator animation) { - try { - finishedCallback.onAnimationFinished(); - } catch (RemoteException e) { - Slog.e(TAG, "RemoteException"); - } - } - }); - anim.start(); - }); resetKeyguardDonePendingLocked(); mHideAnimationRun = false; adjustStatusBarLocked(); @@ -2282,55 +2223,10 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, return mKeyguardViewControllerLazy.get(); } - /** - * Notifies to System UI that the activity behind has now been drawn and it's safe to remove - * the wallpaper and keyguard flag, and WindowManager has started running keyguard exit - * animation. - * - * @param startTime the start time of the animation in uptime milliseconds. Deprecated. - * @param fadeoutDuration the duration of the exit animation, in milliseconds Deprecated. - * @deprecated Will be migrate to remote animation soon. - */ - @Deprecated public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { - startKeyguardExitAnimation(0, startTime, fadeoutDuration, null, null, null, null); - } - - /** - * Notifies to System UI that the activity behind has now been drawn and it's safe to remove - * the wallpaper and keyguard flag, and System UI should start running keyguard exit animation. - * - * @param apps The list of apps to animate. - * @param wallpapers The list of wallpapers to animate. - * @param nonApps The list of non-app windows such as Bubbles to animate. - * @param finishedCallback The callback to invoke when the animation is finished. - */ - public void startKeyguardExitAnimation(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, - RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, - IRemoteAnimationFinishedCallback finishedCallback) { - startKeyguardExitAnimation(transit, 0, 0, apps, wallpapers, nonApps, finishedCallback); - } - - /** - * Notifies to System UI that the activity behind has now been drawn and it's safe to remove - * the wallpaper and keyguard flag, and start running keyguard exit animation. - * - * @param startTime the start time of the animation in uptime milliseconds. Deprecated. - * @param fadeoutDuration the duration of the exit animation, in milliseconds Deprecated. - * @param apps The list of apps to animate. - * @param wallpapers The list of wallpapers to animate. - * @param nonApps The list of non-app windows such as Bubbles to animate. - * @param finishedCallback The callback to invoke when the animation is finished. - */ - private void startKeyguardExitAnimation(@WindowManager.TransitionOldType int transit, - long startTime, long fadeoutDuration, - RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) { Trace.beginSection("KeyguardViewMediator#startKeyguardExitAnimation"); Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM, - new StartKeyguardExitAnimParams(transit, startTime, fadeoutDuration, apps, - wallpapers, nonApps, finishedCallback)); + new StartKeyguardExitAnimParams(startTime, fadeoutDuration)); mHandler.sendMessage(msg); Trace.endSection(); } @@ -2404,26 +2300,12 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, private static class StartKeyguardExitAnimParams { - @WindowManager.TransitionOldType int mTransit; long startTime; long fadeoutDuration; - RemoteAnimationTarget[] mApps; - RemoteAnimationTarget[] mWallpapers; - RemoteAnimationTarget[] mNonApps; - IRemoteAnimationFinishedCallback mFinishedCallback; - private StartKeyguardExitAnimParams(@WindowManager.TransitionOldType int transit, - long startTime, long fadeoutDuration, - RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, - IRemoteAnimationFinishedCallback finishedCallback) { - this.mTransit = transit; + private StartKeyguardExitAnimParams(long startTime, long fadeoutDuration) { this.startTime = startTime; this.fadeoutDuration = fadeoutDuration; - this.mApps = apps; - this.mWallpapers = wallpapers; - this.mNonApps = nonApps; - this.mFinishedCallback = finishedCallback; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java index d08f9736adf68..88b9c6cbddfde 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ActivityLaunchAnimator.java @@ -33,7 +33,6 @@ import android.view.RemoteAnimationTarget; import android.view.SyncRtSurfaceTransactionApplier; import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; import android.view.View; -import android.view.WindowManager; import com.android.internal.jank.InteractionJankMonitor; import com.android.internal.policy.ScreenDecorationsUtils; @@ -160,10 +159,8 @@ public class ActivityLaunchAnimator { } @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] remoteAnimationTargets, + public void onAnimationStart(RemoteAnimationTarget[] remoteAnimationTargets, RemoteAnimationTarget[] remoteAnimationWallpaperTargets, - RemoteAnimationTarget[] remoteAnimationNonAppTargets, IRemoteAnimationFinishedCallback iRemoteAnimationFinishedCallback) throws RemoteException { mMainExecutor.execute(() -> { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 68b5da64c8c40..a407e8e1b7df2 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -222,7 +222,6 @@ import com.android.server.wm.DisplayPolicy; import com.android.server.wm.DisplayRotation; import com.android.server.wm.WindowManagerInternal; import com.android.server.wm.WindowManagerInternal.AppTransitionListener; -import com.android.server.wm.WindowManagerService; import java.io.File; import java.io.FileNotFoundException; @@ -242,7 +241,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final String TAG = "WindowManager"; static final boolean localLOGV = false; static final boolean DEBUG_INPUT = false; - static final boolean DEBUG_KEYGUARD = true; + static final boolean DEBUG_KEYGUARD = false; static final boolean DEBUG_SPLASH_SCREEN = false; static final boolean DEBUG_WAKEUP = false; static final boolean SHOW_SPLASH_SCREENS = true; @@ -1914,7 +1913,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { handleStartTransitionForKeyguardLw(keyguardGoingAway, 0 /* duration */); } }); - mKeyguardDelegate = new KeyguardServiceDelegate(mContext, new StateCallback() { @Override @@ -3138,7 +3136,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private int handleStartTransitionForKeyguardLw(boolean keyguardGoingAway, long duration) { final int res = applyKeyguardOcclusionChange(); if (res != 0) return res; - if (!WindowManagerService.sEnableRemoteKeyguardAnimation && keyguardGoingAway) { + if (keyguardGoingAway) { if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration); } diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java index c77e266ee11ae..e9d64406432ab 100644 --- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java +++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java @@ -1158,7 +1158,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants { * @param startTime the start time of the animation in uptime milliseconds * @param fadeoutDuration the duration of the exit animation, in milliseconds */ - void startKeyguardExitAnimation(long startTime, long fadeoutDuration); + public void startKeyguardExitAnimation(long startTime, long fadeoutDuration); /** * Called when System UI has been started. diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index a95628f633ad1..c2a1c7930b890 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -29,7 +29,6 @@ import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; import com.android.server.UiThread; import com.android.server.policy.WindowManagerPolicy.OnKeyguardExitResult; -import com.android.server.wm.WindowManagerService; import java.io.PrintWriter; @@ -399,7 +398,7 @@ public class KeyguardServiceDelegate { } public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { - if (!WindowManagerService.sEnableRemoteKeyguardAnimation && mKeyguardService != null) { + if (mKeyguardService != null) { mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration); } } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index 7262433c64455..90070c8f50686 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -90,7 +90,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import static com.android.server.wm.WindowManagerInternal.AppTransitionListener; -import static com.android.server.wm.WindowManagerInternal.KeyguardExitAnimationStartListener; import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_AFTER_ANIM; import static com.android.server.wm.WindowStateAnimator.ROOT_TASK_CLIP_NONE; @@ -258,7 +257,6 @@ public class AppTransition implements Dump { private long mLastClipRevealTransitionDuration = DEFAULT_APP_TRANSITION_DURATION; private final ArrayList mListeners = new ArrayList<>(); - private KeyguardExitAnimationStartListener mKeyguardExitAnimationStartListener; private final ExecutorService mDefaultExecutor = Executors.newSingleThreadExecutor(); private int mLastClipRevealMaxTranslation; @@ -447,7 +445,7 @@ public class AppTransition implements Dump { AnimationAdapter.STATUS_BAR_TRANSITION_DURATION); if (mRemoteAnimationController != null) { - mRemoteAnimationController.goodToGo(transit); + mRemoteAnimationController.goodToGo(); } return redoLayout; } @@ -510,11 +508,6 @@ public class AppTransition implements Dump { mListeners.remove(listener); } - void registerKeygaurdExitAnimationStartListener( - KeyguardExitAnimationStartListener listener) { - mKeyguardExitAnimationStartListener = listener; - } - public void notifyAppTransitionFinishedLocked(IBinder token) { for (int i = 0; i < mListeners.size(); i++) { mListeners.get(i).onAppTransitionFinishedLocked(token); diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java index 7ea49af30e4b5..582aeb36b00ba 100644 --- a/services/core/java/com/android/server/wm/AppTransitionController.java +++ b/services/core/java/com/android/server/wm/AppTransitionController.java @@ -102,7 +102,6 @@ public class AppTransitionController { private final DisplayContent mDisplayContent; private final WallpaperController mWallpaperControllerLocked; private RemoteAnimationDefinition mRemoteAnimationDefinition = null; - private static final int KEYGUARD_GOING_AWAY_ANIMATION_DURATION = 400; private final ArrayMap mTempTransitionReasons = new ArrayMap<>(); @@ -438,14 +437,10 @@ public class AppTransitionController { return adapter; } } - if (mRemoteAnimationDefinition != null) { - final RemoteAnimationAdapter adapter = mRemoteAnimationDefinition.getAdapter( - transit, activityTypes); - if (adapter != null) { - return adapter; - } + if (mRemoteAnimationDefinition == null) { + return null; } - return null; + return mRemoteAnimationDefinition.getAdapter(transit, activityTypes); } /** diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index dc8899a56775c..a1d2072c0de78 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -36,7 +36,6 @@ import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceControl.Transaction; -import android.view.WindowManager; import com.android.internal.protolog.ProtoLogImpl; import com.android.internal.protolog.common.ProtoLog; @@ -99,7 +98,7 @@ class RemoteAnimationController implements DeathRecipient { /** * Called when the transition is ready to be started, and all leashes have been set up. */ - void goodToGo(@WindowManager.TransitionOldType int transit) { + void goodToGo() { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "goodToGo()"); if (mPendingAnimations.isEmpty() || mCanceled) { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, @@ -124,15 +123,11 @@ class RemoteAnimationController implements DeathRecipient { // Create the remote wallpaper animation targets (if any) final RemoteAnimationTarget[] wallpaperTargets = createWallpaperAnimations(); - - // TODO(bc-unlock): Create the remote non app animation targets (if any) - final RemoteAnimationTarget[] nonAppTargets = null; - mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> { try { linkToDeathOfRunner(); - mRemoteAnimationAdapter.getRunner().onAnimationStart(transit, appTargets, - wallpaperTargets, nonAppTargets, mFinishedCallback); + mRemoteAnimationAdapter.getRunner().onAnimationStart(appTargets, wallpaperTargets, + mFinishedCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to start remote animation", e); onAnimationFinished(); @@ -279,7 +274,6 @@ class RemoteAnimationController implements DeathRecipient { private void setRunningRemoteAnimation(boolean running) { final int pid = mRemoteAnimationAdapter.getCallingPid(); final int uid = mRemoteAnimationAdapter.getCallingUid(); - if (pid == 0) { throw new RuntimeException("Calling pid of remote animation was null"); } diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index 63732d8d4bdc7..41854072985c2 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -47,7 +47,6 @@ import android.content.Intent; import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; -import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.window.WindowContainerTransaction; @@ -906,13 +905,6 @@ final class TaskDisplayArea extends DisplayArea { } } - @Override - RemoteAnimationTarget createRemoteAnimationTarget( - RemoteAnimationController.RemoteAnimationRecord record) { - final ActivityRecord activity = getTopMostActivity(); - return activity != null ? activity.createRemoteAnimationTarget(record) : null; - } - SurfaceControl getSplitScreenDividerAnchor() { return mSplitScreenDividerAnchor; } diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java index 98eb11f8a9704..46aea23beaf61 100644 --- a/services/core/java/com/android/server/wm/Transition.java +++ b/services/core/java/com/android/server/wm/Transition.java @@ -372,6 +372,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe dc.mWallpaperController.startWallpaperAnimation(anim); } } + } + if (transit == TRANSIT_KEYGUARD_GOING_AWAY) { dc.startKeyguardExitOnNonAppWindows( (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0, (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0, diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java index eed3299cc93da..a3a9eb773abff 100644 --- a/services/core/java/com/android/server/wm/WindowManagerInternal.java +++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java @@ -26,11 +26,9 @@ import android.hardware.display.DisplayManagerInternal; import android.os.IBinder; import android.view.Display; import android.view.IInputFilter; -import android.view.IRemoteAnimationFinishedCallback; import android.view.IWindow; import android.view.InputChannel; import android.view.MagnificationSpec; -import android.view.RemoteAnimationTarget; import android.view.WindowInfo; import android.view.WindowManager.DisplayImePolicy; @@ -155,21 +153,6 @@ public abstract class WindowManagerInternal { public void onAppTransitionFinishedLocked(IBinder token) {} } - /** - * An interface to be notified when keyguard exit animation should start. - */ - public interface KeyguardExitAnimationStartListener { - /** - * Called when keyguard exit animation should start. - * @param apps The list of apps to animate. - * @param wallpapers The list of wallpapers to animate. - * @param finishedCallback The callback to invoke when the animation is finished. - */ - void onAnimationStart(RemoteAnimationTarget[] apps, - RemoteAnimationTarget[] wallpapers, - IRemoteAnimationFinishedCallback finishedCallback); - } - /** * An interface to be notified about hardware keyboard status. */ @@ -388,14 +371,6 @@ public abstract class WindowManagerInternal { */ public abstract void registerAppTransitionListener(AppTransitionListener listener); - /** - * Registers a listener to be notified to start the keyguard exit animation. - * - * @param listener The listener to register. - */ - public abstract void registerKeyguardExitAnimationStartListener( - KeyguardExitAnimationStartListener listener); - /** * Reports that the password for the given user has changed. */ diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index dcefd30cffcf0..931f52933e2af 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -404,8 +404,6 @@ public class WindowManagerService extends IWindowManager.Stub // trying to apply a new one. private static final boolean ALWAYS_KEEP_CURRENT = true; - static final int LOGTAG_INPUT_FOCUS = 62001; - /** * Restrict ability of activities overriding transition animation in a way such that * an activity can do it only when the transition happens within a same task. @@ -414,6 +412,7 @@ public class WindowManagerService extends IWindowManager.Stub */ private static final String DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY = "persist.wm.disable_custom_task_animation"; + static final int LOGTAG_INPUT_FOCUS = 62001; /** * @see #DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY @@ -421,19 +420,6 @@ public class WindowManagerService extends IWindowManager.Stub static boolean sDisableCustomTaskAnimationProperty = SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true); - /** - * Run Keyguard animation as remote animation in System UI instead of local animation in - * the server process. - */ - private static final String ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY = - "persist.wm.enable_remote_keyguard_animation"; - - /** - * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY - */ - public static boolean sEnableRemoteKeyguardAnimation = - SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false); - private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY = "ro.sf.disable_triple_buffer"; @@ -7717,15 +7703,6 @@ public class WindowManagerService extends IWindowManager.Stub } } - @Override - public void registerKeyguardExitAnimationStartListener( - KeyguardExitAnimationStartListener listener) { - synchronized (mGlobalLock) { - getDefaultDisplayContentLocked().mAppTransition - .registerKeygaurdExitAnimationStartListener(listener); - } - } - @Override public void reportPasswordChanged(int userId) { mKeyguardDisableHandler.updateKeyguardEnabled(userId); 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 f97a10f034210..de2cc761c2c56 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -679,10 +679,8 @@ public class ActivityRecordTests extends WindowTestsBase { new RemoteAnimationAdapter(new Stub() { @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, + public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) { } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index 71f19148d6165..91b9449eddb05 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -36,7 +36,6 @@ import android.view.IRemoteAnimationRunner; import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationDefinition; import android.view.RemoteAnimationTarget; -import android.view.WindowManager; import androidx.test.filters.SmallTest; @@ -71,10 +70,8 @@ public class AppChangeTransitionTests extends WindowTestsBase { class TestRemoteAnimationRunner implements IRemoteAnimationRunner { @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, + public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) { for (RemoteAnimationTarget target : apps) { assertNotNull(target.startBounds); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java index 83aca5e2d4829..f1e36098d84e0 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java @@ -265,10 +265,8 @@ public class AppTransitionTests extends WindowTestsBase { private class TestRemoteAnimationRunner implements IRemoteAnimationRunner { boolean mCancelled = false; @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, + public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { } diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index 15e045c85c29f..2efd4b53efccb 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -17,9 +17,6 @@ package com.android.server.wm; import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; -import static android.view.WindowManager.TRANSIT_OLD_ACTIVITY_OPEN; -import static android.view.WindowManager.TRANSIT_OLD_NONE; -import static android.view.WindowManager.TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE; import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; @@ -103,18 +100,15 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); final ArgumentCaptor appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor nonApsCaptor = - ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); - verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), - appsCaptor.capture(), wallpapersCaptor.capture(), nonApsCaptor.capture(), + verify(mMockRunner).onAnimationStart(appsCaptor.capture(), wallpapersCaptor.capture(), finishedCaptor.capture()); assertEquals(1, appsCaptor.getValue().length); final RemoteAnimationTarget app = appsCaptor.getValue()[0]; @@ -142,7 +136,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); adapter.onAnimationCancelled(mMockLeash); verify(mMockRunner).onAnimationCancelled(); @@ -155,7 +149,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); mClock.fastForward(2500); mHandler.timeAdvance(); @@ -176,7 +170,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); mClock.fastForward(2500); mHandler.timeAdvance(); @@ -196,7 +190,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { @Test public void testZeroAnimations() { - mController.goodToGo(TRANSIT_OLD_NONE); + mController.goodToGo(); verifyNoMoreInteractionsExceptAsBinder(mMockRunner); } @@ -205,7 +199,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin"); mController.createRemoteAnimationRecord(win.mActivityRecord, new Point(50, 100), null, new Rect(50, 100, 150, 150), null); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); verifyNoMoreInteractionsExceptAsBinder(mMockRunner); } @@ -219,18 +213,15 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); final ArgumentCaptor appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor nonAppsCaptor = - ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); - verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), - appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), + verify(mMockRunner).onAnimationStart(appsCaptor.capture(), wallpapersCaptor.capture(), finishedCaptor.capture()); assertEquals(1, appsCaptor.getValue().length); assertEquals(mMockLeash, appsCaptor.getValue()[0].leash); @@ -244,7 +235,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); win.mActivityRecord.removeImmediately(); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); verifyNoMoreInteractionsExceptAsBinder(mMockRunner); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); @@ -264,18 +255,15 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mFinishedCallback); ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); - mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); + mController.goodToGo(); mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); final ArgumentCaptor appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor nonAppsCaptor = - ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); - verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE), - appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), + verify(mMockRunner).onAnimationStart(appsCaptor.capture(), wallpapersCaptor.capture(), finishedCaptor.capture()); assertEquals(1, appsCaptor.getValue().length); final RemoteAnimationTarget app = appsCaptor.getValue()[0]; @@ -317,18 +305,15 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mFinishedCallback); ((AnimationAdapter) record.mThumbnailAdapter).startAnimation(mMockThumbnailLeash, mMockTransaction, ANIMATION_TYPE_WINDOW_ANIMATION, mThumbnailFinishedCallback); - mController.goodToGo(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE); + mController.goodToGo(); mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); final ArgumentCaptor appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor nonAppsCaptor = - ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); - verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_TASK_CHANGE_WINDOWING_MODE), - appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), + verify(mMockRunner).onAnimationStart(appsCaptor.capture(), wallpapersCaptor.capture(), finishedCaptor.capture()); assertEquals(1, appsCaptor.getValue().length); final RemoteAnimationTarget app = appsCaptor.getValue()[0]; @@ -369,18 +354,15 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); final ArgumentCaptor appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor nonAppsCaptor = - ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); - verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), - appsCaptor.capture(), wallpapersCaptor.capture(), nonAppsCaptor.capture(), + verify(mMockRunner).onAnimationStart(appsCaptor.capture(), wallpapersCaptor.capture(), finishedCaptor.capture()); assertEquals(1, wallpapersCaptor.getValue().length); } finally { @@ -401,18 +383,15 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null).mAdapter; adapter.startAnimation(mMockLeash, mMockTransaction, ANIMATION_TYPE_APP_TRANSITION, mFinishedCallback); - mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); + mController.goodToGo(); mWm.mAnimator.executeAfterPrepareSurfacesRunnables(); final ArgumentCaptor appsCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor wallpapersCaptor = ArgumentCaptor.forClass(RemoteAnimationTarget[].class); - final ArgumentCaptor nonAPpsCaptor = - ArgumentCaptor.forClass(RemoteAnimationTarget[].class); final ArgumentCaptor finishedCaptor = ArgumentCaptor.forClass(IRemoteAnimationFinishedCallback.class); - verify(mMockRunner).onAnimationStart(eq(TRANSIT_OLD_ACTIVITY_OPEN), - appsCaptor.capture(), wallpapersCaptor.capture(), nonAPpsCaptor.capture(), + verify(mMockRunner).onAnimationStart(appsCaptor.capture(), wallpapersCaptor.capture(), finishedCaptor.capture()); assertEquals(1, wallpapersCaptor.getValue().length); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 99c96bd0de1bd..df5b48a038f31 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -66,7 +66,6 @@ import android.view.RemoteAnimationAdapter; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.SurfaceSession; -import android.view.WindowManager; import androidx.test.filters.SmallTest; @@ -906,10 +905,8 @@ public class WindowContainerTests extends WindowTestsBase { final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( new IRemoteAnimationRunner.Stub() { @Override - public void onAnimationStart(@WindowManager.TransitionOldType int transit, - RemoteAnimationTarget[] apps, + public void onAnimationStart(RemoteAnimationTarget[] apps, RemoteAnimationTarget[] wallpapers, - RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) { try { finishedCallback.onAnimationFinished(); From d00fd92dc885074889273107fa05cbd524841afc Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Wed, 3 Feb 2021 09:51:04 -0500 Subject: [PATCH 002/176] Keyguard SIM PIN: Fix height Some views within the KeyguardSecurityViewFlipper limit their height, while others do not. When a view is marked as GONE, as when the ViewFlipper changes the focused child, disregard those views from the custom max height measurement as not to interfere with normal measurement. Fixes: 178412096 Test: use password or pattern bouncer, go back to aod/ls, reinsert locked SIM Change-Id: I06047bcd8fb7c11eb0bac272f28147e08b18988d (cherry picked from commit 28217d1c010a6f195d5900e6e81150630bcf1933) --- .../src/com/android/keyguard/KeyguardSecurityViewFlipper.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java index 7773fe9fab755..75ef4b32dfdaa 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityViewFlipper.java @@ -128,6 +128,8 @@ public class KeyguardSecurityViewFlipper extends ViewFlipper { final int count = getChildCount(); for (int i = 0; i < count; i++) { final View child = getChildAt(i); + if (child.getVisibility() != View.VISIBLE) continue; + final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.maxWidth > 0 && lp.maxWidth < maxWidth) { From 0dbc01969842d8542ac8efe72d90d57b895d0739 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 4 Feb 2021 21:57:57 +0000 Subject: [PATCH 003/176] Revert "Sandbox letterbox and size compat apps" This reverts commit 4d3f1c5681c4db99ffb4be881cee134b750542eb. Reason for revert: b/179308296 Change-Id: Idccf97038d5aa92268a13bacc512215878e8aefa (cherry picked from commit 0ba6185639c20ee8a55cf697aad00716b14d22e9) --- core/java/android/view/Display.java | 80 +-- core/java/android/view/DisplayInfo.java | 19 - .../src/android/view/DisplayTests.java | 527 ------------------ data/etc/services.core.protolog.json | 18 +- .../com/android/server/wm/ActivityRecord.java | 31 -- .../core/java/com/android/server/wm/Task.java | 12 - .../android/server/wm/SizeCompatTests.java | 209 ++----- .../android/server/wm/TestDisplayContent.java | 5 - 8 files changed, 67 insertions(+), 834 deletions(-) delete mode 100644 core/tests/mockingcoretests/src/android/view/DisplayTests.java diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 41680647ad576..0ba1dfee16f39 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -25,8 +25,8 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.TestApi; import android.app.KeyguardManager; -import android.app.WindowConfiguration; import android.compat.annotation.UnsupportedAppUsage; +import android.content.Context; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; import android.content.res.Resources; @@ -59,8 +59,12 @@ import java.util.List; * an application window, excluding the system decorations. The application display area may * be smaller than the real display area because the system subtracts the space needed * for decor elements such as the status bar. Use {@link WindowMetrics#getBounds()} to query the - * application window bounds. Generally, use {@link WindowManager#getCurrentWindowMetrics()} to - * query the metrics and perform UI-related actions. + * application window bounds. + *
  • The real display area specifies the part of the display that contains content + * including the system decorations. Even so, the real display area may be smaller than the + * physical size of the display if the window manager is emulating a smaller display + * using (adb shell wm size). Use the following methods to query the + * real display area: {@link #getRealSize}, {@link #getRealMetrics}.
  • * *

    * A logical display does not necessarily represent a particular physical display device @@ -673,9 +677,9 @@ public final class Display { @UnsupportedAppUsage public DisplayAdjustments getDisplayAdjustments() { if (mResources != null) { - final DisplayAdjustments currentAdjustments = mResources.getDisplayAdjustments(); - if (!mDisplayAdjustments.equals(currentAdjustments)) { - mDisplayAdjustments = new DisplayAdjustments(currentAdjustments); + final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments(); + if (!mDisplayAdjustments.equals(currentAdjustements)) { + mDisplayAdjustments = new DisplayAdjustments(currentAdjustements); } } @@ -1213,34 +1217,30 @@ public final class Display { } /** - * Provides the largest {@link Point outSize} an app may expect in the current system state, - * without subtracting any window decor. + * Gets the real size of the display without subtracting any window decor or + * applying any compatibility scale factors. *

    - * The size describes the largest potential area the window might occupy. The size is adjusted - * based on the current rotation of the display. + * The size is adjusted based on the current rotation of the display. *

    * The real size may be smaller than the physical size of the screen when the * window manager is emulating a smaller display (using adb shell wm size). - *

    + *

    + * In general, {@link #getRealSize(Point)} and {@link WindowManager#getMaximumWindowMetrics()} + * report the same bounds except that certain areas of the display may not be available to + * windows created in the {@link WindowManager}'s {@link Context}. + * + * For example, imagine a device which has a multi-task mode that limits windows to half of the + * screen. In this case, {@link WindowManager#getMaximumWindowMetrics()} reports the + * bounds of the screen half where the window is located, while {@link #getRealSize(Point)} + * still reports the bounds of the whole display. * * @param outSize Set to the real size of the display. + * + * @see WindowManager#getMaximumWindowMetrics() */ public void getRealSize(Point outSize) { synchronized (this) { updateDisplayInfoLocked(); - if (shouldReportMaxBounds()) { - final Rect bounds = mResources.getConfiguration() - .windowConfiguration.getMaxBounds(); - outSize.x = bounds.width(); - outSize.y = bounds.height(); - if (DEBUG) { - Log.d(TAG, "getRealSize determined from max bounds: " + outSize - + " for uid " + Process.myUid()); - } - // Skip adjusting by fixed rotation, since if it is necessary, the configuration - // should already reflect the expected rotation. - return; - } outSize.x = mDisplayInfo.logicalWidth; outSize.y = mDisplayInfo.logicalHeight; if (mMayAdjustByFixedRotation) { @@ -1250,11 +1250,9 @@ public final class Display { } /** - * Provides the largest {@link DisplayMetrics outMetrics} an app may expect in the current - * system state, without subtracting any window decor. + * Gets display metrics based on the real size of this display. *

    - * The size describes the largest potential area the window might occupy. The size is adjusted - * based on the current rotation of the display. + * The size is adjusted based on the current rotation of the display. *

    * The real size may be smaller than the physical size of the screen when the * window manager is emulating a smaller display (using adb shell wm size). @@ -1265,18 +1263,6 @@ public final class Display { public void getRealMetrics(DisplayMetrics outMetrics) { synchronized (this) { updateDisplayInfoLocked(); - if (shouldReportMaxBounds()) { - mDisplayInfo.getMaxBoundsMetrics(outMetrics, - CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, - mResources.getConfiguration()); - if (DEBUG) { - Log.d(TAG, "getRealMetrics determined from max bounds: " + outMetrics - + " for uid " + Process.myUid()); - } - // Skip adjusting by fixed rotation, since if it is necessary, the configuration - // should already reflect the expected rotation. - return; - } mDisplayInfo.getLogicalMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); if (mMayAdjustByFixedRotation) { @@ -1285,20 +1271,6 @@ public final class Display { } } - /** - * Determines if {@link WindowConfiguration#getMaxBounds()} should be reported as the - * display dimensions. The max bounds field may be smaller than the logical dimensions - * when apps need to be sandboxed. - * @return {@code true} when max bounds should be applied. - */ - private boolean shouldReportMaxBounds() { - if (mResources == null) { - return false; - } - final Configuration config = mResources.getConfiguration(); - return config != null && !config.windowConfiguration.getMaxBounds().isEmpty(); - } - /** * Gets the state of the display, such as whether it is on or off. * diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 8a445041a1f2d..2a00b5a2e5135 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -24,7 +24,6 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH; import static android.view.DisplayInfoProto.NAME; import android.annotation.Nullable; -import android.app.WindowConfiguration; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; @@ -616,29 +615,11 @@ public final class DisplayInfo implements Parcelable { getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight); } - /** - * Populates {@code outMetrics} with details of the logical display. Bounds are limited - * by the logical size of the display. - * - * @param outMetrics the {@link DisplayMetrics} to be populated - * @param compatInfo the {@link CompatibilityInfo} to be applied - * @param configuration the {@link Configuration} - */ public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration) { getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight); } - /** - * Similar to {@link #getLogicalMetrics}, but the limiting bounds are determined from - * {@link WindowConfiguration#getMaxBounds()} - */ - public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, - Configuration configuration) { - Rect bounds = configuration.windowConfiguration.getMaxBounds(); - getMetricsWithSize(outMetrics, compatInfo, configuration, bounds.width(), bounds.height()); - } - public int getNaturalWidth() { return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? logicalWidth : logicalHeight; diff --git a/core/tests/mockingcoretests/src/android/view/DisplayTests.java b/core/tests/mockingcoretests/src/android/view/DisplayTests.java deleted file mode 100644 index 5a3ea35b1194f..0000000000000 --- a/core/tests/mockingcoretests/src/android/view/DisplayTests.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.view; - -import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.Surface.ROTATION_0; -import static android.view.Surface.ROTATION_90; - -import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; - -import static com.google.common.truth.Truth.assertThat; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Point; -import android.graphics.Rect; -import android.hardware.display.DisplayManagerGlobal; -import android.util.DisplayMetrics; -import android.view.DisplayAdjustments.FixedRotationAdjustments; - -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import com.android.dx.mockito.inline.extended.StaticMockitoSession; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.mockito.quality.Strictness; - -import java.util.function.Consumer; - -/** - * Tests for {@link Display}. - * - *

    Build/Install/Run: - * - * atest FrameworksMockingCoreTests:android.view.DisplayTests - */ -@RunWith(AndroidJUnit4.class) -public class DisplayTests { - - private static final int APP_WIDTH = 272; - private static final int APP_HEIGHT = 700; - // Tablet size device, ROTATION_0 corresponds to portrait. - private static final int LOGICAL_WIDTH = 700; - private static final int LOGICAL_HEIGHT = 1800; - - // Bounds of the app when the device is in portrait mode. - private static Rect sAppBoundsPortrait = buildAppBounds(LOGICAL_WIDTH, LOGICAL_HEIGHT); - private static Rect sAppBoundsLandscape = buildAppBounds(LOGICAL_HEIGHT, LOGICAL_WIDTH); - - private StaticMockitoSession mMockitoSession; - - private DisplayManagerGlobal mDisplayManagerGlobal; - private Context mApplicationContext; - private DisplayInfo mDisplayInfo = new DisplayInfo(); - - @Before - public void setupTests() { - mMockitoSession = mockitoSession() - .mockStatic(DisplayManagerGlobal.class) - .strictness(Strictness.LENIENT) - .startMocking(); - - // Ensure no adjustments are set before each test. - mApplicationContext = ApplicationProvider.getApplicationContext(); - DisplayAdjustments displayAdjustments = - mApplicationContext.getResources().getDisplayAdjustments(); - displayAdjustments.setFixedRotationAdjustments(null); - mApplicationContext.getResources().overrideDisplayAdjustments(null); - mApplicationContext.getResources().getConfiguration().windowConfiguration.setAppBounds( - null); - mApplicationContext.getResources().getConfiguration().windowConfiguration.setMaxBounds( - null); - mDisplayInfo.rotation = ROTATION_0; - - mDisplayManagerGlobal = mock(DisplayManagerGlobal.class); - doReturn(mDisplayInfo).when(mDisplayManagerGlobal).getDisplayInfo(anyInt()); - } - - @After - public void teardownTests() { - if (mMockitoSession != null) { - mMockitoSession.finishMocking(); - } - Mockito.framework().clearInlineMocks(); - } - - @Test - public void testConstructor_defaultDisplayAdjustments_matchesDisplayInfo() { - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - assertThat(display.getDisplayAdjustments()).isEqualTo( - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - DisplayInfo actualDisplayInfo = new DisplayInfo(); - display.getDisplayInfo(actualDisplayInfo); - verifyDisplayInfo(actualDisplayInfo, mDisplayInfo); - } - - @Test - public void testConstructor_defaultResources_matchesDisplayInfo() { - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - assertThat(display.getDisplayAdjustments()).isEqualTo( - mApplicationContext.getResources().getDisplayAdjustments()); - DisplayInfo actualDisplayInfo = new DisplayInfo(); - display.getDisplayInfo(actualDisplayInfo); - verifyDisplayInfo(actualDisplayInfo, mDisplayInfo); - } - - @Test - public void testGetRotation_defaultDisplayAdjustments_rotationNotAdjusted() { - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - assertThat(display.getRotation()).isEqualTo(ROTATION_0); - } - - @Test - public void testGetRotation_displayAdjustmentsWithoutOverride_rotationNotAdjusted() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated, but no override is set. - DisplayAdjustments displayAdjustments = DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS; - final FixedRotationAdjustments fixedRotationAdjustments = - new FixedRotationAdjustments(ROTATION_90, APP_WIDTH, APP_HEIGHT, - DisplayCutout.NO_CUTOUT); - displayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments); - // GIVEN display is constructed with display adjustments. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - displayAdjustments); - // THEN rotation is not adjusted since no override was set. - assertThat(display.getRotation()).isEqualTo(ROTATION_0); - } - - @Test - public void testGetRotation_resourcesWithoutOverride_rotationNotAdjusted() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated, but no override is set. - setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN rotation is not adjusted since no override is set. - assertThat(display.getRotation()).isEqualTo(ROTATION_0); - } - - @Test - public void testGetRotation_resourcesWithOverrideDisplayAdjustments_rotationAdjusted() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated, and an override is set. - setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN rotation is adjusted since an override is set. - assertThat(display.getRotation()).isEqualTo(ROTATION_90); - } - - @Test - public void testGetRealSize_defaultResourcesPortrait_matchesLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches display orientation. - verifyRealSizeIsPortrait(display); - } - - @Test - public void testGetRealSize_defaultResourcesLandscape_matchesRotatedLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches display orientation. - verifyRealSizeIsLandscape(display); - } - - @Test - public void testGetRealSize_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - // THEN real size matches display orientation. - verifyRealSizeIsPortrait(display); - } - - @Test - public void testGetRealSize_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - // THEN real size matches display orientation. - verifyRealSizeIsLandscape(display); - } - - @Test - public void testGetRealSize_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated. - setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches display orientation. - verifyRealSizeIsLandscape(display); - } - - @Test - public void testGetRealSize_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated. - setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches display orientation. - verifyRealSizeIsPortrait(display); - } - - @Test - public void testGetRealSize_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated, and an override is set. - setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches app orientation. - verifyRealSizeIsPortrait(display); - } - - @Test - public void testGetRealSize_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated, and an override is set. - setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches app orientation. - verifyRealSizeIsLandscape(display); - } - - @Test - public void testGetRealSize_resourcesPortraitSandboxed_matchesSandboxBounds() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN app is letterboxed. - setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(), - sAppBoundsPortrait); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches app bounds. - verifyRealSizeMatchesApp(display, sAppBoundsPortrait); - } - - @Test - public void testGetRealSize_resourcesLandscapeSandboxed_matchesSandboxBounds() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - // GIVEN app is letterboxed. - setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(), - sAppBoundsLandscape); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real size matches app bounds. - verifyRealSizeMatchesApp(display, sAppBoundsLandscape); - } - - @Test - public void testGetRealMetrics_defaultResourcesPortrait_matchesLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches display orientation. - verifyRealMetricsIsPortrait(display); - } - - @Test - public void testGetRealMetrics_defaultResourcesLandscape_matchesRotatedLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches display orientation. - verifyRealMetricsIsLandscape(display); - } - - @Test - public void testGetRealMetrics_defaultDisplayAdjustmentsPortrait_matchesLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - // THEN real metrics matches display orientation. - verifyRealMetricsIsPortrait(display); - } - - @Test - public void testGetRealMetrics_defaultDisplayAdjustmentsLandscape_matchesLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); - // THEN real metrics matches display orientation. - verifyRealMetricsIsLandscape(display); - } - - @Test - public void testGetRealMetrics_resourcesPortraitWithFixedRotation_notRotatedLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated. - setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches display orientation. - verifyRealMetricsIsLandscape(display); - } - - @Test - public void testGetRealMetrics_resourcesWithLandscapeFixedRotation_notRotatedLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated. - setFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches display orientation. - verifyRealMetricsIsPortrait(display); - } - - @Test - public void testGetRealMetrics_resourcesWithPortraitOverrideRotation_rotatedLogicalSize() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated with an override. - setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_0); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches app orientation. - verifyRealMetricsIsPortrait(display); - } - - @Test - public void testGetRealMetrics_resourcesWithLandscapeOverrideRotation_rotatedLogicalSize() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN fixed rotation adjustments are rotated. - setOverrideFixedRotationAdjustments(mApplicationContext.getResources(), ROTATION_90); - // GIVEN display is constructed with default resources. - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches app orientation. - verifyRealMetricsIsLandscape(display); - } - - @Test - public void testGetRealMetrics_resourcesPortraitSandboxed_matchesSandboxBounds() { - // GIVEN display is not rotated. - setDisplayInfoPortrait(mDisplayInfo); - // GIVEN app is letterboxed. - setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(), - sAppBoundsPortrait); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches app bounds. - verifyRealMetricsMatchesApp(display, sAppBoundsPortrait); - } - - @Test - public void testGetRealMetrics_resourcesLandscapeSandboxed_matchesSandboxBounds() { - // GIVEN display is rotated. - setDisplayInfoLandscape(mDisplayInfo); - // GIVEN app is letterboxed. - setMaxBoundsSandboxedToMatchAppBounds(mApplicationContext.getResources(), - sAppBoundsLandscape); - final Display display = new Display(mDisplayManagerGlobal, DEFAULT_DISPLAY, mDisplayInfo, - mApplicationContext.getResources()); - // THEN real metrics matches app bounds. - verifyRealMetricsMatchesApp(display, sAppBoundsLandscape); - } - - // Given rotated display dimensions, calculate the letterboxed app bounds. - private static Rect buildAppBounds(int displayWidth, int displayHeight) { - final int midWidth = displayWidth / 2; - final int left = midWidth - (APP_WIDTH / 2); - final int right = midWidth + (APP_WIDTH / 2); - final int midHeight = displayHeight / 2; - // Coordinate system starts at top left. - final int top = midHeight - (APP_HEIGHT / 2); - final int bottom = midHeight + (APP_HEIGHT / 2); - return new Rect(left, top, right, bottom); - } - - private static void setDisplayInfoLandscape(DisplayInfo displayInfo) { - displayInfo.rotation = ROTATION_90; - // Flip width & height assignment since the device is rotated. - displayInfo.logicalWidth = LOGICAL_HEIGHT; - displayInfo.logicalHeight = LOGICAL_WIDTH; - } - - private static void setDisplayInfoPortrait(DisplayInfo displayInfo) { - displayInfo.rotation = ROTATION_0; - displayInfo.logicalWidth = LOGICAL_WIDTH; - displayInfo.logicalHeight = LOGICAL_HEIGHT; - } - - /** - * Set max bounds to be sandboxed to the app bounds, indicating the app is in - * size compat mode or letterbox. - */ - private static void setMaxBoundsSandboxedToMatchAppBounds(Resources resources, Rect appBounds) { - resources.getConfiguration().windowConfiguration.setMaxBounds(appBounds); - } - - /** - * Do not compare entire display info, since it is updated to match display the test is run on. - */ - private static void verifyDisplayInfo(DisplayInfo actual, DisplayInfo expected) { - assertThat(actual.displayId).isEqualTo(expected.displayId); - assertThat(actual.rotation).isEqualTo(expected.rotation); - assertThat(actual.logicalWidth).isEqualTo(LOGICAL_WIDTH); - assertThat(actual.logicalHeight).isEqualTo(LOGICAL_HEIGHT); - } - - private static void verifyRealSizeIsLandscape(Display display) { - Point size = new Point(); - display.getRealSize(size); - // Flip the width and height check since the device is rotated. - assertThat(size).isEqualTo(new Point(LOGICAL_HEIGHT, LOGICAL_WIDTH)); - } - - private static void verifyRealMetricsIsLandscape(Display display) { - DisplayMetrics metrics = new DisplayMetrics(); - display.getRealMetrics(metrics); - // Flip the width and height check since the device is rotated. - assertThat(metrics.widthPixels).isEqualTo(LOGICAL_HEIGHT); - assertThat(metrics.heightPixels).isEqualTo(LOGICAL_WIDTH); - } - - private static void verifyRealSizeIsPortrait(Display display) { - Point size = new Point(); - display.getRealSize(size); - assertThat(size).isEqualTo(new Point(LOGICAL_WIDTH, LOGICAL_HEIGHT)); - } - - private static void verifyRealMetricsIsPortrait(Display display) { - DisplayMetrics metrics = new DisplayMetrics(); - display.getRealMetrics(metrics); - assertThat(metrics.widthPixels).isEqualTo(LOGICAL_WIDTH); - assertThat(metrics.heightPixels).isEqualTo(LOGICAL_HEIGHT); - } - - private static void verifyRealSizeMatchesApp(Display display, Rect appBounds) { - Point size = new Point(); - display.getRealSize(size); - assertThat(size).isEqualTo(new Point(appBounds.width(), appBounds.height())); - } - - private static void verifyRealMetricsMatchesApp(Display display, Rect appBounds) { - DisplayMetrics metrics = new DisplayMetrics(); - display.getRealMetrics(metrics); - assertThat(metrics.widthPixels).isEqualTo(appBounds.width()); - assertThat(metrics.heightPixels).isEqualTo(appBounds.height()); - } - - private static FixedRotationAdjustments setOverrideFixedRotationAdjustments( - Resources resources, @Surface.Rotation int rotation) { - FixedRotationAdjustments fixedRotationAdjustments = - setFixedRotationAdjustments(resources, rotation); - resources.overrideDisplayAdjustments( - buildOverrideRotationAdjustments(fixedRotationAdjustments)); - return fixedRotationAdjustments; - } - - private static FixedRotationAdjustments setFixedRotationAdjustments(Resources resources, - @Surface.Rotation int rotation) { - final FixedRotationAdjustments fixedRotationAdjustments = - new FixedRotationAdjustments(rotation, APP_WIDTH, APP_HEIGHT, - DisplayCutout.NO_CUTOUT); - resources.getDisplayAdjustments().setFixedRotationAdjustments(fixedRotationAdjustments); - return fixedRotationAdjustments; - } - - private static Consumer buildOverrideRotationAdjustments( - FixedRotationAdjustments fixedRotationAdjustments) { - return consumedDisplayAdjustments - -> consumedDisplayAdjustments.setFixedRotationAdjustments(fixedRotationAdjustments); - } -} diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json index ac8a296123c6a..222c9bdf2cb42 100644 --- a/data/etc/services.core.protolog.json +++ b/data/etc/services.core.protolog.json @@ -1903,6 +1903,12 @@ "group": "WM_DEBUG_FOCUS_LIGHT", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, + "123161180": { + "message": "SEVER CHILDREN", + "level": "INFO", + "group": "WM_SHOW_TRANSACTIONS", + "at": "com\/android\/server\/wm\/WindowSurfaceController.java" + }, "140319294": { "message": "IME target changed within ActivityRecord", "level": "DEBUG", @@ -2137,12 +2143,6 @@ "group": "WM_ERROR", "at": "com\/android\/server\/wm\/WindowManagerService.java" }, - "332390227": { - "message": "Sandbox max bounds for uid %s to bounds %s due to letterboxing? %s mismatch with parent bounds? %s size compat mode %s", - "level": "DEBUG", - "group": "WM_DEBUG_CONFIGURATION", - "at": "com\/android\/server\/wm\/ActivityRecord.java" - }, "342460966": { "message": "DRAG %s: pos=(%d,%d)", "level": "INFO", @@ -2623,12 +2623,6 @@ "group": "WM_DEBUG_WINDOW_ORGANIZER", "at": "com\/android\/server\/wm\/WindowOrganizerController.java" }, - "910200295": { - "message": "Sandbox max bounds due to mismatched orientation with parent, to %s vs DisplayArea %s", - "level": "DEBUG", - "group": "WM_DEBUG_CONFIGURATION", - "at": "com\/android\/server\/wm\/Task.java" - }, "913494177": { "message": "removeAllWindowsIfPossible: removing win=%s", "level": "WARN", diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 36c503703b9c8..3419883d8bb62 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -16,7 +16,6 @@ package com.android.server.wm; -import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; import static android.app.ActivityOptions.ANIM_CLIP_REVEAL; @@ -82,7 +81,6 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.isFixedOrientationLandscape; import static android.content.pm.ActivityInfo.isFixedOrientationPortrait; -import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.res.Configuration.EMPTY; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; @@ -203,7 +201,6 @@ import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.ACTIVITY; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT_REPEATS; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW_VERBOSE; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -273,7 +270,6 @@ import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.storage.StorageManager; -import android.permission.PermissionManager; import android.service.dreams.DreamActivity; import android.service.dreams.DreamManagerInternal; import android.service.voice.IVoiceInteractionSession; @@ -6775,20 +6771,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // layout traversals. mConfigurationSeq = Math.max(++mConfigurationSeq, 1); getResolvedOverrideConfiguration().seq = mConfigurationSeq; - - // Sandbox max bounds by setting it to the app bounds, if activity is letterboxed or in - // size compat mode. - if (providesMaxBounds()) { - if (DEBUG_CONFIGURATION) { - ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds for uid %s to bounds %s " - + "due to letterboxing? %s mismatch with parent bounds? %s size compat " - + "mode %s", getUid(), - resolvedConfig.windowConfiguration.getBounds(), mLetterbox != null, - !matchParentBounds(), inSizeCompatMode()); - } - resolvedConfig.windowConfiguration - .setMaxBounds(resolvedConfig.windowConfiguration.getBounds()); - } } /** @@ -6972,19 +6954,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return super.getBounds(); } - @Override - public boolean providesMaxBounds() { - // System and SystemUI should always be able to access the physical display bounds, - // so do not provide it with the overridden maximum bounds. - // TODO(b/179179513) check WindowState#mOwnerCanAddInternalSystemWindow instead - if (getUid() == SYSTEM_UID || PermissionManager.checkPermission(INTERNAL_SYSTEM_WINDOW, - getPid(), info.applicationInfo.uid) == PERMISSION_GRANTED) { - return false; - } - // Max bounds should be sandboxed when this is letterboxed or in size compat mode. - return mLetterbox != null || !matchParentBounds() || inSizeCompatMode(); - } - @VisibleForTesting @Override Rect getAnimationBounds(int appRootTaskClipMode) { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 57ba915d46511..d0e2e048ae824 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -77,7 +77,6 @@ import static android.view.WindowManager.TRANSIT_TO_FRONT; import static com.android.internal.policy.DecorView.DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP; import static com.android.internal.policy.DecorView.DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_ADD_REMOVE; -import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_CONFIGURATION; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_RECENTS_ANIMATIONS; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STATES; @@ -145,7 +144,6 @@ import static com.android.server.wm.TaskProto.WINDOW_CONTAINER; import static com.android.server.wm.WindowContainer.AnimationFlags.CHILDREN; import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION; import static com.android.server.wm.WindowContainerChildProto.TASK; -import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ROOT_TASK; import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_MOVEMENT; import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -2882,16 +2880,6 @@ class Task extends WindowContainer { // In FULLSCREEN mode, always start with empty bounds to indicate "fill parent". outBounds.setEmpty(); computeLetterboxBounds(outBounds, newParentConfig); - // Since the task is letterboxed due to mismatched orientation against its parent, - // sandbox max bounds to the app bounds. - if (!outBounds.isEmpty()) { - if (DEBUG_CONFIGURATION) { - ProtoLog.d(WM_DEBUG_CONFIGURATION, "Sandbox max bounds due to mismatched " - + "orientation with parent, to %s vs DisplayArea %s", outBounds, - getDisplayArea() != null ? getDisplayArea().getBounds() : "null"); - } - getResolvedOverrideConfiguration().windowConfiguration.setMaxBounds(outBounds); - } } /** Computes bounds for {@link WindowConfiguration#WINDOWING_MODE_FREEFORM}. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java index 6f775cf301b51..cc4d4eaa9e8b6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java @@ -39,8 +39,6 @@ import static com.android.server.wm.DisplayContent.IME_TARGET_LAYERING; import static com.android.server.wm.Task.ActivityState.STOPPED; import static com.android.server.wm.WindowContainer.POSITION_TOP; -import static com.google.common.truth.Truth.assertThat; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -119,13 +117,13 @@ public class SizeCompatTests extends WindowTestsBase { @Test public void testKeepBoundsWhenChangingFromFreeformToFullscreen() { removeGlobalMinSizeRestriction(); - // Create landscape freeform display and a freeform app. + // create freeform display and a freeform app DisplayContent display = new TestDisplayContent.Builder(mAtm, 2000, 1000) .setCanRotate(false) .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM).build(); setUpApp(display); - // Put app window into portrait freeform and then make it a compat app. + // Put app window into freeform and then make it a compat app. final Rect bounds = new Rect(100, 100, 400, 600); mTask.setBounds(bounds); prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); @@ -138,7 +136,7 @@ public class SizeCompatTests extends WindowTestsBase { final int density = mActivity.getConfiguration().densityDpi; - // Change display configuration to fullscreen. + // change display configuration to fullscreen Configuration c = new Configuration(display.getRequestedOverrideConfiguration()); c.windowConfiguration.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN); display.onRequestedOverrideConfigurationChanged(c); @@ -148,8 +146,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(bounds.width(), mActivity.getBounds().width()); assertEquals(bounds.height(), mActivity.getBounds().height()); assertEquals(density, mActivity.getConfiguration().densityDpi); - // Size compat mode is sandboxed at the activity level. - assertActivityMaxBoundsSandboxedForSizeCompat(); } @Test @@ -175,12 +171,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(appBounds.height(), appBounds.width() * aspectRatio, 0.5f /* delta */); // The decor height should be a part of the effective bounds. assertEquals(mActivity.getBounds().height(), appBounds.height() + notchHeight); - // Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio. - assertActivityMaxBoundsSandboxedForLetterbox(); - // Activity max bounds ignore notch, since an app can be shown past the notch (although app - // is currently limited by the notch). - assertThat(mActivity.getWindowConfiguration().getMaxBounds().height()) - .isEqualTo(displayBounds.height()); mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); assertFitted(); @@ -190,17 +180,9 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(appBounds.width(), appBounds.height() * aspectRatio, 0.5f /* delta */); // The notch is no longer on top. assertEquals(appBounds, mActivity.getBounds()); - // Activity max bounds are sandboxed. - assertActivityMaxBoundsSandboxedForLetterbox(); mActivity.setRequestedOrientation(SCREEN_ORIENTATION_PORTRAIT); assertFitted(); - // Activity max bounds should be sandboxed; activity is letterboxed due to aspect ratio. - assertActivityMaxBoundsSandboxedForLetterbox(); - // Activity max bounds ignore notch, since an app can be shown past the notch (although app - // is currently limited by the notch). - assertThat(mActivity.getWindowConfiguration().getMaxBounds().height()) - .isEqualTo(displayBounds.height()); } @Test @@ -228,9 +210,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(originalBounds.width(), mActivity.getBounds().width()); assertEquals(originalBounds.height(), mActivity.getBounds().height()); assertEquals(originalDpi, mActivity.getConfiguration().densityDpi); - // Activity is sandboxed; it is in size compat mode since it is not resizable and has a - // max aspect ratio. - assertActivityMaxBoundsSandboxedForSizeCompat(); assertScaled(); } @@ -238,13 +217,11 @@ public class SizeCompatTests extends WindowTestsBase { public void testFixedScreenBoundsWhenDisplaySizeChanged() { setUpDisplaySizeWithApp(1000, 2500); prepareUnresizable(mActivity, -1f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); - final DisplayContent display = mActivity.mDisplayContent; assertFitted(); - // Activity and task inherit bounds from TaskDisplayArea, since not sandboxed. - assertMaxBoundsInheritDisplayAreaBounds(); final Rect origBounds = new Rect(mActivity.getBounds()); final Rect currentBounds = mActivity.getWindowConfiguration().getBounds(); + final DisplayContent display = mActivity.mDisplayContent; // Change the size of current display. resizeDisplay(display, 1000, 2000); @@ -261,8 +238,6 @@ public class SizeCompatTests extends WindowTestsBase { // The position of configuration bounds should be the same as compat bounds. assertEquals(mActivity.getBounds().left, currentBounds.left); assertEquals(mActivity.getBounds().top, currentBounds.top); - // Activity is sandboxed to the offset size compat bounds. - assertActivityMaxBoundsSandboxedForSizeCompat(); // Change display size to a different orientation resizeDisplay(display, 2000, 1000); @@ -271,8 +246,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(origBounds.height(), currentBounds.height()); assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation); assertEquals(Configuration.ORIENTATION_PORTRAIT, mActivity.getConfiguration().orientation); - // Activity is sandboxed to the offset size compat bounds. - assertActivityMaxBoundsSandboxedForSizeCompat(); // The previous resize operation doesn't consider the rotation change after size changed. // These setups apply the requested orientation to rotation as real case that the top fixed @@ -292,8 +265,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(origBounds.height(), currentBounds.height()); assertEquals(offsetX, currentBounds.left); assertScaled(); - // Activity is sandboxed due to size compat mode. - assertActivityMaxBoundsSandboxedForSizeCompat(); } @Test @@ -309,8 +280,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(bounds.width(), bounds.height() * maxAspect, 0.0001f /* delta */); // The position should be horizontal centered. assertEquals((displayWidth - bounds.width()) / 2, bounds.left); - // Activity max bounds should be sandboxed since it is letterboxed. - assertActivityMaxBoundsSandboxedForLetterbox(); mActivity.mDisplayContent.setImeLayeringTarget(addWindowToActivity(mActivity)); // Make sure IME cannot attach to the app, otherwise IME window will also be shifted. @@ -322,8 +291,6 @@ public class SizeCompatTests extends WindowTestsBase { // It should keep non-attachable because the resolved bounds will be computed according to // the aspect ratio that won't match its parent bounds. assertFalse(mActivity.mDisplayContent.isImeAttachedToApp()); - // Activity max bounds should be sandboxed since it is letterboxed. - assertActivityMaxBoundsSandboxedForLetterbox(); } @Test @@ -349,13 +316,14 @@ public class SizeCompatTests extends WindowTestsBase { } @Test - public void testMoveToDifferentOrientationDisplay() { + public void testMoveToDifferentOrientDisplay() { setUpDisplaySizeWithApp(1000, 2500); prepareUnresizable(mActivity, -1.f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); assertFitted(); - final Rect currentBounds = mActivity.getWindowConfiguration().getBounds(); - final Rect originalBounds = new Rect(mActivity.getWindowConfiguration().getBounds()); + final Rect configBounds = mActivity.getWindowConfiguration().getBounds(); + final int origWidth = configBounds.width(); + final int origHeight = configBounds.height(); final int notchHeight = 100; final DisplayContent newDisplay = new TestDisplayContent.Builder(mAtm, 2000, 1000) @@ -364,44 +332,37 @@ public class SizeCompatTests extends WindowTestsBase { // Move the non-resizable activity to the new display. mTask.reparent(newDisplay.getDefaultTaskDisplayArea(), true /* onTop */); // The configuration bounds [820, 0 - 1820, 2500] should keep the same. - assertEquals(originalBounds.width(), currentBounds.width()); - assertEquals(originalBounds.height(), currentBounds.height()); + assertEquals(origWidth, configBounds.width()); + assertEquals(origHeight, configBounds.height()); assertScaled(); - // Activity max bounds are sandboxed due to size compat mode on the new display. - assertActivityMaxBoundsSandboxedForSizeCompat(); final Rect newDisplayBounds = newDisplay.getWindowConfiguration().getBounds(); // The scaled bounds should exclude notch area (1000 - 100 == 360 * 2500 / 1000 = 900). assertEquals(newDisplayBounds.height() - notchHeight, - (int) ((float) mActivity.getBounds().width() * originalBounds.height() - / originalBounds.width())); + (int) ((float) mActivity.getBounds().width() * origHeight / origWidth)); // Recompute the natural configuration in the new display. mActivity.clearSizeCompatMode(); mActivity.ensureActivityConfiguration(0 /* globalChanges */, false /* preserveWindow */); // Because the display cannot rotate, the portrait activity will fit the short side of // display with keeping portrait bounds [200, 0 - 700, 1000] in center. - assertEquals(newDisplayBounds.height(), currentBounds.height()); - assertEquals(currentBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(), - currentBounds.width()); + assertEquals(newDisplayBounds.height(), configBounds.height()); + assertEquals(configBounds.height() * newDisplayBounds.height() / newDisplayBounds.width(), + configBounds.width()); assertFitted(); // The appBounds should be [200, 100 - 700, 1000]. final Rect appBounds = mActivity.getWindowConfiguration().getAppBounds(); - assertEquals(currentBounds.width(), appBounds.width()); - assertEquals(currentBounds.height() - notchHeight, appBounds.height()); - // Task max bounds are sandboxed due to letterboxing from orientation mismatch with display. - assertTaskMaxBoundsSandboxed(); + assertEquals(configBounds.width(), appBounds.width()); + assertEquals(configBounds.height() - notchHeight, appBounds.height()); } @Test - public void testFixedOrientationRotateCutoutDisplay() { + public void testFixedOrientRotateCutoutDisplay() { // Create a display with a notch/cutout final int notchHeight = 60; - final int width = 1000; - setUpApp(new TestDisplayContent.Builder(mAtm, width, 2500) + setUpApp(new TestDisplayContent.Builder(mAtm, 1000, 2500) .setNotch(notchHeight).build()); - // Bounds=[0, 0 - 1000, 1400], AppBounds=[0, 60 - 1000, 1460]. - final float maxAspect = 1.4f; + // Bounds=[0, 0 - 1000, 1460], AppBounds=[0, 60 - 1000, 1460]. prepareUnresizable(mActivity, 1.4f /* maxAspect */, SCREEN_ORIENTATION_PORTRAIT); final Rect currentBounds = mActivity.getWindowConfiguration().getBounds(); @@ -409,11 +370,6 @@ public class SizeCompatTests extends WindowTestsBase { final Rect origBounds = new Rect(currentBounds); final Rect origAppBounds = new Rect(appBounds); - // Activity is sandboxed, and bounds include the area consumed by the notch. - assertActivityMaxBoundsSandboxedForLetterbox(); - assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds().height()) - .isEqualTo(Math.round(width * maxAspect) + notchHeight); - // Although the activity is fixed orientation, force rotate the display. rotateDisplay(mActivity.mDisplayContent, ROTATION_270); assertEquals(ROTATION_270, mTask.getWindowConfiguration().getRotation()); @@ -429,13 +385,10 @@ public class SizeCompatTests extends WindowTestsBase { // The position in configuration should be global coordinates. assertEquals(mActivity.getBounds().left, currentBounds.left); assertEquals(mActivity.getBounds().top, currentBounds.top); - - // Activity max bounds are sandboxed due to size compat mode. - assertActivityMaxBoundsSandboxedForSizeCompat(); } @Test - public void testFixedAspectRatioOrientationChangeOrientation() { + public void testFixedAspOrientChangeOrient() { setUpDisplaySizeWithApp(1000, 2500); final float maxAspect = 1.4f; @@ -447,8 +400,6 @@ public class SizeCompatTests extends WindowTestsBase { final Rect originalAppBounds = new Rect(mActivity.getWindowConfiguration().getAppBounds()); assertEquals((int) (originalBounds.width() * maxAspect), originalBounds.height()); - // Activity is sandboxed due to fixed aspect ratio. - assertActivityMaxBoundsSandboxedForLetterbox(); // Change the fixed orientation. mActivity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE); @@ -460,8 +411,6 @@ public class SizeCompatTests extends WindowTestsBase { mActivity.getWindowConfiguration().getAppBounds().height()); assertEquals(originalAppBounds.height(), mActivity.getWindowConfiguration().getAppBounds().width()); - // Activity is sandboxed due to fixed aspect ratio. - assertActivityMaxBoundsSandboxedForLetterbox(); } @Test @@ -510,8 +459,6 @@ public class SizeCompatTests extends WindowTestsBase { // restarted and the override configuration won't be cleared. verify(mActivity, never()).restartProcessIfVisible(); assertScaled(); - // Activity max bounds are sandboxed due to size compat mode, even if is not visible. - assertActivityMaxBoundsSandboxedForSizeCompat(); // Change display density display.mBaseDisplayDensity = (int) (0.7f * display.mBaseDisplayDensity); @@ -586,16 +533,12 @@ public class SizeCompatTests extends WindowTestsBase { // in multi-window mode. mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); assertFalse(activity.shouldUseSizeCompatMode()); - // Activity and task should not be sandboxed. - assertMaxBoundsInheritDisplayAreaBounds(); // The non-resizable activity should not be size compat because the display support // changing windowing mode from fullscreen to freeform. mTask.mDisplayContent.setDisplayWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM); mTask.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FULLSCREEN); assertFalse(activity.shouldUseSizeCompatMode()); - // Activity and task should not be sandboxed. - assertMaxBoundsInheritDisplayAreaBounds(); } @Test @@ -659,9 +602,6 @@ public class SizeCompatTests extends WindowTestsBase { // be transparent. assertFalse(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR)); - // Activity is sandboxed. - assertActivityMaxBoundsSandboxedForLetterbox(); - // Make the activity fill the display. prepareUnresizable(mActivity, 10 /* maxAspect */, SCREEN_ORIENTATION_LANDSCAPE); w.mWinAnimator.mDrawState = WindowStateAnimator.HAS_DRAWN; @@ -671,7 +611,6 @@ public class SizeCompatTests extends WindowTestsBase { // The letterbox should only cover the notch area, so status bar can be transparent. assertEquals(new Rect(notchHeight, 0, 0, 0), mActivity.getLetterboxInsets()); assertTrue(displayPolicy.isFullyTransparentAllowed(w, TYPE_STATUS_BAR)); - assertActivityMaxBoundsSandboxedForLetterbox(); } @Test @@ -696,8 +635,6 @@ public class SizeCompatTests extends WindowTestsBase { assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(taskBounds, activityBounds); - // Activity inherits max bounds from task, since sandboxing applied to task. - assertTaskMaxBoundsSandboxed(); // Task bounds should be 700x1400 with the ratio as the display. assertEquals(displayBounds.height(), taskBounds.height()); @@ -728,8 +665,6 @@ public class SizeCompatTests extends WindowTestsBase { assertScaled(); assertEquals(activityBounds.width(), newActivityBounds.width()); assertEquals(activityBounds.height(), newActivityBounds.height()); - // Activity max bounds are sandboxed due to size compat mode. - assertActivityMaxBoundsSandboxedForSizeCompat(); } @Test @@ -741,30 +676,29 @@ public class SizeCompatTests extends WindowTestsBase { // Portrait fixed app without max aspect. prepareUnresizable(mActivity, 0, SCREEN_ORIENTATION_PORTRAIT); + Rect displayBounds = new Rect(mActivity.mDisplayContent.getBounds()); + Rect activityBounds = new Rect(mActivity.getBounds()); + // App should launch in fullscreen. assertFalse(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); - // Activity and task inherit max bounds from TaskDisplayArea. - assertMaxBoundsInheritDisplayAreaBounds(); + assertEquals(displayBounds, activityBounds); // Rotate display to landscape. rotateDisplay(mActivity.mDisplayContent, ROTATION_90); - final Rect rotatedDisplayBounds = new Rect(mActivity.mDisplayContent.getBounds()); - final Rect rotatedActivityBounds = new Rect(mActivity.getBounds()); - assertTrue(rotatedDisplayBounds.width() > rotatedDisplayBounds.height()); + displayBounds = new Rect(mActivity.mDisplayContent.getBounds()); + activityBounds = new Rect(mActivity.getBounds()); + assertTrue(displayBounds.width() > displayBounds.height()); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); - assertThat(mActivity.inSizeCompatMode()).isTrue(); - // Activity max bounds are sandboxed due to size compat mode. - assertActivityMaxBoundsSandboxedForSizeCompat(); // App bounds should be 700x1400 with the ratio as the display. - assertEquals(rotatedDisplayBounds.height(), rotatedActivityBounds.height()); - assertEquals(rotatedDisplayBounds.height() * rotatedDisplayBounds.height() - / rotatedDisplayBounds.width(), rotatedActivityBounds.width()); + assertEquals(displayBounds.height(), activityBounds.height()); + assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(), + activityBounds.width()); } @Test @@ -797,17 +731,14 @@ public class SizeCompatTests extends WindowTestsBase { final Rect displayBounds = new Rect(display.getBounds()); final Rect taskBounds = new Rect(mTask.getBounds()); final Rect newActivityBounds = new Rect(newActivity.getBounds()); - final float displayAspectRatio = (float) displayBounds.height() / displayBounds.width(); // Task and app bounds should be 700x1400 with the ratio as the display. assertTrue(mTask.isTaskLetterboxed()); assertFalse(newActivity.inSizeCompatMode()); assertEquals(taskBounds, newActivityBounds); assertEquals(displayBounds.height(), taskBounds.height()); - assertThat(taskBounds.width()) - .isEqualTo(Math.round(displayBounds.height() * displayAspectRatio)); - // Task max bounds are sandboxed due to letterbox, with the ratio of the display. - assertTaskMaxBoundsSandboxed(); + assertEquals(displayBounds.height() * displayBounds.height() / displayBounds.width(), + taskBounds.width()); } @Test @@ -847,14 +778,6 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(displayBounds.height(), taskBounds.height()); assertEquals((long) Math.rint(taskBounds.height() / newActivity.info.maxAspectRatio), taskBounds.width()); - // New activity max bounds are sandboxed due to letterbox. - assertThat(newActivity.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(taskBounds); - // Task max bounds are sandboxed due to letterbox, with the ratio of the display. - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds().height()) - .isEqualTo(displayBounds.height()); - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds().width()) - .isEqualTo(Math.round(displayBounds.height() / newActivity.info.maxAspectRatio)); // App bounds should be fullscreen in Task bounds. assertFalse(newActivity.inSizeCompatMode()); @@ -883,9 +806,6 @@ public class SizeCompatTests extends WindowTestsBase { assertFalse(mTask.isTaskLetterboxed()); assertScaled(); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); - assertThat(mActivity.inSizeCompatMode()).isTrue(); - // Activity max bounds are sandboxed due to size compat mode. - assertActivityMaxBoundsSandboxedForSizeCompat(); final Rect activityBounds = new Rect(mActivity.getBounds()); mTask.resumeTopActivityUncheckedLocked(null /* prev */, null /* options */); @@ -896,8 +816,6 @@ public class SizeCompatTests extends WindowTestsBase { assertScaled(); assertEquals(mTask.getLastTaskBoundsComputeActivity(), mActivity); assertEquals(activityBounds, mActivity.getBounds()); - // Activity max bounds are sandboxed due to size compat. - assertActivityMaxBoundsSandboxedForSizeCompat(); } @Test @@ -913,7 +831,6 @@ public class SizeCompatTests extends WindowTestsBase { // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); - assertTaskMaxBoundsSandboxed(); // Rotate display to portrait. rotateDisplay(display, ROTATION_90); @@ -921,7 +838,6 @@ public class SizeCompatTests extends WindowTestsBase { // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); - assertActivityMaxBoundsSandboxedForSizeCompat(); // Rotate display to landscape. rotateDisplay(display, ROTATION_180); @@ -929,7 +845,6 @@ public class SizeCompatTests extends WindowTestsBase { // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); - assertTaskMaxBoundsSandboxed(); } @Test @@ -947,26 +862,20 @@ public class SizeCompatTests extends WindowTestsBase { // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); - // Task is letterboxed due to mismatched orientation request. - assertTaskMaxBoundsSandboxed(); - // Rotate display to landscape. + // Rotate display to portrait. rotateDisplay(display, ROTATION_90); // App should be in size compat. assertFalse(mTask.isTaskLetterboxed()); assertScaled(); - // Activity max bounds are sandboxed due to unresizable app. - assertActivityMaxBoundsSandboxedForSizeCompat(); - // Rotate display to portrait. + // Rotate display to landscape. rotateDisplay(display, ROTATION_180); // In Task letterbox assertTrue(mTask.isTaskLetterboxed()); assertFalse(mActivity.inSizeCompatMode()); - // Task is letterboxed, as in first case. - assertTaskMaxBoundsSandboxed(); } @Test @@ -983,18 +892,12 @@ public class SizeCompatTests extends WindowTestsBase { assertEquals(ORIENTATION_LANDSCAPE, display.getConfiguration().orientation); assertEquals(2800, displayBounds.width()); assertEquals(1400, displayBounds.height()); - Rect displayAreaBounds = new Rect(0, 0, 2400, 1000); - taskDisplayArea.setBounds(displayAreaBounds); + taskDisplayArea.setBounds(0, 0, 2400, 1000); final Rect activityBounds = new Rect(mActivity.getBounds()); assertFalse(mActivity.inSizeCompatMode()); assertEquals(2400, activityBounds.width()); assertEquals(1000, activityBounds.height()); - // Task and activity maximum bounds inherit from TaskDisplayArea bounds. - assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(displayAreaBounds); - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(displayAreaBounds); } @Test @@ -1142,48 +1045,6 @@ public class SizeCompatTests extends WindowTestsBase { assertFalse(mActivity.hasSizeCompatBounds()); } - /** Asserts both the activity and task max bounds inherit from the TaskDisplayArea. */ - private void assertMaxBoundsInheritDisplayAreaBounds() { - final Rect taskDisplayAreaBounds = mTask.getDisplayArea().getBounds(); - assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(taskDisplayAreaBounds); - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(taskDisplayAreaBounds); - } - - /** - * Asserts task-level letterboxing, so both activity and task max bounds - * are sandboxed to the letterbox bounds. - */ - private void assertTaskMaxBoundsSandboxed() { - // Activity inherits max bounds from task, since sandboxing applied to task. - assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(mTask.getBounds()); - // Task max bounds are sandboxed due to letterbox. - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(mTask.getBounds()); - } - - /** Asserts activity-level size compat mode, so only activity max bounds are sandboxed. */ - private void assertActivityMaxBoundsSandboxedForSizeCompat() { - // Activity max bounds are sandboxed due to size compat mode. - assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(mActivity.getWindowConfiguration().getBounds()); - // Task inherits max bounds from display. - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(mTask.getDisplayContent().getBounds()); - } - - /** Asserts activity-level letterboxing, so only activity max bounds are sandboxed. */ - private void assertActivityMaxBoundsSandboxedForLetterbox() { - // Activity is sandboxed due to fixed aspect ratio. - assertThat(mActivity.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(mActivity.getBounds()); - // Task inherits bounds from display. - assertThat(mTask.getConfiguration().windowConfiguration.getMaxBounds()) - .isEqualTo(mTask.getDisplayContent().getBounds()); - } - static Configuration rotateDisplay(DisplayContent display, int rotation) { final Configuration c = new Configuration(); display.getDisplayRotation().setRotation(rotation); diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java index d71993df86020..ae85ceb729587 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java +++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayContent.java @@ -136,11 +136,6 @@ class TestDisplayContent extends DisplayContent { final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId, mInfo, DEFAULT_DISPLAY_ADJUSTMENTS); final TestDisplayContent newDisplay = createInternal(display); - // Ensure letterbox aspect ratio is not overridden on any device target. - // {@link com.android.internal.R.dimen.config_taskLetterboxAspectRatio}, provided by - // the below method, is set on some device form factors. - mService.mWindowManager.setTaskLetterboxAspectRatio(0); - // disable the normal system decorations final DisplayPolicy displayPolicy = newDisplay.getDisplayPolicy(); spyOn(displayPolicy); From 7f7de4e443ede3bf65b39552adb525b8dde51761 Mon Sep 17 00:00:00 2001 From: Alex Kershaw Date: Fri, 5 Feb 2021 16:24:10 +0000 Subject: [PATCH 004/176] Revert "Dispatch TaskOrg events before finishing surface placement" This reverts commit 805cfed0584941386e731b4c63f8fff8f3088824. Reason for revert: Seems to break https://b/179460794 and http://b/179457563 (PackageInstaller) Change-Id: Ibb9ffb8074717401ce8a836d2832acb7dfa0b624 (cherry picked from commit 53fc5edc099473ce75e702233df15c20c22aa267) --- .../core/java/com/android/server/wm/RootWindowContainer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index 61fec0d0ead98..96e0e284afe99 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -847,8 +847,6 @@ class RootWindowContainer extends WindowContainer Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); } - // Send any pending task-info changes that were queued-up during a layout deferment - mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "applySurfaceChanges"); mWmService.openSurfaceTransaction(); try { @@ -865,6 +863,8 @@ class RootWindowContainer extends WindowContainer } } + // Send any pending task-info changes that were queued-up during a layout deferment + mWmService.mAtmService.mTaskOrganizerController.dispatchPendingEvents(); mWmService.mAnimator.executeAfterPrepareSurfacesRunnables(); checkAppTransitionReady(surfacePlacer); From 7d108366a3aa3d7dac41b9e1e9aa07c41e5025dc Mon Sep 17 00:00:00 2001 From: Alex Kershaw Date: Mon, 8 Feb 2021 10:15:55 +0000 Subject: [PATCH 005/176] Revert "Enfore cross user permission to getPackagesForUid" This reverts commit 1dafc3859ae45671d666aa591bdb74a1e45518b3. Reason for revert: Causes bugs https://b.corp.google.com/issues/179465628 and https://b.corp.google.com/issues/179506602 Fixes: 179506602 Fixes: 179465628 Fixes: 179460585 Change-Id: I0596e45484638e33baccec834a8adf2dfa9f4a4d (cherry picked from commit d5bc510fc88704cea72fa9291d7756e8227c7b7b) --- .../core/java/com/android/server/pm/PackageManagerService.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 7e5a00ac2e3c4..cdc33f006be06 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3616,8 +3616,6 @@ public class PackageManagerService extends IPackageManager.Stub final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null; final int userId = UserHandle.getUserId(uid); final int appId = UserHandle.getAppId(uid); - enforceCrossUserPermission(callingUid, userId, - /* requireFullPermission */ false, /* checkShell */ false, "getPackagesForUid"); return getPackagesForUidInternalBody(callingUid, userId, appId, isCallerInstantApp); } From 8606d28d27655d61cfd017310b9f6c590344d218 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Mon, 8 Feb 2021 18:50:05 +0000 Subject: [PATCH 006/176] Revert "Revert "Revert "Turn on the feature flag for Android S S..." Revert submission 13479025-multiuser_test Reason for revert: Bug: 179457252 Reverted Changes: I9e3d23f93:Fix the broken test Id05757c49:Revert "Revert "Turn on the feature flag for Andro... Change-Id: I4f77afda470b226007bfffda7f536df3b1d4d28a (cherry picked from commit 0ded361ef4a92652d70fb95857c3dd899c0f2bb8) --- core/java/android/util/FeatureFlagUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 790773fd83c59..b22921233f055 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -65,7 +65,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put(SETTINGS_DO_NOT_RESTORE_PRESERVED, "true"); DEFAULT_FLAGS.put("settings_tether_all_in_one", "false"); - DEFAULT_FLAGS.put("settings_silky_home", "true"); + DEFAULT_FLAGS.put("settings_silky_home", "false"); DEFAULT_FLAGS.put("settings_contextual_home", "false"); DEFAULT_FLAGS.put(SETTINGS_PROVIDER_MODEL, "false"); } From f2bdedde905122c31704f4983182440bf38484e4 Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Fri, 12 Feb 2021 02:46:22 +0000 Subject: [PATCH 007/176] Revert "Use new GX overlay for new AOD/lockscreen transitions." Revert "Use new GX overlay for new AOD/lockscreen transitions." Revert submission 13519645-aod-lockscreen-animation-flag Reason for revert: b/179947580 Reverted Changes: I343400700:Use new GX overlay for new AOD/lockscreen transiti... I326ad5294:Use new GX overlay for new AOD/lockscreen transiti... Change-Id: I8705764f0a0505d1851cf3d9c988fff0f3ec3cdd (cherry picked from commit 67a2a1c80d3b7463ac648bd17190e4022d7c30ef) --- packages/SystemUI/res/values/flags.xml | 3 --- .../android/systemui/statusbar/FeatureFlags.java | 4 ---- .../android/systemui/statusbar/LightRevealScrim.kt | 4 ++++ .../systemui/statusbar/phone/DozeParameters.java | 9 +++------ .../android/systemui/statusbar/phone/StatusBar.java | 13 ++++--------- .../phone/dagger/StatusBarPhoneModule.java | 7 ++----- .../statusbar/phone/DozeParametersTest.java | 5 +---- .../systemui/statusbar/phone/StatusBarTest.java | 5 +---- 8 files changed, 15 insertions(+), 35 deletions(-) diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index f83965eb73788..3a9fec8c8748d 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -35,9 +35,6 @@ false - - false - false diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java index 862c27907e0fe..7aa41e43be3cc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java @@ -67,10 +67,6 @@ public class FeatureFlags { return mFlagReader.isEnabled(R.bool.flag_brightness_slider); } - public boolean useNewLockscreenAnimations() { - return mFlagReader.isEnabled(R.bool.flag_lockscreen_animations); - } - public boolean isPeopleTileEnabled() { return mFlagReader.isEnabled(R.bool.flag_conversations); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt index c1feacaba440f..2f0f90d318eb0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt @@ -11,10 +11,14 @@ import android.graphics.PorterDuffColorFilter import android.graphics.PorterDuffXfermode import android.graphics.RadialGradient import android.graphics.Shader +import android.os.SystemProperties import android.util.AttributeSet import android.view.View import com.android.systemui.Interpolators +val enableLightReveal = + SystemProperties.getBoolean("persist.sysui.show_new_screen_on_transitions", false) + /** * Provides methods to modify the various properties of a [LightRevealScrim] to reveal between 0% to * 100% of the view(s) underneath the scrim. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java index 85d8df8e60575..8c2fa3349e4a8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java @@ -29,7 +29,6 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.doze.AlwaysOnDisplayPolicy; import com.android.systemui.doze.DozeScreenState; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.tuner.TunerService; @@ -55,7 +54,6 @@ public class DozeParameters implements TunerService.Tunable, private final AlwaysOnDisplayPolicy mAlwaysOnPolicy; private final Resources mResources; private final BatteryController mBatteryController; - private final FeatureFlags mFeatureFlags; private boolean mDozeAlwaysOn; private boolean mControlScreenOffAnimation; @@ -67,8 +65,7 @@ public class DozeParameters implements TunerService.Tunable, AlwaysOnDisplayPolicy alwaysOnDisplayPolicy, PowerManager powerManager, BatteryController batteryController, - TunerService tunerService, - FeatureFlags featureFlags) { + TunerService tunerService) { mResources = resources; mAmbientDisplayConfiguration = ambientDisplayConfiguration; mAlwaysOnPolicy = alwaysOnDisplayPolicy; @@ -77,7 +74,6 @@ public class DozeParameters implements TunerService.Tunable, mControlScreenOffAnimation = !getDisplayNeedsBlanking(); mPowerManager = powerManager; mPowerManager.setDozeAfterScreenOff(!mControlScreenOffAnimation); - mFeatureFlags = featureFlags; tunerService.addTunable( this, @@ -204,7 +200,8 @@ public class DozeParameters implements TunerService.Tunable, * then abruptly showing AOD. */ public boolean shouldControlUnlockedScreenOff() { - return getAlwaysOn() && mFeatureFlags.useNewLockscreenAnimations(); + return getAlwaysOn() && SystemProperties.getBoolean( + "persist.sysui.show_new_screen_on_transitions", false); } private boolean getBoolean(String propName, int resId) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 041a97e1d4045..e63902f26a78f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -35,6 +35,7 @@ import static com.android.systemui.charging.WirelessChargingLayout.UNKNOWN_BATTE import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING; +import static com.android.systemui.statusbar.LightRevealScrimKt.getEnableLightReveal; import static com.android.systemui.statusbar.NotificationLockscreenUserManager.PERMISSION_SELF; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT_TRANSPARENT; @@ -179,7 +180,6 @@ import com.android.systemui.statusbar.AutoHideUiElement; import com.android.systemui.statusbar.BackDropView; import com.android.systemui.statusbar.CommandQueue; import com.android.systemui.statusbar.CrossFadeHelper; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.GestureRecorder; import com.android.systemui.statusbar.KeyboardShortcuts; import com.android.systemui.statusbar.KeyguardIndicationController; @@ -440,7 +440,6 @@ public class StatusBar extends SystemUI implements DemoMode, private final KeyguardViewMediator mKeyguardViewMediator; protected final NotificationInterruptStateProvider mNotificationInterruptStateProvider; private final BrightnessSlider.Factory mBrightnessSliderFactory; - private final FeatureFlags mFeatureFlags; private final List mExpansionChangedListeners; @@ -763,8 +762,7 @@ public class StatusBar extends SystemUI implements DemoMode, Lazy notificationShadeDepthControllerLazy, StatusBarTouchableRegionManager statusBarTouchableRegionManager, NotificationIconAreaController notificationIconAreaController, - BrightnessSlider.Factory brightnessSliderFactory, - FeatureFlags featureFlags) { + BrightnessSlider.Factory brightnessSliderFactory) { super(context); mNotificationsController = notificationsController; mLightBarController = lightBarController; @@ -842,7 +840,6 @@ public class StatusBar extends SystemUI implements DemoMode, mDemoModeController = demoModeController; mNotificationIconAreaController = notificationIconAreaController; mBrightnessSliderFactory = brightnessSliderFactory; - mFeatureFlags = featureFlags; mExpansionChangedListeners = new ArrayList<>(); @@ -1184,11 +1181,9 @@ public class StatusBar extends SystemUI implements DemoMode, mLightRevealScrim = mNotificationShadeWindowView.findViewById(R.id.light_reveal_scrim); - if (mFeatureFlags.useNewLockscreenAnimations() && mDozeParameters.getAlwaysOn()) { + if (getEnableLightReveal()) { mLightRevealScrim.setVisibility(View.VISIBLE); mLightRevealScrim.setRevealEffect(LiftReveal.INSTANCE); - } else { - mLightRevealScrim.setVisibility(View.GONE); } mNotificationPanelViewController.initDependencies( @@ -3619,7 +3614,7 @@ public class StatusBar extends SystemUI implements DemoMode, @Override public void onDozeAmountChanged(float linear, float eased) { - if (mFeatureFlags.useNewLockscreenAnimations()) { + if (getEnableLightReveal()) { mLightRevealScrim.setRevealAmount(1f - linear); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java index b572c57590ae5..9e9533d0e1991 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java @@ -47,7 +47,6 @@ import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.settings.brightness.BrightnessSlider; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.NotificationLockscreenUserManager; import com.android.systemui.statusbar.NotificationMediaManager; @@ -201,8 +200,7 @@ public interface StatusBarPhoneModule { DismissCallbackRegistry dismissCallbackRegistry, StatusBarTouchableRegionManager statusBarTouchableRegionManager, NotificationIconAreaController notificationIconAreaController, - BrightnessSlider.Factory brightnessSliderFactory, - FeatureFlags featureFlags) { + BrightnessSlider.Factory brightnessSliderFactory) { return new StatusBar( context, notificationsController, @@ -281,7 +279,6 @@ public interface StatusBarPhoneModule { notificationShadeDepthController, statusBarTouchableRegionManager, notificationIconAreaController, - brightnessSliderFactory, - featureFlags); + brightnessSliderFactory); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java index b9fd75ef5fda7..fa253e62ef0a8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java @@ -35,7 +35,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.systemui.SysuiTestCase; import com.android.systemui.doze.AlwaysOnDisplayPolicy; import com.android.systemui.doze.DozeScreenState; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.tuner.TunerService; @@ -58,7 +57,6 @@ public class DozeParametersTest extends SysuiTestCase { @Mock private PowerManager mPowerManager; @Mock private TunerService mTunerService; @Mock private BatteryController mBatteryController; - @Mock private FeatureFlags mFeatureFlags; @Before public void setup() { @@ -69,8 +67,7 @@ public class DozeParametersTest extends SysuiTestCase { mAlwaysOnDisplayPolicy, mPowerManager, mBatteryController, - mTunerService, - mFeatureFlags + mTunerService ); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java index 253460db0d075..cae488a561a20 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java @@ -97,7 +97,6 @@ import com.android.systemui.recents.ScreenPinningRequest; import com.android.systemui.settings.brightness.BrightnessSlider; import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.statusbar.CommandQueue; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.KeyguardIndicationController; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationLockscreenUserManager; @@ -259,7 +258,6 @@ public class StatusBarTest extends SysuiTestCase { @Mock private DemoModeController mDemoModeController; @Mock private Lazy mNotificationShadeDepthControllerLazy; @Mock private BrightnessSlider.Factory mBrightnessSliderFactory; - @Mock private FeatureFlags mFeatureFlags; private ShadeController mShadeController; private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock()); private InitController mInitController = new InitController(); @@ -420,8 +418,7 @@ public class StatusBarTest extends SysuiTestCase { mNotificationShadeDepthControllerLazy, mStatusBarTouchableRegionManager, mNotificationIconAreaController, - mBrightnessSliderFactory, - mFeatureFlags); + mBrightnessSliderFactory); when(mNotificationShadeWindowView.findViewById(R.id.lock_icon_container)).thenReturn( mLockIconContainer); From f01a31756f28d3485ea7df7e7ec46fa7b28146fb Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Thu, 18 Feb 2021 17:16:57 +0000 Subject: [PATCH 008/176] Handle isUsbDataSignalingEnabledForUser PO case If there is no DO or COPE PO, then usb data signaling is enabled. Bug: 180547881 Test: Manual testing atest com.android.server.devicepolicy.DevicePolicyManagerTest Change-Id: I32a1f73ca403b6c1c38b7c6fa70cc2f0f0830324 (cherry picked from commit 46149e42b8d5cb57c0ac80cb411d03b6d5815e33) --- .../android/server/devicepolicy/DevicePolicyManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 28df40e8c4b20..7d63e60669639 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -16755,7 +16755,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked( UserHandle.USER_SYSTEM); - return admin != null && admin.mUsbDataSignalingEnabled; + return admin == null || admin.mUsbDataSignalingEnabled; } } From 0cf2ba1ddc17f755dea6bee4d57ecd4f1fec0377 Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Thu, 18 Feb 2021 22:38:50 +0800 Subject: [PATCH 009/176] Fix USB HAL interface binder Bug: 180538375 Test: USB HAL loaded normally Signed-off-by: Albert Wang Change-Id: Ie7081523441b60628076928aad8a1ddec820bc1e (cherry picked from commit 8a5a512ede216b3ab3984284fc147a081bd0d7c8) --- services/usb/java/com/android/server/usb/UsbPortManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index 6bf67154efd59..c53c95cc982e0 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -42,13 +42,13 @@ import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.V1_0.IUsb; import android.hardware.usb.V1_0.PortRole; import android.hardware.usb.V1_0.PortRoleType; import android.hardware.usb.V1_0.Status; import android.hardware.usb.V1_1.PortStatus_1_1; import android.hardware.usb.V1_2.IUsbCallback; import android.hardware.usb.V1_2.PortStatus; -import android.hardware.usb.V1_3.IUsb; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; import android.os.Bundle; From ca5fa812b324b3cd19ffdebbd6a5260fde8dcefd Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Thu, 18 Feb 2021 17:16:57 +0000 Subject: [PATCH 010/176] Handle isUsbDataSignalingEnabledForUser PO case If there is no DO or COPE PO, then usb data signaling is enabled. Bug: 180547881 Test: Manual testing atest com.android.server.devicepolicy.DevicePolicyManagerTest Change-Id: I32a1f73ca403b6c1c38b7c6fa70cc2f0f0830324 (cherry picked from commit 46149e42b8d5cb57c0ac80cb411d03b6d5815e33) --- .../android/server/devicepolicy/DevicePolicyManagerService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 28828faae4113..8f804c5e6f31f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -16792,7 +16792,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked( UserHandle.USER_SYSTEM); - return admin != null && admin.mUsbDataSignalingEnabled; + return admin == null || admin.mUsbDataSignalingEnabled; } } From 047b7b104992d5c4a42f33b767bcb974feb2996d Mon Sep 17 00:00:00 2001 From: Albert Wang Date: Thu, 18 Feb 2021 22:38:50 +0800 Subject: [PATCH 011/176] Fix USB HAL interface binder Bug: 180538375 Test: USB HAL loaded normally Signed-off-by: Albert Wang Change-Id: Ie7081523441b60628076928aad8a1ddec820bc1e (cherry picked from commit 8a5a512ede216b3ab3984284fc147a081bd0d7c8) --- services/usb/java/com/android/server/usb/UsbPortManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java index 6bf67154efd59..c53c95cc982e0 100644 --- a/services/usb/java/com/android/server/usb/UsbPortManager.java +++ b/services/usb/java/com/android/server/usb/UsbPortManager.java @@ -42,13 +42,13 @@ import android.hardware.usb.ParcelableUsbPort; import android.hardware.usb.UsbManager; import android.hardware.usb.UsbPort; import android.hardware.usb.UsbPortStatus; +import android.hardware.usb.V1_0.IUsb; import android.hardware.usb.V1_0.PortRole; import android.hardware.usb.V1_0.PortRoleType; import android.hardware.usb.V1_0.Status; import android.hardware.usb.V1_1.PortStatus_1_1; import android.hardware.usb.V1_2.IUsbCallback; import android.hardware.usb.V1_2.PortStatus; -import android.hardware.usb.V1_3.IUsb; import android.hidl.manager.V1_0.IServiceManager; import android.hidl.manager.V1_0.IServiceNotification; import android.os.Bundle; From 2c65eb8f024d4181ca81f7b18016122792ef1d3c Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Thu, 18 Feb 2021 14:09:37 -0800 Subject: [PATCH 012/176] NativeTombstoneManager: catch ProtoParseException. If we can't parse the proto for some reason, don't nuke system_server. Bug: http://b/159164105 Test: `adb shell crasher` on sc-vf-dev Change-Id: Id8af5f41177d68dacfd9da69eddea4d88d62f420 (cherry picked from commit 2b67941ffe592d9a3f1eb9f87bfce58ebb47d570) --- .../java/com/android/server/os/NativeTombstoneManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/os/NativeTombstoneManager.java b/services/core/java/com/android/server/os/NativeTombstoneManager.java index 9984bfae30fd3..d95a7254efe14 100644 --- a/services/core/java/com/android/server/os/NativeTombstoneManager.java +++ b/services/core/java/com/android/server/os/NativeTombstoneManager.java @@ -42,6 +42,7 @@ import android.system.StructStat; import android.util.Slog; import android.util.SparseArray; import android.util.proto.ProtoInputStream; +import android.util.proto.ProtoParseException; import com.android.internal.annotations.GuardedBy; import com.android.server.BootReceiver; @@ -434,7 +435,7 @@ public final class NativeTombstoneManager { break; } } - } catch (IOException ex) { + } catch (IOException | ProtoParseException ex) { Slog.e(TAG, "Failed to parse tombstone", ex); return Optional.empty(); } From be5d151dbd3bdfbe29f04cb606254f5a764eb746 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Fri, 19 Feb 2021 19:10:04 +0000 Subject: [PATCH 013/176] Revert "Try to ensure tests run sequentially" Revert submission 13593269 Reason for revert: Bug: 180689674 Reverted Changes: I59f6e607f:Update RemovalClient to support new biometric AIDL... I3fdb3fe0b:Try to ensure tests run sequentially Change-Id: Ia9c02759db7238536e21dd05f8e247a91e9ac5aa (cherry picked from commit c0dd229fc6afb78c18b6688f7b5034f6229b222d) --- .../hardware/biometrics/BiometricManager.java | 3 +- .../biometrics/BiometricTestSession.java | 75 +++---------------- .../hardware/biometrics/IAuthService.aidl | 3 +- .../biometrics/IBiometricAuthenticator.aidl | 3 +- .../biometrics/IBiometricService.aidl | 3 +- .../hardware/biometrics/ITestSession.aidl | 2 +- .../biometrics/ITestSessionCallback.aidl | 25 ------- .../android/hardware/face/IFaceService.aidl | 3 +- .../fingerprint/FingerprintManager.java | 3 +- .../fingerprint/IFingerprintService.aidl | 3 +- .../server/biometrics/AuthService.java | 8 +- .../server/biometrics/BiometricService.java | 7 +- .../sensors/face/FaceAuthenticator.java | 6 +- .../biometrics/sensors/face/FaceService.java | 6 +- .../sensors/face/ServiceProvider.java | 8 +- .../face/aidl/BiometricTestSessionImpl.java | 27 +------ .../sensors/face/aidl/FaceProvider.java | 14 ++-- .../biometrics/sensors/face/aidl/Sensor.java | 6 +- .../face/hidl/BiometricTestSessionImpl.java | 29 +------ .../biometrics/sensors/face/hidl/Face10.java | 21 ++---- .../fingerprint/FingerprintAuthenticator.java | 6 +- .../fingerprint/FingerprintService.java | 6 +- .../sensors/fingerprint/ServiceProvider.java | 8 +- .../aidl/BiometricTestSessionImpl.java | 29 +------ .../fingerprint/aidl/FingerprintProvider.java | 14 ++-- .../sensors/fingerprint/aidl/Sensor.java | 6 +- .../hidl/BiometricTestSessionImpl.java | 27 +------ .../fingerprint/hidl/Fingerprint21.java | 20 ++--- .../sensors/iris/IrisAuthenticator.java | 4 +- 29 files changed, 72 insertions(+), 303 deletions(-) delete mode 100644 core/java/android/hardware/biometrics/ITestSessionCallback.aidl diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java index 5b28e0035b09f..4ca31050bd529 100644 --- a/core/java/android/hardware/biometrics/BiometricManager.java +++ b/core/java/android/hardware/biometrics/BiometricManager.java @@ -237,8 +237,7 @@ public class BiometricManager { public BiometricTestSession createTestSession(int sensorId) { try { return new BiometricTestSession(mContext, sensorId, - (context, sensorId1, callback) -> mService - .createTestSession(sensorId1, callback, context.getOpPackageName())); + mService.createTestSession(sensorId, mContext.getOpPackageName())); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/biometrics/BiometricTestSession.java b/core/java/android/hardware/biometrics/BiometricTestSession.java index ff1a17e07c113..1c3560882f1bc 100644 --- a/core/java/android/hardware/biometrics/BiometricTestSession.java +++ b/core/java/android/hardware/biometrics/BiometricTestSession.java @@ -19,7 +19,6 @@ package android.hardware.biometrics; import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; -import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.TestApi; import android.content.Context; @@ -28,9 +27,6 @@ import android.os.RemoteException; import android.util.ArraySet; import android.util.Log; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - /** * Common set of interfaces to test biometric-related APIs, including {@link BiometricPrompt} and * {@link android.hardware.fingerprint.FingerprintManager}. @@ -40,58 +36,22 @@ import java.util.concurrent.TimeUnit; public class BiometricTestSession implements AutoCloseable { private static final String TAG = "BiometricTestSession"; - /** - * @hide - */ - public interface TestSessionProvider { - @NonNull - ITestSession createTestSession(@NonNull Context context, int sensorId, - @NonNull ITestSessionCallback callback) throws RemoteException; - } - private final Context mContext; private final int mSensorId; private final ITestSession mTestSession; // Keep track of users that were tested, which need to be cleaned up when finishing. - @NonNull private final ArraySet mTestedUsers; - - // Track the users currently cleaning up, and provide a latch that gets notified when all - // users have finished cleaning up. This is an imperfect system, as there can technically be - // multiple cleanups per user. Theoretically we should track the cleanup's BaseClientMonitor's - // unique ID, but it's complicated to plumb it through. This should be fine for now. - @Nullable private CountDownLatch mCloseLatch; - @NonNull private final ArraySet mUsersCleaningUp; - - private final ITestSessionCallback mCallback = new ITestSessionCallback.Stub() { - @Override - public void onCleanupStarted(int userId) { - Log.d(TAG, "onCleanupStarted, sensor: " + mSensorId + ", userId: " + userId); - } - - @Override - public void onCleanupFinished(int userId) { - Log.d(TAG, "onCleanupFinished, sensor: " + mSensorId - + ", userId: " + userId - + ", remaining users: " + mUsersCleaningUp.size()); - mUsersCleaningUp.remove(userId); - - if (mUsersCleaningUp.isEmpty() && mCloseLatch != null) { - mCloseLatch.countDown(); - } - } - }; + private final ArraySet mTestedUsers; /** * @hide */ public BiometricTestSession(@NonNull Context context, int sensorId, - @NonNull TestSessionProvider testSessionProvider) throws RemoteException { + @NonNull ITestSession testSession) { mContext = context; mSensorId = sensorId; - mTestSession = testSessionProvider.createTestSession(context, sensorId, mCallback); + mTestSession = testSession; mTestedUsers = new ArraySet<>(); - mUsersCleaningUp = new ArraySet<>(); setTestHalEnabled(true); } @@ -216,11 +176,6 @@ public class BiometricTestSession implements AutoCloseable { @RequiresPermission(TEST_BIOMETRIC) public void cleanupInternalState(int userId) { try { - if (mUsersCleaningUp.contains(userId)) { - Log.w(TAG, "Cleanup already in progress for user: " + userId); - } - - mUsersCleaningUp.add(userId); mTestSession.cleanupInternalState(userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); @@ -230,24 +185,12 @@ public class BiometricTestSession implements AutoCloseable { @Override @RequiresPermission(TEST_BIOMETRIC) public void close() { - // Cleanup can be performed using the test HAL, since it always responds to enumerate with - // zero enrollments. - if (!mTestedUsers.isEmpty()) { - mCloseLatch = new CountDownLatch(1); - for (int user : mTestedUsers) { - cleanupInternalState(user); - } - - try { - Log.d(TAG, "Awaiting latch..."); - mCloseLatch.await(10, TimeUnit.SECONDS); - Log.d(TAG, "Finished awaiting"); - } catch (InterruptedException e) { - Log.e(TAG, "Latch interrupted", e); - } - } - - // Disable the test HAL after the sensor becomes idle. + // Disable the test HAL first, so that enumerate is run on the real HAL, which should have + // no enrollments. Test-only framework enrollments will be deleted. setTestHalEnabled(false); + + for (int user : mTestedUsers) { + cleanupInternalState(user); + } } } diff --git a/core/java/android/hardware/biometrics/IAuthService.aidl b/core/java/android/hardware/biometrics/IAuthService.aidl index d8c9dbc849a9b..0dfd5dbf300e9 100644 --- a/core/java/android/hardware/biometrics/IAuthService.aidl +++ b/core/java/android/hardware/biometrics/IAuthService.aidl @@ -20,7 +20,6 @@ import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback; import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; @@ -33,7 +32,7 @@ import android.hardware.biometrics.SensorPropertiesInternal; */ interface IAuthService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); + ITestSession createTestSession(int sensorId, String opPackageName); // Retrieve static sensor properties for all biometric sensors List getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl index 7639c5dd4d16b..c854ac9847d8c 100644 --- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl +++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl @@ -20,7 +20,6 @@ import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.face.IFaceServiceReceiver; import android.hardware.face.Face; @@ -33,7 +32,7 @@ import android.hardware.face.Face; interface IBiometricAuthenticator { // Creates a test session - ITestSession createTestSession(ITestSessionCallback callback, String opPackageName); + ITestSession createTestSession(String opPackageName); // Retrieve static sensor properties SensorPropertiesInternal getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl index 24331863a05fc..a14a910a9e504 100644 --- a/core/java/android/hardware/biometrics/IBiometricService.aidl +++ b/core/java/android/hardware/biometrics/IBiometricService.aidl @@ -21,7 +21,6 @@ import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; @@ -31,7 +30,7 @@ import android.hardware.biometrics.SensorPropertiesInternal; */ interface IBiometricService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); + ITestSession createTestSession(int sensorId, String opPackageName); // Retrieve static sensor properties for all biometric sensors List getSensorProperties(String opPackageName); diff --git a/core/java/android/hardware/biometrics/ITestSession.aidl b/core/java/android/hardware/biometrics/ITestSession.aidl index f8395a119c0b4..fa7a62c53531e 100644 --- a/core/java/android/hardware/biometrics/ITestSession.aidl +++ b/core/java/android/hardware/biometrics/ITestSession.aidl @@ -18,7 +18,7 @@ package android.hardware.biometrics; import android.hardware.biometrics.SensorPropertiesInternal; /** - * A test service for FingerprintManager and BiometricManager. + * A test service for FingerprintManager and BiometricPrompt. * @hide */ interface ITestSession { diff --git a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl b/core/java/android/hardware/biometrics/ITestSessionCallback.aidl deleted file mode 100644 index 3d9517f29548f..0000000000000 --- a/core/java/android/hardware/biometrics/ITestSessionCallback.aidl +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.hardware.biometrics; - -/** - * ITestSession callback for FingerprintManager and BiometricManager. - * @hide - */ -interface ITestSessionCallback { - void onCleanupStarted(int userId); - void onCleanupFinished(int userId); -} diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index 6e7c701ef5ff8..a2e0b3b1cb411 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -19,7 +19,6 @@ import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.face.IFaceServiceReceiver; import android.hardware.face.Face; import android.hardware.face.FaceSensorPropertiesInternal; @@ -33,7 +32,7 @@ import android.view.Surface; interface IFaceService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); + ITestSession createTestSession(int sensorId, String opPackageName); // Requests a proto dump of the specified sensor byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer); diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 9d086cf203e29..6df2764d3f8bf 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -154,8 +154,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing public BiometricTestSession createTestSession(int sensorId) { try { return new BiometricTestSession(mContext, sensorId, - (context, sensorId1, callback) -> mService - .createTestSession(sensorId1, callback, context.getOpPackageName())); + mService.createTestSession(sensorId, mContext.getOpPackageName())); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index 054c0d0f65132..1694fef0f71bf 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -19,7 +19,6 @@ import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.IFingerprintClientActiveCallback; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IUdfpsOverlayController; @@ -34,7 +33,7 @@ import java.util.List; interface IFingerprintService { // Creates a test session with the specified sensorId - ITestSession createTestSession(int sensorId, ITestSessionCallback callback, String opPackageName); + ITestSession createTestSession(int sensorId, String opPackageName); // Requests a proto dump of the specified sensor byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer); diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index e19745e5c5780..b15a8869b22a4 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -40,7 +40,6 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.face.IFaceService; @@ -145,14 +144,13 @@ public class AuthService extends SystemService { private final class AuthServiceImpl extends IAuthService.Stub { @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) throws RemoteException { + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) + throws RemoteException { Utils.checkPermission(getContext(), TEST_BIOMETRIC); final long identity = Binder.clearCallingIdentity(); try { - return mInjector.getBiometricService() - .createTestSession(sensorId, callback, opPackageName); + return mInjector.getBiometricService().createTestSession(sensorId, opPackageName); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java index 00a4e43f347dc..614c5f1b65bfb 100644 --- a/services/core/java/com/android/server/biometrics/BiometricService.java +++ b/services/core/java/com/android/server/biometrics/BiometricService.java @@ -44,7 +44,6 @@ import android.hardware.biometrics.IBiometricServiceReceiver; import android.hardware.biometrics.IBiometricSysuiReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.PromptInfo; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.fingerprint.FingerprintManager; @@ -571,13 +570,13 @@ public class BiometricService extends SystemService { */ private final class BiometricServiceWrapper extends IBiometricService.Stub { @Override // Binder call - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) throws RemoteException { + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) + throws RemoteException { checkInternalPermission(); for (BiometricSensor sensor : mSensors) { if (sensor.id == sensorId) { - return sensor.impl.createTestSession(callback, opPackageName); + return sensor.impl.createTestSession(opPackageName); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java index 06b049be4501d..f37cf18a13207 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java @@ -21,7 +21,6 @@ import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.face.IFaceService; import android.os.IBinder; @@ -42,9 +41,8 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub { } @Override - public ITestSession createTestSession(@NonNull ITestSessionCallback callback, - @NonNull String opPackageName) throws RemoteException { - return mFaceService.createTestSession(mSensorId, callback, opPackageName); + public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException { + return mFaceService.createTestSession(mSensorId, opPackageName); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java index 6dbd590df8515..b0433d67ff32f 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java @@ -31,7 +31,6 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.IFace; import android.hardware.biometrics.face.SensorProps; import android.hardware.face.Face; @@ -134,8 +133,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba */ private final class FaceServiceWrapper extends IFaceService.Stub { @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) { + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); final ServiceProvider provider = getProviderForSensor(sensorId); @@ -145,7 +143,7 @@ public class FaceService extends SystemService implements BiometricServiceCallba return null; } - return provider.createTestSession(sensorId, callback, opPackageName); + return provider.createTestSession(sensorId, opPackageName); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java index 88edfbf12df11..0b522efb5bac4 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.face.Face; import android.hardware.face.FaceManager; import android.hardware.face.FaceSensorPropertiesInternal; @@ -29,7 +28,6 @@ import android.os.IBinder; import android.os.NativeHandle; import android.util.proto.ProtoOutputStream; -import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; @@ -125,8 +123,7 @@ public interface ServiceProvider { void startPreparedClient(int sensorId, int cookie); - void scheduleInternalCleanup(int sensorId, int userId, - @Nullable BaseClientMonitor.Callback callback); + void scheduleInternalCleanup(int sensorId, int userId); void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto, boolean clearSchedulerBuffer); @@ -136,8 +133,7 @@ public interface ServiceProvider { void dumpInternal(int sensorId, @NonNull PrintWriter pw); @NonNull - ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName); + ITestSession createTestSession(int sensorId, @NonNull String opPackageName); void dumpHal(int sensorId, @NonNull FileDescriptor fd, @NonNull String[] args); } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java index a5e6ddb816699..897ebd719da42 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/BiometricTestSessionImpl.java @@ -21,7 +21,6 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.BaseFrame; import android.hardware.face.Face; @@ -29,12 +28,10 @@ import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceEnrollFrame; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; -import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.Utils; -import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.face.FaceUtils; import java.util.HashSet; @@ -52,7 +49,6 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; - @NonNull private final ITestSessionCallback mCallback; @NonNull private final FaceProvider mProvider; @NonNull private final Sensor mSensor; @NonNull private final Set mEnrollmentIds; @@ -136,11 +132,9 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { }; BiometricTestSessionImpl(@NonNull Context context, int sensorId, - @NonNull ITestSessionCallback callback, @NonNull FaceProvider provider, @NonNull Sensor sensor) { mContext = context; mSensorId = sensorId; - mCallback = callback; mProvider = provider; mSensor = sensor; mEnrollmentIds = new HashSet<>(); @@ -230,25 +224,6 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { - @Override - public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { - try { - mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - - @Override - public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, - boolean success) { - try { - mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - }); + mProvider.scheduleInternalCleanup(mSensorId, userId); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index 1d8f210b394e6..e7f9aa597b13e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -25,7 +25,6 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.IFace; import android.hardware.biometrics.face.SensorProps; import android.hardware.face.Face; @@ -178,8 +177,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { for (int i = 0; i < mSensors.size(); i++) { final int sensorId = mSensors.keyAt(i); scheduleLoadAuthenticatorIds(sensorId); - scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser(), - null /* callback */); + scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser()); } return mDaemon; @@ -564,8 +562,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { } @Override - public void scheduleInternalCleanup(int sensorId, int userId, - @Nullable BaseClientMonitor.Callback callback) { + public void scheduleInternalCleanup(int sensorId, int userId) { mHandler.post(() -> { final IFace daemon = getHalInstance(); if (daemon == null) { @@ -586,7 +583,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { FaceUtils.getInstance(sensorId), mSensors.get(sensorId).getAuthenticatorIds()); - mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback); + mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e); } @@ -649,9 +646,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) { - return mSensors.get(sensorId).createTestSession(callback); + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + return mSensors.get(sensorId).createTestSession(); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java index 3434acbf73cc2..4925ce0bb2b15 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.AuthenticationFrame; import android.hardware.biometrics.face.EnrollmentFrame; import android.hardware.biometrics.face.Error; @@ -460,9 +459,8 @@ public class Sensor { } } - @NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback) { - return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, - mProvider, this); + @NonNull ITestSession createTestSession() { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this); } void createNewSession(@NonNull IFace daemon, int sensorId, int userId) diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java index e8668ed1b6c57..d519d60881c0a 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/BiometricTestSessionImpl.java @@ -21,17 +21,14 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.face.Face; import android.hardware.face.FaceAuthenticationFrame; import android.hardware.face.FaceEnrollFrame; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; -import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.Utils; -import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.face.FaceUtils; import java.util.ArrayList; @@ -46,7 +43,6 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; - @NonNull private final ITestSessionCallback mCallback; @NonNull private final Face10 mFace10; @NonNull private final Face10.HalResultController mHalResultController; @NonNull private final Set mEnrollmentIds; @@ -124,12 +120,10 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { } }; - BiometricTestSessionImpl(@NonNull Context context, int sensorId, - @NonNull ITestSessionCallback callback, @NonNull Face10 face10, + BiometricTestSessionImpl(@NonNull Context context, int sensorId, @NonNull Face10 face10, @NonNull Face10.HalResultController halResultController) { mContext = context; mSensorId = sensorId; - mCallback = callback; mFace10 = face10; mHalResultController = halResultController; mEnrollmentIds = new HashSet<>(); @@ -207,25 +201,6 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mFace10.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { - @Override - public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { - try { - mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - - @Override - public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, - boolean success) { - try { - mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - }); + mFace10.scheduleInternalCleanup(mSensorId, userId); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index ee8823e041bc7..298950fa325a8 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -29,7 +29,6 @@ import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.face.V1_0.IBiometricsFace; import android.hardware.biometrics.face.V1_0.IBiometricsFaceClientCallback; import android.hardware.face.Face; @@ -124,7 +123,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() { @Override public void onUserSwitching(int newUserId) { - scheduleInternalCleanup(newUserId, null /* callback */); + scheduleInternalCleanup(newUserId); scheduleGetFeature(mSensorId, new Binder(), newUserId, BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null, mContext.getOpPackageName()); @@ -438,7 +437,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { Slog.d(TAG, "Face HAL ready, HAL ID: " + halId); if (halId != 0) { scheduleLoadAuthenticatorIds(); - scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */); + scheduleInternalCleanup(ActivityManager.getCurrentUser()); scheduleGetFeature(mSensorId, new Binder(), ActivityManager.getCurrentUser(), BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION, null, @@ -757,8 +756,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { }); } - private void scheduleInternalCleanup(int userId, - @Nullable BaseClientMonitor.Callback callback) { + private void scheduleInternalCleanup(int userId) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -766,14 +764,13 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext, mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId, enrolledList, FaceUtils.getLegacyInstance(mSensorId), mAuthenticatorIds); - mScheduler.scheduleClientMonitor(client, callback); + mScheduler.scheduleClientMonitor(client); }); } @Override - public void scheduleInternalCleanup(int sensorId, int userId, - @Nullable BaseClientMonitor.Callback callback) { - scheduleInternalCleanup(userId, callback); + public void scheduleInternalCleanup(int sensorId, int userId) { + scheduleInternalCleanup(userId); } @Override @@ -947,9 +944,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) { - return new BiometricTestSessionImpl(mContext, mSensorId, callback, this, - mHalResultController); + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + return new BiometricTestSessionImpl(mContext, mSensorId, this, mHalResultController); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java index 32e9409de4b2d..34a909908b5ab 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java @@ -21,7 +21,6 @@ import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.fingerprint.IFingerprintService; import android.os.IBinder; @@ -43,9 +42,8 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub } @Override - public ITestSession createTestSession(@NonNull ITestSessionCallback callback, - @NonNull String opPackageName) throws RemoteException { - return mFingerprintService.createTestSession(mSensorId, callback, opPackageName); + public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException { + return mFingerprintService.createTestSession(mSensorId, opPackageName); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index 396dd5f42d4d8..b302931b99615 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -43,7 +43,6 @@ import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricServiceLockoutResetCallback; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.SensorProps; import android.hardware.fingerprint.Fingerprint; @@ -110,8 +109,7 @@ public class FingerprintService extends SystemService implements BiometricServic */ private final class FingerprintServiceWrapper extends IFingerprintService.Stub { @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) { + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { Utils.checkPermission(getContext(), TEST_BIOMETRIC); final ServiceProvider provider = getProviderForSensor(sensorId); @@ -121,7 +119,7 @@ public class FingerprintService extends SystemService implements BiometricServic return null; } - return provider.createTestSession(sensorId, callback, opPackageName); + return provider.createTestSession(sensorId, opPackageName); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java index dfec2e3e308f7..8785070f0afad 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java @@ -20,7 +20,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; @@ -29,7 +28,6 @@ import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.IBinder; import android.util.proto.ProtoOutputStream; -import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; import com.android.server.biometrics.sensors.LockoutTracker; @@ -104,8 +102,7 @@ public interface ServiceProvider { @NonNull IFingerprintServiceReceiver receiver, int userId, @NonNull String opPackageName); - void scheduleInternalCleanup(int sensorId, int userId, - @Nullable BaseClientMonitor.Callback callback); + void scheduleInternalCleanup(int sensorId, int userId); boolean isHardwareDetected(int sensorId); @@ -140,6 +137,5 @@ public interface ServiceProvider { void dumpInternal(int sensorId, @NonNull PrintWriter pw); @NonNull - ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName); + ITestSession createTestSession(int sensorId, @NonNull String opPackageName); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java index 20b32543f7a03..ea9c709ec79f5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/BiometricTestSessionImpl.java @@ -21,17 +21,14 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.Binder; -import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.HardwareAuthTokenUtils; import com.android.server.biometrics.Utils; -import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import java.util.HashSet; @@ -49,7 +46,6 @@ class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; - @NonNull private final ITestSessionCallback mCallback; @NonNull private final FingerprintProvider mProvider; @NonNull private final Sensor mSensor; @NonNull private final Set mEnrollmentIds; @@ -114,11 +110,9 @@ class BiometricTestSessionImpl extends ITestSession.Stub { }; BiometricTestSessionImpl(@NonNull Context context, int sensorId, - @NonNull ITestSessionCallback callback, @NonNull FingerprintProvider provider, - @NonNull Sensor sensor) { + @NonNull FingerprintProvider provider, @NonNull Sensor sensor) { mContext = context; mSensorId = sensorId; - mCallback = callback; mProvider = provider; mSensor = sensor; mEnrollmentIds = new HashSet<>(); @@ -198,25 +192,6 @@ class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mProvider.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { - @Override - public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { - try { - mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - - @Override - public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, - boolean success) { - try { - mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - }); + mProvider.scheduleInternalCleanup(mSensorId, userId); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index 598cc8992c2db..e3502cb1038f3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -25,7 +25,6 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.SensorProps; import android.hardware.fingerprint.Fingerprint; @@ -186,8 +185,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi for (int i = 0; i < mSensors.size(); i++) { final int sensorId = mSensors.keyAt(i); scheduleLoadAuthenticatorIds(sensorId); - scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser(), - null /* callback */); + scheduleInternalCleanup(sensorId, ActivityManager.getCurrentUser()); } return mDaemon; @@ -541,8 +539,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } @Override - public void scheduleInternalCleanup(int sensorId, int userId, - @Nullable BaseClientMonitor.Callback callback) { + public void scheduleInternalCleanup(int sensorId, int userId) { mHandler.post(() -> { final IFingerprint daemon = getHalInstance(); if (daemon == null) { @@ -562,7 +559,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi mContext.getOpPackageName(), sensorId, enrolledList, FingerprintUtils.getInstance(sensorId), mSensors.get(sensorId).getAuthenticatorIds()); - mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client, callback); + mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when scheduling internal cleanup", e); } @@ -707,9 +704,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) { - return mSensors.get(sensorId).createTestSession(callback); + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + return mSensors.get(sensorId).createTestSession(); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index a98e7db43f790..c83c0fba01335 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java @@ -22,7 +22,6 @@ import android.content.Context; import android.content.pm.UserInfo; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.Error; import android.hardware.biometrics.fingerprint.IFingerprint; import android.hardware.biometrics.fingerprint.ISession; @@ -440,9 +439,8 @@ class Sensor { } } - @NonNull ITestSession createTestSession(@NonNull ITestSessionCallback callback) { - return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, - mProvider, this); + @NonNull ITestSession createTestSession() { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, mProvider, this); } void createNewSession(@NonNull IFingerprint daemon, int sensorId, int userId) diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java index 766a8829e9682..312ee0a267ac3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/BiometricTestSessionImpl.java @@ -21,16 +21,13 @@ import static android.Manifest.permission.TEST_BIOMETRIC; import android.annotation.NonNull; import android.content.Context; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.os.Binder; -import android.os.RemoteException; import android.util.Slog; import com.android.server.biometrics.Utils; -import com.android.server.biometrics.sensors.BaseClientMonitor; import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; import java.util.ArrayList; @@ -50,7 +47,6 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { @NonNull private final Context mContext; private final int mSensorId; - @NonNull private final ITestSessionCallback mCallback; @NonNull private final Fingerprint21 mFingerprint21; @NonNull private final Fingerprint21.HalResultController mHalResultController; @NonNull private final Set mEnrollmentIds; @@ -115,12 +111,10 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { }; BiometricTestSessionImpl(@NonNull Context context, int sensorId, - @NonNull ITestSessionCallback callback, @NonNull Fingerprint21 fingerprint21, @NonNull Fingerprint21.HalResultController halResultController) { mContext = context; mSensorId = sensorId; - mCallback = callback; mFingerprint21 = fingerprint21; mHalResultController = halResultController; mEnrollmentIds = new HashSet<>(); @@ -197,25 +191,6 @@ public class BiometricTestSessionImpl extends ITestSession.Stub { public void cleanupInternalState(int userId) { Utils.checkPermission(mContext, TEST_BIOMETRIC); - mFingerprint21.scheduleInternalCleanup(mSensorId, userId, new BaseClientMonitor.Callback() { - @Override - public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { - try { - mCallback.onCleanupStarted(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - - @Override - public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, - boolean success) { - try { - mCallback.onCleanupFinished(clientMonitor.getTargetUserId()); - } catch (RemoteException e) { - Slog.e(TAG, "Remote exception", e); - } - } - }); + mFingerprint21.scheduleInternalCleanup(mSensorId, userId); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index 6e22a797b435b..bedd66465a1a4 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -30,7 +30,6 @@ import android.hardware.biometrics.BiometricManager; import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint; import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback; import android.hardware.fingerprint.Fingerprint; @@ -159,7 +158,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider private final UserSwitchObserver mUserSwitchObserver = new SynchronousUserSwitchObserver() { @Override public void onUserSwitching(int newUserId) { - scheduleInternalCleanup(newUserId, null /* callback */); + scheduleInternalCleanup(newUserId); } }; @@ -438,7 +437,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider Slog.d(TAG, "Fingerprint HAL ready, HAL ID: " + halId); if (halId != 0) { scheduleLoadAuthenticatorIds(); - scheduleInternalCleanup(ActivityManager.getCurrentUser(), null /* callback */); + scheduleInternalCleanup(ActivityManager.getCurrentUser()); } else { Slog.e(TAG, "Unable to set callback"); mDaemon = null; @@ -662,8 +661,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider }); } - private void scheduleInternalCleanup(int userId, - @Nullable BaseClientMonitor.Callback callback) { + private void scheduleInternalCleanup(int userId) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -673,14 +671,13 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider mContext, mLazyDaemon, userId, mContext.getOpPackageName(), mSensorProperties.sensorId, enrolledList, FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds); - mScheduler.scheduleClientMonitor(client, callback); + mScheduler.scheduleClientMonitor(client); }); } @Override - public void scheduleInternalCleanup(int sensorId, int userId, - @Nullable BaseClientMonitor.Callback callback) { - scheduleInternalCleanup(userId, callback); + public void scheduleInternalCleanup(int sensorId, int userId) { + scheduleInternalCleanup(userId); } @Override @@ -860,9 +857,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider @NonNull @Override - public ITestSession createTestSession(int sensorId, @NonNull ITestSessionCallback callback, - @NonNull String opPackageName) { - return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, callback, this, + public ITestSession createTestSession(int sensorId, @NonNull String opPackageName) { + return new BiometricTestSessionImpl(mContext, mSensorProperties.sensorId, this, mHalResultController); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java index f44e0691bb9d0..8e84613b2d645 100644 --- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java +++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java @@ -21,7 +21,6 @@ import android.hardware.biometrics.IBiometricAuthenticator; import android.hardware.biometrics.IBiometricSensorReceiver; import android.hardware.biometrics.IInvalidationCallback; import android.hardware.biometrics.ITestSession; -import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.iris.IIrisService; import android.os.IBinder; @@ -40,8 +39,7 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub { } @Override - public ITestSession createTestSession(@NonNull ITestSessionCallback callback, - @NonNull String opPackageName) throws RemoteException { + public ITestSession createTestSession(@NonNull String opPackageName) throws RemoteException { return null; } From bc56632da95b52d5f58bc8c771779a0ee8cefc49 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Fri, 19 Feb 2021 19:10:04 +0000 Subject: [PATCH 014/176] Revert "Update RemovalClient to support new biometric AIDL" Revert submission 13593269 Reason for revert: Bug: 180689674 Reverted Changes: I59f6e607f:Update RemovalClient to support new biometric AIDL... I3fdb3fe0b:Try to ensure tests run sequentially Change-Id: I939172f2961f3f2c9f8eddd59261f75552eeb31f (cherry picked from commit 62e2c705c50c3def86a401804c2a5d07bffbf290) --- .../android/hardware/face/FaceManager.java | 23 +++++-------------- .../android/hardware/face/IFaceService.aidl | 5 +--- .../fingerprint/FingerprintManager.java | 21 ++++------------- .../fingerprint/IFingerprintService.aidl | 3 --- .../biometrics/sensors/RemovalClient.java | 7 +++--- .../biometrics/sensors/face/FaceService.java | 17 +------------- .../sensors/face/ServiceProvider.java | 3 --- .../face/aidl/FaceInternalCleanupClient.java | 4 ++-- .../sensors/face/aidl/FaceProvider.java | 21 +---------------- .../sensors/face/aidl/FaceRemovalClient.java | 13 ++++------- .../biometrics/sensors/face/hidl/Face10.java | 14 ----------- .../sensors/face/hidl/FaceRemovalClient.java | 5 +--- .../fingerprint/FingerprintService.java | 16 +------------ .../sensors/fingerprint/ServiceProvider.java | 4 ---- .../FingerprintInternalCleanupClient.java | 4 ++-- .../fingerprint/aidl/FingerprintProvider.java | 23 +------------------ .../aidl/FingerprintRemovalClient.java | 10 ++++---- .../fingerprint/hidl/Fingerprint21.java | 17 -------------- .../hidl/FingerprintRemovalClient.java | 5 +--- .../locksettings/LockSettingsService.java | 23 ++++++++++++------- .../LockSettingsServiceTests.java | 8 +++---- 21 files changed, 54 insertions(+), 192 deletions(-) diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index a9bcdeff7e477..886a8c1fdae57 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -574,23 +574,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver, mContext.getOpPackageName()); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - } - - /** - * Removes all face templates for the given user. - * @hide - */ - @RequiresPermission(MANAGE_BIOMETRIC) - public void removeAll(int userId, @NonNull RemovalCallback callback) { - if (mService != null) { - try { - mRemovalCallback = callback; - mService.removeAll(mToken, userId, mServiceReceiver, mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Slog.w(TAG, "Remote exception in remove: ", e); + if (callback != null) { + callback.onRemovalError(face, FACE_ERROR_HW_UNAVAILABLE, + getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE, + 0 /* vendorCode */)); + } } } } diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index a2e0b3b1cb411..a3e7e2d2c5cbc 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -83,13 +83,10 @@ interface IFaceService { // Cancel enrollment in progress void cancelEnrollment(IBinder token); - // Removes the specified face enrollment for the specified userId. + // Any errors resulting from this call will be returned to the listener void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver, String opPackageName); - // Removes all face enrollments for the specified userId. - void removeAll(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName); - // Get the enrolled face for user. List getEnrolledFaces(int sensorId, int userId, String opPackageName); diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index 6df2764d3f8bf..a614ebfe1793a 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -739,22 +739,11 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing mService.remove(mToken, fp.getBiometricId(), userId, mServiceReceiver, mContext.getOpPackageName()); } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Removes all face templates for the given user. - * @hide - */ - @RequiresPermission(MANAGE_FINGERPRINT) - public void removeAll(int userId, @NonNull RemovalCallback callback) { - if (mService != null) { - try { - mRemovalCallback = callback; - mService.removeAll(mToken, userId, mServiceReceiver, mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); + Slog.w(TAG, "Remote exception in remove: ", e); + if (callback != null) { + callback.onRemovalError(fp, FINGERPRINT_ERROR_HW_UNAVAILABLE, + getErrorString(mContext, FINGERPRINT_ERROR_HW_UNAVAILABLE, + 0 /* vendorCode */)); } } } diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index 1694fef0f71bf..8888247e2823f 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -87,9 +87,6 @@ interface IFingerprintService { void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver, String opPackageName); - // Removes all face enrollments for the specified userId. - void removeAll(IBinder token, int userId, IFingerprintServiceReceiver receiver, String opPackageName); - // Rename the fingerprint specified by fingerId and userId to the given name void rename(int fingerId, int userId, String name); diff --git a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java index 16f82af938560..e0626952fac3c 100644 --- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java @@ -37,16 +37,18 @@ public abstract class RemovalClient mBiometricUtils; private final Map mAuthenticatorIds; public RemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, - int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, - @NonNull Map authenticatorIds, int statsModality) { + int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, + int sensorId, @NonNull Map authenticatorIds, int statsModality) { super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId, statsModality, BiometricsProtoEnums.ACTION_REMOVE, BiometricsProtoEnums.CLIENT_UNKNOWN); + mBiometricId = biometricId; mBiometricUtils = utils; mAuthenticatorIds = authenticatorIds; } @@ -66,7 +68,6 @@ public abstract class RemovalClient provider = getSingleProvider(); - if (provider == null) { - Slog.w(TAG, "Null provider for removeAll"); - return; - } - - provider.second.scheduleRemoveAll(provider.first, token, userId, receiver, - opPackageName); - } - - @Override // Binder call + @Override public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback, final String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java index 0b522efb5bac4..cc24b8960e756 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java @@ -109,9 +109,6 @@ public interface ServiceProvider { void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName); - void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId, - @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName); - void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken); void scheduleSetFeature(int sensorId, @NonNull IBinder token, int userId, int feature, diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java index c6696aed6520d..9680e4e1841e7 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceInternalCleanupClient.java @@ -61,7 +61,7 @@ class FaceInternalCleanupClient extends InternalCleanupClient { // Internal remove does not need to send results to anyone. Cleanup (enumerate + remove) // is all done internally. return new FaceRemovalClient(context, lazyDaemon, token, - null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner, - utils, sensorId, authenticatorIds); + null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils, + sensorId, authenticatorIds); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index e7f9aa597b13e..1b6b9d70d5ac8 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -468,25 +468,6 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { @Override public void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { - scheduleRemoveSpecifiedIds(sensorId, token, new int[] {faceId}, userId, receiver, - opPackageName); - } - - @Override - public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId, - @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { - final List faces = FaceUtils.getInstance(sensorId) - .getBiometricsForUser(mContext, userId); - final int[] faceIds = new int[faces.size()]; - for (int i = 0; i < faces.size(); i++) { - faceIds[i] = faces.get(i).getBiometricId(); - } - - scheduleRemoveSpecifiedIds(sensorId, token, faceIds, userId, receiver, opPackageName); - } - - private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token, int[] faceIds, - int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { mHandler.post(() -> { final IFace daemon = getHalInstance(); if (daemon == null) { @@ -504,7 +485,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { final FaceRemovalClient client = new FaceRemovalClient(mContext, mSensors.get(sensorId).getLazySession(), token, - new ClientMonitorCallbackConverter(receiver), faceIds, userId, + new ClientMonitorCallbackConverter(receiver), faceId, userId, opPackageName, FaceUtils.getInstance(sensorId), sensorId, mSensors.get(sensorId).getAuthenticatorIds()); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java index 48796c173dd8d..1cb5031374ec2 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceRemovalClient.java @@ -38,22 +38,19 @@ import java.util.Map; class FaceRemovalClient extends RemovalClient { private static final String TAG = "FaceRemovalClient"; - final int[] mBiometricIds; - FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, - int[] biometricIds, int userId, @NonNull String owner, - @NonNull BiometricUtils utils, int sensorId, - @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, + int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, + int sensorId, @NonNull Map authenticatorIds) { + super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FACE); - mBiometricIds = biometricIds; } @Override protected void startHalOperation() { try { - getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds); + final int[] ids = new int[]{mBiometricId}; + getFreshDaemon().removeEnrollments(mSequentialId, ids); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting remove", e); mCallback.onClientFinished(this, false /* success */); diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index 298950fa325a8..e46661a5e985f 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -671,20 +671,6 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { }); } - @Override - public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, int userId, - @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName) { - mHandler.post(() -> { - scheduleUpdateActiveUserWithoutHandler(userId); - - // For IBiometricsFace@1.0, remove(0) means remove all enrollments - final FaceRemovalClient client = new FaceRemovalClient(mContext, mLazyDaemon, token, - new ClientMonitorCallbackConverter(receiver), 0 /* faceId */, userId, - opPackageName, - FaceUtils.getLegacyInstance(mSensorId), mSensorId, mAuthenticatorIds); - mScheduler.scheduleClientMonitor(client); - }); - } @Override public void scheduleResetLockout(int sensorId, int userId, @NonNull byte[] hardwareAuthToken) { diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java index 3ae201134debb..d63791c99dd45 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceRemovalClient.java @@ -38,15 +38,12 @@ import java.util.Map; class FaceRemovalClient extends RemovalClient { private static final String TAG = "FaceRemovalClient"; - private final int mBiometricId; - FaceRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, + super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FACE); - mBiometricId = biometricId; } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index b302931b99615..b0e42cd137eb5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -499,21 +499,7 @@ public class FingerprintService extends SystemService implements BiometricServic opPackageName); } - @Override // Binder call - public void removeAll(final IBinder token, final int userId, - final IFingerprintServiceReceiver receiver, final String opPackageName) { - Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); - - final Pair provider = getSingleProvider(); - if (provider == null) { - Slog.w(TAG, "Null provider for removeAll"); - return; - } - provider.second.scheduleRemoveAll(provider.first, token, receiver, userId, - opPackageName); - } - - @Override // Binder call + @Override public void addLockoutResetCallback(final IBiometricServiceLockoutResetCallback callback, final String opPackageName) { Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java index 8785070f0afad..f672ae56e0206 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java @@ -98,10 +98,6 @@ public interface ServiceProvider { @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName); - void scheduleRemoveAll(int sensorId, @NonNull IBinder token, - @NonNull IFingerprintServiceReceiver receiver, int userId, - @NonNull String opPackageName); - void scheduleInternalCleanup(int sensorId, int userId); boolean isHardwareDetected(int sensorId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java index 0de3f4f8cce23..2a0e984e59334 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintInternalCleanupClient.java @@ -60,7 +60,7 @@ class FingerprintInternalCleanupClient extends InternalCleanupClient utils, int sensorId, Map authenticatorIds) { return new FingerprintRemovalClient(context, lazyDaemon, token, - null /* ClientMonitorCallbackConverter */, new int[] {biometricId}, userId, owner, - utils, sensorId, authenticatorIds); + null /* ClientMonitorCallbackConverter */, biometricId, userId, owner, utils, + sensorId, authenticatorIds); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index e3502cb1038f3..0bd2f241ed8d2 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -490,27 +490,6 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi public void scheduleRemove(int sensorId, @NonNull IBinder token, @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName) { - scheduleRemoveSpecifiedIds(sensorId, token, new int[] {fingerId}, userId, receiver, - opPackageName); - } - - @Override - public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, - @NonNull IFingerprintServiceReceiver receiver, int userId, - @NonNull String opPackageName) { - final List fingers = FingerprintUtils.getInstance(sensorId) - .getBiometricsForUser(mContext, userId); - final int[] fingerIds = new int[fingers.size()]; - for (int i = 0; i < fingers.size(); i++) { - fingerIds[i] = fingers.get(i).getBiometricId(); - } - - scheduleRemoveSpecifiedIds(sensorId, token, fingerIds, userId, receiver, opPackageName); - } - - private void scheduleRemoveSpecifiedIds(int sensorId, @NonNull IBinder token, - int[] fingerprintIds, int userId, @NonNull IFingerprintServiceReceiver receiver, - @NonNull String opPackageName) { mHandler.post(() -> { final IFingerprint daemon = getHalInstance(); if (daemon == null) { @@ -528,7 +507,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext, mSensors.get(sensorId).getLazySession(), token, - new ClientMonitorCallbackConverter(receiver), fingerprintIds, userId, + new ClientMonitorCallbackConverter(receiver), fingerId, userId, opPackageName, FingerprintUtils.getInstance(sensorId), sensorId, mSensors.get(sensorId).getAuthenticatorIds()); mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java index c622208262e01..4a99a7b29638b 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java @@ -39,22 +39,20 @@ import java.util.Map; class FingerprintRemovalClient extends RemovalClient { private static final String TAG = "FingerprintRemovalClient"; - private final int[] mBiometricIds; - FingerprintRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, - @Nullable ClientMonitorCallbackConverter listener, int[] biometricIds, int userId, + @Nullable ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, + super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT); - mBiometricIds = biometricIds; } @Override protected void startHalOperation() { try { - getFreshDaemon().removeEnrollments(mSequentialId, mBiometricIds); + final int[] ids = new int[] {mBiometricId}; + getFreshDaemon().removeEnrollments(mSequentialId, ids); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting remove", e); mCallback.onClientFinished(this, false /* success */); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index bedd66465a1a4..554e3d45a3ca3 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -644,23 +644,6 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider }); } - @Override - public void scheduleRemoveAll(int sensorId, @NonNull IBinder token, - @NonNull IFingerprintServiceReceiver receiver, int userId, - @NonNull String opPackageName) { - mHandler.post(() -> { - scheduleUpdateActiveUserWithoutHandler(userId); - - // For IBiometricsFingerprint@2.1, remove(0) means remove all enrollments - final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext, - mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), - 0 /* fingerprintId */, userId, opPackageName, - FingerprintUtils.getLegacyInstance(mSensorId), - mSensorProperties.sensorId, mAuthenticatorIds); - mScheduler.scheduleClientMonitor(client); - }); - } - private void scheduleInternalCleanup(int userId) { mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java index 2f360f31a325f..f6a22f581f1a7 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintRemovalClient.java @@ -39,16 +39,13 @@ import java.util.Map; class FingerprintRemovalClient extends RemovalClient { private static final String TAG = "FingerprintRemovalClient"; - private final int mBiometricId; - FingerprintRemovalClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @NonNull Map authenticatorIds) { - super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId, + super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT); - mBiometricId = biometricId; } @Override diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 8da2d67d6691f..685e9e6ad4205 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -2902,8 +2902,11 @@ public class LockSettingsService extends ILockSettings.Stub { FingerprintManager mFingerprintManager = mInjector.getFingerprintManager(); if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) { if (mFingerprintManager.hasEnrolledFingerprints(userId)) { - final CountDownLatch latch = new CountDownLatch(1); - mFingerprintManager.removeAll(userId, fingerprintManagerRemovalCallback(latch)); + CountDownLatch latch = new CountDownLatch(1); + // For the purposes of M and N, groupId is the same as userId. + Fingerprint finger = new Fingerprint(null, userId, 0, 0); + mFingerprintManager.remove(finger, userId, + fingerprintManagerRemovalCallback(latch)); try { latch.await(10000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -2917,8 +2920,9 @@ public class LockSettingsService extends ILockSettings.Stub { FaceManager mFaceManager = mInjector.getFaceManager(); if (mFaceManager != null && mFaceManager.isHardwareDetected()) { if (mFaceManager.hasEnrolledTemplates(userId)) { - final CountDownLatch latch = new CountDownLatch(1); - mFaceManager.removeAll(userId, faceManagerRemovalCallback(latch)); + CountDownLatch latch = new CountDownLatch(1); + Face face = new Face(null, 0, 0); + mFaceManager.remove(face, userId, faceManagerRemovalCallback(latch)); try { latch.await(10000, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { @@ -2932,8 +2936,10 @@ public class LockSettingsService extends ILockSettings.Stub { CountDownLatch latch) { return new FingerprintManager.RemovalCallback() { @Override - public void onRemovalError(@Nullable Fingerprint fp, int errMsgId, CharSequence err) { - Slog.e(TAG, "Unable to remove fingerprint, error: " + err); + public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence err) { + Slog.e(TAG, String.format( + "Can't remove fingerprint %d in group %d. Reason: %s", + fp.getBiometricId(), fp.getGroupId(), err)); latch.countDown(); } @@ -2949,8 +2955,9 @@ public class LockSettingsService extends ILockSettings.Stub { private FaceManager.RemovalCallback faceManagerRemovalCallback(CountDownLatch latch) { return new FaceManager.RemovalCallback() { @Override - public void onRemovalError(@Nullable Face face, int errMsgId, CharSequence err) { - Slog.e(TAG, "Unable to remove face, error: " + err); + public void onRemovalError(Face face, int errMsgId, CharSequence err) { + Slog.e(TAG, String.format("Can't remove face %d. Reason: %s", + face.getBiometricId(), err)); latch.countDown(); } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 67d69292b476c..1f66c7c02658b 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -339,11 +339,11 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { mService.setLockCredential(nonePassword(), newPattern("123654"), PRIMARY_USER_ID); // Verify fingerprint is removed - verify(mFingerprintManager).removeAll(eq(PRIMARY_USER_ID), any()); - verify(mFaceManager).removeAll(eq(PRIMARY_USER_ID), any()); + verify(mFingerprintManager).remove(any(), eq(PRIMARY_USER_ID), any()); + verify(mFaceManager).remove(any(), eq(PRIMARY_USER_ID), any()); - verify(mFingerprintManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any()); - verify(mFaceManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any()); + verify(mFingerprintManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any()); + verify(mFaceManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any()); } @Test From e36b7b10492969c7092ad6f835f26c9bbf84b65e Mon Sep 17 00:00:00 2001 From: Jamie Garside Date: Tue, 23 Feb 2021 16:28:23 +0000 Subject: [PATCH 015/176] Revert "Update the bouncer to be able to move to either side of a wide screen." This reverts commit 868e770b824b5d776d64fd9364f24a6aa1ed5ab5. Reason for revert: Breaks password entry - b/180993584 Change-Id: I9a1771b795c90b1cfe6c2457d390ac53235c6c94 (cherry picked from commit f713b2d857ecbc0ca58d841212bdcf3ae103b7eb) --- core/java/android/provider/Settings.java | 23 -- core/res/res/values/symbols.xml | 2 - .../validators/GlobalSettingsValidators.java | 5 - .../android/provider/SettingsBackupTest.java | 1 - .../res-keyguard/layout/keyguard_bouncer.xml | 2 +- .../layout/keyguard_host_view.xml | 5 +- .../values-sw600dp-land/bools.xml | 20 -- .../SystemUI/res-keyguard/values/config.xml | 1 - .../keyguard/KeyguardSecurityContainer.java | 223 +----------------- .../KeyguardSecurityContainerController.java | 1 - .../keyguard/KeyguardSecurityModel.java | 9 - .../KeyguardSecurityContainerTest.java | 96 +------- 12 files changed, 14 insertions(+), 374 deletions(-) delete mode 100644 packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index e022d4f62af22..7ec80eda4dd90 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -14623,29 +14623,6 @@ public final class Settings { public static final String POWER_BUTTON_VERY_LONG_PRESS = "power_button_very_long_press"; - - /** - * Keyguard should be on the left hand side of the screen, for wide screen layouts. - * - * @hide - */ - public static final int ONE_HANDED_KEYGUARD_SIDE_LEFT = 0; - - /** - * Keyguard should be on the right hand side of the screen, for wide screen layouts. - * - * @hide - */ - public static final int ONE_HANDED_KEYGUARD_SIDE_RIGHT = 1; - /** - * In one handed mode, which side the keyguard should be on. Allowable values are one of - * the ONE_HANDED_KEYGUARD_SIDE_* constants. - * - * @hide - */ - @Readable - public static final String ONE_HANDED_KEYGUARD_SIDE = "one_handed_keyguard_side"; - /** * Keys we no longer back up under the current schema, but want to continue to * process when restoring historical backup datasets. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e73d6e3af3cbe..b5af5240b8438 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4203,6 +4203,4 @@ - - diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java index ad6a5312f1562..66165b6d1ff2e 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java @@ -147,10 +147,5 @@ public class GlobalSettingsValidators { VALIDATORS.put(Global.DEVELOPMENT_SETTINGS_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.NOTIFICATION_FEEDBACK_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.RESTRICTED_NETWORKING_MODE, BOOLEAN_VALIDATOR); - VALIDATORS.put( - Global.ONE_HANDED_KEYGUARD_SIDE, - new InclusiveIntegerRangeValidator( - /* first= */Global.ONE_HANDED_KEYGUARD_SIDE_LEFT, - /* last= */Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT)); } } diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index efcc86905cd2a..27c91eadad3bf 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -283,7 +283,6 @@ public class SettingsBackupTest { Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS, Settings.Global.EUICC_SWITCH_SLOT_TIMEOUT_MILLIS, Settings.Global.FANCY_IME_ANIMATIONS, - Settings.Global.ONE_HANDED_KEYGUARD_SIDE, Settings.Global.FORCE_ALLOW_ON_EXTERNAL, Settings.Global.FORCED_APP_STANDBY_ENABLED, Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml index 71cdaf5c7091b..79868093fb127 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml @@ -24,7 +24,7 @@ diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml index c75ee51517d1d..04e645bd0a321 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml @@ -41,14 +41,13 @@ android:layout_gravity="center"> diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml deleted file mode 100644 index e09bf7e37ed0c..0000000000000 --- a/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - true - diff --git a/packages/SystemUI/res-keyguard/values/config.xml b/packages/SystemUI/res-keyguard/values/config.xml index 6176f7c1dd0ac..8d9d6ee68c67d 100644 --- a/packages/SystemUI/res-keyguard/values/config.xml +++ b/packages/SystemUI/res-keyguard/values/config.xml @@ -22,5 +22,4 @@ false - false diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index f511ed1c69c49..5f6fd30ffa1b3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -29,17 +29,12 @@ import android.app.AlertDialog; import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; -import android.provider.Settings; import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; -import android.view.Gravity; import android.view.MotionEvent; -import android.view.OrientationEventListener; import android.view.VelocityTracker; -import android.view.View; import android.view.ViewConfiguration; -import android.view.ViewPropertyAnimator; import android.view.WindowInsets; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimationControlListener; @@ -60,7 +55,6 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import java.util.List; @@ -105,12 +99,6 @@ public class KeyguardSecurityContainer extends FrameLayout { private boolean mDisappearAnimRunning; private SwipeListener mSwipeListener; - private boolean mIsSecurityViewLeftAligned = true; - private boolean mOneHandedMode = false; - private SecurityMode mSecurityMode = SecurityMode.Invalid; - private ViewPropertyAnimator mRunningOneHandedAnimator; - private final OrientationEventListener mOrientationEventListener; - private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback = new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) { @@ -169,20 +157,16 @@ public class KeyguardSecurityContainer extends FrameLayout { // Used to notify the container when something interesting happens. public interface SecurityCallback { boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen); - void userActivity(); - void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput); /** - * @param strongAuth wheher the user has authenticated with strong authentication like - * pattern, password or PIN but not by trust agents or fingerprint + * @param strongAuth wheher the user has authenticated with strong authentication like + * pattern, password or PIN but not by trust agents or fingerprint * @param targetUserId a user that needs to be the foreground user at the finish completion. */ void finish(boolean strongAuth, int targetUserId); - void reset(); - void onCancelClicked(); } @@ -240,136 +224,12 @@ public class KeyguardSecurityContainer extends FrameLayout { super(context, attrs, defStyle); mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y); mViewConfiguration = ViewConfiguration.get(context); - - mOrientationEventListener = new OrientationEventListener(context) { - @Override - public void onOrientationChanged(int orientation) { - updateLayoutForSecurityMode(mSecurityMode); - } - }; } void onResume(SecurityMode securityMode, boolean faceAuthEnabled) { - mSecurityMode = securityMode; mSecurityViewFlipper.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback); updateBiometricRetry(securityMode, faceAuthEnabled); - updateLayoutForSecurityMode(securityMode); - mOrientationEventListener.enable(); - } - - void updateLayoutForSecurityMode(SecurityMode securityMode) { - mSecurityMode = securityMode; - mOneHandedMode = canUseOneHandedBouncer(); - - if (mOneHandedMode) { - mIsSecurityViewLeftAligned = isOneHandedKeyguardLeftAligned(mContext); - } - - updateSecurityViewGravity(); - updateSecurityViewLocation(false); - } - - /** Return whether the one-handed keyguard should be enabled. */ - private boolean canUseOneHandedBouncer() { - // Is it enabled? - if (!getResources().getBoolean( - com.android.internal.R.bool.config_enableOneHandedKeyguard)) { - return false; - } - - if (!KeyguardSecurityModel.isSecurityViewOneHanded(mSecurityMode)) { - return false; - } - - return getResources().getBoolean(R.bool.can_use_one_handed_bouncer); - } - - /** Read whether the one-handed keyguard should be on the left/right from settings. */ - private boolean isOneHandedKeyguardLeftAligned(Context context) { - try { - return Settings.Global.getInt(context.getContentResolver(), - Settings.Global.ONE_HANDED_KEYGUARD_SIDE) - == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT; - } catch (Settings.SettingNotFoundException ex) { - return true; - } - } - - private void updateSecurityViewGravity() { - View securityView = findKeyguardSecurityView(); - - if (securityView == null) { - return; - } - - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) securityView.getLayoutParams(); - - if (mOneHandedMode) { - lp.gravity = Gravity.LEFT | Gravity.BOTTOM; - } else { - lp.gravity = Gravity.CENTER_HORIZONTAL; - } - - securityView.setLayoutParams(lp); - } - - /** - * Moves the inner security view to the correct location (in one handed mode) with animation. - * This is triggered when the user taps on the side of the screen that is not currently occupied - * by the security view . - */ - private void updateSecurityViewLocation(boolean animate) { - View securityView = findKeyguardSecurityView(); - - if (securityView == null) { - return; - } - - if (!mOneHandedMode) { - securityView.setTranslationX(0); - return; - } - - if (mRunningOneHandedAnimator != null) { - mRunningOneHandedAnimator.cancel(); - mRunningOneHandedAnimator = null; - } - - int targetTranslation = mIsSecurityViewLeftAligned ? 0 : (int) (getMeasuredWidth() / 2f); - - if (animate) { - mRunningOneHandedAnimator = securityView.animate().translationX(targetTranslation); - mRunningOneHandedAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mRunningOneHandedAnimator.setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mRunningOneHandedAnimator = null; - } - }); - - mRunningOneHandedAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - mRunningOneHandedAnimator.start(); - } else { - securityView.setTranslationX(targetTranslation); - } - } - - @Nullable - private KeyguardSecurityViewFlipper findKeyguardSecurityView() { - for (int i = 0; i < getChildCount(); i++) { - View child = getChildAt(i); - - if (isKeyguardSecurityView(child)) { - return (KeyguardSecurityViewFlipper) child; - } - } - - return null; - } - - private boolean isKeyguardSecurityView(View view) { - return view instanceof KeyguardSecurityViewFlipper; } public void onPause() { @@ -378,7 +238,6 @@ public class KeyguardSecurityContainer extends FrameLayout { mAlertDialog = null; } mSecurityViewFlipper.setWindowInsetsAnimationCallback(null); - mOrientationEventListener.disable(); } @Override @@ -460,44 +319,19 @@ public class KeyguardSecurityContainer extends FrameLayout { if (mSwipeListener != null) { mSwipeListener.onSwipeUp(); } - } else { - if (!mIsDragging) { - handleTap(event); - } } } return true; } - private void handleTap(MotionEvent event) { - // If we're using a fullscreen security mode, skip - if (!mOneHandedMode) { - return; - } - - // Did the tap hit the "other" side of the bouncer? - if ((mIsSecurityViewLeftAligned && (event.getX() > getWidth() / 2f)) - || (!mIsSecurityViewLeftAligned && (event.getX() < getWidth() / 2f))) { - mIsSecurityViewLeftAligned = !mIsSecurityViewLeftAligned; - - Settings.Global.putInt( - mContext.getContentResolver(), - Settings.Global.ONE_HANDED_KEYGUARD_SIDE, - mIsSecurityViewLeftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT - : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT); - - updateSecurityViewLocation(true); - } - } - void setSwipeListener(SwipeListener swipeListener) { mSwipeListener = swipeListener; } private void startSpringAnimation(float startVelocity) { mSpringAnimation - .setStartVelocity(startVelocity) - .animateToFinalPosition(0); + .setStartVelocity(startVelocity) + .animateToFinalPosition(0); } public void startDisappearAnimation(SecurityMode securitySelection) { @@ -607,17 +441,18 @@ public class KeyguardSecurityContainer extends FrameLayout { return insets.inset(0, 0, 0, inset); } + private void showDialog(String title, String message) { if (mAlertDialog != null) { mAlertDialog.dismiss(); } mAlertDialog = new AlertDialog.Builder(mContext) - .setTitle(title) - .setMessage(message) - .setCancelable(false) - .setNeutralButton(R.string.ok, null) - .create(); + .setTitle(title) + .setMessage(message) + .setCancelable(false) + .setNeutralButton(R.string.ok, null) + .create(); if (!(mContext instanceof Activity)) { mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); } @@ -655,44 +490,6 @@ public class KeyguardSecurityContainer extends FrameLayout { } } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int maxHeight = 0; - int maxWidth = 0; - int childState = 0; - - int halfWidthMeasureSpec = MeasureSpec.makeMeasureSpec( - MeasureSpec.getSize(widthMeasureSpec) / 2, - MeasureSpec.getMode(widthMeasureSpec)); - - for (int i = 0; i < getChildCount(); i++) { - final View view = getChildAt(i); - if (view.getVisibility() != GONE) { - if (mOneHandedMode && isKeyguardSecurityView(view)) { - measureChildWithMargins(view, halfWidthMeasureSpec, 0, - heightMeasureSpec, 0); - } else { - measureChildWithMargins(view, widthMeasureSpec, 0, - heightMeasureSpec, 0); - } - final LayoutParams lp = (LayoutParams) view.getLayoutParams(); - maxWidth = Math.max(maxWidth, - view.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); - maxHeight = Math.max(maxHeight, - view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); - childState = combineMeasuredStates(childState, view.getMeasuredState()); - } - } - - // Check against our minimum height and width - maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); - maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); - - setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), - resolveSizeAndState(maxHeight, heightMeasureSpec, - childState << MEASURED_HEIGHT_STATE_SHIFT)); - } - void showAlmostAtWipeDialog(int attempts, int remaining, int userType) { String message = null; switch (userType) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index fdab8db67431f..1a8d420fb3945 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -404,7 +404,6 @@ public class KeyguardSecurityContainerController extends ViewController Date: Tue, 23 Feb 2021 16:28:23 +0000 Subject: [PATCH 016/176] Revert "Update the bouncer to be able to move to either side of a wide screen." This reverts commit 868e770b824b5d776d64fd9364f24a6aa1ed5ab5. Reason for revert: Breaks password entry - b/180993584 Change-Id: I9a1771b795c90b1cfe6c2457d390ac53235c6c94 (cherry picked from commit 0f53fd20d5f5a986f6140de89d7d5623466d847b) --- core/java/android/provider/Settings.java | 23 -- core/res/res/values/symbols.xml | 2 - .../validators/GlobalSettingsValidators.java | 5 - .../android/provider/SettingsBackupTest.java | 1 - .../res-keyguard/layout/keyguard_bouncer.xml | 2 +- .../layout/keyguard_host_view.xml | 5 +- .../values-sw600dp-land/bools.xml | 20 -- .../SystemUI/res-keyguard/values/config.xml | 1 - .../keyguard/KeyguardSecurityContainer.java | 223 +----------------- .../KeyguardSecurityContainerController.java | 1 - .../keyguard/KeyguardSecurityModel.java | 9 - .../KeyguardSecurityContainerTest.java | 96 +------- 12 files changed, 14 insertions(+), 374 deletions(-) delete mode 100644 packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7a3dd62f86d76..a1bbc9f5d1968 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -14615,29 +14615,6 @@ public final class Settings { public static final String POWER_BUTTON_VERY_LONG_PRESS = "power_button_very_long_press"; - - /** - * Keyguard should be on the left hand side of the screen, for wide screen layouts. - * - * @hide - */ - public static final int ONE_HANDED_KEYGUARD_SIDE_LEFT = 0; - - /** - * Keyguard should be on the right hand side of the screen, for wide screen layouts. - * - * @hide - */ - public static final int ONE_HANDED_KEYGUARD_SIDE_RIGHT = 1; - /** - * In one handed mode, which side the keyguard should be on. Allowable values are one of - * the ONE_HANDED_KEYGUARD_SIDE_* constants. - * - * @hide - */ - @Readable - public static final String ONE_HANDED_KEYGUARD_SIDE = "one_handed_keyguard_side"; - /** * Keys we no longer back up under the current schema, but want to continue to * process when restoring historical backup datasets. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index e73d6e3af3cbe..b5af5240b8438 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -4203,6 +4203,4 @@ - - diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java index ad6a5312f1562..66165b6d1ff2e 100644 --- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java +++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java @@ -147,10 +147,5 @@ public class GlobalSettingsValidators { VALIDATORS.put(Global.DEVELOPMENT_SETTINGS_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.NOTIFICATION_FEEDBACK_ENABLED, BOOLEAN_VALIDATOR); VALIDATORS.put(Global.RESTRICTED_NETWORKING_MODE, BOOLEAN_VALIDATOR); - VALIDATORS.put( - Global.ONE_HANDED_KEYGUARD_SIDE, - new InclusiveIntegerRangeValidator( - /* first= */Global.ONE_HANDED_KEYGUARD_SIDE_LEFT, - /* last= */Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT)); } } diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java index 5f56a3dd2dedc..ce1424aa8fb3d 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -283,7 +283,6 @@ public class SettingsBackupTest { Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS, Settings.Global.EUICC_SWITCH_SLOT_TIMEOUT_MILLIS, Settings.Global.FANCY_IME_ANIMATIONS, - Settings.Global.ONE_HANDED_KEYGUARD_SIDE, Settings.Global.FORCE_ALLOW_ON_EXTERNAL, Settings.Global.FORCED_APP_STANDBY_ENABLED, Settings.Global.FORCED_APP_STANDBY_FOR_SMALL_BATTERY_ENABLED, diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml index 71cdaf5c7091b..79868093fb127 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml @@ -24,7 +24,7 @@ diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml index c75ee51517d1d..04e645bd0a321 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml @@ -41,14 +41,13 @@ android:layout_gravity="center"> diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml deleted file mode 100644 index e09bf7e37ed0c..0000000000000 --- a/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - true - diff --git a/packages/SystemUI/res-keyguard/values/config.xml b/packages/SystemUI/res-keyguard/values/config.xml index 6176f7c1dd0ac..8d9d6ee68c67d 100644 --- a/packages/SystemUI/res-keyguard/values/config.xml +++ b/packages/SystemUI/res-keyguard/values/config.xml @@ -22,5 +22,4 @@ false - false diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index f511ed1c69c49..5f6fd30ffa1b3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -29,17 +29,12 @@ import android.app.AlertDialog; import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; -import android.provider.Settings; import android.util.AttributeSet; import android.util.MathUtils; import android.util.TypedValue; -import android.view.Gravity; import android.view.MotionEvent; -import android.view.OrientationEventListener; import android.view.VelocityTracker; -import android.view.View; import android.view.ViewConfiguration; -import android.view.ViewPropertyAnimator; import android.view.WindowInsets; import android.view.WindowInsetsAnimation; import android.view.WindowInsetsAnimationControlListener; @@ -60,7 +55,6 @@ import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardSecurityModel.SecurityMode; import com.android.systemui.Interpolators; import com.android.systemui.R; -import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import java.util.List; @@ -105,12 +99,6 @@ public class KeyguardSecurityContainer extends FrameLayout { private boolean mDisappearAnimRunning; private SwipeListener mSwipeListener; - private boolean mIsSecurityViewLeftAligned = true; - private boolean mOneHandedMode = false; - private SecurityMode mSecurityMode = SecurityMode.Invalid; - private ViewPropertyAnimator mRunningOneHandedAnimator; - private final OrientationEventListener mOrientationEventListener; - private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback = new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) { @@ -169,20 +157,16 @@ public class KeyguardSecurityContainer extends FrameLayout { // Used to notify the container when something interesting happens. public interface SecurityCallback { boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen); - void userActivity(); - void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput); /** - * @param strongAuth wheher the user has authenticated with strong authentication like - * pattern, password or PIN but not by trust agents or fingerprint + * @param strongAuth wheher the user has authenticated with strong authentication like + * pattern, password or PIN but not by trust agents or fingerprint * @param targetUserId a user that needs to be the foreground user at the finish completion. */ void finish(boolean strongAuth, int targetUserId); - void reset(); - void onCancelClicked(); } @@ -240,136 +224,12 @@ public class KeyguardSecurityContainer extends FrameLayout { super(context, attrs, defStyle); mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y); mViewConfiguration = ViewConfiguration.get(context); - - mOrientationEventListener = new OrientationEventListener(context) { - @Override - public void onOrientationChanged(int orientation) { - updateLayoutForSecurityMode(mSecurityMode); - } - }; } void onResume(SecurityMode securityMode, boolean faceAuthEnabled) { - mSecurityMode = securityMode; mSecurityViewFlipper.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback); updateBiometricRetry(securityMode, faceAuthEnabled); - updateLayoutForSecurityMode(securityMode); - mOrientationEventListener.enable(); - } - - void updateLayoutForSecurityMode(SecurityMode securityMode) { - mSecurityMode = securityMode; - mOneHandedMode = canUseOneHandedBouncer(); - - if (mOneHandedMode) { - mIsSecurityViewLeftAligned = isOneHandedKeyguardLeftAligned(mContext); - } - - updateSecurityViewGravity(); - updateSecurityViewLocation(false); - } - - /** Return whether the one-handed keyguard should be enabled. */ - private boolean canUseOneHandedBouncer() { - // Is it enabled? - if (!getResources().getBoolean( - com.android.internal.R.bool.config_enableOneHandedKeyguard)) { - return false; - } - - if (!KeyguardSecurityModel.isSecurityViewOneHanded(mSecurityMode)) { - return false; - } - - return getResources().getBoolean(R.bool.can_use_one_handed_bouncer); - } - - /** Read whether the one-handed keyguard should be on the left/right from settings. */ - private boolean isOneHandedKeyguardLeftAligned(Context context) { - try { - return Settings.Global.getInt(context.getContentResolver(), - Settings.Global.ONE_HANDED_KEYGUARD_SIDE) - == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT; - } catch (Settings.SettingNotFoundException ex) { - return true; - } - } - - private void updateSecurityViewGravity() { - View securityView = findKeyguardSecurityView(); - - if (securityView == null) { - return; - } - - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) securityView.getLayoutParams(); - - if (mOneHandedMode) { - lp.gravity = Gravity.LEFT | Gravity.BOTTOM; - } else { - lp.gravity = Gravity.CENTER_HORIZONTAL; - } - - securityView.setLayoutParams(lp); - } - - /** - * Moves the inner security view to the correct location (in one handed mode) with animation. - * This is triggered when the user taps on the side of the screen that is not currently occupied - * by the security view . - */ - private void updateSecurityViewLocation(boolean animate) { - View securityView = findKeyguardSecurityView(); - - if (securityView == null) { - return; - } - - if (!mOneHandedMode) { - securityView.setTranslationX(0); - return; - } - - if (mRunningOneHandedAnimator != null) { - mRunningOneHandedAnimator.cancel(); - mRunningOneHandedAnimator = null; - } - - int targetTranslation = mIsSecurityViewLeftAligned ? 0 : (int) (getMeasuredWidth() / 2f); - - if (animate) { - mRunningOneHandedAnimator = securityView.animate().translationX(targetTranslation); - mRunningOneHandedAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - mRunningOneHandedAnimator.setListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mRunningOneHandedAnimator = null; - } - }); - - mRunningOneHandedAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - mRunningOneHandedAnimator.start(); - } else { - securityView.setTranslationX(targetTranslation); - } - } - - @Nullable - private KeyguardSecurityViewFlipper findKeyguardSecurityView() { - for (int i = 0; i < getChildCount(); i++) { - View child = getChildAt(i); - - if (isKeyguardSecurityView(child)) { - return (KeyguardSecurityViewFlipper) child; - } - } - - return null; - } - - private boolean isKeyguardSecurityView(View view) { - return view instanceof KeyguardSecurityViewFlipper; } public void onPause() { @@ -378,7 +238,6 @@ public class KeyguardSecurityContainer extends FrameLayout { mAlertDialog = null; } mSecurityViewFlipper.setWindowInsetsAnimationCallback(null); - mOrientationEventListener.disable(); } @Override @@ -460,44 +319,19 @@ public class KeyguardSecurityContainer extends FrameLayout { if (mSwipeListener != null) { mSwipeListener.onSwipeUp(); } - } else { - if (!mIsDragging) { - handleTap(event); - } } } return true; } - private void handleTap(MotionEvent event) { - // If we're using a fullscreen security mode, skip - if (!mOneHandedMode) { - return; - } - - // Did the tap hit the "other" side of the bouncer? - if ((mIsSecurityViewLeftAligned && (event.getX() > getWidth() / 2f)) - || (!mIsSecurityViewLeftAligned && (event.getX() < getWidth() / 2f))) { - mIsSecurityViewLeftAligned = !mIsSecurityViewLeftAligned; - - Settings.Global.putInt( - mContext.getContentResolver(), - Settings.Global.ONE_HANDED_KEYGUARD_SIDE, - mIsSecurityViewLeftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT - : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT); - - updateSecurityViewLocation(true); - } - } - void setSwipeListener(SwipeListener swipeListener) { mSwipeListener = swipeListener; } private void startSpringAnimation(float startVelocity) { mSpringAnimation - .setStartVelocity(startVelocity) - .animateToFinalPosition(0); + .setStartVelocity(startVelocity) + .animateToFinalPosition(0); } public void startDisappearAnimation(SecurityMode securitySelection) { @@ -607,17 +441,18 @@ public class KeyguardSecurityContainer extends FrameLayout { return insets.inset(0, 0, 0, inset); } + private void showDialog(String title, String message) { if (mAlertDialog != null) { mAlertDialog.dismiss(); } mAlertDialog = new AlertDialog.Builder(mContext) - .setTitle(title) - .setMessage(message) - .setCancelable(false) - .setNeutralButton(R.string.ok, null) - .create(); + .setTitle(title) + .setMessage(message) + .setCancelable(false) + .setNeutralButton(R.string.ok, null) + .create(); if (!(mContext instanceof Activity)) { mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); } @@ -655,44 +490,6 @@ public class KeyguardSecurityContainer extends FrameLayout { } } - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - int maxHeight = 0; - int maxWidth = 0; - int childState = 0; - - int halfWidthMeasureSpec = MeasureSpec.makeMeasureSpec( - MeasureSpec.getSize(widthMeasureSpec) / 2, - MeasureSpec.getMode(widthMeasureSpec)); - - for (int i = 0; i < getChildCount(); i++) { - final View view = getChildAt(i); - if (view.getVisibility() != GONE) { - if (mOneHandedMode && isKeyguardSecurityView(view)) { - measureChildWithMargins(view, halfWidthMeasureSpec, 0, - heightMeasureSpec, 0); - } else { - measureChildWithMargins(view, widthMeasureSpec, 0, - heightMeasureSpec, 0); - } - final LayoutParams lp = (LayoutParams) view.getLayoutParams(); - maxWidth = Math.max(maxWidth, - view.getMeasuredWidth() + lp.leftMargin + lp.rightMargin); - maxHeight = Math.max(maxHeight, - view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin); - childState = combineMeasuredStates(childState, view.getMeasuredState()); - } - } - - // Check against our minimum height and width - maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); - maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); - - setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState), - resolveSizeAndState(maxHeight, heightMeasureSpec, - childState << MEASURED_HEIGHT_STATE_SHIFT)); - } - void showAlmostAtWipeDialog(int attempts, int remaining, int userType) { String message = null; switch (userType) { diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java index fdab8db67431f..1a8d420fb3945 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java @@ -404,7 +404,6 @@ public class KeyguardSecurityContainerController extends ViewController Date: Mon, 15 Mar 2021 09:30:13 -0700 Subject: [PATCH 017/176] Check if the sc is valid when finishing seamless rotation If the window is removed, the finish seamless rotation can be triggered from the blast sync timeout. Bug: 182738086 Test: repro steps in bug does not repro anymore Change-Id: I87bef0dbddeb5640e356afb2d2e57334b8690c28 (cherry picked from commit ba40611dce746824aa6eeb376807886110026b9c) --- services/core/java/com/android/server/wm/SeamlessRotator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/services/core/java/com/android/server/wm/SeamlessRotator.java b/services/core/java/com/android/server/wm/SeamlessRotator.java index 1e8b8a5bb576a..4cc369f0a187b 100644 --- a/services/core/java/com/android/server/wm/SeamlessRotator.java +++ b/services/core/java/com/android/server/wm/SeamlessRotator.java @@ -102,6 +102,10 @@ public class SeamlessRotator { * window in the new orientation. */ void finish(Transaction t, WindowContainer win) { + if (win.mSurfaceControl == null || !win.mSurfaceControl.isValid()) { + return; + } + mTransform.reset(); t.setMatrix(win.mSurfaceControl, mTransform, mFloat9); t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y); From 0ceb46cbf9036fe1ef0d3fb7e1f0941c679cbb13 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Mon, 15 Mar 2021 13:26:04 -0400 Subject: [PATCH 018/176] Avoid falsing when the phone is unlocked. With this change, we completely avoid recording motion events when the phone is off the lock screen. We also also return false when asked if the last gesture was a false. Fixes: 182713255 Test: atest SystemUITests && manual Change-Id: I2e16aecb218dd3c862ffefc8c82f67523925ac5e (cherry picked from commit 8a5e237677cdc77b063b80d14a9094e350ea36ee) --- .../classifier/BrightLineFalsingManager.java | 22 +++++++++++++++- .../classifier/FalsingCollectorImpl.java | 11 ++++++-- .../classifier/BrightLineClassifierTest.java | 25 ++++++++++++++++--- .../classifier/FalsingCollectorImplTest.java | 22 +++++++++++++++- 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index efb799294004c..45cefcc564bfc 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -31,6 +31,7 @@ import com.android.systemui.classifier.FalsingDataProvider.SessionListener; import com.android.systemui.dagger.qualifiers.TestHarness; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; @@ -67,6 +68,7 @@ public class BrightLineFalsingManager implements FalsingManager { private final SingleTapClassifier mSingleTapClassifier; private final DoubleTapClassifier mDoubleTapClassifier; private final HistoryTracker mHistoryTracker; + private final KeyguardStateController mKeyguardStateController; private final boolean mTestHarness; private final MetricsLogger mMetricsLogger; private int mIsFalseTouchCalls; @@ -113,7 +115,8 @@ public class BrightLineFalsingManager implements FalsingManager { DockManager dockManager, MetricsLogger metricsLogger, @Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set classifiers, SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier, - HistoryTracker historyTracker, @TestHarness boolean testHarness) { + HistoryTracker historyTracker, KeyguardStateController keyguardStateController, + @TestHarness boolean testHarness) { mDataProvider = falsingDataProvider; mDockManager = dockManager; mMetricsLogger = metricsLogger; @@ -121,6 +124,7 @@ public class BrightLineFalsingManager implements FalsingManager { mSingleTapClassifier = singleTapClassifier; mDoubleTapClassifier = doubleTapClassifier; mHistoryTracker = historyTracker; + mKeyguardStateController = keyguardStateController; mTestHarness = testHarness; mDataProvider.addSessionListener(mSessionListener); @@ -134,6 +138,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + if (skipFalsing()) { + return false; + } + boolean result; mDataProvider.setInteractionType(interactionType); @@ -195,6 +203,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTap(boolean robustCheck, double falsePenalty) { + if (skipFalsing()) { + return false; + } + FalsingClassifier.Result singleTapResult = mSingleTapClassifier.isTap(mDataProvider.getRecentMotionEvents()); mPriorResults = Collections.singleton(singleTapResult); @@ -233,6 +245,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseDoubleTap() { + if (skipFalsing()) { + return false; + } + FalsingClassifier.Result result = mDoubleTapClassifier.classifyGesture(); mPriorResults = Collections.singleton(result); if (result.isFalse()) { @@ -246,6 +262,10 @@ public class BrightLineFalsingManager implements FalsingManager { return result.isFalse(); } + private boolean skipFalsing() { + return !mKeyguardStateController.isShowing(); + } + @Override public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { // TODO: some of these classifiers might allow us to abort early, meaning we don't have to diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java index e090006cca4fd..b359860a0fd7f 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java @@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.SystemClock; @@ -48,6 +49,7 @@ class FalsingCollectorImpl implements FalsingCollector { private final HistoryTracker mHistoryTracker; private final ProximitySensor mProximitySensor; private final StatusBarStateController mStatusBarStateController; + private final KeyguardStateController mKeyguardStateController; private final SystemClock mSystemClock; private int mState; @@ -87,13 +89,14 @@ class FalsingCollectorImpl implements FalsingCollector { FalsingCollectorImpl(FalsingDataProvider falsingDataProvider, FalsingManager falsingManager, KeyguardUpdateMonitor keyguardUpdateMonitor, HistoryTracker historyTracker, ProximitySensor proximitySensor, StatusBarStateController statusBarStateController, - SystemClock systemClock) { + KeyguardStateController keyguardStateController, SystemClock systemClock) { mFalsingDataProvider = falsingDataProvider; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mHistoryTracker = historyTracker; mProximitySensor = proximitySensor; mStatusBarStateController = statusBarStateController; + mKeyguardStateController = keyguardStateController; mSystemClock = systemClock; @@ -255,6 +258,10 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void onTouchEvent(MotionEvent ev) { + if (!mKeyguardStateController.isShowing()) { + avoidGesture(); + return; + } // We delay processing down events to see if another component wants to process them. // If #avoidGesture is called after a MotionEvent.ACTION_DOWN, all following motion events // will be ignored by the collector until another MotionEvent.ACTION_DOWN is passed in. @@ -276,8 +283,8 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void avoidGesture() { + mAvoidGesture = true; if (mPendingDownEvent != null) { - mAvoidGesture = true; mPendingDownEvent.recycle(); mPendingDownEvent = null; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java index b2328504272a7..d015f51055b5a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -35,6 +35,7 @@ import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingDataProvider.GestureCompleteListener; import com.android.systemui.dock.DockManagerFake; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -71,7 +72,10 @@ public class BrightLineClassifierTest extends SysuiTestCase { private FalsingClassifier mClassifierB; private final List mMotionEventList = new ArrayList<>(); @Mock - private HistoryTracker mHistoryTracker;; + private HistoryTracker mHistoryTracker; + @Mock + private KeyguardStateController mKeyguardStateController; + private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private final FalsingClassifier.Result mFalsedResult = FalsingClassifier.Result.falsed(1, ""); @@ -88,9 +92,10 @@ public class BrightLineClassifierTest extends SysuiTestCase { mClassifiers.add(mClassifierA); mClassifiers.add(mClassifierB); when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); + when(mKeyguardStateController.isShowing()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager, mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier, - mHistoryTracker, false); + mHistoryTracker, mKeyguardStateController, false); ArgumentCaptor gestureCompleteListenerCaptor = @@ -120,7 +125,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { } @Test - public void testIsFalseTouch_ClassffiersPass() { + public void testIsFalseTouch_ClassifiersPass() { assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse(); } @@ -233,4 +238,18 @@ public class BrightLineClassifierTest extends SysuiTestCase { assertThat(mFakeExecutor.numPending()).isEqualTo(0); } + + @Test + public void testNoFalsingUnlocked() { + when(mKeyguardStateController.isShowing()).thenReturn(false); + + when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse(); + + when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isFalse(); + + when(mDoubleTapClassifier.classifyGesture()).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java index dc79b88818919..e6aeee7a9184b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java @@ -34,6 +34,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.FakeSystemClock; @@ -62,16 +63,19 @@ public class FalsingCollectorImplTest extends SysuiTestCase { private ProximitySensor mProximitySensor; @Mock private SysuiStatusBarStateController mStatusBarStateController; + @Mock + private KeyguardStateController mKeyguardStateController; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); + when(mKeyguardStateController.isShowing()).thenReturn(true); mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager, mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor, - mStatusBarStateController, new FakeSystemClock()); + mStatusBarStateController, mKeyguardStateController, new FakeSystemClock()); } @Test @@ -159,4 +163,20 @@ public class FalsingCollectorImplTest extends SysuiTestCase { mFalsingCollector.onTouchEvent(up); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } + + @Test + public void testAvoidUnlocked() { + MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); + + when(mKeyguardStateController.isShowing()).thenReturn(false); + + // Nothing passed initially + mFalsingCollector.onTouchEvent(down); + verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); + + // Up event would normally flush the up event. + mFalsingCollector.onTouchEvent(up); + verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); + } } From 30073c91955dec135f18ab7e7059158acc9385f5 Mon Sep 17 00:00:00 2001 From: Nate Myren Date: Mon, 15 Mar 2021 17:53:55 +0000 Subject: [PATCH 019/176] Revert "Make window stable while resizing" This reverts commit 5a9a38128f727ac425f1147c0a663328896e5238. Reason for revert: fixes b/182729646 Change-Id: Idfa7fb9187a4707f4627a41b92f45313fbdc3ca8 (cherry picked from commit 253de9a9ce59ff72f7c15c810eaa979b8fec16d8) --- .../server/wm/InsetsSourceProvider.java | 42 ++++++++++++------- .../com/android/server/wm/WindowFrames.java | 9 +--- .../server/wm/WindowManagerService.java | 5 +++ .../com/android/server/wm/WindowState.java | 24 ++++------- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 35e54912b33e1..45c4233b40aaa 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -30,6 +30,7 @@ import static com.android.server.wm.InsetsSourceProviderProto.CONTROLLABLE; import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET; import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL; import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET; +import static com.android.server.wm.InsetsSourceProviderProto.FINISH_SEAMLESS_ROTATE_FRAME_NUMBER; import static com.android.server.wm.InsetsSourceProviderProto.FRAME; import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME; import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING; @@ -58,7 +59,6 @@ import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; -import java.util.function.Consumer; /** * Controller for a specific inset source on the server. It's called provider as it provides the @@ -84,16 +84,6 @@ class InsetsSourceProvider { private final Rect mImeOverrideFrame = new Rect(); private boolean mIsLeashReadyForDispatching; - private final Consumer mSetLeashPositionConsumer = t -> { - if (mControl != null) { - final SurfaceControl leash = mControl.getLeash(); - if (leash != null) { - final Point position = mControl.getSurfacePosition(); - t.setPosition(leash, position.x, position.y); - } - } - }; - /** The visibility override from the current controlling window. */ private boolean mClientVisible; @@ -159,6 +149,7 @@ class InsetsSourceProvider { // TODO: Ideally, we should wait for the animation to finish so previous window can // animate-out as new one animates-in. mWin.cancelAnimation(); + mWin.mPendingPositionChanged = null; mWin.mProvidedInsetsSources.remove(mSource.getType()); } ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win); @@ -257,16 +248,31 @@ class InsetsSourceProvider { if (mControl != null) { final Point position = getWindowFrameSurfacePosition(); if (mControl.setSurfacePosition(position.x, position.y) && mControlTarget != null) { - if (mWin.getWindowFrames().didFrameSizeChange()) { - mWin.applyWithNextDraw(mSetLeashPositionConsumer); + if (!mWin.getWindowFrames().didFrameSizeChange()) { + updateLeashPosition(-1 /* frameNumber */); + } else if (mWin.mInRelayout) { + updateLeashPosition(mWin.getFrameNumber()); } else { - mSetLeashPositionConsumer.accept(mWin.getPendingTransaction()); + mWin.mPendingPositionChanged = this; } mStateController.notifyControlChanged(mControlTarget); } } } + void updateLeashPosition(long frameNumber) { + if (mControl == null) { + return; + } + final SurfaceControl leash = mControl.getLeash(); + if (leash != null) { + final Transaction t = mDisplayContent.getPendingTransaction(); + final Point position = mControl.getSurfacePosition(); + t.setPosition(leash, position.x, position.y); + deferTransactionUntil(t, leash, frameNumber); + } + } + private Point getWindowFrameSurfacePosition() { final Rect frame = mWin.getFrame(); final Point position = new Point(); @@ -274,6 +280,14 @@ class InsetsSourceProvider { return position; } + private void deferTransactionUntil(Transaction t, SurfaceControl leash, long frameNumber) { + if (frameNumber >= 0) { + final SurfaceControl barrier = mWin.getClientViewRootSurface(); + t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber); + t.deferTransactionUntil(leash, barrier, frameNumber); + } + } + /** * @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget) */ diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index ffd6d21c1026b..9245f8c3efe5e 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -113,7 +113,7 @@ public class WindowFrames { } /** - * @return true if the width or height has changed since last updating resizing window. + * @return true if the width or height has changed since last reported to the client. */ boolean didFrameSizeChange() { return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height()); @@ -134,13 +134,6 @@ public class WindowFrames { return mLastForceReportingResized || mFrameSizeChanged; } - /** - * @return true if the width or height has changed since last reported to the client. - */ - boolean isFrameSizeChangeReported() { - return mFrameSizeChanged || didFrameSizeChange(); - } - /** * Resets the size changed flags so they're all set to false again. This should be called * after the frames are reported to client. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index b95674e511d50..e70ad6f1bdf3f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2234,6 +2234,11 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent dc = win.getDisplayContent(); + if (win.mPendingPositionChanged != null) { + win.mPendingPositionChanged.updateLeashPosition(frameNumber); + win.mPendingPositionChanged = null; + } + if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE) { win.prepareDrawHandlers(); result |= RELAYOUT_RES_BLAST_SYNC; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 7ebc1cc6d5c1f..2eadcd5814175 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -726,6 +726,8 @@ class WindowState extends WindowContainer implements WindowManagerP */ private InsetsState mFrozenInsetsState; + @Nullable InsetsSourceProvider mPendingPositionChanged; + private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f; private KeyInterceptionInfo mKeyInterceptionInfo; @@ -772,12 +774,6 @@ class WindowState extends WindowContainer implements WindowManagerP updateSurfacePosition(t); }; - private final Consumer mSetSurfacePositionConsumer = t -> { - if (mSurfaceControl != null && mSurfaceControl.isValid()) { - t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y); - } - }; - /** * @see #setSurfaceTranslationY(int) */ @@ -2133,8 +2129,6 @@ class WindowState extends WindowContainer implements WindowManagerP : getTask().getWindowConfiguration().hasMovementAnimations(); if (mToken.okToAnimate() && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 - && !mWindowFrames.didFrameSizeChange() - && !surfaceInsetsChanging() && !isDragResizing() && hasMovementAnimation && !mWinAnimator.mLastHidden @@ -5324,17 +5318,13 @@ class WindowState extends WindowContainer implements WindowManagerP // prior to the rotation. if (!mSurfaceAnimator.hasLeash() && mPendingSeamlessRotate == null && !mLastSurfacePosition.equals(mSurfacePosition)) { - final boolean frameSizeChanged = mWindowFrames.isFrameSizeChangeReported(); - final boolean surfaceInsetsChanged = surfaceInsetsChanging(); - final boolean surfaceSizeChanged = frameSizeChanged || surfaceInsetsChanged; + t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y); mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y); - if (surfaceInsetsChanged) { + if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) { mLastSurfaceInsets.set(mAttrs.surfaceInsets); - } - if (surfaceSizeChanged) { - applyWithNextDraw(mSetSurfacePositionConsumer); - } else { - mSetSurfacePositionConsumer.accept(t); + t.deferTransactionUntil(mSurfaceControl, + mWinAnimator.mSurfaceController.mSurfaceControl, + getFrameNumber()); } } } From 7c1ab4bff89190fd8cbe67216587111096d12f35 Mon Sep 17 00:00:00 2001 From: Nate Myren Date: Mon, 15 Mar 2021 17:53:55 +0000 Subject: [PATCH 020/176] Revert "Make window stable while resizing" This reverts commit 5a9a38128f727ac425f1147c0a663328896e5238. Reason for revert: fixes b/182729646 Fixes: 182729646 Change-Id: Idfa7fb9187a4707f4627a41b92f45313fbdc3ca8 (cherry picked from commit 90850f7b483cc659d5ba92e94e583e86b9971d24) --- .../server/wm/InsetsSourceProvider.java | 42 ++++++++++++------- .../com/android/server/wm/WindowFrames.java | 9 +--- .../server/wm/WindowManagerService.java | 5 +++ .../com/android/server/wm/WindowState.java | 24 ++++------- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 35e54912b33e1..45c4233b40aaa 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -30,6 +30,7 @@ import static com.android.server.wm.InsetsSourceProviderProto.CONTROLLABLE; import static com.android.server.wm.InsetsSourceProviderProto.CONTROL_TARGET; import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL; import static com.android.server.wm.InsetsSourceProviderProto.FAKE_CONTROL_TARGET; +import static com.android.server.wm.InsetsSourceProviderProto.FINISH_SEAMLESS_ROTATE_FRAME_NUMBER; import static com.android.server.wm.InsetsSourceProviderProto.FRAME; import static com.android.server.wm.InsetsSourceProviderProto.IME_OVERRIDDEN_FRAME; import static com.android.server.wm.InsetsSourceProviderProto.IS_LEASH_READY_FOR_DISPATCHING; @@ -58,7 +59,6 @@ import com.android.server.wm.SurfaceAnimator.AnimationType; import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback; import java.io.PrintWriter; -import java.util.function.Consumer; /** * Controller for a specific inset source on the server. It's called provider as it provides the @@ -84,16 +84,6 @@ class InsetsSourceProvider { private final Rect mImeOverrideFrame = new Rect(); private boolean mIsLeashReadyForDispatching; - private final Consumer mSetLeashPositionConsumer = t -> { - if (mControl != null) { - final SurfaceControl leash = mControl.getLeash(); - if (leash != null) { - final Point position = mControl.getSurfacePosition(); - t.setPosition(leash, position.x, position.y); - } - } - }; - /** The visibility override from the current controlling window. */ private boolean mClientVisible; @@ -159,6 +149,7 @@ class InsetsSourceProvider { // TODO: Ideally, we should wait for the animation to finish so previous window can // animate-out as new one animates-in. mWin.cancelAnimation(); + mWin.mPendingPositionChanged = null; mWin.mProvidedInsetsSources.remove(mSource.getType()); } ProtoLog.d(WM_DEBUG_IME, "InsetsSource setWin %s", win); @@ -257,16 +248,31 @@ class InsetsSourceProvider { if (mControl != null) { final Point position = getWindowFrameSurfacePosition(); if (mControl.setSurfacePosition(position.x, position.y) && mControlTarget != null) { - if (mWin.getWindowFrames().didFrameSizeChange()) { - mWin.applyWithNextDraw(mSetLeashPositionConsumer); + if (!mWin.getWindowFrames().didFrameSizeChange()) { + updateLeashPosition(-1 /* frameNumber */); + } else if (mWin.mInRelayout) { + updateLeashPosition(mWin.getFrameNumber()); } else { - mSetLeashPositionConsumer.accept(mWin.getPendingTransaction()); + mWin.mPendingPositionChanged = this; } mStateController.notifyControlChanged(mControlTarget); } } } + void updateLeashPosition(long frameNumber) { + if (mControl == null) { + return; + } + final SurfaceControl leash = mControl.getLeash(); + if (leash != null) { + final Transaction t = mDisplayContent.getPendingTransaction(); + final Point position = mControl.getSurfacePosition(); + t.setPosition(leash, position.x, position.y); + deferTransactionUntil(t, leash, frameNumber); + } + } + private Point getWindowFrameSurfacePosition() { final Rect frame = mWin.getFrame(); final Point position = new Point(); @@ -274,6 +280,14 @@ class InsetsSourceProvider { return position; } + private void deferTransactionUntil(Transaction t, SurfaceControl leash, long frameNumber) { + if (frameNumber >= 0) { + final SurfaceControl barrier = mWin.getClientViewRootSurface(); + t.deferTransactionUntil(mWin.getSurfaceControl(), barrier, frameNumber); + t.deferTransactionUntil(leash, barrier, frameNumber); + } + } + /** * @see InsetsStateController#onControlFakeTargetChanged(int, InsetsControlTarget) */ diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index ffd6d21c1026b..9245f8c3efe5e 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -113,7 +113,7 @@ public class WindowFrames { } /** - * @return true if the width or height has changed since last updating resizing window. + * @return true if the width or height has changed since last reported to the client. */ boolean didFrameSizeChange() { return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height()); @@ -134,13 +134,6 @@ public class WindowFrames { return mLastForceReportingResized || mFrameSizeChanged; } - /** - * @return true if the width or height has changed since last reported to the client. - */ - boolean isFrameSizeChangeReported() { - return mFrameSizeChanged || didFrameSizeChange(); - } - /** * Resets the size changed flags so they're all set to false again. This should be called * after the frames are reported to client. diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f0dc7fe08c665..ec012fc36c896 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2232,6 +2232,11 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayContent dc = win.getDisplayContent(); + if (win.mPendingPositionChanged != null) { + win.mPendingPositionChanged.updateLeashPosition(frameNumber); + win.mPendingPositionChanged = null; + } + if (mUseBLASTSync && win.useBLASTSync() && viewVisibility != View.GONE) { win.prepareDrawHandlers(); result |= RELAYOUT_RES_BLAST_SYNC; diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 7ebc1cc6d5c1f..2eadcd5814175 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -726,6 +726,8 @@ class WindowState extends WindowContainer implements WindowManagerP */ private InsetsState mFrozenInsetsState; + @Nullable InsetsSourceProvider mPendingPositionChanged; + private static final float DEFAULT_DIM_AMOUNT_DEAD_WINDOW = 0.5f; private KeyInterceptionInfo mKeyInterceptionInfo; @@ -772,12 +774,6 @@ class WindowState extends WindowContainer implements WindowManagerP updateSurfacePosition(t); }; - private final Consumer mSetSurfacePositionConsumer = t -> { - if (mSurfaceControl != null && mSurfaceControl.isValid()) { - t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y); - } - }; - /** * @see #setSurfaceTranslationY(int) */ @@ -2133,8 +2129,6 @@ class WindowState extends WindowContainer implements WindowManagerP : getTask().getWindowConfiguration().hasMovementAnimations(); if (mToken.okToAnimate() && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 - && !mWindowFrames.didFrameSizeChange() - && !surfaceInsetsChanging() && !isDragResizing() && hasMovementAnimation && !mWinAnimator.mLastHidden @@ -5324,17 +5318,13 @@ class WindowState extends WindowContainer implements WindowManagerP // prior to the rotation. if (!mSurfaceAnimator.hasLeash() && mPendingSeamlessRotate == null && !mLastSurfacePosition.equals(mSurfacePosition)) { - final boolean frameSizeChanged = mWindowFrames.isFrameSizeChangeReported(); - final boolean surfaceInsetsChanged = surfaceInsetsChanging(); - final boolean surfaceSizeChanged = frameSizeChanged || surfaceInsetsChanged; + t.setPosition(mSurfaceControl, mSurfacePosition.x, mSurfacePosition.y); mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y); - if (surfaceInsetsChanged) { + if (surfaceInsetsChanging() && mWinAnimator.hasSurface()) { mLastSurfaceInsets.set(mAttrs.surfaceInsets); - } - if (surfaceSizeChanged) { - applyWithNextDraw(mSetSurfacePositionConsumer); - } else { - mSetSurfacePositionConsumer.accept(t); + t.deferTransactionUntil(mSurfaceControl, + mWinAnimator.mSurfaceController.mSurfaceControl, + getFrameNumber()); } } } From 87405e723e7d5b0c954dccc298eeef02e0d341a5 Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Mon, 15 Mar 2021 13:26:04 -0400 Subject: [PATCH 021/176] Avoid falsing when the phone is unlocked. With this change, we completely avoid recording motion events when the phone is off the lock screen. We also also return false when asked if the last gesture was a false. Fixes: 182713255 Test: atest SystemUITests && manual Change-Id: I2e16aecb218dd3c862ffefc8c82f67523925ac5e (cherry picked from commit 8a5e237677cdc77b063b80d14a9094e350ea36ee) --- .../classifier/BrightLineFalsingManager.java | 22 +++++++++++++++- .../classifier/FalsingCollectorImpl.java | 11 ++++++-- .../classifier/BrightLineClassifierTest.java | 25 ++++++++++++++++--- .../classifier/FalsingCollectorImplTest.java | 22 +++++++++++++++- 4 files changed, 73 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index efb799294004c..45cefcc564bfc 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -31,6 +31,7 @@ import com.android.systemui.classifier.FalsingDataProvider.SessionListener; import com.android.systemui.dagger.qualifiers.TestHarness; import com.android.systemui.dock.DockManager; import com.android.systemui.plugins.FalsingManager; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ThresholdSensor; import java.io.FileDescriptor; @@ -67,6 +68,7 @@ public class BrightLineFalsingManager implements FalsingManager { private final SingleTapClassifier mSingleTapClassifier; private final DoubleTapClassifier mDoubleTapClassifier; private final HistoryTracker mHistoryTracker; + private final KeyguardStateController mKeyguardStateController; private final boolean mTestHarness; private final MetricsLogger mMetricsLogger; private int mIsFalseTouchCalls; @@ -113,7 +115,8 @@ public class BrightLineFalsingManager implements FalsingManager { DockManager dockManager, MetricsLogger metricsLogger, @Named(BRIGHT_LINE_GESTURE_CLASSIFERS) Set classifiers, SingleTapClassifier singleTapClassifier, DoubleTapClassifier doubleTapClassifier, - HistoryTracker historyTracker, @TestHarness boolean testHarness) { + HistoryTracker historyTracker, KeyguardStateController keyguardStateController, + @TestHarness boolean testHarness) { mDataProvider = falsingDataProvider; mDockManager = dockManager; mMetricsLogger = metricsLogger; @@ -121,6 +124,7 @@ public class BrightLineFalsingManager implements FalsingManager { mSingleTapClassifier = singleTapClassifier; mDoubleTapClassifier = doubleTapClassifier; mHistoryTracker = historyTracker; + mKeyguardStateController = keyguardStateController; mTestHarness = testHarness; mDataProvider.addSessionListener(mSessionListener); @@ -134,6 +138,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + if (skipFalsing()) { + return false; + } + boolean result; mDataProvider.setInteractionType(interactionType); @@ -195,6 +203,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTap(boolean robustCheck, double falsePenalty) { + if (skipFalsing()) { + return false; + } + FalsingClassifier.Result singleTapResult = mSingleTapClassifier.isTap(mDataProvider.getRecentMotionEvents()); mPriorResults = Collections.singleton(singleTapResult); @@ -233,6 +245,10 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseDoubleTap() { + if (skipFalsing()) { + return false; + } + FalsingClassifier.Result result = mDoubleTapClassifier.classifyGesture(); mPriorResults = Collections.singleton(result); if (result.isFalse()) { @@ -246,6 +262,10 @@ public class BrightLineFalsingManager implements FalsingManager { return result.isFalse(); } + private boolean skipFalsing() { + return !mKeyguardStateController.isShowing(); + } + @Override public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) { // TODO: some of these classifiers might allow us to abort early, meaning we don't have to diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java index e090006cca4fd..b359860a0fd7f 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java @@ -27,6 +27,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.SystemClock; @@ -48,6 +49,7 @@ class FalsingCollectorImpl implements FalsingCollector { private final HistoryTracker mHistoryTracker; private final ProximitySensor mProximitySensor; private final StatusBarStateController mStatusBarStateController; + private final KeyguardStateController mKeyguardStateController; private final SystemClock mSystemClock; private int mState; @@ -87,13 +89,14 @@ class FalsingCollectorImpl implements FalsingCollector { FalsingCollectorImpl(FalsingDataProvider falsingDataProvider, FalsingManager falsingManager, KeyguardUpdateMonitor keyguardUpdateMonitor, HistoryTracker historyTracker, ProximitySensor proximitySensor, StatusBarStateController statusBarStateController, - SystemClock systemClock) { + KeyguardStateController keyguardStateController, SystemClock systemClock) { mFalsingDataProvider = falsingDataProvider; mFalsingManager = falsingManager; mKeyguardUpdateMonitor = keyguardUpdateMonitor; mHistoryTracker = historyTracker; mProximitySensor = proximitySensor; mStatusBarStateController = statusBarStateController; + mKeyguardStateController = keyguardStateController; mSystemClock = systemClock; @@ -255,6 +258,10 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void onTouchEvent(MotionEvent ev) { + if (!mKeyguardStateController.isShowing()) { + avoidGesture(); + return; + } // We delay processing down events to see if another component wants to process them. // If #avoidGesture is called after a MotionEvent.ACTION_DOWN, all following motion events // will be ignored by the collector until another MotionEvent.ACTION_DOWN is passed in. @@ -276,8 +283,8 @@ class FalsingCollectorImpl implements FalsingCollector { @Override public void avoidGesture() { + mAvoidGesture = true; if (mPendingDownEvent != null) { - mAvoidGesture = true; mPendingDownEvent.recycle(); mPendingDownEvent = null; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java index b2328504272a7..d015f51055b5a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -35,6 +35,7 @@ import com.android.internal.logging.testing.FakeMetricsLogger; import com.android.systemui.SysuiTestCase; import com.android.systemui.classifier.FalsingDataProvider.GestureCompleteListener; import com.android.systemui.dock.DockManagerFake; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.concurrency.FakeExecutor; import com.android.systemui.util.time.FakeSystemClock; @@ -71,7 +72,10 @@ public class BrightLineClassifierTest extends SysuiTestCase { private FalsingClassifier mClassifierB; private final List mMotionEventList = new ArrayList<>(); @Mock - private HistoryTracker mHistoryTracker;; + private HistoryTracker mHistoryTracker; + @Mock + private KeyguardStateController mKeyguardStateController; + private final FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock()); private final FalsingClassifier.Result mFalsedResult = FalsingClassifier.Result.falsed(1, ""); @@ -88,9 +92,10 @@ public class BrightLineClassifierTest extends SysuiTestCase { mClassifiers.add(mClassifierA); mClassifiers.add(mClassifierB); when(mFalsingDataProvider.getRecentMotionEvents()).thenReturn(mMotionEventList); + when(mKeyguardStateController.isShowing()).thenReturn(true); mBrightLineFalsingManager = new BrightLineFalsingManager(mFalsingDataProvider, mDockManager, mMetricsLogger, mClassifiers, mSingleTapClassfier, mDoubleTapClassifier, - mHistoryTracker, false); + mHistoryTracker, mKeyguardStateController, false); ArgumentCaptor gestureCompleteListenerCaptor = @@ -120,7 +125,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { } @Test - public void testIsFalseTouch_ClassffiersPass() { + public void testIsFalseTouch_ClassifiersPass() { assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse(); } @@ -233,4 +238,18 @@ public class BrightLineClassifierTest extends SysuiTestCase { assertThat(mFakeExecutor.numPending()).isEqualTo(0); } + + @Test + public void testNoFalsingUnlocked() { + when(mKeyguardStateController.isShowing()).thenReturn(false); + + when(mClassifierA.classifyGesture(anyDouble(), anyDouble())).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseTouch(0)).isFalse(); + + when(mSingleTapClassfier.isTap(mMotionEventList)).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseTap(false, 0)).isFalse(); + + when(mDoubleTapClassifier.classifyGesture()).thenReturn(mFalsedResult); + assertThat(mBrightLineFalsingManager.isFalseDoubleTap()).isFalse(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java index dc79b88818919..e6aeee7a9184b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingCollectorImplTest.java @@ -34,6 +34,7 @@ import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.SysuiStatusBarStateController; +import com.android.systemui.statusbar.policy.KeyguardStateController; import com.android.systemui.util.sensors.ProximitySensor; import com.android.systemui.util.sensors.ThresholdSensor; import com.android.systemui.util.time.FakeSystemClock; @@ -62,16 +63,19 @@ public class FalsingCollectorImplTest extends SysuiTestCase { private ProximitySensor mProximitySensor; @Mock private SysuiStatusBarStateController mStatusBarStateController; + @Mock + private KeyguardStateController mKeyguardStateController; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.KEYGUARD); + when(mKeyguardStateController.isShowing()).thenReturn(true); mFalsingCollector = new FalsingCollectorImpl(mFalsingDataProvider, mFalsingManager, mKeyguardUpdateMonitor, mHistoryTracker, mProximitySensor, - mStatusBarStateController, new FakeSystemClock()); + mStatusBarStateController, mKeyguardStateController, new FakeSystemClock()); } @Test @@ -159,4 +163,20 @@ public class FalsingCollectorImplTest extends SysuiTestCase { mFalsingCollector.onTouchEvent(up); verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); } + + @Test + public void testAvoidUnlocked() { + MotionEvent down = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0); + MotionEvent up = MotionEvent.obtain(0, 0, MotionEvent.ACTION_UP, 0, 0, 0); + + when(mKeyguardStateController.isShowing()).thenReturn(false); + + // Nothing passed initially + mFalsingCollector.onTouchEvent(down); + verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); + + // Up event would normally flush the up event. + mFalsingCollector.onTouchEvent(up); + verify(mFalsingDataProvider, never()).onMotionEvent(any(MotionEvent.class)); + } } From 49275707a61e1a7d041faa2ec5428b30e17cd238 Mon Sep 17 00:00:00 2001 From: Wei Sheng Shih Date: Wed, 17 Mar 2021 03:12:25 +0000 Subject: [PATCH 022/176] Revert "Enable remote animation for keygaurd." This reverts commit edcdd961d9f76709caf479cc3daf9f3c53683f6e. Reason for revert: suspect of b/182929692 Change-Id: I8c32a10b6e1728c76635b04345fb282e89520355 (cherry picked from commit 7cfddd02541e9ec7c9c4cea7f0874a2283cd116f) --- .../src/com/android/systemui/keyguard/KeyguardService.java | 2 +- .../core/java/com/android/server/wm/WindowManagerService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index 5cc0e65b2a615..97803c1cf2fd5 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -71,7 +71,7 @@ public class KeyguardService extends Service { * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY */ private static boolean sEnableRemoteKeyguardAnimation = - SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, true); + SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false); private final KeyguardViewMediator mKeyguardViewMediator; private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 083026920e911..d2c9e29f9d374 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -431,7 +431,7 @@ public class WindowManagerService extends IWindowManager.Stub * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY */ public static boolean sEnableRemoteKeyguardAnimation = - SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, true); + SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false); private static final String DISABLE_TRIPLE_BUFFERING_PROPERTY = "ro.sf.disable_triple_buffer"; From fad1e20e27312e8e0343a7b71b325949cb19e29e Mon Sep 17 00:00:00 2001 From: Beverly Date: Wed, 17 Mar 2021 12:56:53 -0400 Subject: [PATCH 023/176] Don't show an app icon for uninitalized user System apps running can post toasts before the app packages have been initialized by ApplicationsState. If this happens, don't check for the appEntry, instead automatically hide its icon from the toast. Test: manual Fixes: 182605816 Change-Id: I7e764341d049095da19f391ba9c944871584b921 (cherry picked from commit d581430ab8070baff5e41fb649af349d1953e18a) --- .../settingslib/applications/ApplicationsState.java | 7 +++++++ .../src/com/android/systemui/toast/SystemUIToast.java | 9 +++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index 2528ac1767f83..f180776bbe935 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -1496,6 +1496,13 @@ public class ApplicationsState { } } + /** + * Whether the packages for the user have been initialized. + */ + public boolean isUserAdded(int userId) { + return mEntriesMap.contains(userId); + } + public interface Callbacks { void onRunningStateChanged(boolean running); diff --git a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java index fd19528e6d55e..3892f310e6697 100644 --- a/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java +++ b/packages/SystemUI/src/com/android/systemui/toast/SystemUIToast.java @@ -26,6 +26,7 @@ import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.UserHandle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; @@ -43,6 +44,7 @@ import com.android.systemui.plugins.ToastPlugin; * directly. Instead, use {@link ToastFactory#createToast}. */ public class SystemUIToast implements ToastPlugin.Toast { + static final String TAG = "SystemUIToast"; final Context mContext; final CharSequence mText; final ToastPlugin.Toast mPluginToast; @@ -225,8 +227,12 @@ public class SystemUIToast implements ToastPlugin.Toast { int userId) { final ApplicationsState appState = ApplicationsState.getInstance((Application) context.getApplicationContext()); + if (!appState.isUserAdded(userId)) { + Log.d(TAG, "user hasn't been fully initialized, not showing an app icon for " + + "packageName=" + packageName); + return null; + } final AppEntry appEntry = appState.getEntry(packageName, userId); - if (!ApplicationsState.FILTER_DOWNLOADED_AND_LAUNCHER.filterApp(appEntry)) { return null; } @@ -237,6 +243,5 @@ public class SystemUIToast implements ToastPlugin.Toast { Bitmap iconBmp = iconFactory.createBadgedIconBitmap( appInfo.loadUnbadgedIcon(context.getPackageManager()), user, true).icon; return new BitmapDrawable(context.getResources(), iconBmp); - } } From abdccfec5620acaff95d0cf1bb1b670ab40acfab Mon Sep 17 00:00:00 2001 From: Tianjie Date: Tue, 23 Mar 2021 11:40:08 -0700 Subject: [PATCH 024/176] Clear caller id when reading device config Reading the DeviceConfig with the gmscore call id will result in a security exception. Also clear the caller identity when before calling into locksettings to armRebootEscrow. This is inline with the other usage for RoR preparation. Bug: 183475757 Test: trigger RoR from gmscore Change-Id: Ifc65625fc7aba05d016c127cf6672922a5ffb000 (cherry picked from commit 18fb750cc54c26de452b40414ffe8199e20b47c5) --- .../recoverysystem/RecoverySystemService.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java index 0a6772bd8f6a8..fe21201f5cb7f 100644 --- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java +++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java @@ -734,7 +734,15 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return REBOOT_ERROR_SLOT_MISMATCH; } - if (!mInjector.getLockSettingsService().armRebootEscrow()) { + final long origId = Binder.clearCallingIdentity(); + boolean result; + try { + result = mInjector.getLockSettingsService().armRebootEscrow(); + } finally { + Binder.restoreCallingIdentity(origId); + } + + if (!result) { Slog.w(TAG, "Failure to escrow key for reboot"); return REBOOT_ERROR_ARM_REBOOT_ESCROW_FAILURE; } @@ -742,11 +750,20 @@ public class RecoverySystemService extends IRecoverySystem.Stub implements Reboo return REBOOT_ERROR_NONE; } + private boolean useServerBasedRoR() { + final long origId = Binder.clearCallingIdentity(); + try { + return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA, + "server_based_ror_enabled", false); + } finally { + Binder.restoreCallingIdentity(origId); + } + } + private void reportMetricsOnRebootWithLskf(String packageName, boolean slotSwitch, @ResumeOnRebootRebootErrorCode int errorCode) { int uid = mInjector.getUidFromPackageName(packageName); - boolean serverBased = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_OTA, - "server_based_ror_enabled", false); + boolean serverBased = useServerBasedRoR(); int preparedClientCount; synchronized (this) { preparedClientCount = mCallerPreparedForReboot.size(); From 7708dd74fa7a8cc5aa9f6dd84a3b4ddd9d42883e Mon Sep 17 00:00:00 2001 From: Cassie Wang Date: Tue, 2 Feb 2021 15:21:37 -0800 Subject: [PATCH 025/176] Handle user stopping in AppSearch. When a user stops, we can close its AppSearchImpl instance to release resources. We'll also remove it from our cache of unlocked users so future API calls won't execute on a locked user. Bug: 179407490 Test: atest -m -c --rebuild-module-info CtsAppSearchTestCases FrameworksCoreTests: android.app.appsearch FrameworksServicesTests: com.android.server.appsearch Change-Id: I9a19d3044ed4f0b0f1269a9d15d8ae85e90d2b02 (cherry picked from commit 12539e04e927f9160d584ee6d478abbd16e8d984) --- .../server/appsearch/AppSearchManagerService.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java index 28069743d957b..309e70d8393e3 100644 --- a/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java +++ b/apex/appsearch/service/java/com/android/server/appsearch/AppSearchManagerService.java @@ -86,6 +86,21 @@ public class AppSearchManagerService extends SystemService { } } + @Override + public void onUserStopping(@NonNull TargetUser user) { + synchronized (mUnlockedUserIdsLocked) { + mUnlockedUserIdsLocked.remove(user.getUserIdentifier()); + try { + AppSearchImpl impl = + mImplInstanceManager.getAppSearchImpl( + getContext(), user.getUserIdentifier()); + impl.close(); + } catch (Throwable t) { + Log.e(TAG, "Error handling user stopping.", t); + } + } + } + private class Stub extends IAppSearchManager.Stub { @Override public void setSchema( From 90144a6c4941671435685a2cd60688ef488c4c97 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 026/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: Ib8bc10c111003b6a496147c5c60dcebf960ed081 (cherry picked from commit f3c0343fe5a09831e415b2eb2bd1097e1bbe57de) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e7bd7046fc22..97710680bac26 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && 445500383 == pkg.getVersionCode()) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From 774b989dffcd3360fa7eca6eec92e841117bfb64 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 027/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: Ib8bc10c111003b6a496147c5c60dcebf960ed081 (cherry picked from commit f3c0343fe5a09831e415b2eb2bd1097e1bbe57de) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e7bd7046fc22..97710680bac26 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && 445500383 == pkg.getVersionCode()) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From f3de6f5dd329dd2d6026866a3a38ac2282a006f1 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 028/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: Ib8bc10c111003b6a496147c5c60dcebf960ed081 (cherry picked from commit f3c0343fe5a09831e415b2eb2bd1097e1bbe57de) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e7bd7046fc22..97710680bac26 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && 445500383 == pkg.getVersionCode()) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From 261eafb2232661f91a0bc71c3ac0fa718a82ec0f Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 029/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: Ib8bc10c111003b6a496147c5c60dcebf960ed081 (cherry picked from commit f3c0343fe5a09831e415b2eb2bd1097e1bbe57de) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e7bd7046fc22..97710680bac26 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && 445500383 == pkg.getVersionCode()) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From c3bc0711a272f70952383d0f6a86e23e0875d166 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 030/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: Ib8bc10c111003b6a496147c5c60dcebf960ed081 (cherry picked from commit f3c0343fe5a09831e415b2eb2bd1097e1bbe57de) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e7bd7046fc22..97710680bac26 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && 445500383 == pkg.getVersionCode()) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From 1c3f62116f62f23dec1fbd6b4410e2411f158a6e Mon Sep 17 00:00:00 2001 From: Svet Ganov Date: Wed, 7 Apr 2021 01:46:31 +0000 Subject: [PATCH 031/176] Add fallback for datasource without UPDATE_APP_OP_STATS If the datasource is not in a trusted platform component then in would not have UPDATE_APP_OPS_STATS. The problem is that an app is exposing runtime permission protected data but cannot blame others in a trusted way which would not properly show in permission usage UIs. As a fallback we are adding a proxy op handling blaming the datasource and the caller. bug: 183960997 Test: Assustant on auto projection works Change-Id: I8a341a6c46c75eff86bac7a79c4219ebb7991071 (cherry picked from commit 773862fda5d38d997f458c309856ed145cd5c893) --- .../android/content/PermissionChecker.java | 46 +++++++++++++++---- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java index 049bfe7f23fb2..5089f30585b49 100644 --- a/core/java/android/content/PermissionChecker.java +++ b/core/java/android/content/PermissionChecker.java @@ -1066,11 +1066,25 @@ public final class PermissionChecker { return AppOpsManager.MODE_ERRORED; } if (selfAccess) { - return appOpsManager.startOpNoThrow(op, resolvedAttributionSource.getUid(), - resolvedAttributionSource.getPackageName(), - /*startIfModeDefault*/ false, - resolvedAttributionSource.getAttributionTag(), - message); + // If the datasource is not in a trusted platform component then in would not + // have UPDATE_APP_OPS_STATS and the call below would fail. The problem is that + // an app is exposing runtime permission protected data but cannot blame others + // in a trusted way which would not properly show in permission usage UIs. + // As a fallback we note a proxy op that blames the app and the datasource. + try { + return appOpsManager.startOpNoThrow(op, resolvedAttributionSource.getUid(), + resolvedAttributionSource.getPackageName(), + /*startIfModeDefault*/ false, + resolvedAttributionSource.getAttributionTag(), + message); + } catch (SecurityException e) { + Slog.w(LOG_TAG, "Datasource " + attributionSource + " protecting data with" + + " platform defined runtime permission " + + AppOpsManager.opToPermission(op) + " while not having " + + Manifest.permission.UPDATE_APP_OPS_STATS); + return appOpsManager.startProxyOpNoThrow(op, attributionSource, message, + skipProxyOperation); + } } else { return appOpsManager.startProxyOpNoThrow(op, resolvedAttributionSource, message, skipProxyOperation); @@ -1082,10 +1096,24 @@ public final class PermissionChecker { return AppOpsManager.MODE_ERRORED; } if (selfAccess) { - return appOpsManager.noteOpNoThrow(op, resolvedAttributionSource.getUid(), - resolvedAttributionSource.getPackageName(), - resolvedAttributionSource.getAttributionTag(), - message); + // If the datasource is not in a trusted platform component then in would not + // have UPDATE_APP_OPS_STATS and the call below would fail. The problem is that + // an app is exposing runtime permission protected data but cannot blame others + // in a trusted way which would not properly show in permission usage UIs. + // As a fallback we note a proxy op that blames the app and the datasource. + try { + return appOpsManager.noteOpNoThrow(op, resolvedAttributionSource.getUid(), + resolvedAttributionSource.getPackageName(), + resolvedAttributionSource.getAttributionTag(), + message); + } catch (SecurityException e) { + Slog.w(LOG_TAG, "Datasource " + attributionSource + " protecting data with" + + " platform defined runtime permission " + + AppOpsManager.opToPermission(op) + " while not having " + + Manifest.permission.UPDATE_APP_OPS_STATS); + return appOpsManager.noteProxyOpNoThrow(op, attributionSource, message, + skipProxyOperation); + } } else { return appOpsManager.noteProxyOpNoThrow(op, resolvedAttributionSource, message, skipProxyOperation); From a512213e6ff81033f499f411e0c2b54339beb609 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 032/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: Ib8bc10c111003b6a496147c5c60dcebf960ed081 (cherry picked from commit f3c0343fe5a09831e415b2eb2bd1097e1bbe57de) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 4e7bd7046fc22..97710680bac26 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && 445500383 == pkg.getVersionCode()) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From fc21b7262e479b8123aff037029f890b175d49c7 Mon Sep 17 00:00:00 2001 From: Orion Hodson Date: Thu, 8 Apr 2021 12:30:21 +0000 Subject: [PATCH 033/176] Revert "Remove setFrame from surface_control setGeometry" Revert "Remove setFrame from BufferStateLayer" Revert "Update tests to reflect the new behavior for setGeometry" Revert submission 13843937-sc_remove_set_frame Reason for revert: Candidate CL for b/184807094 Reverted Changes: Iffbd955a3:Remove setFrame I27f17bc61:Update tests to reflect the new behavior for setGe... I5720276c1:Remove setFrame from surface_control setGeometry I32ee0e3e4:Remove setFrame from BufferStateLayer Bug: 184807094 Change-Id: I7f6f0d7799e6e2858af2ce2e8acb5c67db8714f8 (cherry picked from commit 98aa7d4c88834987d5102f0137d206e921583ace) --- native/android/surface_control.cpp | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 7433cf9705668..e0f637959cfb3 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -432,27 +432,14 @@ void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction, const ARect& destination, int32_t transform) { CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); + CHECK_VALID_RECT(source); CHECK_VALID_RECT(destination); - Rect sourceRect = static_cast(source); - // Adjust the source so its top and left are not negative - sourceRect.left = std::max(sourceRect.left, 0); - sourceRect.top = std::max(sourceRect.top, 0); - LOG_ALWAYS_FATAL_IF(sourceRect.isEmpty(), "invalid arg passed as source argument"); - sp surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); - transaction->setCrop(surfaceControl, sourceRect); - - float dsdx = (destination.right - destination.left) / - static_cast(sourceRect.right - sourceRect.left); - float dsdy = (destination.bottom - destination.top) / - static_cast(sourceRect.bottom - sourceRect.top); - - transaction->setPosition(surfaceControl, destination.left - (sourceRect.left * dsdx), - destination.top - (sourceRect.top * dsdy)); - transaction->setMatrix(surfaceControl, dsdx, 0, 0, dsdy); + transaction->setCrop(surfaceControl, static_cast(source)); + transaction->setFrame(surfaceControl, static_cast(destination)); transaction->setTransform(surfaceControl, transform); bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; @@ -471,18 +458,16 @@ void ASurfaceTransaction_setSourceRect(ASurfaceTransaction* aSurfaceTransaction, transaction->setCrop(surfaceControl, static_cast(source)); } -void ASurfaceTransaction_setPosition(ASurfaceTransaction* /* aSurfaceTransaction */, - ASurfaceControl* /* aSurfaceControl */, - const ARect& /* destination */) { - // TODO: Fix this function - /* CHECK_NOT_NULL(aSurfaceTransaction); +void ASurfaceTransaction_setPosition(ASurfaceTransaction* aSurfaceTransaction, + ASurfaceControl* aSurfaceControl, const ARect& destination) { + CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); CHECK_VALID_RECT(destination); sp surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); - transaction->setFrame(surfaceControl, static_cast(destination));*/ + transaction->setFrame(surfaceControl, static_cast(destination)); } void ASurfaceTransaction_setTransform(ASurfaceTransaction* aSurfaceTransaction, From 93bdfca03d527ca8ee40443baea100a84adaea27 Mon Sep 17 00:00:00 2001 From: Orion Hodson Date: Thu, 8 Apr 2021 12:30:21 +0000 Subject: [PATCH 034/176] Revert "Remove setFrame from surface_control setGeometry" Revert "Remove setFrame from BufferStateLayer" Revert "Update tests to reflect the new behavior for setGeometry" Revert submission 13843937-sc_remove_set_frame Reason for revert: Candidate CL for b/184807094 Reverted Changes: Iffbd955a3:Remove setFrame I27f17bc61:Update tests to reflect the new behavior for setGe... I5720276c1:Remove setFrame from surface_control setGeometry I32ee0e3e4:Remove setFrame from BufferStateLayer Bug: 184807094 Change-Id: I7f6f0d7799e6e2858af2ce2e8acb5c67db8714f8 (cherry picked from commit 98aa7d4c88834987d5102f0137d206e921583ace) --- native/android/surface_control.cpp | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp index 7433cf9705668..e0f637959cfb3 100644 --- a/native/android/surface_control.cpp +++ b/native/android/surface_control.cpp @@ -432,27 +432,14 @@ void ASurfaceTransaction_setGeometry(ASurfaceTransaction* aSurfaceTransaction, const ARect& destination, int32_t transform) { CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); + CHECK_VALID_RECT(source); CHECK_VALID_RECT(destination); - Rect sourceRect = static_cast(source); - // Adjust the source so its top and left are not negative - sourceRect.left = std::max(sourceRect.left, 0); - sourceRect.top = std::max(sourceRect.top, 0); - LOG_ALWAYS_FATAL_IF(sourceRect.isEmpty(), "invalid arg passed as source argument"); - sp surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); - transaction->setCrop(surfaceControl, sourceRect); - - float dsdx = (destination.right - destination.left) / - static_cast(sourceRect.right - sourceRect.left); - float dsdy = (destination.bottom - destination.top) / - static_cast(sourceRect.bottom - sourceRect.top); - - transaction->setPosition(surfaceControl, destination.left - (sourceRect.left * dsdx), - destination.top - (sourceRect.top * dsdy)); - transaction->setMatrix(surfaceControl, dsdx, 0, 0, dsdy); + transaction->setCrop(surfaceControl, static_cast(source)); + transaction->setFrame(surfaceControl, static_cast(destination)); transaction->setTransform(surfaceControl, transform); bool transformToInverseDisplay = (NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY & transform) == NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; @@ -471,18 +458,16 @@ void ASurfaceTransaction_setSourceRect(ASurfaceTransaction* aSurfaceTransaction, transaction->setCrop(surfaceControl, static_cast(source)); } -void ASurfaceTransaction_setPosition(ASurfaceTransaction* /* aSurfaceTransaction */, - ASurfaceControl* /* aSurfaceControl */, - const ARect& /* destination */) { - // TODO: Fix this function - /* CHECK_NOT_NULL(aSurfaceTransaction); +void ASurfaceTransaction_setPosition(ASurfaceTransaction* aSurfaceTransaction, + ASurfaceControl* aSurfaceControl, const ARect& destination) { + CHECK_NOT_NULL(aSurfaceTransaction); CHECK_NOT_NULL(aSurfaceControl); CHECK_VALID_RECT(destination); sp surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl); Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction); - transaction->setFrame(surfaceControl, static_cast(destination));*/ + transaction->setFrame(surfaceControl, static_cast(destination)); } void ASurfaceTransaction_setTransform(ASurfaceTransaction* aSurfaceTransaction, From 0b63ce0f181cc64fe2ea200280c46c4cfb7694e0 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Thu, 8 Apr 2021 11:51:29 +0000 Subject: [PATCH 035/176] Revert^3 "Enable smartspace" 3b67a00d95e6d19824030cd1169e213c2231ce71 Change-Id: I4711f24b1ed3535dbf40ffd6ab893e6cd661fe49 (cherry picked from commit 20744ed3b4623b379821af2945ef0cb77fe40648) --- packages/SystemUI/AndroidManifest.xml | 2 - .../plugins/BcSmartspaceDataPlugin.java | 18 ---- packages/SystemUI/res/values/flags.xml | 2 - .../KeyguardClockSwitchController.java | 100 +----------------- .../com/android/systemui/SystemUIFactory.java | 12 +-- .../systemui/statusbar/FeatureFlags.java | 4 - .../KeyguardClockSwitchControllerTest.java | 70 +----------- 7 files changed, 6 insertions(+), 202 deletions(-) diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 88d7710e56c6e..85ecb1c7345da 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -275,8 +275,6 @@ - - diff --git a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java index 35423a979cbcd..f8a9a04596731 100644 --- a/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java +++ b/packages/SystemUI/plugin/bcsmartspace/src/com/android/systemui/plugins/BcSmartspaceDataPlugin.java @@ -16,9 +16,7 @@ package com.android.systemui.plugins; -import android.app.smartspace.SmartspaceTarget; import android.os.Parcelable; -import android.view.ViewGroup; import com.android.systemui.plugins.annotations.ProvidesInterface; @@ -38,25 +36,9 @@ public interface BcSmartspaceDataPlugin extends Plugin { /** Unregister a listener. */ void unregisterListener(SmartspaceTargetListener listener); - /** - * Create a view to be shown within the parent. Do not add the view, as the parent - * will be responsible for correctly setting the LayoutParams - */ - default SmartspaceView getView(ViewGroup parent) { - return null; - } - - /** Updates Smartspace data and propagates it to any listeners. */ - void onTargetsAvailable(List targets); - /** Provides Smartspace data to registered listeners. */ interface SmartspaceTargetListener { /** Each Parcelable is a SmartspaceTarget that represents a card. */ void onSmartspaceTargetsUpdated(List targets); } - - /** View to which this plugin can be registered, in order to get updates. */ - interface SmartspaceView { - void registerDataProvider(BcSmartspaceDataPlugin plugin); - } } diff --git a/packages/SystemUI/res/values/flags.xml b/packages/SystemUI/res/values/flags.xml index bbf204844e29a..834b482a449e9 100644 --- a/packages/SystemUI/res/values/flags.xml +++ b/packages/SystemUI/res/values/flags.xml @@ -50,6 +50,4 @@ false true - - false diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java index 24b7cd118ed67..0675200f81e26 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java @@ -16,15 +16,8 @@ package com.android.keyguard; -import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; -import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; - import android.app.WallpaperManager; -import android.app.smartspace.SmartspaceConfig; -import android.app.smartspace.SmartspaceManager; -import android.app.smartspace.SmartspaceSession; import android.content.ContentResolver; -import android.content.Context; import android.content.res.Resources; import android.provider.Settings; import android.text.TextUtils; @@ -32,7 +25,6 @@ import android.text.format.DateFormat; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import android.widget.RelativeLayout; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; @@ -40,12 +32,8 @@ import com.android.systemui.R; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.dagger.qualifiers.Main; -import com.android.systemui.plugins.BcSmartspaceDataPlugin; import com.android.systemui.plugins.ClockPlugin; -import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shared.plugins.PluginManager; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.notification.stack.AnimationProperties; @@ -55,7 +43,6 @@ import com.android.systemui.util.ViewController; import java.util.Locale; import java.util.TimeZone; -import java.util.concurrent.Executor; import javax.inject.Inject; @@ -81,13 +68,6 @@ public class KeyguardClockSwitchController extends ViewController() { - - @Override - public void onPluginConnected(BcSmartspaceDataPlugin plugin, Context pluginContext) { - if (!mIsSmartspaceEnabled) return; - - View ksa = mView.findViewById(R.id.keyguard_status_area); - int ksaIndex = mView.indexOfChild(ksa); - ksa.setVisibility(View.GONE); - - mSmartspaceView = plugin.getView(mView); - mSmartspaceView.registerDataProvider(plugin); - - RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams( - MATCH_PARENT, WRAP_CONTENT); - lp.addRule(RelativeLayout.BELOW, R.id.new_lockscreen_clock_view); - mView.addView((View) mSmartspaceView, ksaIndex, lp); - - View nic = mView.findViewById( - com.android.systemui.R.id.left_aligned_notification_icon_container); - lp = (RelativeLayout.LayoutParams) nic.getLayoutParams(); - lp.addRule(RelativeLayout.BELOW, ((View) mSmartspaceView).getId()); - nic.setLayoutParams(lp); - - createSmartspaceSession(plugin); - } - - @Override - public void onPluginDisconnected(BcSmartspaceDataPlugin plugin) { - if (!mIsSmartspaceEnabled) return; - - mView.removeView((View) mSmartspaceView); - mView.findViewById(R.id.keyguard_status_area).setVisibility(View.VISIBLE); - - View nic = mView.findViewById( - com.android.systemui.R.id.left_aligned_notification_icon_container); - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) - nic.getLayoutParams(); - lp.addRule(RelativeLayout.BELOW, R.id.keyguard_status_area); - nic.setLayoutParams(lp); - - mSmartspaceView = null; - } - - private void createSmartspaceSession(BcSmartspaceDataPlugin plugin) { - mSmartspaceSession = getContext().getSystemService(SmartspaceManager.class) - .createSmartspaceSession( - new SmartspaceConfig.Builder(getContext(), "lockscreen").build()); - mSmartspaceCallback = targets -> plugin.onTargetsAvailable(targets); - mSmartspaceSession.registerSmartspaceUpdates(mUiExecutor, mSmartspaceCallback); - mSmartspaceSession.requestSmartspaceUpdate(); - } - }; - mPluginManager.addPluginListener(mPluginListener, BcSmartspaceDataPlugin.class, false); } @Override @@ -233,13 +147,6 @@ public class KeyguardClockSwitchController extends ViewController T getInstance() { return (T) mFactory; @@ -89,13 +88,13 @@ public class SystemUIFactory { public void init(Context context, boolean fromTest) throws ExecutionException, InterruptedException { // Only initialize components for the main system ui process running as the primary user - mInitializeComponents = !fromTest + final boolean initializeComponents = !fromTest && android.os.Process.myUserHandle().isSystem() && ActivityThread.currentProcessName().equals(ActivityThread.currentPackageName()); mRootComponent = buildGlobalRootComponent(context); // Stand up WMComponent mWMComponent = mRootComponent.getWMComponentBuilder().build(); - if (mInitializeComponents) { + if (initializeComponents) { // Only initialize when not starting from tests since this currently initializes some // components that shouldn't be run in the test environment mWMComponent.init(); @@ -103,7 +102,7 @@ public class SystemUIFactory { // And finally, retrieve whatever SysUI needs from WMShell and build SysUI. SysUIComponent.Builder builder = mRootComponent.getSysUIComponent(); - if (mInitializeComponents) { + if (initializeComponents) { // Only initialize when not starting from tests since this currently initializes some // components that shouldn't be run in the test environment builder = prepareSysUIComponentBuilder(builder, mWMComponent) @@ -135,7 +134,7 @@ public class SystemUIFactory { .setStartingSurface(Optional.ofNullable(null)); } mSysUIComponent = builder.build(); - if (mInitializeComponents) { + if (initializeComponents) { mSysUIComponent.init(); } @@ -161,9 +160,6 @@ public class SystemUIFactory { .build(); } - protected boolean shouldInitializeComponents() { - return mInitializeComponents; - } public GlobalRootComponent getRootComponent() { return mRootComponent; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java index ec3a857dbc840..f51fbedebad25 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/FeatureFlags.java @@ -97,8 +97,4 @@ public class FeatureFlags { public boolean isOngoingCallStatusBarChipEnabled() { return mFlagReader.isEnabled(R.bool.flag_ongoing_call_status_bar_chip); } - - public boolean isSmartspaceEnabled() { - return mFlagReader.isEnabled(R.bool.flag_smartspace); - } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java index 0fcd79b357c3a..70a7b7a5acbcf 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java @@ -18,34 +18,26 @@ package com.android.keyguard; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.ContentResolver; -import android.content.Context; import android.content.res.Resources; import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; -import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; -import android.widget.RelativeLayout; import com.android.internal.colorextraction.ColorExtractor; import com.android.keyguard.clock.ClockManager; -import com.android.systemui.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.colorextraction.SysuiColorExtractor; -import com.android.systemui.plugins.BcSmartspaceDataPlugin; import com.android.systemui.plugins.ClockPlugin; import com.android.systemui.plugins.statusbar.StatusBarStateController; -import com.android.systemui.shared.plugins.PluginManager; -import com.android.systemui.statusbar.FeatureFlags; import com.android.systemui.statusbar.StatusBarState; import com.android.systemui.statusbar.phone.NotificationIconAreaController; import com.android.systemui.statusbar.phone.NotificationIconContainer; @@ -58,8 +50,6 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; -import java.util.concurrent.Executor; - @SmallTest @RunWith(AndroidTestingRunner.class) public class KeyguardClockSwitchControllerTest extends SysuiTestCase { @@ -88,12 +78,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { ContentResolver mContentResolver; @Mock BroadcastDispatcher mBroadcastDispatcher; - @Mock - private PluginManager mPluginManager; - @Mock - private FeatureFlags mFeatureFlags; - @Mock - private Executor mExecutor; private KeyguardClockSwitchController mController; @@ -103,8 +87,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { when(mView.findViewById(com.android.systemui.R.id.left_aligned_notification_icon_container)) .thenReturn(mNotificationIcons); - when(mView.getContext()).thenReturn(getContext()); - when(mFeatureFlags.isSmartspaceEnabled()).thenReturn(true); when(mView.isAttachedToWindow()).thenReturn(true); when(mResources.getString(anyInt())).thenReturn("h:mm"); mController = new KeyguardClockSwitchController( @@ -116,10 +98,7 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { mKeyguardSliceViewController, mNotificationIconAreaController, mContentResolver, - mBroadcastDispatcher, - mPluginManager, - mFeatureFlags, - mExecutor); + mBroadcastDispatcher); when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE); when(mColorExtractor.getColors(anyInt())).thenReturn(mGradientColors); @@ -203,45 +182,6 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { verify(mView).setClockPlugin(mClockPlugin, StatusBarState.SHADE); } - @Test - public void testSmartspacePluginConnectedRemovesKeyguardStatusArea() { - mController.init(); - - View statusArea = mock(View.class); - when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea); - - View nic = mock(View.class); - when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic); - when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class)); - - BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class); - TestView view = mock(TestView.class); - when(plugin.getView(any())).thenReturn(view); - - mController.mPluginListener.onPluginConnected(plugin, mContext); - verify(statusArea).setVisibility(View.GONE); - } - - @Test - public void testSmartspacePluginDisconnectedShowsKeyguardStatusArea() { - mController.init(); - - View statusArea = mock(View.class); - when(mView.findViewById(R.id.keyguard_status_area)).thenReturn(statusArea); - - View nic = mock(View.class); - when(mView.findViewById(R.id.left_aligned_notification_icon_container)).thenReturn(nic); - when(nic.getLayoutParams()).thenReturn(mock(RelativeLayout.LayoutParams.class)); - - BcSmartspaceDataPlugin plugin = mock(BcSmartspaceDataPlugin.class); - TestView view = mock(TestView.class); - when(plugin.getView(any())).thenReturn(view); - - mController.mPluginListener.onPluginConnected(plugin, mContext); - mController.mPluginListener.onPluginDisconnected(plugin); - verify(statusArea).setVisibility(View.VISIBLE); - } - private void verifyAttachment(VerificationMode times) { verify(mClockManager, times).addOnClockChangedListener( any(ClockManager.ClockChangedListener.class)); @@ -251,12 +191,4 @@ public class KeyguardClockSwitchControllerTest extends SysuiTestCase { any(ColorExtractor.OnColorsChangedListener.class)); verify(mView, times).updateColors(mGradientColors); } - - private static class TestView extends View implements BcSmartspaceDataPlugin.SmartspaceView { - TestView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public void registerDataProvider(BcSmartspaceDataPlugin plugin) { } - } } From 17f6811f593c6a795460359731f6d5653ae91a10 Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Mon, 12 Apr 2021 16:39:20 +0000 Subject: [PATCH 036/176] Revert "[SettingsProvider] remove in-lock calls to PackageManager.getPackageUid()" This reverts commit 25728b15e487b01963f11d425d38d2e2f8e63b06. Reason for revert: b/185085629 Change-Id: I2af49e3cb79af5bd80a0f69a2c09be5bbb45aeee (cherry picked from commit 7a659fca89413816376f748191fb9f5d00b93e6f) --- .../providers/settings/SettingsProvider.java | 142 +++++++------ .../providers/settings/SettingsState.java | 188 ++++++++++-------- 2 files changed, 177 insertions(+), 153 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 6440d2a53f848..91667c4e88c74 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -16,6 +16,7 @@ package com.android.providers.settings; +import static android.os.Process.INVALID_UID; import static android.os.Process.ROOT_UID; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; @@ -363,11 +364,6 @@ public class SettingsProvider extends ContentProvider { mHandler = new Handler(mHandlerThread.getLooper()); mSettingsRegistry = new SettingsRegistry(); } - SettingsState.cacheSystemPackageNamesAndSystemSignature(getContext()); - synchronized (mLock) { - mSettingsRegistry.migrateAllLegacySettingsIfNeededLocked(); - mSettingsRegistry.syncSsaidTableOnStartLocked(); - } mHandler.post(() -> { registerBroadcastReceivers(); startWatchingUserRestrictionChanges(); @@ -2503,6 +2499,8 @@ public class SettingsProvider extends ContentProvider { mHandler = new MyHandler(getContext().getMainLooper()); mGenerationRegistry = new GenerationRegistry(mLock); mBackupManager = new BackupManager(getContext()); + migrateAllLegacySettingsIfNeeded(); + syncSsaidTableOnStart(); } private void generateUserKeyLocked(int userId) { @@ -2589,36 +2587,38 @@ public class SettingsProvider extends ContentProvider { return getSettingLocked(SETTINGS_TYPE_SSAID, userId, uid); } - private void syncSsaidTableOnStartLocked() { - // Verify that each user's packages and ssaid's are in sync. - for (UserInfo user : mUserManager.getAliveUsers()) { - // Get all uids for the user's packages. - final List packages; - try { - packages = mPackageManager.getInstalledPackages( + public void syncSsaidTableOnStart() { + synchronized (mLock) { + // Verify that each user's packages and ssaid's are in sync. + for (UserInfo user : mUserManager.getAliveUsers()) { + // Get all uids for the user's packages. + final List packages; + try { + packages = mPackageManager.getInstalledPackages( PackageManager.MATCH_UNINSTALLED_PACKAGES, user.id).getList(); - } catch (RemoteException e) { - throw new IllegalStateException("Package manager not available"); - } - final Set appUids = new HashSet<>(); - for (PackageInfo info : packages) { - appUids.add(Integer.toString(info.applicationInfo.uid)); - } + } catch (RemoteException e) { + throw new IllegalStateException("Package manager not available"); + } + final Set appUids = new HashSet<>(); + for (PackageInfo info : packages) { + appUids.add(Integer.toString(info.applicationInfo.uid)); + } - // Get all uids currently stored in the user's ssaid table. - final Set ssaidUids = new HashSet<>( - getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id)); - ssaidUids.remove(SSAID_USER_KEY); + // Get all uids currently stored in the user's ssaid table. + final Set ssaidUids = new HashSet<>( + getSettingsNamesLocked(SETTINGS_TYPE_SSAID, user.id)); + ssaidUids.remove(SSAID_USER_KEY); - // Perform a set difference for the appUids and ssaidUids. - ssaidUids.removeAll(appUids); + // Perform a set difference for the appUids and ssaidUids. + ssaidUids.removeAll(appUids); - // If there are ssaidUids left over they need to be removed from the table. - final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, - user.id); - for (String uid : ssaidUids) { - ssaidSettings.deleteSettingLocked(uid); + // If there are ssaidUids left over they need to be removed from the table. + final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, + user.id); + for (String uid : ssaidUids) { + ssaidSettings.deleteSettingLocked(uid); + } } } } @@ -2911,7 +2911,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), - setting.getPackageName())) { + setting.getPackageName(), INVALID_UID, userId)) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } @@ -2931,7 +2931,7 @@ public class SettingsProvider extends ContentProvider { boolean someSettingChanged = false; Setting setting = settingsState.getSettingLocked(name); if (!SettingsState.isSystemPackage(getContext(), - setting.getPackageName())) { + setting.getPackageName(), INVALID_UID, userId)) { if (prefix != null && !setting.getName().startsWith(prefix)) { continue; } @@ -3009,38 +3009,40 @@ public class SettingsProvider extends ContentProvider { return mSettingsStates.get(key); } - private void migrateAllLegacySettingsIfNeededLocked() { - final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); - File globalFile = getSettingsFile(key); - if (SettingsState.stateFileExists(globalFile)) { - return; - } - - mSettingsCreationBuildId = Build.ID; - - final long identity = Binder.clearCallingIdentity(); - try { - List users = mUserManager.getAliveUsers(); - - final int userCount = users.size(); - for (int i = 0; i < userCount; i++) { - final int userId = users.get(i).id; - - DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId); - SQLiteDatabase database = dbHelper.getWritableDatabase(); - migrateLegacySettingsForUserLocked(dbHelper, database, userId); - - // Upgrade to the latest version. - UpgradeController upgrader = new UpgradeController(userId); - upgrader.upgradeIfNeededLocked(); - - // Drop from memory if not a running user. - if (!mUserManager.isUserRunning(new UserHandle(userId))) { - removeUserStateLocked(userId, false); - } + private void migrateAllLegacySettingsIfNeeded() { + synchronized (mLock) { + final int key = makeKey(SETTINGS_TYPE_GLOBAL, UserHandle.USER_SYSTEM); + File globalFile = getSettingsFile(key); + if (SettingsState.stateFileExists(globalFile)) { + return; + } + + mSettingsCreationBuildId = Build.ID; + + final long identity = Binder.clearCallingIdentity(); + try { + List users = mUserManager.getAliveUsers(); + + final int userCount = users.size(); + for (int i = 0; i < userCount; i++) { + final int userId = users.get(i).id; + + DatabaseHelper dbHelper = new DatabaseHelper(getContext(), userId); + SQLiteDatabase database = dbHelper.getWritableDatabase(); + migrateLegacySettingsForUserLocked(dbHelper, database, userId); + + // Upgrade to the latest version. + UpgradeController upgrader = new UpgradeController(userId); + upgrader.upgradeIfNeededLocked(); + + // Drop from memory if not a running user. + if (!mUserManager.isUserRunning(new UserHandle(userId))) { + removeUserStateLocked(userId, false); + } + } + } finally { + Binder.restoreCallingIdentity(identity); } - } finally { - Binder.restoreCallingIdentity(identity); } } @@ -5034,9 +5036,19 @@ public class SettingsProvider extends ContentProvider { // In the upgrade case we pretend the call is made from the app // that made the last change to the setting to properly determine // whether the call has been made by a system component. + int callingUid = -1; try { - final boolean systemSet = SettingsState.isSystemPackage( - getContext(), setting.getPackageName()); + callingUid = mPackageManager.getPackageUid(setting.getPackageName(), 0, userId); + } catch (RemoteException e) { + /* ignore - handled below */ + } + if (callingUid < 0) { + Slog.e(LOG_TAG, "Unknown package: " + setting.getPackageName()); + continue; + } + try { + final boolean systemSet = SettingsState.isSystemPackage(getContext(), + setting.getPackageName(), callingUid, userId); if (systemSet) { settings.insertSettingOverrideableByRestoreLocked(name, setting.getValue(), setting.getTag(), true, setting.getPackageName()); diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 911ff9916d6c6..53d868ac00501 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -17,13 +17,14 @@ package com.android.providers.settings; import static android.os.Process.FIRST_APPLICATION_UID; +import static android.os.Process.INVALID_UID; import android.annotation.NonNull; -import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; +import android.content.pm.Signature; import android.os.Binder; import android.os.Build; import android.os.FileUtils; @@ -36,10 +37,10 @@ import android.provider.Settings; import android.providers.settings.SettingsOperationProto; import android.text.TextUtils; import android.util.ArrayMap; -import android.util.ArraySet; import android.util.AtomicFile; import android.util.Base64; import android.util.Slog; +import android.util.SparseIntArray; import android.util.TimeUtils; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; @@ -148,7 +149,13 @@ final class SettingsState { private static final String NULL_VALUE = "null"; - private static final ArraySet sSystemPackages = new ArraySet<>(); + private static final Object sLock = new Object(); + + @GuardedBy("sLock") + private static final SparseIntArray sSystemUids = new SparseIntArray(); + + @GuardedBy("sLock") + private static Signature sSystemSignature; private final Object mWriteLock = new Object(); @@ -634,7 +641,7 @@ final class SettingsState { /** * Dump historical operations as a proto buf. * - * @param proto The proto buf stream to dump to + * @param proto The proto buf stream to dump to * @param fieldId The repeated field ID to use to save an operation to. */ void dumpHistoricalOperations(@NonNull ProtoOutputStream proto, long fieldId) { @@ -1041,7 +1048,6 @@ final class SettingsState { /** * Uses AtomicFile to check if the file or its backup exists. - * * @param file The file to check for existence * @return whether the original or backup exist */ @@ -1301,9 +1307,9 @@ final class SettingsState { if (NULL_VALUE.equals(value)) { value = null; } + final boolean callerSystem = !forceNonSystemPackage && - !isNull() && (isCalledFromSystem(packageName) - || isSystemPackage(mContext, packageName)); + !isNull() && isSystemPackage(mContext, packageName); // Settings set by the system are always defaults. if (callerSystem) { setDefault = true; @@ -1428,92 +1434,98 @@ final class SettingsState { return sb.toString(); } - // Cache the list of names of system packages. This is only called once on system boot. - public static void cacheSystemPackageNamesAndSystemSignature(@NonNull Context context) { - final PackageManager packageManager = context.getPackageManager(); - final long identity = Binder.clearCallingIdentity(); - try { - sSystemPackages.add(SYSTEM_PACKAGE_NAME); - // Cache SetupWizard package name. - final String setupWizPackageName = packageManager.getSetupWizardPackageName(); - if (setupWizPackageName != null) { - sSystemPackages.add(setupWizPackageName); + // Check if a specific package belonging to the caller is part of the system package. + public static boolean isSystemPackage(Context context, String packageName) { + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + return isSystemPackage(context, packageName, callingUid, callingUserId); + } + + // Check if a specific package, uid, and user ID are part of the system package. + public static boolean isSystemPackage(Context context, String packageName, int uid, + int userId) { + synchronized (sLock) { + if (SYSTEM_PACKAGE_NAME.equals(packageName)) { + return true; } - final List packageInfos = packageManager.getInstalledPackages(0); - final int installedPackagesCount = packageInfos.size(); - for (int i = 0; i < installedPackagesCount; i++) { - if (shouldAddToSystemPackages(packageInfos.get(i))) { - sSystemPackages.add(packageInfos.get(i).packageName); + + // Shell and Root are not considered a part of the system + if (SHELL_PACKAGE_NAME.equals(packageName) + || ROOT_PACKAGE_NAME.equals(packageName)) { + return false; + } + + if (uid != INVALID_UID) { + // Native services running as a special UID get a pass + final int callingAppId = UserHandle.getAppId(uid); + if (callingAppId < FIRST_APPLICATION_UID) { + sSystemUids.put(callingAppId, callingAppId); + return true; } } - } finally { - Binder.restoreCallingIdentity(identity); - } - } - private static boolean shouldAddToSystemPackages(@NonNull PackageInfo packageInfo) { - // Shell and Root are not considered a part of the system - if (isShellOrRoot(packageInfo.packageName)) { + final long identity = Binder.clearCallingIdentity(); + try { + try { + uid = context.getPackageManager().getPackageUidAsUser(packageName, 0, userId); + } catch (PackageManager.NameNotFoundException e) { + return false; + } + + // If the system or a special system UID (like telephony), done. + if (UserHandle.getAppId(uid) < FIRST_APPLICATION_UID) { + sSystemUids.put(uid, uid); + return true; + } + + // If already known system component, done. + if (sSystemUids.indexOfKey(uid) >= 0) { + return true; + } + + // If SetupWizard, done. + String setupWizPackage = context.getPackageManager().getSetupWizardPackageName(); + if (packageName.equals(setupWizPackage)) { + sSystemUids.put(uid, uid); + return true; + } + + // If a persistent system app, done. + PackageInfo packageInfo; + try { + packageInfo = context.getPackageManager().getPackageInfoAsUser( + packageName, PackageManager.GET_SIGNATURES, userId); + if ((packageInfo.applicationInfo.flags + & ApplicationInfo.FLAG_PERSISTENT) != 0 + && (packageInfo.applicationInfo.flags + & ApplicationInfo.FLAG_SYSTEM) != 0) { + sSystemUids.put(uid, uid); + return true; + } + } catch (PackageManager.NameNotFoundException e) { + return false; + } + + // Last check if system signed. + if (sSystemSignature == null) { + try { + sSystemSignature = context.getPackageManager().getPackageInfoAsUser( + SYSTEM_PACKAGE_NAME, PackageManager.GET_SIGNATURES, + UserHandle.USER_SYSTEM).signatures[0]; + } catch (PackageManager.NameNotFoundException e) { + /* impossible */ + return false; + } + } + if (sSystemSignature.equals(packageInfo.signatures[0])) { + sSystemUids.put(uid, uid); + return true; + } + } finally { + Binder.restoreCallingIdentity(identity); + } + return false; } - // Already added - if (sSystemPackages.contains(packageInfo.packageName)) { - return false; - } - return isSystemPackage(packageInfo.applicationInfo); - } - - private static boolean isShellOrRoot(@NonNull String packageName) { - return (SHELL_PACKAGE_NAME.equals(packageName) - || ROOT_PACKAGE_NAME.equals(packageName)); - } - - private static boolean isCalledFromSystem(@NonNull String packageName) { - // Shell and Root are not considered a part of the system - if (isShellOrRoot(packageName)) { - return false; - } - final int callingUid = Binder.getCallingUid(); - // Native services running as a special UID get a pass - final int callingAppId = UserHandle.getAppId(callingUid); - return (callingAppId < FIRST_APPLICATION_UID); - } - - public static boolean isSystemPackage(@NonNull Context context, @NonNull String packageName) { - // Check shell or root before trying to retrieve ApplicationInfo to fail fast - if (isShellOrRoot(packageName)) { - return false; - } - // If it's a known system package or known to be platform signed - if (sSystemPackages.contains(packageName)) { - return true; - } - ApplicationInfo aInfo = null; - try { - // Notice that this makes a call to package manager inside the lock - aInfo = context.getPackageManager().getApplicationInfo(packageName, 0); - } catch (PackageManager.NameNotFoundException ignored) { - } - return isSystemPackage(aInfo); - } - - private static boolean isSystemPackage(@Nullable ApplicationInfo aInfo) { - if (aInfo == null) { - return false; - } - // If the system or a special system UID (like telephony), done. - if (aInfo.uid < FIRST_APPLICATION_UID) { - return true; - } - // If a persistent system app, done. - if ((aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0 - && (aInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { - return true; - } - // Platform signed packages are considered to be from the system - if (aInfo.isSignedWithPlatformKey()) { - return true; - } - return false; } } From 98b3c58991df6bb6cdb224f84e1b86a356be8dbd Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Tue, 13 Apr 2021 22:08:45 -0700 Subject: [PATCH 037/176] Fix NullPointerException in BatteryUsageStats Bug: 185287730 Test: Build and launch Settings on a crosshatch Change-Id: Iccdd8a0f3839b98dbb5c09599f35ac15985daa4c (cherry picked from commit 153f2acfee7c9a51a231cae6120b01be15bc20dc) --- core/java/android/os/BatteryUsageStats.java | 8 +++----- core/java/com/android/internal/os/BatteryStatsImpl.java | 4 ++-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index 48f4ca4035ce2..8ea59ce370183 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -24,7 +24,6 @@ import com.android.internal.os.BatteryStatsHistory; import com.android.internal.os.BatteryStatsHistoryIterator; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; /** @@ -233,8 +232,6 @@ public final class BatteryUsageStats implements Parcelable { mHistoryBuffer = null; mHistoryTagPool = null; } - System.out.println("From Parcel = " + Arrays.toString( - mCustomPowerComponentNames)); } @Override @@ -293,6 +290,7 @@ public final class BatteryUsageStats implements Parcelable { * Builder for BatteryUsageStats. */ public static final class Builder { + @NonNull private final String[] mCustomPowerComponentNames; private final int mCustomTimeComponentCount; private final boolean mIncludePowerModels; @@ -311,11 +309,11 @@ public final class BatteryUsageStats implements Parcelable { private Parcel mHistoryBuffer; private List mHistoryTagPool; - public Builder(String[] customPowerComponentNames, int customTimeComponentCount) { + public Builder(@NonNull String[] customPowerComponentNames, int customTimeComponentCount) { this(customPowerComponentNames, customTimeComponentCount, false); } - public Builder(String[] customPowerComponentNames, int customTimeComponentCount, + public Builder(@NonNull String[] customPowerComponentNames, int customTimeComponentCount, boolean includePowerModels) { mCustomPowerComponentNames = customPowerComponentNames; mCustomTimeComponentCount = customTimeComponentCount; diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index e83f365738da0..cb1900f300c02 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -6951,9 +6951,9 @@ public class BatteryStatsImpl extends BatteryStats { /** * Returns the names of custom power components. */ - public @Nullable String[] getCustomPowerComponentNames() { + public @NonNull String[] getCustomPowerComponentNames() { if (mGlobalMeasuredEnergyStats == null) { - return null; + return new String[0]; } final String[] names = mGlobalMeasuredEnergyStats.getCustomBucketNames(); for (int i = 0; i < names.length; i++) { From 6f06021e0142116e46415a549f0dc3d381e99e3f Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 038/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: I42d00d33f49ee708148233d608164459a9ca5929 (cherry picked from commit 8f5096b6d64b242f3e17d74e1292e7a5849afc70) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index f3c71ce216cd9..18e323c213275 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && (445500383 == pkg.getVersionCode() || 438500084 == pkg.getVersionCode())) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From 40941e03636561e543cd3815270b61be7cb477c7 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Wed, 14 Apr 2021 16:10:10 +0800 Subject: [PATCH 039/176] Rename SettingsPreferenceTheme to PreferenceTheme.SettingsBase Bug: 185206291 Test: rebuild Change-Id: I89862583caec3db43716b55c8bc43c3f6580c919 (cherry picked from commit e0c507d5a8a7baa45160471b53dc96a240d24017) --- .../SettingsTheme/res/values/styles_preference.xml | 4 ++-- packages/SettingsLib/SettingsTheme/res/values/themes.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml index dcbdc07d1335b..cec8b3294418b 100644 --- a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml +++ b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml @@ -15,7 +15,7 @@ limitations under the License. --> - + - From 5dfec1a0611de93931ad4c99287efd9fc108a205 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Mon, 29 Mar 2021 18:52:29 -0600 Subject: [PATCH 040/176] Temporary stop-gap for Chrome target SDK issue. The Chrome team was planning to provide a new prebuilt SDK last week which returned to targeting the official R SDK level, but other challenges prevented them from doing so. They still intend to land an updated prebuilt which targets R, but to unblock testing this change makes that change on their behalf; when we see a very specific Chrome version code we force the target SDK back to R. This code will safely become a no-op during their next prebuilt, which should have a different version code. Bug: 183905675 Test: manual Change-Id: I42d00d33f49ee708148233d608164459a9ca5929 (cherry picked from commit 8f5096b6d64b242f3e17d74e1292e7a5849afc70) --- .../android/content/pm/parsing/ParsingPackageUtils.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index f3c71ce216cd9..18e323c213275 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -2800,6 +2800,12 @@ public class ParsingPackageUtils { } private void convertSplitPermissions(ParsingPackage pkg) { + // STOPSHIP(b/183905675): REMOVE THIS TERRIBLE, HORRIBLE, NO GOOD, VERY BAD HACK + if ("com.android.chrome".equals(pkg.getPackageName()) + && (445500383 == pkg.getVersionCode() || 438500084 == pkg.getVersionCode())) { + pkg.setTargetSdkVersion(Build.VERSION_CODES.R); + } + final int listSize = mSplitPermissionInfos.size(); for (int is = 0; is < listSize; is++) { final PermissionManager.SplitPermissionInfo spi = mSplitPermissionInfos.get(is); From 6d87fdf788ab627d02c082ffd62d20059161dc47 Mon Sep 17 00:00:00 2001 From: Edgar Wang Date: Wed, 14 Apr 2021 16:10:10 +0800 Subject: [PATCH 041/176] Rename SettingsPreferenceTheme to PreferenceTheme.SettingsBase Bug: 185206291 Test: rebuild Change-Id: I89862583caec3db43716b55c8bc43c3f6580c919 (cherry picked from commit e0c507d5a8a7baa45160471b53dc96a240d24017) --- .../SettingsTheme/res/values/styles_preference.xml | 4 ++-- packages/SettingsLib/SettingsTheme/res/values/themes.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml index dcbdc07d1335b..cec8b3294418b 100644 --- a/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml +++ b/packages/SettingsLib/SettingsTheme/res/values/styles_preference.xml @@ -15,7 +15,7 @@ limitations under the License. --> - + - From 1260b5cabb34a81e87ab72b5d05c2abfcf742624 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Mon, 19 Apr 2021 18:39:17 +0000 Subject: [PATCH 042/176] Revert "Add icon for "Extra dim" used in accessibility shortcut" This reverts commit e9f44933ac3558b39eb2e7f88bee579ba8c03a7a. Reason for revert: Bug: 185737105 Change-Id: I7978fb859451a47182bf7a2147a50254731bfc2d (cherry picked from commit 56a7a55e651dbae3b370888063b325478e0f42b4) --- .../dialog/AccessibilityTargetHelper.java | 3 +- .../ic_accessibility_reduce_bright_colors.xml | 63 ------------------- core/res/res/values/colors.xml | 3 +- core/res/res/values/dimens.xml | 6 -- core/res/res/values/symbols.xml | 1 - 5 files changed, 3 insertions(+), 73 deletions(-) delete mode 100644 core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java index 0854955a92d5b..9d06bb92b2056 100644 --- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java +++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java @@ -230,6 +230,7 @@ public final class AccessibilityTargetHelper { context.getDrawable(R.drawable.ic_accessibility_color_inversion), Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED); + // TODO: Update with shortcut icon final ToggleAllowListingFeatureTarget reduceBrightColors = new ToggleAllowListingFeatureTarget(context, shortcutType, @@ -237,7 +238,7 @@ public final class AccessibilityTargetHelper { REDUCE_BRIGHT_COLORS_COMPONENT_NAME.flattenToString()), REDUCE_BRIGHT_COLORS_COMPONENT_NAME.flattenToString(), context.getString(R.string.reduce_bright_colors_feature_name), - context.getDrawable(R.drawable.ic_accessibility_reduce_bright_colors), + null, Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED); targets.add(magnification); diff --git a/core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml b/core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml deleted file mode 100644 index 1e840d26ca133..0000000000000 --- a/core/res/res/drawable/ic_accessibility_reduce_bright_colors.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 3ad20c6031157..0213c60e9f60c 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -231,8 +231,7 @@ @color/loading_gradient_background_color_light @color/loading_gradient_highlight_color_light - #5F6368 - #3C4043 + #ff3C4043 #ffC4C6C6 diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 062b0809c2478..0e436e36b4742 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -570,12 +570,6 @@ 4dp - - 32dp - - - 18dp - 8dp diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 512f2764a74f8..7bf047cbdab34 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3389,7 +3389,6 @@ - From 70154c60f62b486ada63f4b3da437de838758157 Mon Sep 17 00:00:00 2001 From: Evan Severson Date: Tue, 20 Apr 2021 09:04:31 -0700 Subject: [PATCH 043/176] Fix typo in sensor privacy init Should be getting the value at index i, not using int i as a key. Also when iterating over the state we should be holding the lock. Test: Push sensor_privacy.xml file and reboot Fixes: 185881144 Change-Id: I09823d888b05b674b32254d39ab030ce0e6c2acf (cherry picked from commit 30a3a67dad3ae348c47f33976d36bdd28e322efe) --- .../android/server/SensorPrivacyService.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/SensorPrivacyService.java b/services/core/java/com/android/server/SensorPrivacyService.java index 3ba4c34fb1a7b..e8bc812e5ea88 100644 --- a/services/core/java/com/android/server/SensorPrivacyService.java +++ b/services/core/java/com/android/server/SensorPrivacyService.java @@ -197,16 +197,16 @@ public final class SensorPrivacyService extends SystemService { if (readPersistedSensorPrivacyStateLocked()) { persistSensorPrivacyStateLocked(); } - } - for (int i = 0; i < mIndividualEnabled.size(); i++) { - int userId = mIndividualEnabled.keyAt(i); - SparseBooleanArray userIndividualEnabled = - mIndividualEnabled.get(i); - for (int j = 0; j < userIndividualEnabled.size(); j++) { - int sensor = userIndividualEnabled.keyAt(i); - boolean enabled = userIndividualEnabled.valueAt(j); - setUserRestriction(userId, sensor, enabled); + for (int i = 0; i < mIndividualEnabled.size(); i++) { + int userId = mIndividualEnabled.keyAt(i); + SparseBooleanArray userIndividualEnabled = + mIndividualEnabled.valueAt(i); + for (int j = 0; j < userIndividualEnabled.size(); j++) { + int sensor = userIndividualEnabled.keyAt(i); + boolean enabled = userIndividualEnabled.valueAt(j); + setUserRestriction(userId, sensor, enabled); + } } } From e8d4391b5d52cf9233bd8f41b9cb40f12b13c3c5 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Wed, 28 Apr 2021 22:32:20 +0000 Subject: [PATCH 044/176] Revert "Support FLAG_ACTIVITY_LAUNCH_ADJACENT for launch root with adjacent" This reverts commit d8abe76ba18e9baf6dcef68a65a03b6651c7e5ef. Reason for revert: Bug: 186614428 Change-Id: Id7d1f57a11f0698f9377b00008994f9a6c3038d3 (cherry picked from commit 48f90b317b9845ee241b0175cd73a7f55d5b1dd9) --- .../window/WindowContainerTransaction.java | 39 --------- .../shell/splitscreen/StageCoordinator.java | 3 - .../android/server/wm/ActivityStarter.java | 4 +- .../server/wm/RootWindowContainer.java | 24 +++-- .../core/java/com/android/server/wm/Task.java | 28 +----- .../android/server/wm/TaskDisplayArea.java | 87 ++++--------------- .../server/wm/TaskLaunchParamsModifier.java | 3 +- .../server/wm/WindowOrganizerController.java | 21 ----- .../server/wm/ActivityStarterTests.java | 8 +- .../server/wm/RootWindowContainerTests.java | 3 +- .../server/wm/TaskDisplayAreaTests.java | 60 ++----------- 11 files changed, 40 insertions(+), 240 deletions(-) diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index c0af57214e5e5..f93e413961529 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -338,33 +338,6 @@ public final class WindowContainerTransaction implements Parcelable { return this; } - /** - * Sets the container as launch adjacent flag root. Task starting with - * {@link FLAG_ACTIVITY_LAUNCH_ADJACENT} will be launching to. - * - * @hide - */ - @NonNull - public WindowContainerTransaction setLaunchAdjacentFlagRoot( - @NonNull WindowContainerToken container) { - mHierarchyOps.add(HierarchyOp.createForSetLaunchAdjacentFlagRoot(container.asBinder(), - false /* clearRoot */)); - return this; - } - - /** - * Clears launch adjacent flag root for the display area of passing container. - * - * @hide - */ - @NonNull - public WindowContainerTransaction clearLaunchAdjacentFlagRoot( - @NonNull WindowContainerToken container) { - mHierarchyOps.add(HierarchyOp.createForSetLaunchAdjacentFlagRoot(container.asBinder(), - true /* clearRoot */)); - return this; - } - /** * Starts a task by id. The task is expected to already exist (eg. as a recent task). * @param taskId Id of task to start. @@ -704,7 +677,6 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT = 3; public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4; public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5; - public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT = 6; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. @@ -762,14 +734,6 @@ public final class WindowContainerTransaction implements Parcelable { fullOptions); } - /** Create a hierarchy op for setting launch adjacent flag root. */ - public static HierarchyOp createForSetLaunchAdjacentFlagRoot(IBinder container, - boolean clearRoot) { - return new HierarchyOp(HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT, container, null, - null, null, clearRoot, null); - } - - private HierarchyOp(int type, @Nullable IBinder container, @Nullable IBinder reparent, int[] windowingModes, int[] activityTypes, boolean toTop, @Nullable Bundle launchOptions) { @@ -865,9 +829,6 @@ public final class WindowContainerTransaction implements Parcelable { + " adjacentRoot=" + mReparent + "}"; case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "{LaunchTask: " + mLaunchOptions + "}"; - case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: - return "{SetAdjacentFlagRoot: container=" + mContainer + " clearRoot=" + mToTop - + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index efaa2696cbebd..c91a92ad32427 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -337,7 +337,6 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make the stages adjacent to each other so they occlude what's behind them. wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token); - wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token); mTaskOrganizer.applyTransaction(wct); } } @@ -347,7 +346,6 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Deactivate the main stage if it no longer has a root task. mMainStage.deactivate(wct); - wct.clearLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token); mTaskOrganizer.applyTransaction(wct); } } @@ -451,7 +449,6 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make sure the main stage is active. mMainStage.activate(getMainStageBounds(), wct); - mSideStage.setBounds(getSideStageBounds(), wct); mTaskOrganizer.applyTransaction(wct); } } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 08a9f0928b8b3..9be973be87fc3 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2761,8 +2761,8 @@ class ActivityStarter { final boolean onTop = (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; - return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop, - mLaunchParams, launchFlags, mRequest.realCallingPid, mRequest.realCallingUid); + return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, onTop, mLaunchParams, + mRequest.realCallingPid, mRequest.realCallingUid); } private boolean isLaunchModeOneOf(int mode1, int mode2) { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index d9c5fa43d9e40..c81f31eb9f77d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2810,11 +2810,10 @@ class RootWindowContainer extends WindowContainer return false; } - Task getLaunchRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options, - @Nullable Task candidateTask, boolean onTop) { - return getLaunchRootTask(r, options, candidateTask, null /* sourceTask */, onTop, - null /* launchParams */, 0 /* launchFlags */, -1 /* no realCallingPid */, - -1 /* no realCallingUid */); + Task getLaunchRootTask(@Nullable ActivityRecord r, + @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) { + return getLaunchRootTask(r, options, candidateTask, onTop, null /* launchParams */, + -1 /* no realCallingPid */, -1 /* no realCallingUid */); } /** @@ -2823,18 +2822,15 @@ class RootWindowContainer extends WindowContainer * @param r The activity we are trying to launch. Can be null. * @param options The activity options used to the launch. Can be null. * @param candidateTask The possible task the activity might be launched in. Can be null. - * @param sourceTask The task requesting to start activity. Can be null. * @param launchParams The resolved launch params to use. - * @param launchFlags The launch flags for this launch. * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} * @return The root task to use for the launch or INVALID_TASK_ID. */ Task getLaunchRootTask(@Nullable ActivityRecord r, - @Nullable ActivityOptions options, @Nullable Task candidateTask, - @Nullable Task sourceTask, boolean onTop, - @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags, - int realCallingPid, int realCallingUid) { + @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop, + @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, + int realCallingUid) { int taskId = INVALID_TASK_ID; int displayId = INVALID_DISPLAY; TaskDisplayArea taskDisplayArea = null; @@ -2898,7 +2894,7 @@ class RootWindowContainer extends WindowContainer // Falling back to default task container taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea(); rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, - sourceTask, launchParams, launchFlags, activityType, onTop); + launchParams, activityType, onTop); if (rootTask != null) { return rootTask; } @@ -2953,8 +2949,8 @@ class RootWindowContainer extends WindowContainer } } - return container.getOrCreateRootTask(r, options, candidateTask, sourceTask, launchParams, - launchFlags, activityType, onTop); + return container.getOrCreateRootTask( + r, options, candidateTask, launchParams, activityType, onTop); } /** @return true if activity record is null or can be launched on provided display. */ diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 2a0041afd9d0d..d4707d6f5f5ae 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -7952,17 +7952,6 @@ class Task extends WindowContainer { private boolean mHasBeenVisible; private boolean mRemoveWithTaskOrganizer; - /** - * Records the source task that requesting to build a new task, used to determine which of - * the adjacent roots should be launch root of the new task. - */ - private Task mSourceTask; - - /** - * Records launch flags to apply when launching new task. - */ - private int mLaunchFlags; - Builder(ActivityTaskManagerService atm) { mAtmService = atm; } @@ -7972,16 +7961,6 @@ class Task extends WindowContainer { return this; } - Builder setSourceTask(Task sourceTask) { - mSourceTask = sourceTask; - return this; - } - - Builder setLaunchFlags(int launchFlags) { - mLaunchFlags = launchFlags; - return this; - } - Builder setTaskId(int taskId) { mTaskId = taskId; return this; @@ -8236,14 +8215,9 @@ class Task extends WindowContainer { tda.getRootPinnedTask().dismissPip(); } - if (mIntent != null) { - mLaunchFlags |= mIntent.getFlags(); - } - // Task created by organizer are added as root. final Task launchRootTask = mCreatedByOrganizer - ? null : tda.getLaunchRootTask(mWindowingMode, mActivityType, mActivityOptions, - mSourceTask, mLaunchFlags); + ? null : tda.getLaunchRootTask(mWindowingMode, mActivityType, mActivityOptions); if (launchRootTask != null) { // Since this task will be put into a root task, its windowingMode will be // inherited. diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index cda8c4b78b0cd..4d85e7bda9000 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -27,7 +27,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -44,6 +43,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; +import android.content.Intent; import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; @@ -132,11 +132,6 @@ final class TaskDisplayArea extends DisplayArea { } private final ArrayList mLaunchRootTasks = new ArrayList<>(); - /** - * A launch root task for activity launching with {@link FLAG_ACTIVITY_LAUNCH_ADJACENT} flag. - */ - private Task mLaunchAdjacentFlagRootTask; - /** * A focusable root task that is purposely to be positioned at the top. Although the root * task may not have the topmost index, it is used as a preferred candidate to prevent being @@ -1018,9 +1013,6 @@ final class TaskDisplayArea extends DisplayArea { if (mPreferredTopFocusableRootTask == rootTask) { mPreferredTopFocusableRootTask = null; } - if (mLaunchAdjacentFlagRootTask == rootTask) { - mLaunchAdjacentFlagRootTask = null; - } mDisplayContent.releaseSelfIfNeeded(); onRootTaskOrderChanged(rootTask); } @@ -1055,11 +1047,11 @@ final class TaskDisplayArea extends DisplayArea { * Returns an existing root task compatible with the windowing mode and activity type or * creates one if a compatible root task doesn't exist. * - * @see #getOrCreateRootTask(int, int, boolean, Task, Task, ActivityOptions, int) + * @see #getOrCreateRootTask(int, int, boolean, Intent, Task, ActivityOptions) */ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop) { - return getOrCreateRootTask(windowingMode, activityType, onTop, null /* candidateTask */, - null /* sourceTask */, null /* options */, 0 /* intent */); + return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */, + null /* candidateTask */, null /* options */); } /** @@ -1068,21 +1060,11 @@ final class TaskDisplayArea extends DisplayArea { * For one level task, the candidate task would be reused to also be the root task or create * a new root task if no candidate task. * - * @param windowingMode The windowing mode the root task should be created in. - * @param activityType The activityType the root task should be created in. - * @param onTop If true the root task will be created at the top of the display, - * else at the bottom. - * @param candidateTask The possible task the activity might be launched in. Can be null. - * @param sourceTask The task requesting to start activity. Used to determine which of the - * adjacent roots should be launch root of the new task. Can be null. - * @param options The activity options used to the launch. Can be null. - * @param launchFlags The launch flags for this launch. - * @return The root task to use for the launch. * @see #getRootTask(int, int) + * @see #createRootTask(int, int, boolean) */ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop, - @Nullable Task candidateTask, @Nullable Task sourceTask, - @Nullable ActivityOptions options, int launchFlags) { + Intent intent, Task candidateTask, ActivityOptions options) { // Need to pass in a determined windowing mode to see if a new root task should be created, // so use its parent's windowing mode if it is undefined. if (!alwaysCreateRootTask( @@ -1095,8 +1077,7 @@ final class TaskDisplayArea extends DisplayArea { } else if (candidateTask != null) { final Task rootTask = candidateTask; final int position = onTop ? POSITION_TOP : POSITION_BOTTOM; - final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options, - sourceTask, launchFlags); + final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options); if (launchRootTask != null) { if (rootTask.getParent() == null) { @@ -1122,9 +1103,8 @@ final class TaskDisplayArea extends DisplayArea { .setActivityType(activityType) .setOnTop(onTop) .setParent(this) - .setSourceTask(sourceTask) + .setIntent(intent) .setActivityOptions(options) - .setLaunchFlags(launchFlags) .build(); } @@ -1134,9 +1114,9 @@ final class TaskDisplayArea extends DisplayArea { * * @see #getOrCreateRootTask(int, int, boolean) */ - Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options, - @Nullable Task candidateTask, @Nullable Task sourceTask, - @Nullable LaunchParams launchParams, int launchFlags, int activityType, boolean onTop) { + Task getOrCreateRootTask(@Nullable ActivityRecord r, + @Nullable ActivityOptions options, @Nullable Task candidateTask, + @Nullable LaunchParams launchParams, int activityType, boolean onTop) { int windowingMode = WINDOWING_MODE_UNDEFINED; if (launchParams != null) { // If launchParams isn't null, windowing mode is already resolved. @@ -1150,8 +1130,8 @@ final class TaskDisplayArea extends DisplayArea { // UNDEFINED windowing mode is a valid result and means that the new root task will inherit // it's display's windowing mode. windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType); - return getOrCreateRootTask(windowingMode, activityType, onTop, candidateTask, sourceTask, - options, launchFlags); + return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */, + candidateTask, options); } @VisibleForTesting @@ -1219,24 +1199,6 @@ final class TaskDisplayArea extends DisplayArea { } } - void setLaunchAdjacentFlagRootTask(@Nullable Task adjacentFlagRootTask) { - if (adjacentFlagRootTask != null) { - if (!adjacentFlagRootTask.mCreatedByOrganizer) { - throw new IllegalArgumentException( - "Can't set not mCreatedByOrganizer as launch adjacent flag root tr=" - + adjacentFlagRootTask); - } - - if (adjacentFlagRootTask.mAdjacentTask == null) { - throw new UnsupportedOperationException( - "Can't set non-adjacent root as launch adjacent flag root tr=" - + adjacentFlagRootTask); - } - } - - mLaunchAdjacentFlagRootTask = adjacentFlagRootTask; - } - private @Nullable LaunchRootTaskDef getLaunchRootTaskDef(Task rootTask) { LaunchRootTaskDef def = null; for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) { @@ -1247,9 +1209,7 @@ final class TaskDisplayArea extends DisplayArea { return def; } - @Nullable - Task getLaunchRootTask(int windowingMode, int activityType, @Nullable ActivityOptions options, - @Nullable Task sourceTask, int launchFlags) { + Task getLaunchRootTask(int windowingMode, int activityType, ActivityOptions options) { // Try to use the launch root task in options if available. if (options != null) { final Task launchRootTask = Task.fromWindowContainerToken(options.getLaunchRootTask()); @@ -1259,19 +1219,6 @@ final class TaskDisplayArea extends DisplayArea { } } - // Use launch-adjacent-flag-root if launching with launch-adjacent flag. - if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 - && mLaunchAdjacentFlagRootTask != null) { - // If the adjacent launch is coming from the same root, launch to adjacent root instead. - if (sourceTask != null - && sourceTask.getRootTask().mTaskId == mLaunchAdjacentFlagRootTask.mTaskId - && mLaunchAdjacentFlagRootTask.mAdjacentTask != null) { - return mLaunchAdjacentFlagRootTask.mAdjacentTask; - } else { - return mLaunchAdjacentFlagRootTask; - } - } - for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) { if (mLaunchRootTasks.get(i).contains(windowingMode, activityType)) { return mLaunchRootTasks.get(i).task; @@ -2016,11 +1963,7 @@ final class TaskDisplayArea extends DisplayArea { // Reparent task to corresponding launch root or display area. final WindowContainer launchRoot = task.supportsSplitScreenWindowingMode() ? toDisplayArea.getLaunchRootTask( - task.getWindowingMode(), - task.getActivityType(), - null /* options */, - null /* sourceTask */, - 0 /* launchFlags */) + task.getWindowingMode(), task.getActivityType(), null /* options */) : null; task.reparent(launchRoot == null ? toDisplayArea : launchRoot, POSITION_TOP); diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 29677b22ea816..625cff3409124 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -292,8 +292,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { mSupervisor.mRootWindowContainer.resolveActivityType(root, options, task); display.forAllTaskDisplayAreas(displayArea -> { final Task launchRoot = displayArea.getLaunchRootTask( - resolvedMode, activityType, null /* ActivityOptions */, - null /* sourceTask*/, 0 /* launchFlags */); + resolvedMode, activityType, null /* ActivityOptions */); if (launchRoot == null) { return false; } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index c29211f3bb656..12a6a54764d50 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -22,7 +22,6 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; @@ -321,26 +320,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } break; } - case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: { - final WindowContainer wc = WindowContainer.fromBinder( - hop.getContainer()); - final Task task = wc != null ? wc.asTask() : null; - if (task == null) { - throw new IllegalArgumentException("Cannot set " - + "non-task as launch root: " + wc); - } else if (!task.mCreatedByOrganizer) { - throw new UnsupportedOperationException("Cannot set " - + "non-organized task as adjacent flag root: " + wc); - } else if (task.mAdjacentTask == null) { - throw new UnsupportedOperationException("Cannot set " - + "non-adjacent task as adjacent flag root: " + wc); - } - - final boolean clearRoot = hop.getToTop(); - task.getDisplayArea() - .setLaunchAdjacentFlagRootTask(clearRoot ? null : task); - break; - } case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId); break; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index e6ac52d2bf6f0..98260318ea9d7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -339,8 +339,8 @@ public class ActivityStarterTests extends WindowTestsBase { // Direct starter to use spy stack. doReturn(stack).when(mRootWindowContainer) .getLaunchRootTask(any(), any(), any(), anyBoolean()); - doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(), - anyBoolean(), any(), anyInt(), anyInt(), anyInt()); + doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), + anyBoolean(), any(), anyInt(), anyInt()); } // Set up mock package manager internal and make sure no unmocked methods are called @@ -1119,8 +1119,8 @@ public class ActivityStarterTests extends WindowTestsBase { stack.addChild(targetRecord); - doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(), - anyBoolean(), any(), anyInt(), anyInt(), anyInt()); + doReturn(stack).when(mRootWindowContainer) + .getLaunchRootTask(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt()); starter.mStartActivity = new ActivityBuilder(mAtm).build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index 4f5511b55d3a0..0bf237dc6545c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -980,8 +980,7 @@ public class RootWindowContainerTests extends WindowTestsBase { doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId, 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info); final Task result = mRootWindowContainer.getLaunchRootTask(r, options, - null /* task */, null /* sourceTask */, true /* onTop */, null /* launchParams */, - 0 /* launchFlags */, 300 /* test realCallerPid */, + null /* task */, true /* onTop */, null, 300 /* test realCallerPid */, 300 /* test realCallerUid */); // Assert that the root task is returned as expected. diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index 9289ce41cd1e4..92d4edec85f49 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -28,7 +28,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; @@ -75,52 +74,6 @@ import org.junit.runner.RunWith; @RunWith(WindowTestRunner.class) public class TaskDisplayAreaTests extends WindowTestsBase { - @Test - public void getLaunchRootTask_checksLaunchAdjacentFlagRoot() { - final Task rootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - rootTask.mCreatedByOrganizer = true; - final Task adjacentRootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - adjacentRootTask.mCreatedByOrganizer = true; - final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); - adjacentRootTask.mAdjacentTask = rootTask; - rootTask.mAdjacentTask = adjacentRootTask; - - taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask); - Task actualRootTask = taskDisplayArea.getLaunchRootTask( - WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, null /* options */, - null /* sourceTask */, FLAG_ACTIVITY_LAUNCH_ADJACENT); - assertSame(adjacentRootTask, actualRootTask.getRootTask()); - - taskDisplayArea.setLaunchAdjacentFlagRootTask(null); - actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED, - ACTIVITY_TYPE_STANDARD, null /* options */, null /* sourceTask */, - FLAG_ACTIVITY_LAUNCH_ADJACENT); - assertNull(actualRootTask); - } - - @Test - public void getLaunchRootTask_fromLaunchAdjacentFlagRoot_checksAdjacentRoot() { - final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); - final Task rootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - rootTask.mCreatedByOrganizer = true; - final Task adjacentRootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - adjacentRootTask.mCreatedByOrganizer = true; - final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); - adjacentRootTask.mAdjacentTask = rootTask; - rootTask.mAdjacentTask = adjacentRootTask; - - taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask); - final Task actualRootTask = taskDisplayArea.getLaunchRootTask( - WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, null /* options */, - adjacentRootTask /* sourceTask */, FLAG_ACTIVITY_LAUNCH_ADJACENT); - - assertSame(rootTask, actualRootTask.getRootTask()); - } - @Test public void getOrCreateLaunchRootRespectsResolvedWindowingMode() { final Task rootTask = createTask( @@ -137,8 +90,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { launchParams.mWindowingMode = WINDOWING_MODE_FREEFORM; final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( - activity, null /* options */, candidateRootTask, null /* sourceTask */, - launchParams, 0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, true /* onTop */); + activity, null /* options */, candidateRootTask, + launchParams, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertSame(rootTask, actualRootTask.getRootTask()); } @@ -158,9 +111,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( - activity, options, candidateRootTask, null /* sourceTask */, - null /* launchParams */, 0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, - true /* onTop */); + activity, options, candidateRootTask, + null /* launchParams */, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertSame(rootTask, actualRootTask.getRootTask()); } @@ -506,8 +458,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); final Task rootTask = taskDisplayArea.getOrCreateRootTask(windowingMode, activityType, - false /* onTop */, candidateTask /* candidateTask */, null /* sourceTask */, - null /* activityOptions */, 0 /* launchFlags */); + false /* onTop */, null /* intent */, candidateTask /* candidateTask */, + null /* activityOptions */); assertEquals(reuseCandidate, rootTask == candidateTask); } From 5d32c60217be91fe1053a6d53aad09963df083a0 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Wed, 28 Apr 2021 22:32:20 +0000 Subject: [PATCH 045/176] Revert "Support FLAG_ACTIVITY_LAUNCH_ADJACENT for launch root with adjacent" This reverts commit d8abe76ba18e9baf6dcef68a65a03b6651c7e5ef. Reason for revert: Bug: 186614428 Change-Id: Id7d1f57a11f0698f9377b00008994f9a6c3038d3 (cherry picked from commit 48f90b317b9845ee241b0175cd73a7f55d5b1dd9) --- .../window/WindowContainerTransaction.java | 39 --------- .../shell/splitscreen/StageCoordinator.java | 3 - .../android/server/wm/ActivityStarter.java | 4 +- .../server/wm/RootWindowContainer.java | 24 +++-- .../core/java/com/android/server/wm/Task.java | 28 +----- .../android/server/wm/TaskDisplayArea.java | 87 ++++--------------- .../server/wm/TaskLaunchParamsModifier.java | 3 +- .../server/wm/WindowOrganizerController.java | 21 ----- .../server/wm/ActivityStarterTests.java | 8 +- .../server/wm/RootWindowContainerTests.java | 3 +- .../server/wm/TaskDisplayAreaTests.java | 60 ++----------- 11 files changed, 40 insertions(+), 240 deletions(-) diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java index c0af57214e5e5..f93e413961529 100644 --- a/core/java/android/window/WindowContainerTransaction.java +++ b/core/java/android/window/WindowContainerTransaction.java @@ -338,33 +338,6 @@ public final class WindowContainerTransaction implements Parcelable { return this; } - /** - * Sets the container as launch adjacent flag root. Task starting with - * {@link FLAG_ACTIVITY_LAUNCH_ADJACENT} will be launching to. - * - * @hide - */ - @NonNull - public WindowContainerTransaction setLaunchAdjacentFlagRoot( - @NonNull WindowContainerToken container) { - mHierarchyOps.add(HierarchyOp.createForSetLaunchAdjacentFlagRoot(container.asBinder(), - false /* clearRoot */)); - return this; - } - - /** - * Clears launch adjacent flag root for the display area of passing container. - * - * @hide - */ - @NonNull - public WindowContainerTransaction clearLaunchAdjacentFlagRoot( - @NonNull WindowContainerToken container) { - mHierarchyOps.add(HierarchyOp.createForSetLaunchAdjacentFlagRoot(container.asBinder(), - true /* clearRoot */)); - return this; - } - /** * Starts a task by id. The task is expected to already exist (eg. as a recent task). * @param taskId Id of task to start. @@ -704,7 +677,6 @@ public final class WindowContainerTransaction implements Parcelable { public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT = 3; public static final int HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS = 4; public static final int HIERARCHY_OP_TYPE_LAUNCH_TASK = 5; - public static final int HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT = 6; // The following key(s) are for use with mLaunchOptions: // When launching a task (eg. from recents), this is the taskId to be launched. @@ -762,14 +734,6 @@ public final class WindowContainerTransaction implements Parcelable { fullOptions); } - /** Create a hierarchy op for setting launch adjacent flag root. */ - public static HierarchyOp createForSetLaunchAdjacentFlagRoot(IBinder container, - boolean clearRoot) { - return new HierarchyOp(HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT, container, null, - null, null, clearRoot, null); - } - - private HierarchyOp(int type, @Nullable IBinder container, @Nullable IBinder reparent, int[] windowingModes, int[] activityTypes, boolean toTop, @Nullable Bundle launchOptions) { @@ -865,9 +829,6 @@ public final class WindowContainerTransaction implements Parcelable { + " adjacentRoot=" + mReparent + "}"; case HIERARCHY_OP_TYPE_LAUNCH_TASK: return "{LaunchTask: " + mLaunchOptions + "}"; - case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: - return "{SetAdjacentFlagRoot: container=" + mContainer + " clearRoot=" + mToTop - + "}"; default: return "{mType=" + mType + " container=" + mContainer + " reparent=" + mReparent + " mToTop=" + mToTop + " mWindowingMode=" + mWindowingModes diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index efaa2696cbebd..c91a92ad32427 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -337,7 +337,6 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make the stages adjacent to each other so they occlude what's behind them. wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token); - wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token); mTaskOrganizer.applyTransaction(wct); } } @@ -347,7 +346,6 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Deactivate the main stage if it no longer has a root task. mMainStage.deactivate(wct); - wct.clearLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token); mTaskOrganizer.applyTransaction(wct); } } @@ -451,7 +449,6 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, final WindowContainerTransaction wct = new WindowContainerTransaction(); // Make sure the main stage is active. mMainStage.activate(getMainStageBounds(), wct); - mSideStage.setBounds(getSideStageBounds(), wct); mTaskOrganizer.applyTransaction(wct); } } diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 08a9f0928b8b3..9be973be87fc3 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -2761,8 +2761,8 @@ class ActivityStarter { final boolean onTop = (aOptions == null || !aOptions.getAvoidMoveToFront()) && !mLaunchTaskBehind; - return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, mSourceRootTask, onTop, - mLaunchParams, launchFlags, mRequest.realCallingPid, mRequest.realCallingUid); + return mRootWindowContainer.getLaunchRootTask(r, aOptions, task, onTop, mLaunchParams, + mRequest.realCallingPid, mRequest.realCallingUid); } private boolean isLaunchModeOneOf(int mode1, int mode2) { diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java index d9c5fa43d9e40..c81f31eb9f77d 100644 --- a/services/core/java/com/android/server/wm/RootWindowContainer.java +++ b/services/core/java/com/android/server/wm/RootWindowContainer.java @@ -2810,11 +2810,10 @@ class RootWindowContainer extends WindowContainer return false; } - Task getLaunchRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options, - @Nullable Task candidateTask, boolean onTop) { - return getLaunchRootTask(r, options, candidateTask, null /* sourceTask */, onTop, - null /* launchParams */, 0 /* launchFlags */, -1 /* no realCallingPid */, - -1 /* no realCallingUid */); + Task getLaunchRootTask(@Nullable ActivityRecord r, + @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop) { + return getLaunchRootTask(r, options, candidateTask, onTop, null /* launchParams */, + -1 /* no realCallingPid */, -1 /* no realCallingUid */); } /** @@ -2823,18 +2822,15 @@ class RootWindowContainer extends WindowContainer * @param r The activity we are trying to launch. Can be null. * @param options The activity options used to the launch. Can be null. * @param candidateTask The possible task the activity might be launched in. Can be null. - * @param sourceTask The task requesting to start activity. Can be null. * @param launchParams The resolved launch params to use. - * @param launchFlags The launch flags for this launch. * @param realCallingPid The pid from {@link ActivityStarter#setRealCallingPid} * @param realCallingUid The uid from {@link ActivityStarter#setRealCallingUid} * @return The root task to use for the launch or INVALID_TASK_ID. */ Task getLaunchRootTask(@Nullable ActivityRecord r, - @Nullable ActivityOptions options, @Nullable Task candidateTask, - @Nullable Task sourceTask, boolean onTop, - @Nullable LaunchParamsController.LaunchParams launchParams, int launchFlags, - int realCallingPid, int realCallingUid) { + @Nullable ActivityOptions options, @Nullable Task candidateTask, boolean onTop, + @Nullable LaunchParamsController.LaunchParams launchParams, int realCallingPid, + int realCallingUid) { int taskId = INVALID_TASK_ID; int displayId = INVALID_DISPLAY; TaskDisplayArea taskDisplayArea = null; @@ -2898,7 +2894,7 @@ class RootWindowContainer extends WindowContainer // Falling back to default task container taskDisplayArea = taskDisplayArea.mDisplayContent.getDefaultTaskDisplayArea(); rootTask = taskDisplayArea.getOrCreateRootTask(r, options, candidateTask, - sourceTask, launchParams, launchFlags, activityType, onTop); + launchParams, activityType, onTop); if (rootTask != null) { return rootTask; } @@ -2953,8 +2949,8 @@ class RootWindowContainer extends WindowContainer } } - return container.getOrCreateRootTask(r, options, candidateTask, sourceTask, launchParams, - launchFlags, activityType, onTop); + return container.getOrCreateRootTask( + r, options, candidateTask, launchParams, activityType, onTop); } /** @return true if activity record is null or can be launched on provided display. */ diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 2a0041afd9d0d..d4707d6f5f5ae 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -7952,17 +7952,6 @@ class Task extends WindowContainer { private boolean mHasBeenVisible; private boolean mRemoveWithTaskOrganizer; - /** - * Records the source task that requesting to build a new task, used to determine which of - * the adjacent roots should be launch root of the new task. - */ - private Task mSourceTask; - - /** - * Records launch flags to apply when launching new task. - */ - private int mLaunchFlags; - Builder(ActivityTaskManagerService atm) { mAtmService = atm; } @@ -7972,16 +7961,6 @@ class Task extends WindowContainer { return this; } - Builder setSourceTask(Task sourceTask) { - mSourceTask = sourceTask; - return this; - } - - Builder setLaunchFlags(int launchFlags) { - mLaunchFlags = launchFlags; - return this; - } - Builder setTaskId(int taskId) { mTaskId = taskId; return this; @@ -8236,14 +8215,9 @@ class Task extends WindowContainer { tda.getRootPinnedTask().dismissPip(); } - if (mIntent != null) { - mLaunchFlags |= mIntent.getFlags(); - } - // Task created by organizer are added as root. final Task launchRootTask = mCreatedByOrganizer - ? null : tda.getLaunchRootTask(mWindowingMode, mActivityType, mActivityOptions, - mSourceTask, mLaunchFlags); + ? null : tda.getLaunchRootTask(mWindowingMode, mActivityType, mActivityOptions); if (launchRootTask != null) { // Since this task will be put into a root task, its windowingMode will be // inherited. diff --git a/services/core/java/com/android/server/wm/TaskDisplayArea.java b/services/core/java/com/android/server/wm/TaskDisplayArea.java index cda8c4b78b0cd..4d85e7bda9000 100644 --- a/services/core/java/com/android/server/wm/TaskDisplayArea.java +++ b/services/core/java/com/android/server/wm/TaskDisplayArea.java @@ -27,7 +27,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_BEHIND; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSET; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -44,6 +43,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.annotation.Nullable; import android.app.ActivityOptions; import android.app.WindowConfiguration; +import android.content.Intent; import android.os.UserHandle; import android.util.IntArray; import android.util.Slog; @@ -132,11 +132,6 @@ final class TaskDisplayArea extends DisplayArea { } private final ArrayList mLaunchRootTasks = new ArrayList<>(); - /** - * A launch root task for activity launching with {@link FLAG_ACTIVITY_LAUNCH_ADJACENT} flag. - */ - private Task mLaunchAdjacentFlagRootTask; - /** * A focusable root task that is purposely to be positioned at the top. Although the root * task may not have the topmost index, it is used as a preferred candidate to prevent being @@ -1018,9 +1013,6 @@ final class TaskDisplayArea extends DisplayArea { if (mPreferredTopFocusableRootTask == rootTask) { mPreferredTopFocusableRootTask = null; } - if (mLaunchAdjacentFlagRootTask == rootTask) { - mLaunchAdjacentFlagRootTask = null; - } mDisplayContent.releaseSelfIfNeeded(); onRootTaskOrderChanged(rootTask); } @@ -1055,11 +1047,11 @@ final class TaskDisplayArea extends DisplayArea { * Returns an existing root task compatible with the windowing mode and activity type or * creates one if a compatible root task doesn't exist. * - * @see #getOrCreateRootTask(int, int, boolean, Task, Task, ActivityOptions, int) + * @see #getOrCreateRootTask(int, int, boolean, Intent, Task, ActivityOptions) */ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop) { - return getOrCreateRootTask(windowingMode, activityType, onTop, null /* candidateTask */, - null /* sourceTask */, null /* options */, 0 /* intent */); + return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */, + null /* candidateTask */, null /* options */); } /** @@ -1068,21 +1060,11 @@ final class TaskDisplayArea extends DisplayArea { * For one level task, the candidate task would be reused to also be the root task or create * a new root task if no candidate task. * - * @param windowingMode The windowing mode the root task should be created in. - * @param activityType The activityType the root task should be created in. - * @param onTop If true the root task will be created at the top of the display, - * else at the bottom. - * @param candidateTask The possible task the activity might be launched in. Can be null. - * @param sourceTask The task requesting to start activity. Used to determine which of the - * adjacent roots should be launch root of the new task. Can be null. - * @param options The activity options used to the launch. Can be null. - * @param launchFlags The launch flags for this launch. - * @return The root task to use for the launch. * @see #getRootTask(int, int) + * @see #createRootTask(int, int, boolean) */ Task getOrCreateRootTask(int windowingMode, int activityType, boolean onTop, - @Nullable Task candidateTask, @Nullable Task sourceTask, - @Nullable ActivityOptions options, int launchFlags) { + Intent intent, Task candidateTask, ActivityOptions options) { // Need to pass in a determined windowing mode to see if a new root task should be created, // so use its parent's windowing mode if it is undefined. if (!alwaysCreateRootTask( @@ -1095,8 +1077,7 @@ final class TaskDisplayArea extends DisplayArea { } else if (candidateTask != null) { final Task rootTask = candidateTask; final int position = onTop ? POSITION_TOP : POSITION_BOTTOM; - final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options, - sourceTask, launchFlags); + final Task launchRootTask = getLaunchRootTask(windowingMode, activityType, options); if (launchRootTask != null) { if (rootTask.getParent() == null) { @@ -1122,9 +1103,8 @@ final class TaskDisplayArea extends DisplayArea { .setActivityType(activityType) .setOnTop(onTop) .setParent(this) - .setSourceTask(sourceTask) + .setIntent(intent) .setActivityOptions(options) - .setLaunchFlags(launchFlags) .build(); } @@ -1134,9 +1114,9 @@ final class TaskDisplayArea extends DisplayArea { * * @see #getOrCreateRootTask(int, int, boolean) */ - Task getOrCreateRootTask(@Nullable ActivityRecord r, @Nullable ActivityOptions options, - @Nullable Task candidateTask, @Nullable Task sourceTask, - @Nullable LaunchParams launchParams, int launchFlags, int activityType, boolean onTop) { + Task getOrCreateRootTask(@Nullable ActivityRecord r, + @Nullable ActivityOptions options, @Nullable Task candidateTask, + @Nullable LaunchParams launchParams, int activityType, boolean onTop) { int windowingMode = WINDOWING_MODE_UNDEFINED; if (launchParams != null) { // If launchParams isn't null, windowing mode is already resolved. @@ -1150,8 +1130,8 @@ final class TaskDisplayArea extends DisplayArea { // UNDEFINED windowing mode is a valid result and means that the new root task will inherit // it's display's windowing mode. windowingMode = validateWindowingMode(windowingMode, r, candidateTask, activityType); - return getOrCreateRootTask(windowingMode, activityType, onTop, candidateTask, sourceTask, - options, launchFlags); + return getOrCreateRootTask(windowingMode, activityType, onTop, null /* intent */, + candidateTask, options); } @VisibleForTesting @@ -1219,24 +1199,6 @@ final class TaskDisplayArea extends DisplayArea { } } - void setLaunchAdjacentFlagRootTask(@Nullable Task adjacentFlagRootTask) { - if (adjacentFlagRootTask != null) { - if (!adjacentFlagRootTask.mCreatedByOrganizer) { - throw new IllegalArgumentException( - "Can't set not mCreatedByOrganizer as launch adjacent flag root tr=" - + adjacentFlagRootTask); - } - - if (adjacentFlagRootTask.mAdjacentTask == null) { - throw new UnsupportedOperationException( - "Can't set non-adjacent root as launch adjacent flag root tr=" - + adjacentFlagRootTask); - } - } - - mLaunchAdjacentFlagRootTask = adjacentFlagRootTask; - } - private @Nullable LaunchRootTaskDef getLaunchRootTaskDef(Task rootTask) { LaunchRootTaskDef def = null; for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) { @@ -1247,9 +1209,7 @@ final class TaskDisplayArea extends DisplayArea { return def; } - @Nullable - Task getLaunchRootTask(int windowingMode, int activityType, @Nullable ActivityOptions options, - @Nullable Task sourceTask, int launchFlags) { + Task getLaunchRootTask(int windowingMode, int activityType, ActivityOptions options) { // Try to use the launch root task in options if available. if (options != null) { final Task launchRootTask = Task.fromWindowContainerToken(options.getLaunchRootTask()); @@ -1259,19 +1219,6 @@ final class TaskDisplayArea extends DisplayArea { } } - // Use launch-adjacent-flag-root if launching with launch-adjacent flag. - if ((launchFlags & FLAG_ACTIVITY_LAUNCH_ADJACENT) != 0 - && mLaunchAdjacentFlagRootTask != null) { - // If the adjacent launch is coming from the same root, launch to adjacent root instead. - if (sourceTask != null - && sourceTask.getRootTask().mTaskId == mLaunchAdjacentFlagRootTask.mTaskId - && mLaunchAdjacentFlagRootTask.mAdjacentTask != null) { - return mLaunchAdjacentFlagRootTask.mAdjacentTask; - } else { - return mLaunchAdjacentFlagRootTask; - } - } - for (int i = mLaunchRootTasks.size() - 1; i >= 0; --i) { if (mLaunchRootTasks.get(i).contains(windowingMode, activityType)) { return mLaunchRootTasks.get(i).task; @@ -2016,11 +1963,7 @@ final class TaskDisplayArea extends DisplayArea { // Reparent task to corresponding launch root or display area. final WindowContainer launchRoot = task.supportsSplitScreenWindowingMode() ? toDisplayArea.getLaunchRootTask( - task.getWindowingMode(), - task.getActivityType(), - null /* options */, - null /* sourceTask */, - 0 /* launchFlags */) + task.getWindowingMode(), task.getActivityType(), null /* options */) : null; task.reparent(launchRoot == null ? toDisplayArea : launchRoot, POSITION_TOP); diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 29677b22ea816..625cff3409124 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -292,8 +292,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier { mSupervisor.mRootWindowContainer.resolveActivityType(root, options, task); display.forAllTaskDisplayAreas(displayArea -> { final Task launchRoot = displayArea.getLaunchRootTask( - resolvedMode, activityType, null /* ActivityOptions */, - null /* sourceTask*/, 0 /* launchFlags */); + resolvedMode, activityType, null /* ActivityOptions */); if (launchRoot == null) { return false; } diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index c29211f3bb656..12a6a54764d50 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -22,7 +22,6 @@ import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REPARENT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_ADJACENT_ROOTS; -import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT; import static android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_SET_LAUNCH_ROOT; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; @@ -321,26 +320,6 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } break; } - case HIERARCHY_OP_TYPE_SET_LAUNCH_ADJACENT_FLAG_ROOT: { - final WindowContainer wc = WindowContainer.fromBinder( - hop.getContainer()); - final Task task = wc != null ? wc.asTask() : null; - if (task == null) { - throw new IllegalArgumentException("Cannot set " - + "non-task as launch root: " + wc); - } else if (!task.mCreatedByOrganizer) { - throw new UnsupportedOperationException("Cannot set " - + "non-organized task as adjacent flag root: " + wc); - } else if (task.mAdjacentTask == null) { - throw new UnsupportedOperationException("Cannot set " - + "non-adjacent task as adjacent flag root: " + wc); - } - - final boolean clearRoot = hop.getToTop(); - task.getDisplayArea() - .setLaunchAdjacentFlagRootTask(clearRoot ? null : task); - break; - } case HIERARCHY_OP_TYPE_CHILDREN_TASKS_REPARENT: effects |= reparentChildrenTasksHierarchyOp(hop, transition, syncId); break; diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index e6ac52d2bf6f0..98260318ea9d7 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -339,8 +339,8 @@ public class ActivityStarterTests extends WindowTestsBase { // Direct starter to use spy stack. doReturn(stack).when(mRootWindowContainer) .getLaunchRootTask(any(), any(), any(), anyBoolean()); - doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(), - anyBoolean(), any(), anyInt(), anyInt(), anyInt()); + doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), + anyBoolean(), any(), anyInt(), anyInt()); } // Set up mock package manager internal and make sure no unmocked methods are called @@ -1119,8 +1119,8 @@ public class ActivityStarterTests extends WindowTestsBase { stack.addChild(targetRecord); - doReturn(stack).when(mRootWindowContainer).getLaunchRootTask(any(), any(), any(), any(), - anyBoolean(), any(), anyInt(), anyInt(), anyInt()); + doReturn(stack).when(mRootWindowContainer) + .getLaunchRootTask(any(), any(), any(), anyBoolean(), any(), anyInt(), anyInt()); starter.mStartActivity = new ActivityBuilder(mAtm).build(); diff --git a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java index 4f5511b55d3a0..0bf237dc6545c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/RootWindowContainerTests.java @@ -980,8 +980,7 @@ public class RootWindowContainerTests extends WindowTestsBase { doReturn(true).when(mSupervisor).canPlaceEntityOnDisplay(secondaryDisplay.mDisplayId, 300 /* test realCallerPid */, 300 /* test realCallerUid */, r.info); final Task result = mRootWindowContainer.getLaunchRootTask(r, options, - null /* task */, null /* sourceTask */, true /* onTop */, null /* launchParams */, - 0 /* launchFlags */, 300 /* test realCallerPid */, + null /* task */, true /* onTop */, null, 300 /* test realCallerPid */, 300 /* test realCallerUid */); // Assert that the root task is returned as expected. diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java index 9289ce41cd1e4..92d4edec85f49 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskDisplayAreaTests.java @@ -28,7 +28,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; -import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE; import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; @@ -75,52 +74,6 @@ import org.junit.runner.RunWith; @RunWith(WindowTestRunner.class) public class TaskDisplayAreaTests extends WindowTestsBase { - @Test - public void getLaunchRootTask_checksLaunchAdjacentFlagRoot() { - final Task rootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - rootTask.mCreatedByOrganizer = true; - final Task adjacentRootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - adjacentRootTask.mCreatedByOrganizer = true; - final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); - adjacentRootTask.mAdjacentTask = rootTask; - rootTask.mAdjacentTask = adjacentRootTask; - - taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask); - Task actualRootTask = taskDisplayArea.getLaunchRootTask( - WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, null /* options */, - null /* sourceTask */, FLAG_ACTIVITY_LAUNCH_ADJACENT); - assertSame(adjacentRootTask, actualRootTask.getRootTask()); - - taskDisplayArea.setLaunchAdjacentFlagRootTask(null); - actualRootTask = taskDisplayArea.getLaunchRootTask(WINDOWING_MODE_UNDEFINED, - ACTIVITY_TYPE_STANDARD, null /* options */, null /* sourceTask */, - FLAG_ACTIVITY_LAUNCH_ADJACENT); - assertNull(actualRootTask); - } - - @Test - public void getLaunchRootTask_fromLaunchAdjacentFlagRoot_checksAdjacentRoot() { - final ActivityRecord activity = createNonAttachedActivityRecord(mDisplayContent); - final Task rootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - rootTask.mCreatedByOrganizer = true; - final Task adjacentRootTask = createTask( - mDisplayContent, WINDOWING_MODE_MULTI_WINDOW, ACTIVITY_TYPE_STANDARD); - adjacentRootTask.mCreatedByOrganizer = true; - final TaskDisplayArea taskDisplayArea = rootTask.getDisplayArea(); - adjacentRootTask.mAdjacentTask = rootTask; - rootTask.mAdjacentTask = adjacentRootTask; - - taskDisplayArea.setLaunchAdjacentFlagRootTask(adjacentRootTask); - final Task actualRootTask = taskDisplayArea.getLaunchRootTask( - WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_STANDARD, null /* options */, - adjacentRootTask /* sourceTask */, FLAG_ACTIVITY_LAUNCH_ADJACENT); - - assertSame(rootTask, actualRootTask.getRootTask()); - } - @Test public void getOrCreateLaunchRootRespectsResolvedWindowingMode() { final Task rootTask = createTask( @@ -137,8 +90,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { launchParams.mWindowingMode = WINDOWING_MODE_FREEFORM; final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( - activity, null /* options */, candidateRootTask, null /* sourceTask */, - launchParams, 0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, true /* onTop */); + activity, null /* options */, candidateRootTask, + launchParams, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertSame(rootTask, actualRootTask.getRootTask()); } @@ -158,9 +111,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { options.setLaunchWindowingMode(WINDOWING_MODE_FREEFORM); final Task actualRootTask = taskDisplayArea.getOrCreateRootTask( - activity, options, candidateRootTask, null /* sourceTask */, - null /* launchParams */, 0 /* launchFlags */, ACTIVITY_TYPE_STANDARD, - true /* onTop */); + activity, options, candidateRootTask, + null /* launchParams */, ACTIVITY_TYPE_STANDARD, true /* onTop */); assertSame(rootTask, actualRootTask.getRootTask()); } @@ -506,8 +458,8 @@ public class TaskDisplayAreaTests extends WindowTestsBase { boolean reuseCandidate) { final TaskDisplayArea taskDisplayArea = candidateTask.getDisplayArea(); final Task rootTask = taskDisplayArea.getOrCreateRootTask(windowingMode, activityType, - false /* onTop */, candidateTask /* candidateTask */, null /* sourceTask */, - null /* activityOptions */, 0 /* launchFlags */); + false /* onTop */, null /* intent */, candidateTask /* candidateTask */, + null /* activityOptions */); assertEquals(reuseCandidate, rootTask == candidateTask); } From cb9c2b77d3a7bc2d2920c93732782a6217666ba5 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Sat, 1 May 2021 01:10:37 +0800 Subject: [PATCH 046/176] Make sure to reorder side stage above main stage to prevent flicker Always reorder side stage to the top whenever there's a child task appeared in side stage. This is needed to prevent main stage occludes newly launched task in side stage and causing itself flipping between fullscreen and multi-window windowing mode. Fix: 186614428 Bug: 169271875 Test: enter staged split by launching task with adjacent flag, screen won't flicker Change-Id: I9176a97439d687bbc7b0bf2dd9ddfdaecacfa455 (cherry picked from commit 57b13e327fe1d98981c29f6a2a32b07417283849) --- .../com/android/wm/shell/splitscreen/StageCoordinator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index efaa2696cbebd..f7160e55012c3 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -452,6 +452,10 @@ class StageCoordinator implements SplitLayout.LayoutChangeListener, // Make sure the main stage is active. mMainStage.activate(getMainStageBounds(), wct); mSideStage.setBounds(getSideStageBounds(), wct); + // Reorder side stage to the top whenever there's a new child task appeared in side + // stage. This is needed to prevent main stage occludes side stage and makes main stage + // flipping between fullscreen and multi-window windowing mode. + wct.reorder(mSideStage.mRootTaskInfo.token, true); mTaskOrganizer.applyTransaction(wct); } } From e837ade575042950d38fd7b8181a685f7c7430fd Mon Sep 17 00:00:00 2001 From: Collin Fijalkovich Date: Fri, 30 Apr 2021 16:33:02 +0000 Subject: [PATCH 047/176] Revert "Enable remote animation for keygaurd going away." This reverts commit d0ba2859dd8cc851475b0e481adde30cb0eae795. Reason for revert: Checking for cause of test breakage Change-Id: I32f434f2e0c9b7d20bcd0ba51c0b770df8dfa575 (cherry picked from commit 124c7e37e446e928d8ff91c45851520579883d01) --- .../systemui/keyguard/KeyguardService.java | 28 ++++--------------- .../KeyguardUnlockAnimationController.kt | 2 +- .../keyguard/KeyguardViewMediator.java | 2 +- .../server/policy/PhoneWindowManager.java | 2 +- .../keyguard/KeyguardServiceDelegate.java | 6 ++-- .../server/wm/WindowManagerService.java | 27 ++---------------- 6 files changed, 13 insertions(+), 54 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index f1431f5cd40be..666afed41c351 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -51,7 +51,6 @@ import com.android.internal.policy.IKeyguardExitCallback; import com.android.internal.policy.IKeyguardService; import com.android.internal.policy.IKeyguardStateCallback; import com.android.systemui.SystemUIApplication; -import com.android.wm.shell.transition.Transitions; import javax.inject.Inject; @@ -63,29 +62,16 @@ public class KeyguardService extends Service { * Run Keyguard animation as remote animation in System UI instead of local animation in * the server process. * - * 0: Runs all keyguard animation as local animation - * 1: Only runs keyguard going away animation as remote animation - * 2: Runs all keyguard animation as remote animation - * * Note: Must be consistent with WindowManagerService. */ private static final String ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY = "persist.wm.enable_remote_keyguard_animation"; - private static final int sEnableRemoteKeyguardAnimation = - SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 1); - /** * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY */ - public static boolean sEnableRemoteKeyguardGoingAwayAnimation = - !Transitions.ENABLE_SHELL_TRANSITIONS && sEnableRemoteKeyguardAnimation >= 1; - - /** - * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY - */ - public static boolean sEnableRemoteKeyguardOccludeAnimation = - !Transitions.ENABLE_SHELL_TRANSITIONS && sEnableRemoteKeyguardAnimation >= 2; + static boolean sEnableRemoteKeyguardAnimation = + SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false); private final KeyguardViewMediator mKeyguardViewMediator; private final KeyguardLifecyclesDispatcher mKeyguardLifecyclesDispatcher; @@ -97,22 +83,20 @@ public class KeyguardService extends Service { mKeyguardViewMediator = keyguardViewMediator; mKeyguardLifecyclesDispatcher = keyguardLifecyclesDispatcher; - RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); - if (sEnableRemoteKeyguardGoingAwayAnimation) { + if (sEnableRemoteKeyguardAnimation) { + RemoteAnimationDefinition definition = new RemoteAnimationDefinition(); final RemoteAnimationAdapter exitAnimationAdapter = new RemoteAnimationAdapter(mExitAnimationRunner, 0, 0); definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, exitAnimationAdapter); definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY_ON_WALLPAPER, exitAnimationAdapter); - } - if (sEnableRemoteKeyguardOccludeAnimation) { final RemoteAnimationAdapter occludeAnimationAdapter = new RemoteAnimationAdapter(mOccludeAnimationRunner, 0, 0); definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_OCCLUDE, occludeAnimationAdapter); definition.addRemoteAnimation(TRANSIT_OLD_KEYGUARD_UNOCCLUDE, occludeAnimationAdapter); + ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay( + DEFAULT_DISPLAY, definition); } - ActivityTaskManager.getInstance().registerRemoteAnimationsForDisplay( - DEFAULT_DISPLAY, definition); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt index 85ee0dca88059..411c328cd3101 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt @@ -280,7 +280,7 @@ class KeyguardUnlockAnimationController @Inject constructor( } override fun onKeyguardDismissAmountChanged() { - if (!KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation) { + if (!KeyguardService.sEnableRemoteKeyguardAnimation) { return } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index b7da7addf027a..48f9a58d7d1ac 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -2100,7 +2100,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, playSounds(false); } - if (KeyguardService.sEnableRemoteKeyguardGoingAwayAnimation) { + if (KeyguardService.sEnableRemoteKeyguardAnimation) { mSurfaceBehindRemoteAnimationFinishedCallback = finishedCallback; mSurfaceBehindRemoteAnimationRunning = true; diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 7f325f1590ec8..27f5350661f0b 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -3014,7 +3014,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private int handleStartTransitionForKeyguardLw(boolean keyguardGoingAway, long duration) { final int res = applyKeyguardOcclusionChange(); if (res != 0) return res; - if (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation && keyguardGoingAway) { + if (!WindowManagerService.sEnableRemoteKeyguardAnimation && keyguardGoingAway) { if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation"); startKeyguardExitAnimation(SystemClock.uptimeMillis(), duration); } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index 6e478ee7bf1b5..44f14b4d5b0df 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -263,8 +263,7 @@ public class KeyguardServiceDelegate { */ @Deprecated public void setOccluded(boolean isOccluded, boolean animate) { - if (!WindowManagerService.sEnableRemoteKeyguardOccludeAnimation - && mKeyguardService != null) { + if (!WindowManagerService.sEnableRemoteKeyguardAnimation && mKeyguardService != null) { if (DEBUG) Log.v(TAG, "setOccluded(" + isOccluded + ") animate=" + animate); mKeyguardService.setOccluded(isOccluded, animate); } @@ -404,8 +403,7 @@ public class KeyguardServiceDelegate { } public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) { - if (!WindowManagerService.sEnableRemoteKeyguardGoingAwayAnimation - && mKeyguardService != null) { + if (!WindowManagerService.sEnableRemoteKeyguardAnimation && mKeyguardService != null) { mKeyguardService.startKeyguardExitAnimation(startTime, fadeoutDuration); } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index fbeb968eb90ff..1657a136d61d3 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -420,42 +420,19 @@ public class WindowManagerService extends IWindowManager.Stub static boolean sDisableCustomTaskAnimationProperty = SystemProperties.getBoolean(DISABLE_CUSTOM_TASK_ANIMATION_PROPERTY, true); - /** - * Use WMShell for app transition. - */ - public static final String ENABLE_SHELL_TRANSITIONS = "persist.debug.shell_transit"; - - /** - * @see #ENABLE_SHELL_TRANSITIONS - */ - public static final boolean sEnableShellTransitions = - SystemProperties.getBoolean(ENABLE_SHELL_TRANSITIONS, false); - /** * Run Keyguard animation as remote animation in System UI instead of local animation in * the server process. - * - * 0: Runs all keyguard animation as local animation - * 1: Only runs keyguard going away animation as remote animation - * 2: Runs all keyguard animation as remote animation */ private static final String ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY = "persist.wm.enable_remote_keyguard_animation"; - private static final int sEnableRemoteKeyguardAnimation = - SystemProperties.getInt(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, 1); - /** * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY */ - public static final boolean sEnableRemoteKeyguardGoingAwayAnimation = !sEnableShellTransitions - && sEnableRemoteKeyguardAnimation >= 1; + public static boolean sEnableRemoteKeyguardAnimation = + SystemProperties.getBoolean(ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY, false); - /** - * @see #ENABLE_REMOTE_KEYGUARD_ANIMATION_PROPERTY - */ - public static final boolean sEnableRemoteKeyguardOccludeAnimation = !sEnableShellTransitions - && sEnableRemoteKeyguardAnimation >= 2; /** * Allows a fullscreen windowing mode activity to launch in its desired orientation directly From 47fd3f63435477aa019b7e90fc707ad8bacd7335 Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Fri, 30 Apr 2021 15:09:41 -0400 Subject: [PATCH 048/176] Call StatusBar#finishKeyguardFadingAway after the fling animation. This isn't currently isn't being called with the new keyguard unlock animation if bypassing the keyguard due to biometric unlock. This results in ScrimController#expansionAffectsAlpha remaining false after an unlock, which in turn results in a transparent shade scrim even when unlocked+expanded. Filed b/186873982 to track a permanent fix (for a safer fix-forward, I am checking if the new unlock animation is running before calling #finishKeyguardFadingAway, but that's likely not necessary). Bug: 186760125 Test: manual Change-Id: I79a70034a02af45d69dc0e80554141c65f6b5ed8 (cherry picked from commit 261120400fe146ef5c342e4bafb3ec460fbd25a9) --- .../statusbar/phone/StatusBarKeyguardViewManager.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index f403cc94d831d..1ef8470180f34 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -591,6 +591,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb if (mStatusBar.isInLaunchTransition() || mKeyguardStateController.isFlingingToDismissKeyguard()) { + final boolean wasFlingingToDismissKeyguard = + mKeyguardStateController.isFlingingToDismissKeyguard(); mStatusBar.fadeKeyguardAfterLaunchTransition(new Runnable() { @Override public void run() { @@ -604,6 +606,11 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb public void run() { mStatusBar.hideKeyguard(); mNotificationShadeWindowController.setKeyguardFadingAway(false); + + if (wasFlingingToDismissKeyguard) { + mStatusBar.finishKeyguardFadingAway(); + } + mViewMediatorCallback.keyguardGone(); executeAfterKeyguardGoneAction(); } From 4c5c16462604798acec9b8dcb9d8b18b40b48a8d Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Mon, 3 May 2021 19:55:48 +0000 Subject: [PATCH 049/176] Revert "Fix VIP conversations alerting incorrectly." This reverts commit 64c85ac6f5f20d031a7e192366b8335fab0253c2. Reason for revert: DF blocking Bug: 187009701 Change-Id: I04dfdf20ad5c7df3c6dddf0cc12540b179162f0b (cherry picked from commit 25c273584ad92f566c41c635a886be9375f50d39) --- .../statusbar/NotificationListener.java | 3 +- .../NotificationGroupManagerLegacy.java | 438 ++---------------- .../NotificationGroupAlertTransferHelper.java | 365 ++++----------- 3 files changed, 118 insertions(+), 688 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java index 5437ce63475ec..7f31fddbfb6c3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.statusbar.RemoteInputController.processForRemoteInput; import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; +import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; import android.annotation.NonNull; import android.annotation.SuppressLint; @@ -34,7 +35,6 @@ import android.util.Log; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.dagger.StatusBarModule; import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins; -import com.android.systemui.statusbar.phone.StatusBar; import java.util.ArrayList; import java.util.List; @@ -46,7 +46,6 @@ import java.util.List; @SuppressLint("OverrideAbstract") public class NotificationListener extends NotificationListenerWithPlugins { private static final String TAG = "NotificationListener"; - private static final boolean DEBUG = StatusBar.DEBUG; private final Context mContext; private final NotificationManager mNotificationManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java index d95c265c14608..d6356de5ea51b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java @@ -16,9 +16,7 @@ package com.android.systemui.statusbar.notification.collection.legacy; -import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.Notification; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; @@ -33,7 +31,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; -import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.wm.shell.bubbles.Bubbles; @@ -42,12 +39,10 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.TreeSet; import javax.inject.Inject; @@ -63,21 +58,13 @@ import dagger.Lazy; public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, StateListener, GroupMembershipManager, GroupExpansionManager, Dumpable { - private static final String TAG = "NotifGroupManager"; - private static final boolean DEBUG = StatusBar.DEBUG; - private static final boolean SPEW = StatusBar.SPEW; - /** - * The maximum amount of time (in ms) between the posting of notifications that can be - * considered part of the same update batch. - */ - private static final long POST_BATCH_MAX_AGE = 5000; + private static final String TAG = "NotificationGroupManager"; private final HashMap mGroupMap = new HashMap<>(); private final ArraySet mExpansionChangeListeners = new ArraySet<>(); private final ArraySet mGroupChangeListeners = new ArraySet<>(); private final Lazy mPeopleNotificationIdentifier; private final Optional mBubblesOptional; - private final EventBuffer mEventBuffer = new EventBuffer(); private int mBarState = -1; private HashMap mIsolatedEntries = new HashMap<>(); private HeadsUpManager mHeadsUpManager; @@ -147,14 +134,8 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * When we want to remove an entry from being tracked for grouping */ public void onEntryRemoved(NotificationEntry removed) { - if (SPEW) { - Log.d(TAG, "onEntryRemoved: entry=" + removed); - } onEntryRemovedInternal(removed, removed.getSbn()); - StatusBarNotification oldSbn = mIsolatedEntries.remove(removed.getKey()); - if (oldSbn != null) { - updateSuppression(mGroupMap.get(oldSbn.getGroupKey())); - } + mIsolatedEntries.remove(removed.getKey()); } /** @@ -181,9 +162,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, // the close future. See b/23676310 for reference. return; } - if (SPEW) { - Log.d(TAG, "onEntryRemovedInternal: entry=" + removed + " group=" + group.groupKey); - } if (isGroupChild(removed.getKey(), isGroup, isGroupSummary)) { group.children.remove(removed.getKey()); } else { @@ -204,9 +182,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * Notify the group manager that a new entry was added */ public void onEntryAdded(final NotificationEntry added) { - if (SPEW) { - Log.d(TAG, "onEntryAdded: entry=" + added); - } updateIsolation(added); onEntryAddedInternal(added); } @@ -220,16 +195,13 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, String groupKey = getGroupKey(sbn); NotificationGroup group = mGroupMap.get(groupKey); if (group == null) { - group = new NotificationGroup(groupKey); + group = new NotificationGroup(); mGroupMap.put(groupKey, group); for (OnGroupChangeListener listener : mGroupChangeListeners) { listener.onGroupCreated(group, groupKey); } } - if (SPEW) { - Log.d(TAG, "onEntryAddedInternal: entry=" + added + " group=" + group.groupKey); - } if (isGroupChild) { NotificationEntry existing = group.children.get(added.getKey()); if (existing != null && existing != added) { @@ -241,11 +213,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, + " added removed" + added.isRowRemoved(), new Throwable()); } group.children.put(added.getKey(), added); - addToPostBatchHistory(group, added); updateSuppression(group); } else { group.summary = added; - addToPostBatchHistory(group, added); group.expanded = added.areChildrenExpanded(); updateSuppression(group); if (!group.children.isEmpty()) { @@ -261,27 +231,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, } } - private void addToPostBatchHistory(NotificationGroup group, @Nullable NotificationEntry entry) { - if (entry == null) { - return; - } - boolean didAdd = group.postBatchHistory.add(new PostRecord(entry)); - if (didAdd) { - trimPostBatchHistory(group.postBatchHistory); - } - } - - /** remove all history that's too old to be in the batch. */ - private void trimPostBatchHistory(@NonNull TreeSet postBatchHistory) { - if (postBatchHistory.size() <= 1) { - return; - } - long batchStartTime = postBatchHistory.last().postTime - POST_BATCH_MAX_AGE; - while (!postBatchHistory.isEmpty() && postBatchHistory.first().postTime < batchStartTime) { - postBatchHistory.pollFirst(); - } - } - private void onEntryBecomingChild(NotificationEntry entry) { updateIsolation(entry); } @@ -290,9 +239,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, if (group == null) { return; } - NotificationEntry prevAlertOverride = group.alertOverride; - group.alertOverride = getPriorityConversationAlertOverride(group); - int childCount = 0; boolean hasBubbles = false; for (NotificationEntry entry : group.children.values()) { @@ -309,148 +255,18 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, group.suppressed = group.summary != null && !group.expanded && (childCount == 1 || (childCount == 0 - && group.summary.getSbn().getNotification().isGroupSummary() - && (hasIsolatedChildren(group) || hasBubbles))); - - boolean alertOverrideChanged = prevAlertOverride != group.alertOverride; - boolean suppressionChanged = prevSuppressed != group.suppressed; - if (alertOverrideChanged || suppressionChanged) { - if (DEBUG && alertOverrideChanged) { - Log.d(TAG, group + " alertOverride was=" + prevAlertOverride + " now=" - + group.alertOverride); - } - if (DEBUG && suppressionChanged) { - Log.d(TAG, group + " suppressed changed to " + group.suppressed); - } - if (!mIsUpdatingUnchangedGroup) { - if (alertOverrideChanged) { - mEventBuffer.notifyAlertOverrideChanged(group, prevAlertOverride); - } - if (suppressionChanged) { - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupSuppressionChanged(group, group.suppressed); - } - } - mEventBuffer.notifyGroupsChanged(); - } else { - if (DEBUG) { - Log.d(TAG, group + " did not notify listeners of above change(s)"); + && group.summary.getSbn().getNotification().isGroupSummary() + && (hasIsolatedChildren(group) || hasBubbles))); + if (prevSuppressed != group.suppressed) { + for (OnGroupChangeListener listener : mGroupChangeListeners) { + if (!mIsUpdatingUnchangedGroup) { + listener.onGroupSuppressionChanged(group, group.suppressed); + listener.onGroupsChanged(); } } } } - /** - * Finds the isolated logical child of this group which is should be alerted instead. - * - * Notifications from priority conversations are isolated from their groups to make them more - * prominent, however apps may post these with a GroupAlertBehavior that has the group receiving - * the alert. This would lead to the group alerting even though the conversation that was - * updated was not actually a part of that group. This method finds the best priority - * conversation in this situation, if there is one, so they can be set as the alertOverride of - * the group. - * - * @param group the group to check - * @return the entry which should receive the alert instead of the group, if any. - */ - @Nullable - private NotificationEntry getPriorityConversationAlertOverride(NotificationGroup group) { - // GOAL: if there is a priority child which wouldn't alert based on its groupAlertBehavior, - // but which should be alerting (because priority conversations are isolated), find it. - if (group == null || group.summary == null) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: null group or summary"); - } - return null; - } - if (isIsolated(group.summary.getKey())) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: isolated group"); - } - return null; - } - - // Precondiions: - // * Only necessary when all notifications in the group use GROUP_ALERT_SUMMARY - // * Only necessary when at least one notification in the group is on a priority channel - if (group.summary.getSbn().getNotification().getGroupAlertBehavior() - != Notification.GROUP_ALERT_SUMMARY) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: summary != GROUP_ALERT_SUMMARY"); - } - return null; - } - - // Get the important children first, copy the keys for the final importance check, - // then add the non-isolated children to the map for unified lookup. - HashMap children = getImportantConversations(group); - if (children == null || children.isEmpty()) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: no important conversations"); - } - return null; - } - HashSet importantChildKeys = new HashSet<>(children.keySet()); - children.putAll(group.children); - - // Ensure all children have GROUP_ALERT_SUMMARY - for (NotificationEntry child : children.values()) { - if (child.getSbn().getNotification().getGroupAlertBehavior() - != Notification.GROUP_ALERT_SUMMARY) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: " - + "child != GROUP_ALERT_SUMMARY"); - } - return null; - } - } - - // Create a merged post history from all the children - TreeSet combinedHistory = new TreeSet<>(group.postBatchHistory); - for (String importantChildKey : importantChildKeys) { - NotificationGroup importantChildGroup = mGroupMap.get(importantChildKey); - combinedHistory.addAll(importantChildGroup.postBatchHistory); - } - trimPostBatchHistory(combinedHistory); - - // This is a streamlined implementation of the following idea: - // * From the subset of notifications in the latest 'batch' of updates. A batch is: - // * Notifs posted less than POST_BATCH_MAX_AGE before the most recently posted. - // * Only including notifs newer than the second-to-last post of any notification. - // * Find the newest child in the batch -- the with the largest 'when' value. - // * If the newest child is a priority conversation, set that as the override. - HashSet batchKeys = new HashSet<>(); - long newestChildWhen = -1; - NotificationEntry newestChild = null; - // Iterate backwards through the post history, tracking the child with the smallest sort key - for (PostRecord record : combinedHistory.descendingSet()) { - if (batchKeys.contains(record.key)) { - // Once you see a notification again, the batch has ended - break; - } - batchKeys.add(record.key); - NotificationEntry child = children.get(record.key); - if (child != null) { - long childWhen = child.getSbn().getNotification().when; - if (newestChild == null || childWhen > newestChildWhen) { - newestChildWhen = childWhen; - newestChild = child; - } - } - } - if (newestChild != null && importantChildKeys.contains(newestChild.getKey())) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: result=" + newestChild); - } - return newestChild; - } - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: result=null, newestChild=" - + newestChild); - } - return null; - } - private boolean hasIsolatedChildren(NotificationGroup group) { return getNumberOfIsolatedChildren(group.summary.getSbn().getGroupKey()) != 0; } @@ -465,33 +281,12 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, return count; } - @Nullable - private HashMap getImportantConversations(NotificationGroup group) { - String groupKey = group.summary.getSbn().getGroupKey(); - HashMap result = null; - for (StatusBarNotification sbn : mIsolatedEntries.values()) { - if (sbn.getGroupKey().equals(groupKey)) { - NotificationEntry entry = mGroupMap.get(sbn.getKey()).summary; - if (isImportantConversation(entry)) { - if (result == null) { - result = new HashMap<>(); - } - result.put(sbn.getKey(), entry); - } - } - } - return result; - } - /** * Update an entry's group information * @param entry notification entry to update * @param oldNotification previous notification info before this update */ public void onEntryUpdated(NotificationEntry entry, StatusBarNotification oldNotification) { - if (SPEW) { - Log.d(TAG, "onEntryUpdated: entry=" + entry); - } onEntryUpdated(entry, oldNotification.getGroupKey(), oldNotification.isGroup(), oldNotification.getNotification().isGroupSummary()); } @@ -530,17 +325,7 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * Whether the given notification is the summary of a group that is being suppressed */ public boolean isSummaryOfSuppressedGroup(StatusBarNotification sbn) { - return sbn.getNotification().isGroupSummary() && isGroupSuppressed(getGroupKey(sbn)); - } - - /** - * If the given notification is a summary, get the group for it. - */ - public NotificationGroup getGroupForSummary(StatusBarNotification sbn) { - if (sbn.getNotification().isGroupSummary()) { - return mGroupMap.get(getGroupKey(sbn)); - } - return null; + return isGroupSuppressed(getGroupKey(sbn)) && sbn.getNotification().isGroupSummary(); } private boolean isOnlyChild(StatusBarNotification sbn) { @@ -760,7 +545,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) { return false; } - if (isImportantConversation(entry)) { + int peopleNotificationType = + mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry); + if (peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON) { return true; } if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.getKey())) { @@ -773,25 +560,18 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, || isGroupNotFullyVisible(notificationGroup)); } - private boolean isImportantConversation(NotificationEntry entry) { - int peopleNotificationType = - mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry); - return peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON; - } - /** * Isolate a notification from its group so that it visually shows as its own group. * * @param entry the notification to isolate */ private void isolateNotification(NotificationEntry entry) { - if (SPEW) { - Log.d(TAG, "isolateNotification: entry=" + entry); - } + StatusBarNotification sbn = entry.getSbn(); + // We will be isolated now, so lets update the groups onEntryRemovedInternal(entry, entry.getSbn()); - mIsolatedEntries.put(entry.getKey(), entry.getSbn()); + mIsolatedEntries.put(sbn.getKey(), sbn); onEntryAddedInternal(entry); // We also need to update the suppression of the old group, because this call comes @@ -808,14 +588,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * Update the isolation of an entry, splitting it from the group. */ public void updateIsolation(NotificationEntry entry) { - // We need to buffer a few events because we do isolation changes in 3 steps: - // removeInternal, update mIsolatedEntries, addInternal. This means that often the - // alertOverride will update on the removal, however processing the event in that case can - // cause problems because the mIsolatedEntries map is not in its final state, so the event - // listener may be unable to correctly determine the true state of the group. By delaying - // the alertOverride change until after the add phase, we can ensure that listeners only - // have to handle a consistent state. - mEventBuffer.startBuffering(); boolean isIsolated = isIsolated(entry.getSbn().getKey()); if (shouldIsolate(entry)) { if (!isIsolated) { @@ -824,7 +596,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, } else if (isIsolated) { stopIsolatingNotification(entry); } - mEventBuffer.flushAndStopBuffering(); } /** @@ -833,15 +604,15 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * @param entry the notification to un-isolate */ private void stopIsolatingNotification(NotificationEntry entry) { - if (SPEW) { - Log.d(TAG, "stopIsolatingNotification: entry=" + entry); - } - // not isolated anymore, we need to update the groups - onEntryRemovedInternal(entry, entry.getSbn()); - mIsolatedEntries.remove(entry.getKey()); - onEntryAddedInternal(entry); - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupsChanged(); + StatusBarNotification sbn = entry.getSbn(); + if (isIsolated(sbn.getKey())) { + // not isolated anymore, we need to update the groups + onEntryRemovedInternal(entry, entry.getSbn()); + mIsolatedEntries.remove(sbn.getKey()); + onEntryAddedInternal(entry); + for (OnGroupChangeListener listener : mGroupChangeListeners) { + listener.onGroupsChanged(); + } } } @@ -876,155 +647,34 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, setStatusBarState(newState); } - /** - * A record of a notification being posted, containing the time of the post and the key of the - * notification entry. These are stored in a TreeSet by the NotificationGroup and used to - * calculate a batch of notifications. - */ - public static class PostRecord implements Comparable { - public final long postTime; - public final String key; - - /** constructs a record containing the post time and key from the notification entry */ - public PostRecord(@NonNull NotificationEntry entry) { - this.postTime = entry.getSbn().getPostTime(); - this.key = entry.getKey(); - } - - @Override - public int compareTo(PostRecord o) { - int postTimeComparison = Long.compare(this.postTime, o.postTime); - return postTimeComparison == 0 - ? String.CASE_INSENSITIVE_ORDER.compare(this.key, o.key) - : postTimeComparison; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PostRecord that = (PostRecord) o; - return postTime == that.postTime && key.equals(that.key); - } - - @Override - public int hashCode() { - return Objects.hash(postTime, key); - } - } - /** * Represents a notification group in the notification shade. */ public static class NotificationGroup { - public final String groupKey; public final HashMap children = new HashMap<>(); - public final TreeSet postBatchHistory = new TreeSet<>(); public NotificationEntry summary; public boolean expanded; /** * Is this notification group suppressed, i.e its summary is hidden */ public boolean suppressed; - /** - * The child (which is isolated from this group) to which the alert should be transferred, - * due to priority conversations. - */ - public NotificationEntry alertOverride; - - NotificationGroup(String groupKey) { - this.groupKey = groupKey; - } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(" groupKey: ").append(groupKey); - sb.append("\n summary:"); - appendEntry(sb, summary); - sb.append("\n children size: ").append(children.size()); + String result = " summary:\n " + + (summary != null ? summary.getSbn() : "null") + + (summary != null && summary.getDebugThrowable() != null + ? Log.getStackTraceString(summary.getDebugThrowable()) + : ""); + result += "\n children size: " + children.size(); for (NotificationEntry child : children.values()) { - appendEntry(sb, child); - } - sb.append("\n alertOverride:"); - appendEntry(sb, alertOverride); - sb.append("\n summary suppressed: ").append(suppressed); - return sb.toString(); - } - - private void appendEntry(StringBuilder sb, NotificationEntry entry) { - sb.append("\n ").append(entry != null ? entry.getSbn() : "null"); - if (entry != null && entry.getDebugThrowable() != null) { - sb.append(Log.getStackTraceString(entry.getDebugThrowable())); - } - } - } - - /** - * This class is a toggleable buffer for a subset of events of {@link OnGroupChangeListener}. - * When buffering, instead of notifying the listeners it will set internal state that will allow - * it to notify listeners of those events later - */ - private class EventBuffer { - private final HashMap mOldAlertOverrideByGroup = new HashMap<>(); - private boolean mIsBuffering = false; - private boolean mDidGroupsChange = false; - - void notifyAlertOverrideChanged(NotificationGroup group, - NotificationEntry oldAlertOverride) { - if (mIsBuffering) { - // The value in this map is the override before the event. If there is an entry - // already in the map, then we are effectively coalescing two events, which means - // we need to preserve the original initial value. - mOldAlertOverrideByGroup.putIfAbsent(group.groupKey, oldAlertOverride); - } else { - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupAlertOverrideChanged(group, oldAlertOverride, - group.alertOverride); - } - } - } - - void notifyGroupsChanged() { - if (mIsBuffering) { - mDidGroupsChange = true; - } else { - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupsChanged(); - } - } - } - - void startBuffering() { - mIsBuffering = true; - } - - void flushAndStopBuffering() { - // stop buffering so that we can call our own helpers - mIsBuffering = false; - // alert all group alert override changes for groups that were not removed - for (Map.Entry entry : mOldAlertOverrideByGroup.entrySet()) { - NotificationGroup group = mGroupMap.get(entry.getKey()); - if (group == null) { - // The group can be null if this alertOverride changed before the group was - // permanently removed, meaning that there's no guarantee that listeners will - // that field clear. - continue; - } - NotificationEntry oldAlertOverride = entry.getValue(); - if (group.alertOverride == oldAlertOverride) { - // If the final alertOverride equals the initial, it means we coalesced two - // events which undid the change, so we can drop it entirely. - continue; - } - notifyAlertOverrideChanged(group, oldAlertOverride); - } - mOldAlertOverrideByGroup.clear(); - // alert that groups changed - if (mDidGroupsChange) { - notifyGroupsChanged(); - mDidGroupsChange = false; + result += "\n " + child.getSbn() + + (child.getDebugThrowable() != null + ? Log.getStackTraceString(child.getDebugThrowable()) + : ""); } + result += "\n summary suppressed: " + suppressed; + return result; } } @@ -1063,18 +713,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, NotificationGroup group, boolean suppressed) {} - /** - * The alert override of a group has changed. - * - * @param group the group that has changed - * @param oldAlertOverride the previous notification to which the group's alerts were sent - * @param newAlertOverride the notification to which the group's alerts should now be sent - */ - default void onGroupAlertOverrideChanged( - NotificationGroup group, - @Nullable NotificationEntry oldAlertOverride, - @Nullable NotificationEntry newAlertOverride) {} - /** * A group of children just received a summary notification and should therefore become * children of it. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java index 9787a9446019c..3181f520dca22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java @@ -22,12 +22,12 @@ import android.app.Notification; import android.os.SystemClock; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; -import android.util.Log; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -41,21 +41,17 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import java.util.ArrayList; -import java.util.List; import java.util.Objects; /** * A helper class dealing with the alert interactions between {@link NotificationGroupManagerLegacy} * and {@link HeadsUpManager}. In particular, this class deals with keeping - * the correct notification in a group alerting based off the group suppression and alertOverride. + * the correct notification in a group alerting based off the group suppression. */ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener, StateListener { private static final long ALERT_TRANSFER_TIMEOUT = 300; - private static final String TAG = "NotifGroupAlertTransfer"; - private static final boolean DEBUG = StatusBar.DEBUG; - private static final boolean SPEW = StatusBar.SPEW; /** * The list of entries containing group alert metadata for each group. Keyed by group key. @@ -146,98 +142,41 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis @Override public void onGroupSuppressionChanged(NotificationGroup group, boolean suppressed) { - if (DEBUG) { - Log.d(TAG, "!! onGroupSuppressionChanged: group.summary=" + group.summary - + " suppressed=" + suppressed); + if (suppressed) { + if (mHeadsUpManager.isAlerting(group.summary.getKey())) { + handleSuppressedSummaryAlerted(group.summary, mHeadsUpManager); + } + } else { + // Group summary can be null if we are no longer suppressed because the summary was + // removed. In that case, we don't need to alert the summary. + if (group.summary == null) { + return; + } + GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey( + group.summary.getSbn())); + // Group is no longer suppressed. We should check if we need to transfer the alert + // back to the summary now that it's no longer suppressed. + if (groupAlertEntry.mAlertSummaryOnNextAddition) { + if (!mHeadsUpManager.isAlerting(group.summary.getKey())) { + alertNotificationWhenPossible(group.summary, mHeadsUpManager); + } + groupAlertEntry.mAlertSummaryOnNextAddition = false; + } else { + checkShouldTransferBack(groupAlertEntry); + } } - NotificationEntry oldAlertOverride = group.alertOverride; - onGroupChanged(group, oldAlertOverride); - } - - @Override - public void onGroupAlertOverrideChanged(NotificationGroup group, - @Nullable NotificationEntry oldAlertOverride, - @Nullable NotificationEntry newAlertOverride) { - if (DEBUG) { - Log.d(TAG, "!! onGroupAlertOverrideChanged: group.summary=" + group.summary - + " oldAlertOverride=" + oldAlertOverride - + " newAlertOverride=" + newAlertOverride); - } - onGroupChanged(group, oldAlertOverride); } }; - /** - * Called when either the suppressed or alertOverride fields of the group changed - * - * @param group the group which changed - * @param oldAlertOverride the previous value of group.alertOverride - */ - private void onGroupChanged(NotificationGroup group, - NotificationEntry oldAlertOverride) { - // Group summary can be null if we are no longer suppressed because the summary was - // removed. In that case, we don't need to alert the summary. - if (group.summary == null) { - if (DEBUG) { - Log.d(TAG, "onGroupChanged: summary is null"); - } - return; - } - if (group.suppressed || group.alertOverride != null) { - checkForForwardAlertTransfer(group.summary, oldAlertOverride); - } else { - if (DEBUG) { - Log.d(TAG, "onGroupChanged: maybe transfer back"); - } - GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey( - group.summary.getSbn())); - // Group is no longer suppressed or overridden. - // We should check if we need to transfer the alert back to the summary. - if (groupAlertEntry.mAlertSummaryOnNextAddition) { - if (!mHeadsUpManager.isAlerting(group.summary.getKey())) { - alertNotificationWhenPossible(group.summary); - } - groupAlertEntry.mAlertSummaryOnNextAddition = false; - } else { - checkShouldTransferBack(groupAlertEntry); - } - } - } - @Override public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) { - if (DEBUG) { - Log.d(TAG, "!! onHeadsUpStateChanged: entry=" + entry + " isHeadsUp=" + isHeadsUp); - } - if (isHeadsUp && entry.getSbn().getNotification().isGroupSummary()) { - // a group summary is alerting; trigger the forward transfer checks - checkForForwardAlertTransfer(entry, /* oldAlertOverride */ null); - } + onAlertStateChanged(entry, isHeadsUp, mHeadsUpManager); } - /** - * Handles changes in a group's suppression or alertOverride, but where at least one of those - * conditions is still true (either the group is suppressed, the group has an alertOverride, - * or both). The method determined which kind of child needs to receive the alert, finds the - * entry currently alerting, and makes the transfer. - * - * Internally, this is handled with two main cases: the override needs the alert, or there is - * no override but the summary is suppressed (so an isolated child needs the alert). - * - * @param summary the notification entry of the summary of the logical group. - * @param oldAlertOverride the former value of group.alertOverride, before whatever event - * required us to check for for a transfer condition. - */ - private void checkForForwardAlertTransfer(NotificationEntry summary, - NotificationEntry oldAlertOverride) { - if (DEBUG) { - Log.d(TAG, "checkForForwardAlertTransfer: enter"); - } - NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn()); - if (group != null && group.alertOverride != null) { - handleOverriddenSummaryAlerted(summary); - } else if (mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn())) { - handleSuppressedSummaryAlerted(summary, oldAlertOverride); + private void onAlertStateChanged(NotificationEntry entry, boolean isAlerting, + AlertingNotificationManager alertManager) { + if (isAlerting && mGroupManager.isSummaryOfSuppressedGroup(entry.getSbn())) { + handleSuppressedSummaryAlerted(entry, alertManager); } } @@ -247,16 +186,9 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis // see as early as we can if we need to abort a transfer. @Override public void onPendingEntryAdded(NotificationEntry entry) { - if (DEBUG) { - Log.d(TAG, "!! onPendingEntryAdded: entry=" + entry); - } String groupKey = mGroupManager.getGroupKey(entry.getSbn()); GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(groupKey); - if (groupAlertEntry != null && groupAlertEntry.mGroup.alertOverride == null) { - // new pending group entries require us to transfer back from the child to the - // group, but alertOverrides are only present in very limited circumstances, so - // while it's possible the group should ALSO alert, the previous detection which set - // this alertOverride won't be invalidated by this notification added to this group. + if (groupAlertEntry != null) { checkShouldTransferBack(groupAlertEntry); } } @@ -330,128 +262,43 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } /** - * Handles the scenario where a summary that has been suppressed is itself, or has a former - * alertOverride (in the form of an isolated logical child) which was alerted. A suppressed + * Handles the scenario where a summary that has been suppressed is alerted. A suppressed * summary should for all intents and purposes be invisible to the user and as a result should * not alert. When this is the case, it is our responsibility to pass the alert to the * appropriate child which will be the representative notification alerting for the group. * - * @param summary the summary that is suppressed and (potentially) alerting - * @param oldAlertOverride the alertOverride before whatever event triggered this method. If - * the alert override was removed, this will be the entry that should - * be transferred back from. + * @param summary the summary that is suppressed and alerting + * @param alertManager the alert manager that manages the alerting summary */ private void handleSuppressedSummaryAlerted(@NonNull NotificationEntry summary, - NotificationEntry oldAlertOverride) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: summary=" + summary); - } + @NonNull AlertingNotificationManager alertManager) { + StatusBarNotification sbn = summary.getSbn(); GroupAlertEntry groupAlertEntry = - mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn())); - + mGroupAlertEntries.get(mGroupManager.getGroupKey(sbn)); if (!mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn()) + || !alertManager.isAlerting(sbn.getKey()) || groupAlertEntry == null) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: invalid state"); - } - return; - } - boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey()); - boolean priorityIsAlerting = oldAlertOverride != null - && mHeadsUpManager.isAlerting(oldAlertOverride.getKey()); - if (!summaryIsAlerting && !priorityIsAlerting) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: no summary or override alerting"); - } return; } if (pendingInflationsWillAddChildren(groupAlertEntry.mGroup)) { // New children will actually be added to this group, let's not transfer the alert. - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: pending inflations"); - } return; } NotificationEntry child = mGroupManager.getLogicalChildren(summary.getSbn()).iterator().next(); - if (summaryIsAlerting) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: transfer summary -> child"); + if (child != null) { + if (child.getRow().keepInParent() + || child.isRowRemoved() + || child.isRowDismissed()) { + // The notification is actually already removed. No need to alert it. + return; } - tryTransferAlertState(summary, /*from*/ summary, /*to*/ child, groupAlertEntry); - return; - } - // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure - // it's not too late to transfer back, then transfer the alert from the oldAlertOverride to - // the isolated child which should receive the alert. - if (!canStillTransferBack(groupAlertEntry)) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: transfer from override: too late"); - } - return; - } - - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: transfer override -> child"); - } - tryTransferAlertState(summary, /*from*/ oldAlertOverride, /*to*/ child, groupAlertEntry); - } - - /** - * Checks for and handles the scenario where the given entry is the summary of a group which - * has an alertOverride, and either the summary itself or one of its logical isolated children - * is currently alerting (which happens if the summary is suppressed). - */ - private void handleOverriddenSummaryAlerted(NotificationEntry summary) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: summary=" + summary); - } - GroupAlertEntry groupAlertEntry = - mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn())); - NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn()); - if (group == null || group.alertOverride == null || groupAlertEntry == null) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: invalid state"); - } - return; - } - boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey()); - if (summaryIsAlerting) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: transfer summary -> override"); - } - tryTransferAlertState(summary, /*from*/ summary, group.alertOverride, groupAlertEntry); - return; - } - // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure - // it's not too late to transfer back, then remove the alert from any of the logical - // children, and if one of them was alerting, we can alert the override. - if (!canStillTransferBack(groupAlertEntry)) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: transfer from child: too late"); - } - return; - } - List children = mGroupManager.getLogicalChildren(summary.getSbn()); - if (children == null) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: no children"); - } - return; - } - children.remove(group.alertOverride); // do not release the alert on our desired destination - boolean releasedChild = releaseChildAlerts(children); - if (releasedChild) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: transfer child -> override"); - } - tryTransferAlertState(summary, /*from*/ null, group.alertOverride, groupAlertEntry); - } else { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: no child alert released"); + if (!alertManager.isAlerting(child.getKey()) && onlySummaryAlerts(summary)) { + groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime(); } + transferAlertState(summary, child, alertManager); } } @@ -460,37 +307,14 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis * immediately to have the incorrect one up as short as possible. The second should alert * when possible. * - * @param summary entry of the summary * @param fromEntry entry to transfer alert from * @param toEntry entry to transfer to + * @param alertManager alert manager for the alert type */ - private void tryTransferAlertState( - NotificationEntry summary, - NotificationEntry fromEntry, - NotificationEntry toEntry, - GroupAlertEntry groupAlertEntry) { - if (toEntry != null) { - if (toEntry.getRow().keepInParent() - || toEntry.isRowRemoved() - || toEntry.isRowDismissed()) { - // The notification is actually already removed. No need to alert it. - return; - } - if (!mHeadsUpManager.isAlerting(toEntry.getKey()) && onlySummaryAlerts(summary)) { - groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime(); - } - if (DEBUG) { - Log.d(TAG, "transferAlertState: fromEntry=" + fromEntry + " toEntry=" + toEntry); - } - transferAlertState(fromEntry, toEntry); - } - } - private void transferAlertState(@Nullable NotificationEntry fromEntry, - @NonNull NotificationEntry toEntry) { - if (fromEntry != null) { - mHeadsUpManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */); - } - alertNotificationWhenPossible(toEntry); + private void transferAlertState(@NonNull NotificationEntry fromEntry, @NonNull NotificationEntry toEntry, + @NonNull AlertingNotificationManager alertManager) { + alertManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */); + alertNotificationWhenPossible(toEntry, alertManager); } /** @@ -502,13 +326,11 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis * more children are coming. Thus, if a child is added within a certain timeframe after we * transfer, we back out and alert the summary again. * - * An alert can only transfer back within a small window of time after a transfer away from the - * summary to a child happened. - * * @param groupAlertEntry group alert entry to check */ private void checkShouldTransferBack(@NonNull GroupAlertEntry groupAlertEntry) { - if (canStillTransferBack(groupAlertEntry)) { + if (SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime + < ALERT_TRANSFER_TIMEOUT) { NotificationEntry summary = groupAlertEntry.mGroup.summary; if (!onlySummaryAlerts(summary)) { @@ -516,17 +338,30 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } ArrayList children = mGroupManager.getLogicalChildren( summary.getSbn()); - int numActiveChildren = children.size(); + int numChildren = children.size(); int numPendingChildren = getPendingChildrenNotAlerting(groupAlertEntry.mGroup); - int numChildren = numActiveChildren + numPendingChildren; + numChildren += numPendingChildren; if (numChildren <= 1) { return; } - boolean releasedChild = releaseChildAlerts(children); + boolean releasedChild = false; + for (int i = 0; i < children.size(); i++) { + NotificationEntry entry = children.get(i); + if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) { + releasedChild = true; + mHeadsUpManager.removeNotification( + entry.getKey(), true /* releaseImmediately */); + } + if (mPendingAlerts.containsKey(entry.getKey())) { + // This is the child that would've been removed if it was inflated. + releasedChild = true; + mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true; + } + } if (releasedChild && !mHeadsUpManager.isAlerting(summary.getKey())) { - boolean notifyImmediately = numActiveChildren > 1; + boolean notifyImmediately = (numChildren - numPendingChildren) > 1; if (notifyImmediately) { - alertNotificationWhenPossible(summary); + alertNotificationWhenPossible(summary, mHeadsUpManager); } else { // Should wait until the pending child inflates before alerting. groupAlertEntry.mAlertSummaryOnNextAddition = true; @@ -536,61 +371,25 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } } - private boolean canStillTransferBack(@NonNull GroupAlertEntry groupAlertEntry) { - return SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime - < ALERT_TRANSFER_TIMEOUT; - } - - private boolean releaseChildAlerts(List children) { - boolean releasedChild = false; - if (SPEW) { - Log.d(TAG, "releaseChildAlerts: numChildren=" + children.size()); - } - for (int i = 0; i < children.size(); i++) { - NotificationEntry entry = children.get(i); - if (SPEW) { - Log.d(TAG, "releaseChildAlerts: checking i=" + i + " entry=" + entry - + " onlySummaryAlerts=" + onlySummaryAlerts(entry) - + " isAlerting=" + mHeadsUpManager.isAlerting(entry.getKey()) - + " isPendingAlert=" + mPendingAlerts.containsKey(entry.getKey())); - } - if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) { - releasedChild = true; - mHeadsUpManager.removeNotification( - entry.getKey(), true /* releaseImmediately */); - } - if (mPendingAlerts.containsKey(entry.getKey())) { - // This is the child that would've been removed if it was inflated. - releasedChild = true; - mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true; - } - } - if (SPEW) { - Log.d(TAG, "releaseChildAlerts: didRelease=" + releasedChild); - } - return releasedChild; - } - /** * Tries to alert the notification. If its content view is not inflated, we inflate and continue * when the entry finishes inflating the view. * * @param entry entry to show + * @param alertManager alert manager for the alert type */ - private void alertNotificationWhenPossible(@NonNull NotificationEntry entry) { - @InflationFlag int contentFlag = mHeadsUpManager.getContentFlag(); + private void alertNotificationWhenPossible(@NonNull NotificationEntry entry, + @NonNull AlertingNotificationManager alertManager) { + @InflationFlag int contentFlag = alertManager.getContentFlag(); final RowContentBindParams params = mRowContentBindStage.getStageParams(entry); if ((params.getContentViews() & contentFlag) == 0) { - if (DEBUG) { - Log.d(TAG, "alertNotificationWhenPossible: async requestRebind entry=" + entry); - } mPendingAlerts.put(entry.getKey(), new PendingAlertInfo(entry)); params.requireContentViews(contentFlag); mRowContentBindStage.requestRebind(entry, en -> { PendingAlertInfo alertInfo = mPendingAlerts.remove(entry.getKey()); if (alertInfo != null) { if (alertInfo.isStillValid()) { - alertNotificationWhenPossible(entry); + alertNotificationWhenPossible(entry, mHeadsUpManager); } else { // The transfer is no longer valid. Free the content. mRowContentBindStage.getStageParams(entry).markContentViewsFreeable( @@ -601,16 +400,10 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis }); return; } - if (mHeadsUpManager.isAlerting(entry.getKey())) { - if (DEBUG) { - Log.d(TAG, "alertNotificationWhenPossible: continue alerting entry=" + entry); - } - mHeadsUpManager.updateNotification(entry.getKey(), true /* alert */); + if (alertManager.isAlerting(entry.getKey())) { + alertManager.updateNotification(entry.getKey(), true /* alert */); } else { - if (DEBUG) { - Log.d(TAG, "alertNotificationWhenPossible: start alerting entry=" + entry); - } - mHeadsUpManager.showNotification(entry); + alertManager.showNotification(entry); } } From c90d868b6eb5757cf776371bac70e0889c922855 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Mon, 3 May 2021 19:55:48 +0000 Subject: [PATCH 050/176] Revert "Fix VIP conversations alerting incorrectly." This reverts commit 64c85ac6f5f20d031a7e192366b8335fab0253c2. Reason for revert: DF blocking Bug: 187009701 Change-Id: I04dfdf20ad5c7df3c6dddf0cc12540b179162f0b (cherry picked from commit 25c273584ad92f566c41c635a886be9375f50d39) --- .../statusbar/NotificationListener.java | 3 +- .../NotificationGroupManagerLegacy.java | 438 ++---------------- .../NotificationGroupAlertTransferHelper.java | 365 ++++----------- 3 files changed, 118 insertions(+), 688 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java index 5437ce63475ec..7f31fddbfb6c3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java @@ -18,6 +18,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.statusbar.RemoteInputController.processForRemoteInput; import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON; +import static com.android.systemui.statusbar.phone.StatusBar.DEBUG; import android.annotation.NonNull; import android.annotation.SuppressLint; @@ -34,7 +35,6 @@ import android.util.Log; import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.statusbar.dagger.StatusBarModule; import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins; -import com.android.systemui.statusbar.phone.StatusBar; import java.util.ArrayList; import java.util.List; @@ -46,7 +46,6 @@ import java.util.List; @SuppressLint("OverrideAbstract") public class NotificationListener extends NotificationListenerWithPlugins { private static final String TAG = "NotificationListener"; - private static final boolean DEBUG = StatusBar.DEBUG; private final Context mContext; private final NotificationManager mNotificationManager; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java index d95c265c14608..d6356de5ea51b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java @@ -16,9 +16,7 @@ package com.android.systemui.statusbar.notification.collection.legacy; -import android.annotation.NonNull; import android.annotation.Nullable; -import android.app.Notification; import android.service.notification.StatusBarNotification; import android.util.ArraySet; import android.util.Log; @@ -33,7 +31,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager; import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager; import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier; -import com.android.systemui.statusbar.phone.StatusBar; import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.wm.shell.bubbles.Bubbles; @@ -42,12 +39,10 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.TreeSet; import javax.inject.Inject; @@ -63,21 +58,13 @@ import dagger.Lazy; public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, StateListener, GroupMembershipManager, GroupExpansionManager, Dumpable { - private static final String TAG = "NotifGroupManager"; - private static final boolean DEBUG = StatusBar.DEBUG; - private static final boolean SPEW = StatusBar.SPEW; - /** - * The maximum amount of time (in ms) between the posting of notifications that can be - * considered part of the same update batch. - */ - private static final long POST_BATCH_MAX_AGE = 5000; + private static final String TAG = "NotificationGroupManager"; private final HashMap mGroupMap = new HashMap<>(); private final ArraySet mExpansionChangeListeners = new ArraySet<>(); private final ArraySet mGroupChangeListeners = new ArraySet<>(); private final Lazy mPeopleNotificationIdentifier; private final Optional mBubblesOptional; - private final EventBuffer mEventBuffer = new EventBuffer(); private int mBarState = -1; private HashMap mIsolatedEntries = new HashMap<>(); private HeadsUpManager mHeadsUpManager; @@ -147,14 +134,8 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * When we want to remove an entry from being tracked for grouping */ public void onEntryRemoved(NotificationEntry removed) { - if (SPEW) { - Log.d(TAG, "onEntryRemoved: entry=" + removed); - } onEntryRemovedInternal(removed, removed.getSbn()); - StatusBarNotification oldSbn = mIsolatedEntries.remove(removed.getKey()); - if (oldSbn != null) { - updateSuppression(mGroupMap.get(oldSbn.getGroupKey())); - } + mIsolatedEntries.remove(removed.getKey()); } /** @@ -181,9 +162,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, // the close future. See b/23676310 for reference. return; } - if (SPEW) { - Log.d(TAG, "onEntryRemovedInternal: entry=" + removed + " group=" + group.groupKey); - } if (isGroupChild(removed.getKey(), isGroup, isGroupSummary)) { group.children.remove(removed.getKey()); } else { @@ -204,9 +182,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * Notify the group manager that a new entry was added */ public void onEntryAdded(final NotificationEntry added) { - if (SPEW) { - Log.d(TAG, "onEntryAdded: entry=" + added); - } updateIsolation(added); onEntryAddedInternal(added); } @@ -220,16 +195,13 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, String groupKey = getGroupKey(sbn); NotificationGroup group = mGroupMap.get(groupKey); if (group == null) { - group = new NotificationGroup(groupKey); + group = new NotificationGroup(); mGroupMap.put(groupKey, group); for (OnGroupChangeListener listener : mGroupChangeListeners) { listener.onGroupCreated(group, groupKey); } } - if (SPEW) { - Log.d(TAG, "onEntryAddedInternal: entry=" + added + " group=" + group.groupKey); - } if (isGroupChild) { NotificationEntry existing = group.children.get(added.getKey()); if (existing != null && existing != added) { @@ -241,11 +213,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, + " added removed" + added.isRowRemoved(), new Throwable()); } group.children.put(added.getKey(), added); - addToPostBatchHistory(group, added); updateSuppression(group); } else { group.summary = added; - addToPostBatchHistory(group, added); group.expanded = added.areChildrenExpanded(); updateSuppression(group); if (!group.children.isEmpty()) { @@ -261,27 +231,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, } } - private void addToPostBatchHistory(NotificationGroup group, @Nullable NotificationEntry entry) { - if (entry == null) { - return; - } - boolean didAdd = group.postBatchHistory.add(new PostRecord(entry)); - if (didAdd) { - trimPostBatchHistory(group.postBatchHistory); - } - } - - /** remove all history that's too old to be in the batch. */ - private void trimPostBatchHistory(@NonNull TreeSet postBatchHistory) { - if (postBatchHistory.size() <= 1) { - return; - } - long batchStartTime = postBatchHistory.last().postTime - POST_BATCH_MAX_AGE; - while (!postBatchHistory.isEmpty() && postBatchHistory.first().postTime < batchStartTime) { - postBatchHistory.pollFirst(); - } - } - private void onEntryBecomingChild(NotificationEntry entry) { updateIsolation(entry); } @@ -290,9 +239,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, if (group == null) { return; } - NotificationEntry prevAlertOverride = group.alertOverride; - group.alertOverride = getPriorityConversationAlertOverride(group); - int childCount = 0; boolean hasBubbles = false; for (NotificationEntry entry : group.children.values()) { @@ -309,148 +255,18 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, group.suppressed = group.summary != null && !group.expanded && (childCount == 1 || (childCount == 0 - && group.summary.getSbn().getNotification().isGroupSummary() - && (hasIsolatedChildren(group) || hasBubbles))); - - boolean alertOverrideChanged = prevAlertOverride != group.alertOverride; - boolean suppressionChanged = prevSuppressed != group.suppressed; - if (alertOverrideChanged || suppressionChanged) { - if (DEBUG && alertOverrideChanged) { - Log.d(TAG, group + " alertOverride was=" + prevAlertOverride + " now=" - + group.alertOverride); - } - if (DEBUG && suppressionChanged) { - Log.d(TAG, group + " suppressed changed to " + group.suppressed); - } - if (!mIsUpdatingUnchangedGroup) { - if (alertOverrideChanged) { - mEventBuffer.notifyAlertOverrideChanged(group, prevAlertOverride); - } - if (suppressionChanged) { - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupSuppressionChanged(group, group.suppressed); - } - } - mEventBuffer.notifyGroupsChanged(); - } else { - if (DEBUG) { - Log.d(TAG, group + " did not notify listeners of above change(s)"); + && group.summary.getSbn().getNotification().isGroupSummary() + && (hasIsolatedChildren(group) || hasBubbles))); + if (prevSuppressed != group.suppressed) { + for (OnGroupChangeListener listener : mGroupChangeListeners) { + if (!mIsUpdatingUnchangedGroup) { + listener.onGroupSuppressionChanged(group, group.suppressed); + listener.onGroupsChanged(); } } } } - /** - * Finds the isolated logical child of this group which is should be alerted instead. - * - * Notifications from priority conversations are isolated from their groups to make them more - * prominent, however apps may post these with a GroupAlertBehavior that has the group receiving - * the alert. This would lead to the group alerting even though the conversation that was - * updated was not actually a part of that group. This method finds the best priority - * conversation in this situation, if there is one, so they can be set as the alertOverride of - * the group. - * - * @param group the group to check - * @return the entry which should receive the alert instead of the group, if any. - */ - @Nullable - private NotificationEntry getPriorityConversationAlertOverride(NotificationGroup group) { - // GOAL: if there is a priority child which wouldn't alert based on its groupAlertBehavior, - // but which should be alerting (because priority conversations are isolated), find it. - if (group == null || group.summary == null) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: null group or summary"); - } - return null; - } - if (isIsolated(group.summary.getKey())) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: isolated group"); - } - return null; - } - - // Precondiions: - // * Only necessary when all notifications in the group use GROUP_ALERT_SUMMARY - // * Only necessary when at least one notification in the group is on a priority channel - if (group.summary.getSbn().getNotification().getGroupAlertBehavior() - != Notification.GROUP_ALERT_SUMMARY) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: summary != GROUP_ALERT_SUMMARY"); - } - return null; - } - - // Get the important children first, copy the keys for the final importance check, - // then add the non-isolated children to the map for unified lookup. - HashMap children = getImportantConversations(group); - if (children == null || children.isEmpty()) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: no important conversations"); - } - return null; - } - HashSet importantChildKeys = new HashSet<>(children.keySet()); - children.putAll(group.children); - - // Ensure all children have GROUP_ALERT_SUMMARY - for (NotificationEntry child : children.values()) { - if (child.getSbn().getNotification().getGroupAlertBehavior() - != Notification.GROUP_ALERT_SUMMARY) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: " - + "child != GROUP_ALERT_SUMMARY"); - } - return null; - } - } - - // Create a merged post history from all the children - TreeSet combinedHistory = new TreeSet<>(group.postBatchHistory); - for (String importantChildKey : importantChildKeys) { - NotificationGroup importantChildGroup = mGroupMap.get(importantChildKey); - combinedHistory.addAll(importantChildGroup.postBatchHistory); - } - trimPostBatchHistory(combinedHistory); - - // This is a streamlined implementation of the following idea: - // * From the subset of notifications in the latest 'batch' of updates. A batch is: - // * Notifs posted less than POST_BATCH_MAX_AGE before the most recently posted. - // * Only including notifs newer than the second-to-last post of any notification. - // * Find the newest child in the batch -- the with the largest 'when' value. - // * If the newest child is a priority conversation, set that as the override. - HashSet batchKeys = new HashSet<>(); - long newestChildWhen = -1; - NotificationEntry newestChild = null; - // Iterate backwards through the post history, tracking the child with the smallest sort key - for (PostRecord record : combinedHistory.descendingSet()) { - if (batchKeys.contains(record.key)) { - // Once you see a notification again, the batch has ended - break; - } - batchKeys.add(record.key); - NotificationEntry child = children.get(record.key); - if (child != null) { - long childWhen = child.getSbn().getNotification().when; - if (newestChild == null || childWhen > newestChildWhen) { - newestChildWhen = childWhen; - newestChild = child; - } - } - } - if (newestChild != null && importantChildKeys.contains(newestChild.getKey())) { - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: result=" + newestChild); - } - return newestChild; - } - if (SPEW) { - Log.d(TAG, "getPriorityConversationAlertOverride: result=null, newestChild=" - + newestChild); - } - return null; - } - private boolean hasIsolatedChildren(NotificationGroup group) { return getNumberOfIsolatedChildren(group.summary.getSbn().getGroupKey()) != 0; } @@ -465,33 +281,12 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, return count; } - @Nullable - private HashMap getImportantConversations(NotificationGroup group) { - String groupKey = group.summary.getSbn().getGroupKey(); - HashMap result = null; - for (StatusBarNotification sbn : mIsolatedEntries.values()) { - if (sbn.getGroupKey().equals(groupKey)) { - NotificationEntry entry = mGroupMap.get(sbn.getKey()).summary; - if (isImportantConversation(entry)) { - if (result == null) { - result = new HashMap<>(); - } - result.put(sbn.getKey(), entry); - } - } - } - return result; - } - /** * Update an entry's group information * @param entry notification entry to update * @param oldNotification previous notification info before this update */ public void onEntryUpdated(NotificationEntry entry, StatusBarNotification oldNotification) { - if (SPEW) { - Log.d(TAG, "onEntryUpdated: entry=" + entry); - } onEntryUpdated(entry, oldNotification.getGroupKey(), oldNotification.isGroup(), oldNotification.getNotification().isGroupSummary()); } @@ -530,17 +325,7 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * Whether the given notification is the summary of a group that is being suppressed */ public boolean isSummaryOfSuppressedGroup(StatusBarNotification sbn) { - return sbn.getNotification().isGroupSummary() && isGroupSuppressed(getGroupKey(sbn)); - } - - /** - * If the given notification is a summary, get the group for it. - */ - public NotificationGroup getGroupForSummary(StatusBarNotification sbn) { - if (sbn.getNotification().isGroupSummary()) { - return mGroupMap.get(getGroupKey(sbn)); - } - return null; + return isGroupSuppressed(getGroupKey(sbn)) && sbn.getNotification().isGroupSummary(); } private boolean isOnlyChild(StatusBarNotification sbn) { @@ -760,7 +545,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) { return false; } - if (isImportantConversation(entry)) { + int peopleNotificationType = + mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry); + if (peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON) { return true; } if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.getKey())) { @@ -773,25 +560,18 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, || isGroupNotFullyVisible(notificationGroup)); } - private boolean isImportantConversation(NotificationEntry entry) { - int peopleNotificationType = - mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry); - return peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON; - } - /** * Isolate a notification from its group so that it visually shows as its own group. * * @param entry the notification to isolate */ private void isolateNotification(NotificationEntry entry) { - if (SPEW) { - Log.d(TAG, "isolateNotification: entry=" + entry); - } + StatusBarNotification sbn = entry.getSbn(); + // We will be isolated now, so lets update the groups onEntryRemovedInternal(entry, entry.getSbn()); - mIsolatedEntries.put(entry.getKey(), entry.getSbn()); + mIsolatedEntries.put(sbn.getKey(), sbn); onEntryAddedInternal(entry); // We also need to update the suppression of the old group, because this call comes @@ -808,14 +588,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * Update the isolation of an entry, splitting it from the group. */ public void updateIsolation(NotificationEntry entry) { - // We need to buffer a few events because we do isolation changes in 3 steps: - // removeInternal, update mIsolatedEntries, addInternal. This means that often the - // alertOverride will update on the removal, however processing the event in that case can - // cause problems because the mIsolatedEntries map is not in its final state, so the event - // listener may be unable to correctly determine the true state of the group. By delaying - // the alertOverride change until after the add phase, we can ensure that listeners only - // have to handle a consistent state. - mEventBuffer.startBuffering(); boolean isIsolated = isIsolated(entry.getSbn().getKey()); if (shouldIsolate(entry)) { if (!isIsolated) { @@ -824,7 +596,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, } else if (isIsolated) { stopIsolatingNotification(entry); } - mEventBuffer.flushAndStopBuffering(); } /** @@ -833,15 +604,15 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, * @param entry the notification to un-isolate */ private void stopIsolatingNotification(NotificationEntry entry) { - if (SPEW) { - Log.d(TAG, "stopIsolatingNotification: entry=" + entry); - } - // not isolated anymore, we need to update the groups - onEntryRemovedInternal(entry, entry.getSbn()); - mIsolatedEntries.remove(entry.getKey()); - onEntryAddedInternal(entry); - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupsChanged(); + StatusBarNotification sbn = entry.getSbn(); + if (isIsolated(sbn.getKey())) { + // not isolated anymore, we need to update the groups + onEntryRemovedInternal(entry, entry.getSbn()); + mIsolatedEntries.remove(sbn.getKey()); + onEntryAddedInternal(entry); + for (OnGroupChangeListener listener : mGroupChangeListeners) { + listener.onGroupsChanged(); + } } } @@ -876,155 +647,34 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, setStatusBarState(newState); } - /** - * A record of a notification being posted, containing the time of the post and the key of the - * notification entry. These are stored in a TreeSet by the NotificationGroup and used to - * calculate a batch of notifications. - */ - public static class PostRecord implements Comparable { - public final long postTime; - public final String key; - - /** constructs a record containing the post time and key from the notification entry */ - public PostRecord(@NonNull NotificationEntry entry) { - this.postTime = entry.getSbn().getPostTime(); - this.key = entry.getKey(); - } - - @Override - public int compareTo(PostRecord o) { - int postTimeComparison = Long.compare(this.postTime, o.postTime); - return postTimeComparison == 0 - ? String.CASE_INSENSITIVE_ORDER.compare(this.key, o.key) - : postTimeComparison; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - PostRecord that = (PostRecord) o; - return postTime == that.postTime && key.equals(that.key); - } - - @Override - public int hashCode() { - return Objects.hash(postTime, key); - } - } - /** * Represents a notification group in the notification shade. */ public static class NotificationGroup { - public final String groupKey; public final HashMap children = new HashMap<>(); - public final TreeSet postBatchHistory = new TreeSet<>(); public NotificationEntry summary; public boolean expanded; /** * Is this notification group suppressed, i.e its summary is hidden */ public boolean suppressed; - /** - * The child (which is isolated from this group) to which the alert should be transferred, - * due to priority conversations. - */ - public NotificationEntry alertOverride; - - NotificationGroup(String groupKey) { - this.groupKey = groupKey; - } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(" groupKey: ").append(groupKey); - sb.append("\n summary:"); - appendEntry(sb, summary); - sb.append("\n children size: ").append(children.size()); + String result = " summary:\n " + + (summary != null ? summary.getSbn() : "null") + + (summary != null && summary.getDebugThrowable() != null + ? Log.getStackTraceString(summary.getDebugThrowable()) + : ""); + result += "\n children size: " + children.size(); for (NotificationEntry child : children.values()) { - appendEntry(sb, child); - } - sb.append("\n alertOverride:"); - appendEntry(sb, alertOverride); - sb.append("\n summary suppressed: ").append(suppressed); - return sb.toString(); - } - - private void appendEntry(StringBuilder sb, NotificationEntry entry) { - sb.append("\n ").append(entry != null ? entry.getSbn() : "null"); - if (entry != null && entry.getDebugThrowable() != null) { - sb.append(Log.getStackTraceString(entry.getDebugThrowable())); - } - } - } - - /** - * This class is a toggleable buffer for a subset of events of {@link OnGroupChangeListener}. - * When buffering, instead of notifying the listeners it will set internal state that will allow - * it to notify listeners of those events later - */ - private class EventBuffer { - private final HashMap mOldAlertOverrideByGroup = new HashMap<>(); - private boolean mIsBuffering = false; - private boolean mDidGroupsChange = false; - - void notifyAlertOverrideChanged(NotificationGroup group, - NotificationEntry oldAlertOverride) { - if (mIsBuffering) { - // The value in this map is the override before the event. If there is an entry - // already in the map, then we are effectively coalescing two events, which means - // we need to preserve the original initial value. - mOldAlertOverrideByGroup.putIfAbsent(group.groupKey, oldAlertOverride); - } else { - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupAlertOverrideChanged(group, oldAlertOverride, - group.alertOverride); - } - } - } - - void notifyGroupsChanged() { - if (mIsBuffering) { - mDidGroupsChange = true; - } else { - for (OnGroupChangeListener listener : mGroupChangeListeners) { - listener.onGroupsChanged(); - } - } - } - - void startBuffering() { - mIsBuffering = true; - } - - void flushAndStopBuffering() { - // stop buffering so that we can call our own helpers - mIsBuffering = false; - // alert all group alert override changes for groups that were not removed - for (Map.Entry entry : mOldAlertOverrideByGroup.entrySet()) { - NotificationGroup group = mGroupMap.get(entry.getKey()); - if (group == null) { - // The group can be null if this alertOverride changed before the group was - // permanently removed, meaning that there's no guarantee that listeners will - // that field clear. - continue; - } - NotificationEntry oldAlertOverride = entry.getValue(); - if (group.alertOverride == oldAlertOverride) { - // If the final alertOverride equals the initial, it means we coalesced two - // events which undid the change, so we can drop it entirely. - continue; - } - notifyAlertOverrideChanged(group, oldAlertOverride); - } - mOldAlertOverrideByGroup.clear(); - // alert that groups changed - if (mDidGroupsChange) { - notifyGroupsChanged(); - mDidGroupsChange = false; + result += "\n " + child.getSbn() + + (child.getDebugThrowable() != null + ? Log.getStackTraceString(child.getDebugThrowable()) + : ""); } + result += "\n summary suppressed: " + suppressed; + return result; } } @@ -1063,18 +713,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, NotificationGroup group, boolean suppressed) {} - /** - * The alert override of a group has changed. - * - * @param group the group that has changed - * @param oldAlertOverride the previous notification to which the group's alerts were sent - * @param newAlertOverride the notification to which the group's alerts should now be sent - */ - default void onGroupAlertOverrideChanged( - NotificationGroup group, - @Nullable NotificationEntry oldAlertOverride, - @Nullable NotificationEntry newAlertOverride) {} - /** * A group of children just received a summary notification and should therefore become * children of it. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java index 9787a9446019c..3181f520dca22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java @@ -22,12 +22,12 @@ import android.app.Notification; import android.os.SystemClock; import android.service.notification.StatusBarNotification; import android.util.ArrayMap; -import android.util.Log; import com.android.internal.statusbar.NotificationVisibility; import com.android.systemui.Dependency; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener; +import com.android.systemui.statusbar.AlertingNotificationManager; import com.android.systemui.statusbar.notification.NotificationEntryListener; import com.android.systemui.statusbar.notification.NotificationEntryManager; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -41,21 +41,17 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import java.util.ArrayList; -import java.util.List; import java.util.Objects; /** * A helper class dealing with the alert interactions between {@link NotificationGroupManagerLegacy} * and {@link HeadsUpManager}. In particular, this class deals with keeping - * the correct notification in a group alerting based off the group suppression and alertOverride. + * the correct notification in a group alerting based off the group suppression. */ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener, StateListener { private static final long ALERT_TRANSFER_TIMEOUT = 300; - private static final String TAG = "NotifGroupAlertTransfer"; - private static final boolean DEBUG = StatusBar.DEBUG; - private static final boolean SPEW = StatusBar.SPEW; /** * The list of entries containing group alert metadata for each group. Keyed by group key. @@ -146,98 +142,41 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis @Override public void onGroupSuppressionChanged(NotificationGroup group, boolean suppressed) { - if (DEBUG) { - Log.d(TAG, "!! onGroupSuppressionChanged: group.summary=" + group.summary - + " suppressed=" + suppressed); + if (suppressed) { + if (mHeadsUpManager.isAlerting(group.summary.getKey())) { + handleSuppressedSummaryAlerted(group.summary, mHeadsUpManager); + } + } else { + // Group summary can be null if we are no longer suppressed because the summary was + // removed. In that case, we don't need to alert the summary. + if (group.summary == null) { + return; + } + GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey( + group.summary.getSbn())); + // Group is no longer suppressed. We should check if we need to transfer the alert + // back to the summary now that it's no longer suppressed. + if (groupAlertEntry.mAlertSummaryOnNextAddition) { + if (!mHeadsUpManager.isAlerting(group.summary.getKey())) { + alertNotificationWhenPossible(group.summary, mHeadsUpManager); + } + groupAlertEntry.mAlertSummaryOnNextAddition = false; + } else { + checkShouldTransferBack(groupAlertEntry); + } } - NotificationEntry oldAlertOverride = group.alertOverride; - onGroupChanged(group, oldAlertOverride); - } - - @Override - public void onGroupAlertOverrideChanged(NotificationGroup group, - @Nullable NotificationEntry oldAlertOverride, - @Nullable NotificationEntry newAlertOverride) { - if (DEBUG) { - Log.d(TAG, "!! onGroupAlertOverrideChanged: group.summary=" + group.summary - + " oldAlertOverride=" + oldAlertOverride - + " newAlertOverride=" + newAlertOverride); - } - onGroupChanged(group, oldAlertOverride); } }; - /** - * Called when either the suppressed or alertOverride fields of the group changed - * - * @param group the group which changed - * @param oldAlertOverride the previous value of group.alertOverride - */ - private void onGroupChanged(NotificationGroup group, - NotificationEntry oldAlertOverride) { - // Group summary can be null if we are no longer suppressed because the summary was - // removed. In that case, we don't need to alert the summary. - if (group.summary == null) { - if (DEBUG) { - Log.d(TAG, "onGroupChanged: summary is null"); - } - return; - } - if (group.suppressed || group.alertOverride != null) { - checkForForwardAlertTransfer(group.summary, oldAlertOverride); - } else { - if (DEBUG) { - Log.d(TAG, "onGroupChanged: maybe transfer back"); - } - GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey( - group.summary.getSbn())); - // Group is no longer suppressed or overridden. - // We should check if we need to transfer the alert back to the summary. - if (groupAlertEntry.mAlertSummaryOnNextAddition) { - if (!mHeadsUpManager.isAlerting(group.summary.getKey())) { - alertNotificationWhenPossible(group.summary); - } - groupAlertEntry.mAlertSummaryOnNextAddition = false; - } else { - checkShouldTransferBack(groupAlertEntry); - } - } - } - @Override public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) { - if (DEBUG) { - Log.d(TAG, "!! onHeadsUpStateChanged: entry=" + entry + " isHeadsUp=" + isHeadsUp); - } - if (isHeadsUp && entry.getSbn().getNotification().isGroupSummary()) { - // a group summary is alerting; trigger the forward transfer checks - checkForForwardAlertTransfer(entry, /* oldAlertOverride */ null); - } + onAlertStateChanged(entry, isHeadsUp, mHeadsUpManager); } - /** - * Handles changes in a group's suppression or alertOverride, but where at least one of those - * conditions is still true (either the group is suppressed, the group has an alertOverride, - * or both). The method determined which kind of child needs to receive the alert, finds the - * entry currently alerting, and makes the transfer. - * - * Internally, this is handled with two main cases: the override needs the alert, or there is - * no override but the summary is suppressed (so an isolated child needs the alert). - * - * @param summary the notification entry of the summary of the logical group. - * @param oldAlertOverride the former value of group.alertOverride, before whatever event - * required us to check for for a transfer condition. - */ - private void checkForForwardAlertTransfer(NotificationEntry summary, - NotificationEntry oldAlertOverride) { - if (DEBUG) { - Log.d(TAG, "checkForForwardAlertTransfer: enter"); - } - NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn()); - if (group != null && group.alertOverride != null) { - handleOverriddenSummaryAlerted(summary); - } else if (mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn())) { - handleSuppressedSummaryAlerted(summary, oldAlertOverride); + private void onAlertStateChanged(NotificationEntry entry, boolean isAlerting, + AlertingNotificationManager alertManager) { + if (isAlerting && mGroupManager.isSummaryOfSuppressedGroup(entry.getSbn())) { + handleSuppressedSummaryAlerted(entry, alertManager); } } @@ -247,16 +186,9 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis // see as early as we can if we need to abort a transfer. @Override public void onPendingEntryAdded(NotificationEntry entry) { - if (DEBUG) { - Log.d(TAG, "!! onPendingEntryAdded: entry=" + entry); - } String groupKey = mGroupManager.getGroupKey(entry.getSbn()); GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(groupKey); - if (groupAlertEntry != null && groupAlertEntry.mGroup.alertOverride == null) { - // new pending group entries require us to transfer back from the child to the - // group, but alertOverrides are only present in very limited circumstances, so - // while it's possible the group should ALSO alert, the previous detection which set - // this alertOverride won't be invalidated by this notification added to this group. + if (groupAlertEntry != null) { checkShouldTransferBack(groupAlertEntry); } } @@ -330,128 +262,43 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } /** - * Handles the scenario where a summary that has been suppressed is itself, or has a former - * alertOverride (in the form of an isolated logical child) which was alerted. A suppressed + * Handles the scenario where a summary that has been suppressed is alerted. A suppressed * summary should for all intents and purposes be invisible to the user and as a result should * not alert. When this is the case, it is our responsibility to pass the alert to the * appropriate child which will be the representative notification alerting for the group. * - * @param summary the summary that is suppressed and (potentially) alerting - * @param oldAlertOverride the alertOverride before whatever event triggered this method. If - * the alert override was removed, this will be the entry that should - * be transferred back from. + * @param summary the summary that is suppressed and alerting + * @param alertManager the alert manager that manages the alerting summary */ private void handleSuppressedSummaryAlerted(@NonNull NotificationEntry summary, - NotificationEntry oldAlertOverride) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: summary=" + summary); - } + @NonNull AlertingNotificationManager alertManager) { + StatusBarNotification sbn = summary.getSbn(); GroupAlertEntry groupAlertEntry = - mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn())); - + mGroupAlertEntries.get(mGroupManager.getGroupKey(sbn)); if (!mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn()) + || !alertManager.isAlerting(sbn.getKey()) || groupAlertEntry == null) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: invalid state"); - } - return; - } - boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey()); - boolean priorityIsAlerting = oldAlertOverride != null - && mHeadsUpManager.isAlerting(oldAlertOverride.getKey()); - if (!summaryIsAlerting && !priorityIsAlerting) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: no summary or override alerting"); - } return; } if (pendingInflationsWillAddChildren(groupAlertEntry.mGroup)) { // New children will actually be added to this group, let's not transfer the alert. - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: pending inflations"); - } return; } NotificationEntry child = mGroupManager.getLogicalChildren(summary.getSbn()).iterator().next(); - if (summaryIsAlerting) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: transfer summary -> child"); + if (child != null) { + if (child.getRow().keepInParent() + || child.isRowRemoved() + || child.isRowDismissed()) { + // The notification is actually already removed. No need to alert it. + return; } - tryTransferAlertState(summary, /*from*/ summary, /*to*/ child, groupAlertEntry); - return; - } - // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure - // it's not too late to transfer back, then transfer the alert from the oldAlertOverride to - // the isolated child which should receive the alert. - if (!canStillTransferBack(groupAlertEntry)) { - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: transfer from override: too late"); - } - return; - } - - if (DEBUG) { - Log.d(TAG, "handleSuppressedSummaryAlerted: transfer override -> child"); - } - tryTransferAlertState(summary, /*from*/ oldAlertOverride, /*to*/ child, groupAlertEntry); - } - - /** - * Checks for and handles the scenario where the given entry is the summary of a group which - * has an alertOverride, and either the summary itself or one of its logical isolated children - * is currently alerting (which happens if the summary is suppressed). - */ - private void handleOverriddenSummaryAlerted(NotificationEntry summary) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: summary=" + summary); - } - GroupAlertEntry groupAlertEntry = - mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn())); - NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn()); - if (group == null || group.alertOverride == null || groupAlertEntry == null) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: invalid state"); - } - return; - } - boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey()); - if (summaryIsAlerting) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: transfer summary -> override"); - } - tryTransferAlertState(summary, /*from*/ summary, group.alertOverride, groupAlertEntry); - return; - } - // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure - // it's not too late to transfer back, then remove the alert from any of the logical - // children, and if one of them was alerting, we can alert the override. - if (!canStillTransferBack(groupAlertEntry)) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: transfer from child: too late"); - } - return; - } - List children = mGroupManager.getLogicalChildren(summary.getSbn()); - if (children == null) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: no children"); - } - return; - } - children.remove(group.alertOverride); // do not release the alert on our desired destination - boolean releasedChild = releaseChildAlerts(children); - if (releasedChild) { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: transfer child -> override"); - } - tryTransferAlertState(summary, /*from*/ null, group.alertOverride, groupAlertEntry); - } else { - if (DEBUG) { - Log.d(TAG, "handleOverriddenSummaryAlerted: no child alert released"); + if (!alertManager.isAlerting(child.getKey()) && onlySummaryAlerts(summary)) { + groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime(); } + transferAlertState(summary, child, alertManager); } } @@ -460,37 +307,14 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis * immediately to have the incorrect one up as short as possible. The second should alert * when possible. * - * @param summary entry of the summary * @param fromEntry entry to transfer alert from * @param toEntry entry to transfer to + * @param alertManager alert manager for the alert type */ - private void tryTransferAlertState( - NotificationEntry summary, - NotificationEntry fromEntry, - NotificationEntry toEntry, - GroupAlertEntry groupAlertEntry) { - if (toEntry != null) { - if (toEntry.getRow().keepInParent() - || toEntry.isRowRemoved() - || toEntry.isRowDismissed()) { - // The notification is actually already removed. No need to alert it. - return; - } - if (!mHeadsUpManager.isAlerting(toEntry.getKey()) && onlySummaryAlerts(summary)) { - groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime(); - } - if (DEBUG) { - Log.d(TAG, "transferAlertState: fromEntry=" + fromEntry + " toEntry=" + toEntry); - } - transferAlertState(fromEntry, toEntry); - } - } - private void transferAlertState(@Nullable NotificationEntry fromEntry, - @NonNull NotificationEntry toEntry) { - if (fromEntry != null) { - mHeadsUpManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */); - } - alertNotificationWhenPossible(toEntry); + private void transferAlertState(@NonNull NotificationEntry fromEntry, @NonNull NotificationEntry toEntry, + @NonNull AlertingNotificationManager alertManager) { + alertManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */); + alertNotificationWhenPossible(toEntry, alertManager); } /** @@ -502,13 +326,11 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis * more children are coming. Thus, if a child is added within a certain timeframe after we * transfer, we back out and alert the summary again. * - * An alert can only transfer back within a small window of time after a transfer away from the - * summary to a child happened. - * * @param groupAlertEntry group alert entry to check */ private void checkShouldTransferBack(@NonNull GroupAlertEntry groupAlertEntry) { - if (canStillTransferBack(groupAlertEntry)) { + if (SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime + < ALERT_TRANSFER_TIMEOUT) { NotificationEntry summary = groupAlertEntry.mGroup.summary; if (!onlySummaryAlerts(summary)) { @@ -516,17 +338,30 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } ArrayList children = mGroupManager.getLogicalChildren( summary.getSbn()); - int numActiveChildren = children.size(); + int numChildren = children.size(); int numPendingChildren = getPendingChildrenNotAlerting(groupAlertEntry.mGroup); - int numChildren = numActiveChildren + numPendingChildren; + numChildren += numPendingChildren; if (numChildren <= 1) { return; } - boolean releasedChild = releaseChildAlerts(children); + boolean releasedChild = false; + for (int i = 0; i < children.size(); i++) { + NotificationEntry entry = children.get(i); + if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) { + releasedChild = true; + mHeadsUpManager.removeNotification( + entry.getKey(), true /* releaseImmediately */); + } + if (mPendingAlerts.containsKey(entry.getKey())) { + // This is the child that would've been removed if it was inflated. + releasedChild = true; + mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true; + } + } if (releasedChild && !mHeadsUpManager.isAlerting(summary.getKey())) { - boolean notifyImmediately = numActiveChildren > 1; + boolean notifyImmediately = (numChildren - numPendingChildren) > 1; if (notifyImmediately) { - alertNotificationWhenPossible(summary); + alertNotificationWhenPossible(summary, mHeadsUpManager); } else { // Should wait until the pending child inflates before alerting. groupAlertEntry.mAlertSummaryOnNextAddition = true; @@ -536,61 +371,25 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis } } - private boolean canStillTransferBack(@NonNull GroupAlertEntry groupAlertEntry) { - return SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime - < ALERT_TRANSFER_TIMEOUT; - } - - private boolean releaseChildAlerts(List children) { - boolean releasedChild = false; - if (SPEW) { - Log.d(TAG, "releaseChildAlerts: numChildren=" + children.size()); - } - for (int i = 0; i < children.size(); i++) { - NotificationEntry entry = children.get(i); - if (SPEW) { - Log.d(TAG, "releaseChildAlerts: checking i=" + i + " entry=" + entry - + " onlySummaryAlerts=" + onlySummaryAlerts(entry) - + " isAlerting=" + mHeadsUpManager.isAlerting(entry.getKey()) - + " isPendingAlert=" + mPendingAlerts.containsKey(entry.getKey())); - } - if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) { - releasedChild = true; - mHeadsUpManager.removeNotification( - entry.getKey(), true /* releaseImmediately */); - } - if (mPendingAlerts.containsKey(entry.getKey())) { - // This is the child that would've been removed if it was inflated. - releasedChild = true; - mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true; - } - } - if (SPEW) { - Log.d(TAG, "releaseChildAlerts: didRelease=" + releasedChild); - } - return releasedChild; - } - /** * Tries to alert the notification. If its content view is not inflated, we inflate and continue * when the entry finishes inflating the view. * * @param entry entry to show + * @param alertManager alert manager for the alert type */ - private void alertNotificationWhenPossible(@NonNull NotificationEntry entry) { - @InflationFlag int contentFlag = mHeadsUpManager.getContentFlag(); + private void alertNotificationWhenPossible(@NonNull NotificationEntry entry, + @NonNull AlertingNotificationManager alertManager) { + @InflationFlag int contentFlag = alertManager.getContentFlag(); final RowContentBindParams params = mRowContentBindStage.getStageParams(entry); if ((params.getContentViews() & contentFlag) == 0) { - if (DEBUG) { - Log.d(TAG, "alertNotificationWhenPossible: async requestRebind entry=" + entry); - } mPendingAlerts.put(entry.getKey(), new PendingAlertInfo(entry)); params.requireContentViews(contentFlag); mRowContentBindStage.requestRebind(entry, en -> { PendingAlertInfo alertInfo = mPendingAlerts.remove(entry.getKey()); if (alertInfo != null) { if (alertInfo.isStillValid()) { - alertNotificationWhenPossible(entry); + alertNotificationWhenPossible(entry, mHeadsUpManager); } else { // The transfer is no longer valid. Free the content. mRowContentBindStage.getStageParams(entry).markContentViewsFreeable( @@ -601,16 +400,10 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis }); return; } - if (mHeadsUpManager.isAlerting(entry.getKey())) { - if (DEBUG) { - Log.d(TAG, "alertNotificationWhenPossible: continue alerting entry=" + entry); - } - mHeadsUpManager.updateNotification(entry.getKey(), true /* alert */); + if (alertManager.isAlerting(entry.getKey())) { + alertManager.updateNotification(entry.getKey(), true /* alert */); } else { - if (DEBUG) { - Log.d(TAG, "alertNotificationWhenPossible: start alerting entry=" + entry); - } - mHeadsUpManager.showNotification(entry); + alertManager.showNotification(entry); } } From 699f52e08491b1f38b23081bb94a41df2b358a83 Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Wed, 5 May 2021 11:25:10 -0700 Subject: [PATCH 051/176] [SettingProvider] add checks for null applicationInfo BUG: 187301322 Test: builds Change-Id: I20d68f5dd11d0e34acc35d6a985fee0991157741 (cherry picked from commit d7baae817045f5ce4f756fd0787b6344c11fc444) --- .../providers/settings/SettingsProvider.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 941f47f525510..0a57390964879 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1873,6 +1873,9 @@ public class SettingsProvider extends ContentProvider { // The calling package is already verified. PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId); + if (packageInfo.applicationInfo == null) { + return; + } // Privileged apps can do whatever they want. if ((packageInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { @@ -1893,6 +1896,10 @@ public class SettingsProvider extends ContentProvider { // The calling package is already verified. PackageInfo packageInfo = getCallingPackageInfoOrThrow(userId); + if (packageInfo.applicationInfo == null) { + return; + } + // Privileged apps can do whatever they want. if ((packageInfo.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) { @@ -2577,6 +2584,9 @@ public class SettingsProvider extends ContentProvider { final String ssaid = HexEncoding.encodeToString(m.doFinal(), false /* upperCase */) .substring(0, 16); + if (callingPkg.applicationInfo == null) { + throw new IllegalStateException("Application info not accessible"); + } // Save the ssaid in the ssaid table. final String uid = Integer.toString(callingPkg.applicationInfo.uid); final SettingsState ssaidSettings = getSettingsLocked(SETTINGS_TYPE_SSAID, userId); @@ -2604,6 +2614,9 @@ public class SettingsProvider extends ContentProvider { } final Set appUids = new HashSet<>(); for (PackageInfo info : packages) { + if (info == null || info.applicationInfo == null) { + continue; + } appUids.add(Integer.toString(info.applicationInfo.uid)); } @@ -3804,6 +3817,9 @@ public class SettingsProvider extends ContentProvider { final SettingsState ssaidSettings = getSsaidSettingsLocked(userId); for (PackageInfo info : packages) { + if (info == null || info.applicationInfo == null) { + continue; + } // Check if the UID already has an entry in the table. final String uid = Integer.toString(info.applicationInfo.uid); final Setting ssaid = ssaidSettings.getSettingLocked(uid); From 7a153718b48147c552b19872e8a31451243eb8c0 Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Wed, 5 May 2021 20:46:25 +0000 Subject: [PATCH 052/176] Revert "Migrate the usage of sCompatibilityModeEnabled" This reverts commit 0a98d27b04f225d5b87efa206ef289ba08ee5ad9. Reason for revert: b/187301322 Change-Id: Iae9acc88841f214a5e3a14f83c3d5ee8b9ffd422 Bug: 187301322 (cherry picked from commit a02ce471bea5f0715108ee34372c0772f00eeb48) --- .../pm/parsing/ParsingPackageUtils.java | 7 ----- .../server/pm/PackageManagerService.java | 28 +++++-------------- .../server/pm/parsing/PackageInfoUtils.java | 2 +- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 7cc59524c93d4..3b972a4fbb118 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -3067,13 +3067,6 @@ public class ParsingPackageUtils { } } - /** - * @hide - */ - public static void setCompatibilityModeEnabled(boolean compatibilityModeEnabled) { - sCompatibilityModeEnabled = compatibilityModeEnabled; - } - /** * @hide */ diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 47046bd71e2ae..ca8af4199a214 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -134,7 +134,6 @@ import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTi import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive; import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures; -import static com.android.server.pm.parsing.PackageInfoUtils.checkUseInstalledOrHidden; import android.Manifest; import android.annotation.AppIdInt; @@ -2517,8 +2516,8 @@ public class PackageManagerService extends IPackageManager.Stub if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName()); - PackageSetting ps = a == null ? null : mSettings.getPackageLPr(a.getPackageName()); if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) { + PackageSetting ps = mSettings.getPackageLPr(component.getPackageName()); if (ps == null) return null; if (shouldFilterApplicationLocked( ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) { @@ -2528,8 +2527,8 @@ public class PackageManagerService extends IPackageManager.Stub a, flags, ps.readUserState(userId), userId, ps); } if (resolveComponentName().equals(component)) { - return generateDelegateActivityInfo(pkg, ps, new PackageUserState(), - mResolveActivity, flags, userId); + return PackageParser.generateActivityInfo( + mResolveActivity, flags, new PackageUserState(), userId); } return null; } @@ -3175,8 +3174,8 @@ public class PackageManagerService extends IPackageManager.Stub return result; } final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo); - ephemeralInstaller.activityInfo = generateDelegateActivityInfo(ps.getPkg(), ps, - ps.readUserState(userId), instantAppInstallerActivity(), 0 /*flags*/, userId); + ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo( + instantAppInstallerActivity(), 0, ps.readUserState(userId), userId); ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART | IntentFilter.MATCH_ADJUSTMENT_NORMAL; // add a non-generic filter @@ -3260,7 +3259,7 @@ public class PackageManagerService extends IPackageManager.Stub ai.flags = ps.pkgFlags; ai.privateFlags = ps.pkgPrivateFlags; pi.applicationInfo = - PackageInfoUtils.generateApplicationInfo(p, flags, state, userId, ps); + PackageParser.generateApplicationInfo(ai, flags, state, userId); if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for [" + ps.name + "]. Provides a minimum info."); @@ -3376,19 +3375,6 @@ public class PackageManagerService extends IPackageManager.Stub return getInstalledPackagesBody(flags, userId, callingUid); } - private static ActivityInfo generateDelegateActivityInfo(@Nullable AndroidPackage pkg, - @Nullable PackageSetting ps, @NonNull PackageUserState state, - @Nullable ActivityInfo activity, int flags, int userId) { - if (activity == null || pkg == null - || !checkUseInstalledOrHidden(pkg, ps, state, flags)) { - return null; - } - final ActivityInfo info = new ActivityInfo(activity); - info.applicationInfo = - PackageInfoUtils.generateApplicationInfo(pkg, flags, state, userId, ps); - return info; - } - public ParceledListSlice getInstalledPackagesBody(int flags, int userId, int callingUid) { // writer @@ -23652,7 +23638,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( mContext.getContentResolver(), android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; - ParsingPackageUtils.setCompatibilityModeEnabled(compatibilityModeEnabled); + PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); if (DEBUG_SETTINGS) { Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index b89dbdc863e0c..61f51e36202cf 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -417,7 +417,7 @@ public class PackageInfoUtils { * Returns true if the package is installed and not hidden, or if the caller * explicitly wanted all uninstalled and hidden packages as well. */ - public static boolean checkUseInstalledOrHidden(AndroidPackage pkg, + private static boolean checkUseInstalledOrHidden(AndroidPackage pkg, PackageSetting pkgSetting, PackageUserState state, @PackageManager.PackageInfoFlags int flags) { // Returns false if the package is hidden system app until installed. From 0c85b16003198451369b2dc9ae2798ddf2c411ea Mon Sep 17 00:00:00 2001 From: Todd Kennedy Date: Wed, 5 May 2021 20:46:25 +0000 Subject: [PATCH 053/176] Revert "Migrate the usage of sCompatibilityModeEnabled" This reverts commit 0a98d27b04f225d5b87efa206ef289ba08ee5ad9. Reason for revert: b/187301322 Change-Id: Iae9acc88841f214a5e3a14f83c3d5ee8b9ffd422 Bug: 187301322 (cherry picked from commit a02ce471bea5f0715108ee34372c0772f00eeb48) --- .../pm/parsing/ParsingPackageUtils.java | 7 ----- .../server/pm/PackageManagerService.java | 28 +++++-------------- .../server/pm/parsing/PackageInfoUtils.java | 2 +- 3 files changed, 8 insertions(+), 29 deletions(-) diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 7cc59524c93d4..3b972a4fbb118 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -3067,13 +3067,6 @@ public class ParsingPackageUtils { } } - /** - * @hide - */ - public static void setCompatibilityModeEnabled(boolean compatibilityModeEnabled) { - sCompatibilityModeEnabled = compatibilityModeEnabled; - } - /** * @hide */ diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 47046bd71e2ae..ca8af4199a214 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -134,7 +134,6 @@ import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTi import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive; import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures; -import static com.android.server.pm.parsing.PackageInfoUtils.checkUseInstalledOrHidden; import android.Manifest; import android.annotation.AppIdInt; @@ -2517,8 +2516,8 @@ public class PackageManagerService extends IPackageManager.Stub if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a); AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName()); - PackageSetting ps = a == null ? null : mSettings.getPackageLPr(a.getPackageName()); if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) { + PackageSetting ps = mSettings.getPackageLPr(component.getPackageName()); if (ps == null) return null; if (shouldFilterApplicationLocked( ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) { @@ -2528,8 +2527,8 @@ public class PackageManagerService extends IPackageManager.Stub a, flags, ps.readUserState(userId), userId, ps); } if (resolveComponentName().equals(component)) { - return generateDelegateActivityInfo(pkg, ps, new PackageUserState(), - mResolveActivity, flags, userId); + return PackageParser.generateActivityInfo( + mResolveActivity, flags, new PackageUserState(), userId); } return null; } @@ -3175,8 +3174,8 @@ public class PackageManagerService extends IPackageManager.Stub return result; } final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo); - ephemeralInstaller.activityInfo = generateDelegateActivityInfo(ps.getPkg(), ps, - ps.readUserState(userId), instantAppInstallerActivity(), 0 /*flags*/, userId); + ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo( + instantAppInstallerActivity(), 0, ps.readUserState(userId), userId); ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART | IntentFilter.MATCH_ADJUSTMENT_NORMAL; // add a non-generic filter @@ -3260,7 +3259,7 @@ public class PackageManagerService extends IPackageManager.Stub ai.flags = ps.pkgFlags; ai.privateFlags = ps.pkgPrivateFlags; pi.applicationInfo = - PackageInfoUtils.generateApplicationInfo(p, flags, state, userId, ps); + PackageParser.generateApplicationInfo(ai, flags, state, userId); if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for [" + ps.name + "]. Provides a minimum info."); @@ -3376,19 +3375,6 @@ public class PackageManagerService extends IPackageManager.Stub return getInstalledPackagesBody(flags, userId, callingUid); } - private static ActivityInfo generateDelegateActivityInfo(@Nullable AndroidPackage pkg, - @Nullable PackageSetting ps, @NonNull PackageUserState state, - @Nullable ActivityInfo activity, int flags, int userId) { - if (activity == null || pkg == null - || !checkUseInstalledOrHidden(pkg, ps, state, flags)) { - return null; - } - final ActivityInfo info = new ActivityInfo(activity); - info.applicationInfo = - PackageInfoUtils.generateApplicationInfo(pkg, flags, state, userId, ps); - return info; - } - public ParceledListSlice getInstalledPackagesBody(int flags, int userId, int callingUid) { // writer @@ -23652,7 +23638,7 @@ public class PackageManagerService extends IPackageManager.Stub boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt( mContext.getContentResolver(), android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1; - ParsingPackageUtils.setCompatibilityModeEnabled(compatibilityModeEnabled); + PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled); if (DEBUG_SETTINGS) { Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled); diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java index b89dbdc863e0c..61f51e36202cf 100644 --- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java +++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java @@ -417,7 +417,7 @@ public class PackageInfoUtils { * Returns true if the package is installed and not hidden, or if the caller * explicitly wanted all uninstalled and hidden packages as well. */ - public static boolean checkUseInstalledOrHidden(AndroidPackage pkg, + private static boolean checkUseInstalledOrHidden(AndroidPackage pkg, PackageSetting pkgSetting, PackageUserState state, @PackageManager.PackageInfoFlags int flags) { // Returns false if the package is hidden system app until installed. From 5ff6dc00ae0f6e26d5190ad85fb9c26af6fdab5c Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Thu, 6 May 2021 17:48:29 +0000 Subject: [PATCH 054/176] Revert "Don't defer FGS notification if it's already shown" Revert "Verify behavior when FGS uses existing notification" Revert submission 14414063-fgs-defer-fixes Reason for revert: b/187373264 Reverted Changes: I081a3cc88:Don't defer FGS notification if it's already shown... I083583550:Verify behavior when FGS uses existing notificatio... Bug: 187373264 Change-Id: I82edba69c583791ec603107b3407ce7a5efe83a0 (cherry picked from commit 94badc521453fa4be8c906fd94cea812889f0a58) --- .../java/com/android/server/am/ActiveServices.java | 12 ------------ .../notification/NotificationManagerInternal.java | 3 --- .../notification/NotificationManagerService.java | 7 ------- 3 files changed, 22 deletions(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index b261231794110..5700bb367b041 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -155,7 +155,6 @@ import com.android.server.AppStateTracker; import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.am.ActivityManagerService.ItemMatcher; -import com.android.server.notification.NotificationManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.wm.ActivityServiceConnectionsHolder; @@ -1977,17 +1976,6 @@ public final class ActiveServices { // DeviceConfig element has been set showNow = isLegacyApp && mAm.mConstants.mFlagFgsNotificationDeferralApiGated; } - if (!showNow) { - // did we already show it? - showNow = r.mFgsNotificationShown; - } - if (!showNow) { - // Is the notification already showing for any reason? - final NotificationManagerInternal nmi = - LocalServices.getService(NotificationManagerInternal.class); - showNow = nmi.isNotificationShown(r.appInfo.packageName, null, - r.foregroundId, UserHandle.getUserId(uid)); - } if (!showNow) { // has the app forced deferral? if (!r.foregroundNoti.isForegroundDisplayForceDeferred()) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java index 0528b95d1a6e6..dc9839c6da0ef 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java +++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java @@ -30,9 +30,6 @@ public interface NotificationManagerInternal { void cancelNotification(String pkg, String basePkg, int callingUid, int callingPid, String tag, int id, int userId); - /** is the given notification currently showing? */ - boolean isNotificationShown(String pkg, String tag, int notificationId, int userId); - void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId); void onConversationRemoved(String pkg, int uid, Set shortcuts); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index f382c787ed47c..40b9929e214a1 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6049,13 +6049,6 @@ public class NotificationManagerService extends SystemService { cancelNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, userId); } - @Override - public boolean isNotificationShown(String pkg, String tag, int notificationId, int userId) { - synchronized (mNotificationLock) { - return findNotificationLocked(pkg, tag, notificationId, userId) != null; - } - } - @Override public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, int userId) { From 82672f737119871d13df1242cd37a5aa276f3b1a Mon Sep 17 00:00:00 2001 From: Aurimas Liutikas Date: Wed, 12 May 2021 21:56:31 +0000 Subject: [PATCH 055/176] Revert "Fix incompatibilities with Kotlin 1.5.0" This reverts commit b8ca1157ab6d463a19f6a7bbfeb25d1f9f1be911. Reason for revert: b/187908823 Change-Id: I9606c5730f4e8697a9319939acda0a9b7a74634d (cherry picked from commit c5b4071877530ba3eb6ce5f55fc8c101ea1f35e4) --- .../android/systemui/controls/ui/ControlsUiControllerImpl.kt | 2 +- .../src/com/android/systemui/privacy/PrivacyChipBuilder.kt | 2 +- tools/codegen/src/com/android/codegen/Utils.kt | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt index a904cefc48a06..26be98743eed9 100644 --- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt @@ -120,7 +120,7 @@ class ControlsUiControllerImpl @Inject constructor ( private val onSeedingComplete = Consumer { accepted -> if (accepted) { - selectedStructure = controlsController.get().getFavorites().maxByOrNull { + selectedStructure = controlsController.get().getFavorites().maxBy { it.controls.size } ?: EMPTY_STRUCTURE updatePreferences(selectedStructure) diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt index eec69f98b9be7..1d2e74703b42b 100644 --- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt @@ -28,7 +28,7 @@ class PrivacyChipBuilder(private val context: Context, itemsList: List Unit) { * cccc dd */ fun Iterable>.columnize(separator: String = " | "): String { - val col1w = map { (a, _) -> a.length }.maxOrNull()!! - val col2w = map { (_, b) -> b.length }.maxOrNull()!! + val col1w = map { (a, _) -> a.length }.max()!! + val col2w = map { (_, b) -> b.length }.max()!! return map { it.first.padEnd(col1w) + separator + it.second.padEnd(col2w) }.joinToString("\n") } From 3b294863e663bda599b833b66580d81bc537c9c5 Mon Sep 17 00:00:00 2001 From: Silin Huang Date: Thu, 20 May 2021 15:59:05 -0700 Subject: [PATCH 056/176] Recreate QuickAccessWallet for Wallet Tile and Lockscreen Icon when the default payment app has changed. Also to avoid a wallet client that doesn't have ServiceInfo is living too long, don't make it final and re-create the wallet client if it has a null service info. Fix: 187972400 Test: manual, see demo- the default payment app is GPay, check Tile and Lockscreen Icon, then change the default payment app and check again. https://drive.google.com/file/d/10-I339VPuxJRGXJT-XmwmnZs4MHaH3gm/view?usp=sharing&resourcekey=0-wDtRXNNr_Tg9ptxk1Tpxsw Change-Id: Ie9a05795bff447424b299132fa60ae2efb2092be (cherry picked from commit e3474a76cdfcddd1c2e04425fc368c2441e874a6) --- .../qs/tiles/QuickAccessWalletTile.java | 66 +++++++++++++++++-- .../phone/KeyguardBottomAreaView.java | 35 ++++++++-- .../NotificationPanelViewController.java | 6 +- .../systemui/wallet/ui/WalletActivity.java | 16 +++-- .../qs/tiles/QuickAccessWalletTileTest.java | 12 +++- .../phone/NotificationPanelViewTest.java | 4 -- 6 files changed, 112 insertions(+), 27 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java index e467925551013..611f0e366859f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/QuickAccessWalletTile.java @@ -20,9 +20,11 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT; import android.content.Intent; import android.content.pm.PackageManager; +import android.database.ContentObserver; import android.graphics.drawable.Drawable; import android.os.Handler; import android.os.Looper; +import android.provider.Settings; import android.service.quickaccesswallet.GetWalletCardsError; import android.service.quickaccesswallet.GetWalletCardsRequest; import android.service.quickaccesswallet.GetWalletCardsResponse; @@ -66,16 +68,16 @@ public class QuickAccessWalletTile extends QSTileImpl { private final CharSequence mLabel = mContext.getString(R.string.wallet_title); private final WalletCardRetriever mCardRetriever = new WalletCardRetriever(); - // TODO(b/180959290): Re-create the QAW Client when the default NFC payment app changes. - private final QuickAccessWalletClient mQuickAccessWalletClient; private final KeyguardStateController mKeyguardStateController; private final PackageManager mPackageManager; private final SecureSettings mSecureSettings; private final Executor mExecutor; private final FeatureFlags mFeatureFlags; - @VisibleForTesting Drawable mCardViewDrawable; + private QuickAccessWalletClient mQuickAccessWalletClient; + private ContentObserver mDefaultPaymentAppObserver; private WalletCard mSelectedCard; + @VisibleForTesting Drawable mCardViewDrawable; @Inject public QuickAccessWalletTile( @@ -87,15 +89,14 @@ public class QuickAccessWalletTile extends QSTileImpl { StatusBarStateController statusBarStateController, ActivityStarter activityStarter, QSLogger qsLogger, - QuickAccessWalletClient quickAccessWalletClient, KeyguardStateController keyguardStateController, PackageManager packageManager, SecureSettings secureSettings, - @Background Executor executor, + @Main Executor executor, FeatureFlags featureFlags) { super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger, statusBarStateController, activityStarter, qsLogger); - mQuickAccessWalletClient = quickAccessWalletClient; + mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext); mKeyguardStateController = keyguardStateController; mPackageManager = packageManager; mSecureSettings = secureSettings; @@ -115,6 +116,12 @@ public class QuickAccessWalletTile extends QSTileImpl { protected void handleSetListening(boolean listening) { super.handleSetListening(listening); if (listening) { + setupDefaultPaymentAppObserver(); + // Re-create wallet client to avoid a client that doesn't have service info is living + // too long. + if (!mQuickAccessWalletClient.isWalletServiceAvailable()) { + reCreateWalletClient(); + } queryWalletCards(); } } @@ -174,6 +181,7 @@ public class QuickAccessWalletTile extends QSTileImpl { state.stateDescription = state.secondaryLabel; } else { state.state = Tile.STATE_UNAVAILABLE; + state.secondaryLabel = null; } state.sideViewCustomDrawable = isDeviceLocked ? null : mCardViewDrawable; } @@ -202,7 +210,30 @@ public class QuickAccessWalletTile extends QSTileImpl { return label == null ? mLabel : label; } + @Override + protected void handleDestroy() { + super.handleDestroy(); + if (mDefaultPaymentAppObserver != null) { + mSecureSettings.unregisterContentObserver(mDefaultPaymentAppObserver); + } + mQuickAccessWalletClient = null; + } + + @VisibleForTesting + void overrideQuickAccessWalletClientForTest(QuickAccessWalletClient quickAccessWalletClient) { + mQuickAccessWalletClient = quickAccessWalletClient; + } + + @VisibleForTesting + QuickAccessWalletClient getQuickAccessWalletClient() { + return mQuickAccessWalletClient; + } + private void queryWalletCards() { + if (!mQuickAccessWalletClient.isWalletFeatureAvailable()) { + Log.w(TAG, "QAW feature not unavailable, unable to query wallet cards,"); + return; + } int cardWidth = mContext.getResources().getDimensionPixelSize(R.dimen.wallet_tile_card_view_width); int cardHeight = @@ -213,6 +244,29 @@ public class QuickAccessWalletTile extends QSTileImpl { mQuickAccessWalletClient.getWalletCards(mExecutor, request, mCardRetriever); } + private void reCreateWalletClient() { + mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext); + } + + private void setupDefaultPaymentAppObserver() { + if (mDefaultPaymentAppObserver == null) { + mDefaultPaymentAppObserver = new ContentObserver(null /* handler */) { + @Override + public void onChange(boolean selfChange) { + mExecutor.execute(() -> { + reCreateWalletClient(); + queryWalletCards(); + }); + } + }; + + mSecureSettings.registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT), + false /* notifyForDescendants */, + mDefaultPaymentAppObserver); + } + } + private class WalletCardRetriever implements QuickAccessWalletClient.OnWalletCardsRetrievedCallback { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 7f919b5f5cf5e..04be581e0ccfa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -194,6 +194,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL private ActivityIntentHelper mActivityIntentHelper; private KeyguardUpdateMonitor mKeyguardUpdateMonitor; private ContentObserver mWalletPreferenceObserver; + private ContentObserver mDefaultPaymentAppObserver; private SecureSettings mSecureSettings; public KeyguardBottomAreaView(Context context) { @@ -335,6 +336,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL if (mWalletPreferenceObserver != null) { mSecureSettings.unregisterContentObserver(mWalletPreferenceObserver); } + if (mDefaultPaymentAppObserver != null) { + mSecureSettings.unregisterContentObserver(mDefaultPaymentAppObserver); + } } private void initAccessibility() { @@ -935,9 +939,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL /** * Initialize the wallet feature, only enabling if the feature is enabled within the platform. */ - public void initWallet(QuickAccessWalletClient client, Executor uiExecutor, - SecureSettings secureSettings) { - mQuickAccessWalletClient = client; + public void initWallet(Executor uiExecutor, SecureSettings secureSettings) { + mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext); mSecureSettings = secureSettings; setupWalletPreferenceObserver(); updateWalletPreference(); @@ -953,7 +956,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL mWalletPreferenceObserver = new ContentObserver(null /* handler */) { @Override public void onChange(boolean selfChange) { - mUiExecutor.execute(() -> updateWalletPreference()); + mUiExecutor.execute(() -> { + updateWalletPreference(); + }); } }; @@ -962,10 +967,30 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL false /* notifyForDescendants */, mWalletPreferenceObserver); } + + if (mDefaultPaymentAppObserver == null) { + mDefaultPaymentAppObserver = new ContentObserver(null /* handler */) { + @Override + public void onChange(boolean selfChange) { + mUiExecutor.execute(() -> { + mQuickAccessWalletClient = QuickAccessWalletClient.create(mContext); + updateWalletPreference(); + queryWalletCards(); + updateWalletVisibility(); + }); + } + }; + + mSecureSettings.registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT), + false /* notifyForDescendants */, + mDefaultPaymentAppObserver); + } } private void updateWalletPreference() { - mWalletEnabled = mQuickAccessWalletClient.isWalletFeatureAvailable() + mWalletEnabled = mQuickAccessWalletClient.isWalletServiceAvailable() + && mQuickAccessWalletClient.isWalletFeatureAvailable() && mQuickAccessWalletClient.isWalletFeatureAvailableWhenDeviceLocked(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index 9d8a9bfafe49c..0e0e14538fb55 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -54,7 +54,6 @@ import android.os.PowerManager; import android.os.SystemClock; import android.os.UserManager; import android.os.VibrationEffect; -import android.service.quickaccesswallet.QuickAccessWalletClient; import android.util.Log; import android.util.MathUtils; import android.view.DisplayCutout; @@ -573,7 +572,6 @@ public class NotificationPanelViewController extends PanelViewController { private int mScreenCornerRadius; private int mNotificationScrimPadding; - private final QuickAccessWalletClient mQuickAccessWalletClient; private final Executor mUiExecutor; private final SecureSettings mSecureSettings; @@ -649,7 +647,6 @@ public class NotificationPanelViewController extends PanelViewController { AmbientState ambientState, LockIconViewController lockIconViewController, FeatureFlags featureFlags, - QuickAccessWalletClient quickAccessWalletClient, KeyguardMediaController keyguardMediaController, PrivacyDotViewController privacyDotViewController, @Main Executor uiExecutor, @@ -703,7 +700,6 @@ public class NotificationPanelViewController extends PanelViewController { mScrimController.setClipsQsScrim(!mShouldUseSplitNotificationShade); mUserManager = userManager; mMediaDataManager = mediaDataManager; - mQuickAccessWalletClient = quickAccessWalletClient; mUiExecutor = uiExecutor; mSecureSettings = secureSettings; pulseExpansionHandler.setPulseExpandAbortListener(() -> { @@ -1098,7 +1094,7 @@ public class NotificationPanelViewController extends PanelViewController { mKeyguardBottomArea.setFalsingManager(mFalsingManager); if (mFeatureFlags.isQuickAccessWalletEnabled()) { - mKeyguardBottomArea.initWallet(mQuickAccessWalletClient, mUiExecutor, mSecureSettings); + mKeyguardBottomArea.initWallet(mUiExecutor, mSecureSettings); } } diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java index 83aa01f8d3931..c6123e77076d7 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletActivity.java @@ -24,6 +24,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.service.quickaccesswallet.QuickAccessWalletClient; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.Window; @@ -52,7 +53,7 @@ import javax.inject.Inject; */ public class WalletActivity extends LifecycleActivity { - private final QuickAccessWalletClient mQuickAccessWalletClient; + private static final String TAG = "WalletActivity"; private final KeyguardStateController mKeyguardStateController; private final KeyguardDismissUtil mKeyguardDismissUtil; private final ActivityStarter mActivityStarter; @@ -65,7 +66,6 @@ public class WalletActivity extends LifecycleActivity { @Inject public WalletActivity( - QuickAccessWalletClient quickAccessWalletClient, KeyguardStateController keyguardStateController, KeyguardDismissUtil keyguardDismissUtil, ActivityStarter activityStarter, @@ -74,7 +74,6 @@ public class WalletActivity extends LifecycleActivity { FalsingManager falsingManager, UserTracker userTracker, StatusBarKeyguardViewManager keyguardViewManager) { - mQuickAccessWalletClient = quickAccessWalletClient; mKeyguardStateController = keyguardStateController; mKeyguardDismissUtil = keyguardDismissUtil; mActivityStarter = activityStarter; @@ -103,10 +102,11 @@ public class WalletActivity extends LifecycleActivity { getActionBar().setHomeActionContentDescription(R.string.accessibility_desc_close); WalletView walletView = requireViewById(R.id.wallet_view); + QuickAccessWalletClient walletClient = QuickAccessWalletClient.create(this); mWalletScreenController = new WalletScreenController( this, walletView, - mQuickAccessWalletClient, + walletClient, mActivityStarter, mExecutor, mHandler, @@ -116,6 +116,10 @@ public class WalletActivity extends LifecycleActivity { walletView.getAppButton().setOnClickListener( v -> { + if (walletClient.createWalletIntent() == null) { + Log.w(TAG, "Unable to create wallet app intent."); + return; + } if (!mKeyguardStateController.isUnlocked() && mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) { return; @@ -123,12 +127,12 @@ public class WalletActivity extends LifecycleActivity { if (mKeyguardStateController.isUnlocked()) { mActivityStarter.startActivity( - mQuickAccessWalletClient.createWalletIntent(), true); + walletClient.createWalletIntent(), true); finish(); } else { mKeyguardDismissUtil.executeWhenUnlocked(() -> { mActivityStarter.startActivity( - mQuickAccessWalletClient.createWalletIntent(), true); + walletClient.createWalletIntent(), true); finish(); return false; }, false, true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java index 7533cf1310de9..fdd880d0846fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/QuickAccessWalletTileTest.java @@ -21,6 +21,7 @@ import static android.provider.Settings.Secure.NFC_PAYMENT_DEFAULT_COMPONENT; import static com.google.common.truth.Truth.assertThat; +import static junit.framework.Assert.assertNotSame; import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertNotNull; @@ -155,12 +156,12 @@ public class QuickAccessWalletTileTest extends SysuiTestCase { mStatusBarStateController, mActivityStarter, mQSLogger, - mQuickAccessWalletClient, mKeyguardStateController, mPackageManager, mSecureSettings, MoreExecutors.directExecutor(), mFeatureFlags); + mTile.overrideQuickAccessWalletClientForTest(mQuickAccessWalletClient); } @Test @@ -174,6 +175,15 @@ public class QuickAccessWalletTileTest extends SysuiTestCase { assertFalse(mTile.isAvailable()); } + @Test + public void testWalletServiceUnavailable_recreateWalletClient() { + when(mQuickAccessWalletClient.isWalletServiceAvailable()).thenReturn(false); + + mTile.handleSetListening(true); + + assertNotSame(mQuickAccessWalletClient, mTile.getQuickAccessWalletClient()); + } + @Test public void testIsAvailable_qawFeatureAvailable() { when(mPackageManager.hasSystemFeature(FEATURE_NFC_HOST_CARD_EMULATION)).thenReturn(true); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java index 6b4797fc57235..4fc3bfea90ec8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java @@ -39,7 +39,6 @@ import android.content.res.Resources; import android.hardware.biometrics.BiometricSourceType; import android.os.PowerManager; import android.os.UserManager; -import android.service.quickaccesswallet.QuickAccessWalletClient; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.util.DisplayMetrics; @@ -245,8 +244,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { @Mock private LockIconViewController mLockIconViewController; @Mock - private QuickAccessWalletClient mQuickAccessWalletClient; - @Mock private KeyguardMediaController mKeyguardMediaController; @Mock private PrivacyDotViewController mPrivacyDotViewController; @@ -361,7 +358,6 @@ public class NotificationPanelViewTest extends SysuiTestCase { mAmbientState, mLockIconViewController, mFeatureFlags, - mQuickAccessWalletClient, mKeyguardMediaController, mPrivacyDotViewController, new FakeExecutor(new FakeSystemClock()), From e5ab1b8d8770eb3db39cd590de91980389824af5 Mon Sep 17 00:00:00 2001 From: Li Li Date: Wed, 26 May 2021 21:11:44 -0700 Subject: [PATCH 057/176] Fix process group of webview zygote New processes forked from webview zygote should have their own process group. Otherwise, some operations applied to any children will wrongly impact all other children, like freezing or kill. Bug: 62435375 Bug: 168907513 Bug: 189211698 Test: Verified webview children have their own cgroupfs node. Also, freezing any children won't impact other children and webview zygote itself. Change-Id: I0606a8c8360fbb9e0851e2f799c6aaee521937ca (cherry picked from commit da9ad351295b69485663594fcd23faf74fc5c663) --- .../java/com/android/server/am/ProcessList.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 457fe0f88aa7c..9098e68392fd3 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2377,6 +2377,7 @@ public final class ProcessList { } final Process.ProcessStartResult startResult; + boolean regularZygote = false; if (hostingRecord.usesWebviewZygote()) { startResult = startWebView(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, @@ -2396,12 +2397,8 @@ public final class ProcessList { app.getDisabledCompatChanges(), pkgDataInfoMap, allowlistedAppDataInfoMap, false, false, new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); - - if (Process.createProcessGroup(uid, startResult.pid) < 0) { - Slog.e(ActivityManagerService.TAG, "Unable to create process group for " - + app.processName + " (" + startResult.pid + ")"); - } } else { + regularZygote = true; startResult = Process.start(entryPoint, app.processName, uid, uid, gids, runtimeFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, @@ -2410,6 +2407,15 @@ public final class ProcessList { allowlistedAppDataInfoMap, bindMountAppsData, bindMountAppStorageDirs, new String[]{PROC_START_SEQ_IDENT + app.getStartSeq()}); } + + if (!regularZygote) { + // webview and app zygote don't have the permission to create the nodes + if (Process.createProcessGroup(uid, startResult.pid) < 0) { + Slog.e(ActivityManagerService.TAG, "Unable to create process group for " + + app.processName + " (" + startResult.pid + ")"); + } + } + // This runs after Process.start() as this method may block app process starting time // if dir is not cached. Running this method after Process.start() can make it // cache the dir asynchronously, so zygote can use it without waiting for it. From 42999ba415531b63dfa7b0607e9264a35c94b86a Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 1 Jun 2021 15:12:15 -0400 Subject: [PATCH 058/176] Don't destroy the FalsingManager in Wallet. When FalsingManager#cleanupInternal is called, it no longer produces valid results. With this change, we check that the FalsingManager is not used after being destroyed, and also avoid destroying it in WalletScreenController. Fixes: 188174214 Test: manual Change-Id: I0ce67de5a326b56dee11c1d63c1d592640c0713d (cherry picked from commit dbdeb8da5ab0dad02f25edfe313e59d506e718f3) --- .../systemui/plugins/FalsingManager.java | 11 ++++++-- .../classifier/BrightLineFalsingManager.java | 19 +++++++++++++- .../classifier/FalsingManagerProxy.java | 8 +++--- .../wallet/ui/WalletScreenController.java | 1 - .../classifier/BrightLineClassifierTest.java | 2 +- .../classifier/FalsingManagerFake.java | 25 ++++++++++++++----- 6 files changed, 51 insertions(+), 15 deletions(-) rename packages/SystemUI/{ => tests}/src/com/android/systemui/classifier/FalsingManagerFake.java (85%) diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java index 5ac8961aceebc..b4fac5cbb6ab4 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java @@ -114,7 +114,12 @@ public interface FalsingManager { /** From com.android.systemui.Dumpable. */ void dump(FileDescriptor fd, PrintWriter pw, String[] args); - void cleanup(); + /** + * Don't call this. It's meant for internal use to allow switching between implementations. + * + * Tests may also call it. + **/ + void cleanupInternal(); /** Call to report a ProximityEvent to the FalsingManager. */ void onProximityEvent(ProximityEvent proximityEvent); @@ -136,7 +141,9 @@ public interface FalsingManager { void onFalse(); } - /** Listener that is alerted when a double tap is required to confirm a single tap. */ + /** + * Listener that is alerted when a double tap is required to confirm a single tap. + **/ interface FalsingTapListener { void onDoubleTapRequired(); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index c821d100f5534..020401ecd2f82 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -82,6 +82,8 @@ public class BrightLineFalsingManager implements FalsingManager { private final List mFalsingBeliefListeners = new ArrayList<>(); private List mFalsingTapListeners = new ArrayList<>(); + private boolean mDestroyed; + private final SessionListener mSessionListener = new SessionListener() { @Override public void onSessionEnded() { @@ -196,6 +198,8 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + checkDestroyed(); + mPriorInteractionType = interactionType; if (skipFalsing(interactionType)) { mPriorResults = getPassedResult(1); @@ -221,6 +225,8 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isSimpleTap() { + checkDestroyed(); + FalsingClassifier.Result result = mSingleTapClassifier.isTap( mDataProvider.getRecentMotionEvents(), 0); mPriorResults = Collections.singleton(result); @@ -228,8 +234,16 @@ public class BrightLineFalsingManager implements FalsingManager { return !result.isFalse(); } + private void checkDestroyed() { + if (mDestroyed) { + Log.wtf(TAG, "Tried to use FalsingManager after being destroyed!"); + } + } + @Override public boolean isFalseTap(@Penalty int penalty) { + checkDestroyed(); + if (skipFalsing(GENERIC)) { mPriorResults = getPassedResult(1); logDebug("Skipped falsing"); @@ -292,6 +306,8 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseDoubleTap() { + checkDestroyed(); + if (skipFalsing(GENERIC)) { mPriorResults = getPassedResult(1); logDebug("Skipped falsing"); @@ -406,7 +422,8 @@ public class BrightLineFalsingManager implements FalsingManager { } @Override - public void cleanup() { + public void cleanupInternal() { + mDestroyed = true; mDataProvider.removeSessionListener(mSessionListener); mDataProvider.removeGestureCompleteListener(mGestureFinalizedListener); mClassifiers.forEach(FalsingClassifier::cleanup); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index ee0dba0a50873..5a24f354eaf65 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -79,7 +79,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { public void onPluginConnected(FalsingPlugin plugin, Context context) { FalsingManager pluginFalsingManager = plugin.getFalsingManager(context); if (pluginFalsingManager != null) { - mInternalFalsingManager.cleanup(); + mInternalFalsingManager.cleanupInternal(); mInternalFalsingManager = pluginFalsingManager; } } @@ -109,7 +109,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { */ private void setupFalsingManager() { if (mInternalFalsingManager != null) { - mInternalFalsingManager.cleanup(); + mInternalFalsingManager.cleanupInternal(); } mInternalFalsingManager = mBrightLineFalsingManagerProvider.get(); } @@ -195,10 +195,10 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { } @Override - public void cleanup() { + public void cleanupInternal() { mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener); mPluginManager.removePluginListener(mPluginListener); mDumpManager.unregisterDumpable(DUMPABLE_TAG); - mInternalFalsingManager.cleanup(); + mInternalFalsingManager.cleanupInternal(); } } diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java index d0662e7301d86..8da80caefdd37 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java @@ -260,7 +260,6 @@ public class WalletScreenController implements mIsDismissed = true; mSelectedCardId = null; mHandler.removeCallbacks(mSelectionRunnable); - mFalsingManager.cleanup(); mWalletClient.notifyWalletDismissed(); mWalletClient.removeWalletServiceEventListener(this); mWalletView.animateDismissal(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java index a7f9fe4e0a2c2..3eb1a9e624c8e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -118,7 +118,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { verify(mFalsingDataProvider).addSessionListener( any(FalsingDataProvider.SessionListener.class)); - mBrightLineFalsingManager.cleanup(); + mBrightLineFalsingManager.cleanupInternal(); verify(mFalsingDataProvider).removeSessionListener( any(FalsingDataProvider.SessionListener.class)); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java similarity index 85% rename from packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java rename to packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java index dba530edc27fc..87d1b6b8cb303 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package com.android.systemui.classifier; +import static com.google.common.truth.Truth.assertWithMessage; + import android.net.Uri; import com.android.internal.annotations.VisibleForTesting; @@ -34,10 +36,11 @@ public class FalsingManagerFake implements FalsingManager { private boolean mIsSimpleTap; private boolean mIsFalseDoubleTap; private boolean mIsUnlockingDisabled; - private boolean mIsClassiferEnabled; + private boolean mIsClassifierEnabled; private boolean mShouldEnforceBouncer; private boolean mIsReportingEnabled; private boolean mIsFalseRobustTap; + private boolean mDestroyed; private final List mFalsingBeliefListeners = new ArrayList<>(); private final List mTapListeners = new ArrayList<>(); @@ -64,6 +67,7 @@ public class FalsingManagerFake implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + checkDestroyed(); return mIsFalseTouch; } @@ -81,27 +85,30 @@ public class FalsingManagerFake implements FalsingManager { @Override public boolean isSimpleTap() { + checkDestroyed(); return mIsSimpleTap; } @Override public boolean isFalseTap(@Penalty int penalty) { + checkDestroyed(); return mIsFalseRobustTap; } @Override public boolean isFalseDoubleTap() { + checkDestroyed(); return mIsFalseDoubleTap; } @VisibleForTesting - public void setIsClassiferEnabled(boolean isClassiferEnabled) { - mIsClassiferEnabled = isClassiferEnabled; + public void setIsClassifierEnabled(boolean isClassifierEnabled) { + mIsClassifierEnabled = isClassifierEnabled; } @Override public boolean isClassifierEnabled() { - return mIsClassiferEnabled; + return mIsClassifierEnabled; } @Override @@ -129,7 +136,13 @@ public class FalsingManagerFake implements FalsingManager { } @Override - public void cleanup() { + public void cleanupInternal() { + mDestroyed = true; + } + + private void checkDestroyed() { + assertWithMessage("FakeFasingManager has been destroyed") + .that(mDestroyed).isFalse(); } @Override From 0a32d1c3e3bdf660ab25ab138551dfd33c7c5c4f Mon Sep 17 00:00:00 2001 From: Dave Mankoff Date: Tue, 1 Jun 2021 15:12:15 -0400 Subject: [PATCH 059/176] Don't destroy the FalsingManager in Wallet. When FalsingManager#cleanupInternal is called, it no longer produces valid results. With this change, we check that the FalsingManager is not used after being destroyed, and also avoid destroying it in WalletScreenController. Fixes: 188174214 Test: manual Change-Id: I0ce67de5a326b56dee11c1d63c1d592640c0713d (cherry picked from commit b4935a25caccfb4021c8546209b5db7219747792) --- packages/SystemUI/Android.bp | 14 +++++++++-- .../systemui/plugins/FalsingManager.java | 11 ++++++-- .../classifier/BrightLineFalsingManager.java | 19 +++++++++++++- .../classifier/FalsingManagerProxy.java | 8 +++--- .../wallet/ui/WalletScreenController.java | 1 - .../classifier/BrightLineClassifierTest.java | 2 +- .../classifier/FalsingManagerFake.java | 25 ++++++++++++++----- 7 files changed, 63 insertions(+), 17 deletions(-) rename packages/SystemUI/{ => tests}/src/com/android/systemui/classifier/FalsingManagerFake.java (85%) diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 4f587ebba89cd..b357a9478ab61 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -105,11 +105,21 @@ android_library { filegroup { name: "SystemUI-tests-utils", srcs: [ + "tests/src/com/android/systemui/SysuiTestCase.java", + "tests/src/com/android/systemui/TestableDependency.java", + "tests/src/com/android/systemui/classifier/FalsingManagerFake.java", "tests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilder.java", "tests/src/com/android/systemui/statusbar/RankingBuilder.java", "tests/src/com/android/systemui/statusbar/SbnBuilder.java", - "tests/src/com/android/systemui/util/concurrency/FakeExecutor.java", - "tests/src/com/android/systemui/util/time/FakeSystemClock.java", + "tests/src/com/android/systemui/SysuiTestableContext.java", + "tests/src/com/android/systemui/utils/leaks/BaseLeakChecker.java", + "tests/src/com/android/systemui/utils/leaks/LeakCheckedTest.java", + "tests/src/com/android/systemui/**/Fake*.java", + "tests/src/com/android/systemui/**/Fake*.kt", + ], + exclude_srcs: [ + "tests/src/com/android/systemui/**/*Test.java", + "tests/src/com/android/systemui/**/*Test.kt", ], path: "tests/src", } diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java index 5ac8961aceebc..b4fac5cbb6ab4 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java @@ -114,7 +114,12 @@ public interface FalsingManager { /** From com.android.systemui.Dumpable. */ void dump(FileDescriptor fd, PrintWriter pw, String[] args); - void cleanup(); + /** + * Don't call this. It's meant for internal use to allow switching between implementations. + * + * Tests may also call it. + **/ + void cleanupInternal(); /** Call to report a ProximityEvent to the FalsingManager. */ void onProximityEvent(ProximityEvent proximityEvent); @@ -136,7 +141,9 @@ public interface FalsingManager { void onFalse(); } - /** Listener that is alerted when a double tap is required to confirm a single tap. */ + /** + * Listener that is alerted when a double tap is required to confirm a single tap. + **/ interface FalsingTapListener { void onDoubleTapRequired(); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java index c821d100f5534..020401ecd2f82 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java @@ -82,6 +82,8 @@ public class BrightLineFalsingManager implements FalsingManager { private final List mFalsingBeliefListeners = new ArrayList<>(); private List mFalsingTapListeners = new ArrayList<>(); + private boolean mDestroyed; + private final SessionListener mSessionListener = new SessionListener() { @Override public void onSessionEnded() { @@ -196,6 +198,8 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + checkDestroyed(); + mPriorInteractionType = interactionType; if (skipFalsing(interactionType)) { mPriorResults = getPassedResult(1); @@ -221,6 +225,8 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isSimpleTap() { + checkDestroyed(); + FalsingClassifier.Result result = mSingleTapClassifier.isTap( mDataProvider.getRecentMotionEvents(), 0); mPriorResults = Collections.singleton(result); @@ -228,8 +234,16 @@ public class BrightLineFalsingManager implements FalsingManager { return !result.isFalse(); } + private void checkDestroyed() { + if (mDestroyed) { + Log.wtf(TAG, "Tried to use FalsingManager after being destroyed!"); + } + } + @Override public boolean isFalseTap(@Penalty int penalty) { + checkDestroyed(); + if (skipFalsing(GENERIC)) { mPriorResults = getPassedResult(1); logDebug("Skipped falsing"); @@ -292,6 +306,8 @@ public class BrightLineFalsingManager implements FalsingManager { @Override public boolean isFalseDoubleTap() { + checkDestroyed(); + if (skipFalsing(GENERIC)) { mPriorResults = getPassedResult(1); logDebug("Skipped falsing"); @@ -406,7 +422,8 @@ public class BrightLineFalsingManager implements FalsingManager { } @Override - public void cleanup() { + public void cleanupInternal() { + mDestroyed = true; mDataProvider.removeSessionListener(mSessionListener); mDataProvider.removeGestureCompleteListener(mGestureFinalizedListener); mClassifiers.forEach(FalsingClassifier::cleanup); diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java index ee0dba0a50873..5a24f354eaf65 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java @@ -79,7 +79,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { public void onPluginConnected(FalsingPlugin plugin, Context context) { FalsingManager pluginFalsingManager = plugin.getFalsingManager(context); if (pluginFalsingManager != null) { - mInternalFalsingManager.cleanup(); + mInternalFalsingManager.cleanupInternal(); mInternalFalsingManager = pluginFalsingManager; } } @@ -109,7 +109,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { */ private void setupFalsingManager() { if (mInternalFalsingManager != null) { - mInternalFalsingManager.cleanup(); + mInternalFalsingManager.cleanupInternal(); } mInternalFalsingManager = mBrightLineFalsingManagerProvider.get(); } @@ -195,10 +195,10 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable { } @Override - public void cleanup() { + public void cleanupInternal() { mDeviceConfig.removeOnPropertiesChangedListener(mDeviceConfigListener); mPluginManager.removePluginListener(mPluginListener); mDumpManager.unregisterDumpable(DUMPABLE_TAG); - mInternalFalsingManager.cleanup(); + mInternalFalsingManager.cleanupInternal(); } } diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java index d0662e7301d86..8da80caefdd37 100644 --- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java +++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java @@ -260,7 +260,6 @@ public class WalletScreenController implements mIsDismissed = true; mSelectedCardId = null; mHandler.removeCallbacks(mSelectionRunnable); - mFalsingManager.cleanup(); mWalletClient.notifyWalletDismissed(); mWalletClient.removeWalletServiceEventListener(this); mWalletView.animateDismissal(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java index a7f9fe4e0a2c2..3eb1a9e624c8e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/BrightLineClassifierTest.java @@ -118,7 +118,7 @@ public class BrightLineClassifierTest extends SysuiTestCase { verify(mFalsingDataProvider).addSessionListener( any(FalsingDataProvider.SessionListener.class)); - mBrightLineFalsingManager.cleanup(); + mBrightLineFalsingManager.cleanupInternal(); verify(mFalsingDataProvider).removeSessionListener( any(FalsingDataProvider.SessionListener.class)); } diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java similarity index 85% rename from packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java rename to packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java index dba530edc27fc..87d1b6b8cb303 100644 --- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java +++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/FalsingManagerFake.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package com.android.systemui.classifier; +import static com.google.common.truth.Truth.assertWithMessage; + import android.net.Uri; import com.android.internal.annotations.VisibleForTesting; @@ -34,10 +36,11 @@ public class FalsingManagerFake implements FalsingManager { private boolean mIsSimpleTap; private boolean mIsFalseDoubleTap; private boolean mIsUnlockingDisabled; - private boolean mIsClassiferEnabled; + private boolean mIsClassifierEnabled; private boolean mShouldEnforceBouncer; private boolean mIsReportingEnabled; private boolean mIsFalseRobustTap; + private boolean mDestroyed; private final List mFalsingBeliefListeners = new ArrayList<>(); private final List mTapListeners = new ArrayList<>(); @@ -64,6 +67,7 @@ public class FalsingManagerFake implements FalsingManager { @Override public boolean isFalseTouch(@Classifier.InteractionType int interactionType) { + checkDestroyed(); return mIsFalseTouch; } @@ -81,27 +85,30 @@ public class FalsingManagerFake implements FalsingManager { @Override public boolean isSimpleTap() { + checkDestroyed(); return mIsSimpleTap; } @Override public boolean isFalseTap(@Penalty int penalty) { + checkDestroyed(); return mIsFalseRobustTap; } @Override public boolean isFalseDoubleTap() { + checkDestroyed(); return mIsFalseDoubleTap; } @VisibleForTesting - public void setIsClassiferEnabled(boolean isClassiferEnabled) { - mIsClassiferEnabled = isClassiferEnabled; + public void setIsClassifierEnabled(boolean isClassifierEnabled) { + mIsClassifierEnabled = isClassifierEnabled; } @Override public boolean isClassifierEnabled() { - return mIsClassiferEnabled; + return mIsClassifierEnabled; } @Override @@ -129,7 +136,13 @@ public class FalsingManagerFake implements FalsingManager { } @Override - public void cleanup() { + public void cleanupInternal() { + mDestroyed = true; + } + + private void checkDestroyed() { + assertWithMessage("FakeFasingManager has been destroyed") + .that(mDestroyed).isFalse(); } @Override From cd187b7176c289a4b9a637df77de7c95731aa490 Mon Sep 17 00:00:00 2001 From: Christopher Tate Date: Thu, 3 Jun 2021 09:30:03 -0700 Subject: [PATCH 060/176] Fix false-positive matching of notification to FGS A combination of "uninitialized == 0 which is a valid and commonly used notification ID" with an incomplete check for "FGS with this notification." Bug: 189990824 Test: atest CtsAppTestCases:android.app.cts.ServiceTest Test: atest CtsAppTestCases:android.app.cts.NotificationManagerTest Change-Id: I845600325c4098e6b6af2f038de4c7aac9899694 (cherry picked from commit 97a609b82c7ee97cad0cdce853a8408a36b6ba78) --- services/core/java/com/android/server/am/ActiveServices.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 9e42900988432..e16a68d2167b3 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -2002,7 +2002,9 @@ public final class ActiveServices { for (int i = 0; i < smap.mServicesByInstanceName.size(); i++) { final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i); - if (id != sr.foregroundId || !pkg.equals(sr.appInfo.packageName)) { + if (!sr.isForeground + || id != sr.foregroundId + || !pkg.equals(sr.appInfo.packageName)) { // Not this one; keep looking continue; } From de91407e93e2bc5df51b4af43e5586867d133365 Mon Sep 17 00:00:00 2001 From: John Reck Date: Wed, 16 Jun 2021 15:48:33 -0400 Subject: [PATCH 061/176] Fix ripples not going away Fixes: 191141356 Test: ripples on calculator Change-Id: Icabf80914c5ba9c0649e69ef0fa67c03d6ad5cdd (cherry picked from commit 85933d4c5585ce09d2c0f2617efed2c7f1f7be22) --- .../android/graphics/drawable/RippleDrawable.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index fe80b5845bf51..1651a8cdcad5f 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -221,6 +221,7 @@ public class RippleDrawable extends LayerDrawable { private boolean mForceSoftware; // Patterned + private boolean mAddRipple = false; private float mTargetBackgroundOpacity; private ValueAnimator mBackgroundAnimation; private float mBackgroundOpacity; @@ -716,6 +717,7 @@ public class RippleDrawable extends LayerDrawable { } cancelExitingRipples(); + exitPatternedAnimation(); } @Override @@ -807,7 +809,7 @@ public class RippleDrawable extends LayerDrawable { } private void startPatternedAnimation() { - mRippleActive = true; + mAddRipple = true; invalidateSelf(false); } @@ -862,17 +864,17 @@ public class RippleDrawable extends LayerDrawable { h = bounds.height(); w = bounds.width(); } - boolean shouldAnimate = mRippleActive; + boolean addRipple = mAddRipple; boolean shouldExit = mExitingAnimation; - mRippleActive = false; mExitingAnimation = false; - if (mRunningAnimations.size() > 0 && !shouldAnimate) { + mAddRipple = false; + if (mRunningAnimations.size() > 0 && !addRipple) { // update paint when view is invalidated getRipplePaint(); } drawContent(canvas); drawPatternedBackground(canvas, cx, cy); - if (shouldAnimate && mRunningAnimations.size() <= MAX_RIPPLES) { + if (addRipple && mRunningAnimations.size() <= MAX_RIPPLES) { RippleAnimationSession.AnimationProperties properties = createAnimationProperties(x, y, cx, cy, w, h); mRunningAnimations.add(new RippleAnimationSession(properties, !useCanvasProps) From a9fc1129b709ffc926495e96f73036eed534ca7b Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Mon, 21 Jun 2021 14:21:03 -0700 Subject: [PATCH 062/176] canScheduleExactAlarms returns true for older apps Callers that don't target S can schedule exact alarms so should get a return value of true when they call canScheduleExactAlarm. Test: atest FrameworksMockingServicesTests:AlarmManagerServiceTest Bug: 191328951 Change-Id: I1cd1d0fb3d3d922360494552e653ed540bfe5227 (cherry picked from commit a7807022feed9b2d0645d8f9e11b04972e051b47) --- .../framework/java/android/app/AlarmManager.java | 16 +++++++++++----- .../server/alarm/AlarmManagerService.java | 3 +++ .../server/alarm/AlarmManagerServiceTest.java | 8 ++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java index 1efe5cb2f53e2..4843415fdbdda 100644 --- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java +++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java @@ -1285,14 +1285,20 @@ public class AlarmManager { } /** - * Called to check if the caller has the permission - * {@link Manifest.permission#SCHEDULE_EXACT_ALARM}. - * - * Apps can start {@link android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM} to + * Called to check if the caller can schedule exact alarms. + *

    + * Apps targeting {@link Build.VERSION_CODES#S} or higher can schedule exact alarms if they + * have the {@link Manifest.permission#SCHEDULE_EXACT_ALARM} permission. These apps can also + * start {@link android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM} to * request this from the user. + *

    + * Apps targeting lower sdk versions, can always schedule exact alarms. * - * @return {@code true} if the caller has the permission, {@code false} otherwise. + * @return {@code true} if the caller can schedule exact alarms. * @see android.provider.Settings#ACTION_REQUEST_SCHEDULE_EXACT_ALARM + * @see #setExact(int, long, PendingIntent) + * @see #setExactAndAllowWhileIdle(int, long, PendingIntent) + * @see #setAlarmClock(AlarmClockInfo, PendingIntent) */ public boolean canScheduleExactAlarms() { return hasScheduleExactAlarm(mContext.getOpPackageName(), mContext.getUserId()); diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index fb5129f184170..70e548d4c5476 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -2572,6 +2572,9 @@ public class AlarmManagerService extends SystemService { throw new SecurityException("Uid " + callingUid + " cannot query hasScheduleExactAlarm for uid " + uid); } + if (!isExactAlarmChangeEnabled(packageName, userId)) { + return true; + } return (uid > 0) ? hasScheduleExactAlarmInternal(packageName, uid) : false; } diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java index 280204dfd4811..eab1afbd931e6 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -1914,11 +1914,11 @@ public class AlarmManagerServiceTest { public void hasScheduleExactAlarmBinderCallChangeDisabled() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false); - mockExactAlarmPermissionGrant(true, false, MODE_DEFAULT); - assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); + mockExactAlarmPermissionGrant(false, true, MODE_DEFAULT); + assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - mockExactAlarmPermissionGrant(true, true, MODE_ALLOWED); - assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); + mockExactAlarmPermissionGrant(true, false, MODE_ERRORED); + assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); } private void mockChangeEnabled(long changeId, boolean enabled) { From 0c5758bc41498c677880dde4013ac4370bdbc6c5 Mon Sep 17 00:00:00 2001 From: Bill Lin Date: Tue, 22 Jun 2021 11:22:37 +0800 Subject: [PATCH 063/176] Fix SysUI NPE crash during the boot/init progress When Device boot and SystemUI servies starting, settings provider may callback onChange() when OneHandedController register observer. If the callback timing earlier han mEventCallback registered by WMShll#initOneHanded, then the NPE will happen. The simple fix is to add NPE check in OneHandedController#notifyExpandNotifcation() we can just ignore the callback during init time since the singal is to expand notification and come from shorcut after user enable and tap shortcut.(No need to act for the signal during boot progress.) Test: manual reboot device and observe Test: atest WMShellUnitTests Bug: 191600033 Change-Id: I73849afa9904031759da304298221dbb222aeaaa (cherry picked from commit c4bdf37af2bb70df47969e557c27c6c7a1cdbada) --- .../wm/shell/onehanded/OneHandedController.java | 4 +++- .../wm/shell/onehanded/OneHandedControllerTest.java | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java index 7e673c6e32c20..b5c54023c4926 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java @@ -482,7 +482,9 @@ public class OneHandedController implements RemoteCallable @VisibleForTesting void notifyExpandNotification() { - mMainExecutor.execute(() -> mEventCallback.notifyExpandNotification()); + if (mEventCallback != null) { + mMainExecutor.execute(() -> mEventCallback.notifyExpandNotification()); + } } @VisibleForTesting diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java index 47789b7490ee2..950900337918b 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedControllerTest.java @@ -435,4 +435,17 @@ public class OneHandedControllerTest extends OneHandedTestCase { verify(mSpiedOneHandedController).notifyShortcutState(anyInt()); } + + @Test + public void testNotifyExpandNotification_withNullCheckProtection() { + when(mSpiedOneHandedController.isOneHandedEnabled()).thenReturn(false); + when(mSpiedTransitionState.getState()).thenReturn(STATE_NONE); + when(mSpiedTransitionState.isTransitioning()).thenReturn(false); + when(mSpiedOneHandedController.isSwipeToNotificationEnabled()).thenReturn(true); + mSpiedOneHandedController.setOneHandedEnabled(true); + mSpiedOneHandedController.notifyExpandNotification(); + + // Verify no NPE crash and mMockShellMainExecutor never be execute. + verify(mMockShellMainExecutor, never()).execute(any()); + } } From d5252a86128472218173064001a982c4d7d1119d Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Mon, 28 Jun 2021 07:53:10 -0700 Subject: [PATCH 064/176] Fix boot time race condition in BatteryStatsImpl We need some services to create a battery stats snapshot captured at the time of battery reset. The issue is that if the battery stats reset occurs during boot, before the system is ready, those services may not be prepared. The fix is to postpone battery stats reset until after the system server is ready. Bug: 191120091 Test: run PowerOnOffTest#testPowerOnOff repeatedly Change-Id: Ib486e4caeeac7c933288c3a1055259c05f45c6c8 (cherry picked from commit 77fc0fffe13fe04289831ac03ea9209421f969df) --- .../android/internal/os/BatteryStatsImpl.java | 32 +++++++++++++++---- .../server/am/ActivityManagerService.java | 1 + .../server/am/BatteryStatsService.java | 7 ++++ 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index b17df2a762034..699c8995a6fa8 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -191,6 +191,11 @@ public class BatteryStatsImpl extends BatteryStats { @VisibleForTesting public static final int WAKE_LOCK_WEIGHT = 50; + private static final int RESET_REASON_CORRUPT_FILE = 1; + private static final int RESET_REASON_ADB_COMMAND = 2; + private static final int RESET_REASON_FULL_CHARGE = 3; + private static final int RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE = 4; + protected Clocks mClocks; private final AtomicFile mStatsFile; @@ -747,6 +752,7 @@ public class BatteryStatsImpl extends BatteryStats { // CPU update, even if we aren't currently running wake locks. boolean mDistributeWakelockCpu; + private boolean mSystemReady; boolean mShuttingDown; final HistoryEventTracker mActiveEvents = new HistoryEventTracker(); @@ -11212,7 +11218,7 @@ public class BatteryStatsImpl extends BatteryStats { long uptimeUs = mSecUptime * 1000; long mSecRealtime = mClocks.elapsedRealtime(); long realtimeUs = mSecRealtime * 1000; - resetAllStatsLocked(mSecUptime, mSecRealtime); + resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_ADB_COMMAND); mDischargeStartLevel = mHistoryCur.batteryLevel; pullPendingStateUpdatesLocked(); addHistoryRecordLocked(mSecRealtime, mSecUptime); @@ -11241,8 +11247,10 @@ public class BatteryStatsImpl extends BatteryStats { initActiveHistoryEventsLocked(mSecRealtime, mSecUptime); } - private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis) { - if (mBatteryResetListener != null) { + private void resetAllStatsLocked(long uptimeMillis, long elapsedRealtimeMillis, + int resetReason) { + if (mBatteryResetListener != null && mSystemReady + && resetReason != RESET_REASON_CORRUPT_FILE) { mBatteryResetListener.prepareForBatteryStatsReset(); } @@ -13479,6 +13487,13 @@ public class BatteryStatsImpl extends BatteryStats { return false; } + /** + * Notifies BatteryStatsImpl that the system server is ready. + */ + public void onSystemReady() { + mSystemReady = true; + } + @GuardedBy("this") protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery, final int oldStatus, final int level, final int chargeUah) { @@ -13496,7 +13511,8 @@ public class BatteryStatsImpl extends BatteryStats { // we have gone through a significant charge (from a very low // level to a now very high level). boolean reset = false; - if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL + if (!mNoAutoReset && mSystemReady + && (oldStatus == BatteryManager.BATTERY_STATUS_FULL || level >= 90 || (mDischargeCurrentLevel < 20 && level >= 80))) { Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus @@ -13536,7 +13552,7 @@ public class BatteryStatsImpl extends BatteryStats { }); } doWrite = true; - resetAllStatsLocked(mSecUptime, mSecRealtime); + resetAllStatsLocked(mSecUptime, mSecRealtime, RESET_REASON_FULL_CHARGE); if (chargeUah > 0 && level > 0) { // Only use the reported coulomb charge value if it is supported and reported. mEstimatedBatteryCapacityMah = (int) ((chargeUah / 1000) / (level / 100.0)); @@ -14504,7 +14520,8 @@ public class BatteryStatsImpl extends BatteryStats { ? null : new MeasuredEnergyStats(supportedStandardBuckets, customBucketNames); // Supported power buckets changed since last boot. // Existing data is no longer reliable. - resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime()); + resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), + RESET_REASON_MEASURED_ENERGY_BUCKETS_CHANGE); } } @@ -14951,7 +14968,8 @@ public class BatteryStatsImpl extends BatteryStats { } } catch (Exception e) { Slog.e(TAG, "Error reading battery statistics", e); - resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime()); + resetAllStatsLocked(SystemClock.uptimeMillis(), SystemClock.elapsedRealtime(), + RESET_REASON_CORRUPT_FILE); } finally { stats.recycle(); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ec2e56eb93ef0..49c00fe0b25eb 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -7635,6 +7635,7 @@ public class ActivityManagerService extends IActivityManager.Stub t.traceEnd(); t.traceBegin("ActivityManagerStartApps"); + mBatteryStatsService.onSystemReady(); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(currentUserId), currentUserId); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 2e62d8b129d3e..dc1f03d3abc41 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -398,6 +398,13 @@ public final class BatteryStatsService extends IBatteryStats.Stub registerStatsCallbacks(); } + /** + * Notifies BatteryStatsService that the system server is ready. + */ + public void onSystemReady() { + mStats.onSystemReady(); + } + private final class LocalService extends BatteryStatsInternal { @Override public String[] getWifiIfaces() { From ef5b4276e1f2d803dbd88636bcaff137977e5bef Mon Sep 17 00:00:00 2001 From: Dmitri Plotnikov Date: Mon, 28 Jun 2021 09:22:15 -0700 Subject: [PATCH 065/176] Disable the BatteryUsageStatsStore feature Bug: 191120091 Test: run PowerOnOffTest#testPowerOnOff Change-Id: I536bbf04ac3233575487bbffd120cbdfa305c41f (cherry picked from commit 483702e0dfbb4af2919017ab2e8371b30b0f4fce) --- .../com/android/internal/os/BatteryUsageStatsProvider.java | 7 +++++++ .../java/com/android/server/am/BatteryStatsService.java | 6 +++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index 8943db6c8a1e6..00385793b62b2 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -23,6 +23,7 @@ import android.os.BatteryUsageStats; import android.os.BatteryUsageStatsQuery; import android.os.SystemClock; import android.os.UidBatteryConsumer; +import android.util.Log; import android.util.SparseArray; import com.android.internal.annotations.VisibleForTesting; @@ -36,6 +37,7 @@ import java.util.Map; * usage data attributed to subsystems and UIDs. */ public class BatteryUsageStatsProvider { + private static final String TAG = "BatteryUsageStatsProv"; private final Context mContext; private final BatteryStats mStats; private final BatteryUsageStatsStore mBatteryUsageStatsStore; @@ -234,6 +236,11 @@ public class BatteryUsageStatsProvider { final BatteryUsageStats.Builder builder = new BatteryUsageStats.Builder( mStats.getCustomEnergyConsumerNames(), includePowerModels); + if (mBatteryUsageStatsStore == null) { + Log.e(TAG, "BatteryUsageStatsStore is unavailable"); + return builder.build(); + } + final long[] timestamps = mBatteryUsageStatsStore.listBatteryUsageStatsTimestamps(); for (long timestamp : timestamps) { if (timestamp > query.getFromTimestamp() && timestamp <= query.getToTimestamp()) { diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 2e62d8b129d3e..c5b69c6e2cbfd 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -126,7 +126,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub Watchdog.Monitor { static final String TAG = "BatteryStatsService"; static final boolean DBG = false; - private static final boolean BATTERY_USAGE_STORE_ENABLED = true; + private static final boolean BATTERY_USAGE_STORE_ENABLED = false; private static IBatteryStats sService; @@ -784,6 +784,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub bus = getBatteryUsageStats(List.of(powerProfileQuery)).get(0); break; case FrameworkStatsLog.BATTERY_USAGE_STATS_BEFORE_RESET: + if (!BATTERY_USAGE_STORE_ENABLED) { + return StatsManager.PULL_SKIP; + } + final long sessionStart = mBatteryUsageStatsStore .getLastBatteryUsageStatsBeforeResetAtomPullTimestamp(); final long sessionEnd = mStats.getStartClockTime(); From a3894f99a570ee39521cddfc0d64c3baba911e46 Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Wed, 30 Jun 2021 13:09:02 +0000 Subject: [PATCH 066/176] Revert "Enforce package visibility to the api checkUriPermission" Revert "Add tests for the api Context#checkUriPermission" Revert submission 15065651-pm_package_visibility_check_uri_permission Reason for revert: [Regression] Cross-profile sharing is broken Reverted Changes: Iea2f2d8a8:Enforce package visibility to the api checkUriPerm... I0a4ed9350:Add tests for the api Context#checkUriPermission Bug: 192357488 Change-Id: I0050e70121e23e8457dbfc061f488c40f7ec2a93 (cherry picked from commit 48e920c2f33443e7c763f7e61b3c81b73ead6c43) --- .../com/android/server/am/ActivityManagerService.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 119e4872c8150..7754223ae2d0d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5690,16 +5690,6 @@ public class ActivityManagerService extends IActivityManager.Stub if (pid == MY_PID) { return PackageManager.PERMISSION_GRANTED; } - try { - if (uid != 0) { // bypass the root - final String[] packageNames = getPackageManager().getPackagesForUid(uid); - if (ArrayUtils.isEmpty(packageNames)) { - // The uid is not existed or not visible to the caller. - return PackageManager.PERMISSION_DENIED; - } - } - } catch (RemoteException e) { - } return mUgmInternal.checkUriPermission(new GrantUri(userId, uri, modeFlags), uid, modeFlags) ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED; } From b522ef7b9a12b73e597d2887da2dfe8f32d19e80 Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Wed, 30 Jun 2021 13:09:02 +0000 Subject: [PATCH 067/176] Revert "Enforce package visibility to the api checkUriPermission" Revert "Add tests for the api Context#checkUriPermission" Revert submission 15065651-pm_package_visibility_check_uri_permission Reason for revert: [Regression] Cross-profile sharing is broken Reverted Changes: Iea2f2d8a8:Enforce package visibility to the api checkUriPerm... I0a4ed9350:Add tests for the api Context#checkUriPermission Bug: 192357488 Change-Id: I0050e70121e23e8457dbfc061f488c40f7ec2a93 (cherry picked from commit 48e920c2f33443e7c763f7e61b3c81b73ead6c43) --- .../com/android/server/am/ActivityManagerService.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index efaf4eb01a9c8..1a81c59196901 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5690,16 +5690,6 @@ public class ActivityManagerService extends IActivityManager.Stub if (pid == MY_PID) { return PackageManager.PERMISSION_GRANTED; } - try { - if (uid != 0) { // bypass the root - final String[] packageNames = getPackageManager().getPackagesForUid(uid); - if (ArrayUtils.isEmpty(packageNames)) { - // The uid is not existed or not visible to the caller. - return PackageManager.PERMISSION_DENIED; - } - } - } catch (RemoteException e) { - } return mUgmInternal.checkUriPermission(new GrantUri(userId, uri, modeFlags), uid, modeFlags) ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED; } From 9b84579c2056ab2c64e516332f6ddb902b1dc10e Mon Sep 17 00:00:00 2001 From: Chris Li Date: Thu, 8 Jul 2021 13:08:18 -0700 Subject: [PATCH 068/176] Revert the window context creation in NavigationBarController In ag/14981905, we changed it to use WindowContext of TYPE_NAVIGATION_BAR, but looks like this context is also used for creating windows of other types. Revert it to fix the crash. Will fix the context usages in NavigationBar later. Bug: 193107004 Test: revert Change-Id: I4ec66982aa929039764fc276e9452151d959268e (cherry picked from commit db18b6e3d314a86ef2cff652cc267b1662105afb) --- .../systemui/navigationbar/NavigationBarController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index ecea0820028c2..6344c591803d2 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -17,7 +17,6 @@ package com.android.systemui.navigationbar; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.systemui.shared.recents.utilities.Utilities.isTablet; @@ -350,7 +349,9 @@ public class NavigationBarController implements Callbacks, Log.w(TAG, "Cannot get WindowManager."); return; } - final Context context = mContext.createWindowContext(display, TYPE_NAVIGATION_BAR, null); + final Context context = isOnDefaultDisplay + ? mContext + : mContext.createDisplayContext(display); NavigationBar navBar = new NavigationBar(context, mWindowManager, mAssistManagerLazy, From 204601504132ce17e88c47470a2ca4fb355d36c5 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Thu, 8 Jul 2021 13:08:18 -0700 Subject: [PATCH 069/176] Revert the window context creation in NavigationBarController In ag/14981905, we changed it to use WindowContext of TYPE_NAVIGATION_BAR, but looks like this context is also used for creating windows of other types. Revert it to fix the crash. Will fix the context usages in NavigationBar later. Bug: 193107004 Test: revert Change-Id: I4ec66982aa929039764fc276e9452151d959268e (cherry picked from commit db18b6e3d314a86ef2cff652cc267b1662105afb) --- .../systemui/navigationbar/NavigationBarController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index ecea0820028c2..6344c591803d2 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -17,7 +17,6 @@ package com.android.systemui.navigationbar; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.systemui.shared.recents.utilities.Utilities.isTablet; @@ -350,7 +349,9 @@ public class NavigationBarController implements Callbacks, Log.w(TAG, "Cannot get WindowManager."); return; } - final Context context = mContext.createWindowContext(display, TYPE_NAVIGATION_BAR, null); + final Context context = isOnDefaultDisplay + ? mContext + : mContext.createDisplayContext(display); NavigationBar navBar = new NavigationBar(context, mWindowManager, mAssistManagerLazy, From 4afbece1b18b32745381f6cbbb5e63969517dd68 Mon Sep 17 00:00:00 2001 From: Chris Li Date: Thu, 8 Jul 2021 13:08:18 -0700 Subject: [PATCH 070/176] Revert the window context creation in NavigationBarController In ag/14981905, we changed it to use WindowContext of TYPE_NAVIGATION_BAR, but looks like this context is also used for creating windows of other types. Revert it to fix the crash. Will fix the context usages in NavigationBar later. Bug: 193107004 Test: revert Change-Id: I4ec66982aa929039764fc276e9452151d959268e (cherry picked from commit db18b6e3d314a86ef2cff652cc267b1662105afb) --- .../systemui/navigationbar/NavigationBarController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index ecea0820028c2..6344c591803d2 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -17,7 +17,6 @@ package com.android.systemui.navigationbar; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.systemui.shared.recents.utilities.Utilities.isTablet; @@ -350,7 +349,9 @@ public class NavigationBarController implements Callbacks, Log.w(TAG, "Cannot get WindowManager."); return; } - final Context context = mContext.createWindowContext(display, TYPE_NAVIGATION_BAR, null); + final Context context = isOnDefaultDisplay + ? mContext + : mContext.createDisplayContext(display); NavigationBar navBar = new NavigationBar(context, mWindowManager, mAssistManagerLazy, From b9b87e4f220b169f915e56b667a384c05efcd74a Mon Sep 17 00:00:00 2001 From: Chris Li Date: Thu, 8 Jul 2021 13:08:18 -0700 Subject: [PATCH 071/176] Revert the window context creation in NavigationBarController In ag/14981905, we changed it to use WindowContext of TYPE_NAVIGATION_BAR, but looks like this context is also used for creating windows of other types. Revert it to fix the crash. Will fix the context usages in NavigationBar later. Bug: 193107004 Test: revert Change-Id: I4ec66982aa929039764fc276e9452151d959268e (cherry picked from commit db18b6e3d314a86ef2cff652cc267b1662105afb) --- .../systemui/navigationbar/NavigationBarController.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java index ecea0820028c2..6344c591803d2 100644 --- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java @@ -17,7 +17,6 @@ package com.android.systemui.navigationbar; import static android.view.Display.DEFAULT_DISPLAY; -import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON; import static com.android.systemui.shared.recents.utilities.Utilities.isTablet; @@ -350,7 +349,9 @@ public class NavigationBarController implements Callbacks, Log.w(TAG, "Cannot get WindowManager."); return; } - final Context context = mContext.createWindowContext(display, TYPE_NAVIGATION_BAR, null); + final Context context = isOnDefaultDisplay + ? mContext + : mContext.createDisplayContext(display); NavigationBar navBar = new NavigationBar(context, mWindowManager, mAssistManagerLazy, From 7f0baaf6393f3e156aba7e9dad6b33a258d78750 Mon Sep 17 00:00:00 2001 From: Naomi Musgrave Date: Tue, 3 Aug 2021 08:37:28 +0000 Subject: [PATCH 072/176] Revert "MediaProjection captures DisplayArea" This reverts commit 45dd2a320205a58a44cd636aaa4ec6bed175b27b. Reason for revert: b/195280234 is blocking droidfood Bug: b/195280234 Change-Id: I09593dffb797d1e4c60cff52e7901ed6c00f719c (cherry picked from commit da38617955f2ebad65c6cc67efb1dd22571fa153) --- .../display/DisplayManagerInternal.java | 23 --- .../display/VirtualDisplayConfig.java | 56 +----- core/java/android/view/Surface.java | 15 -- .../media/projection/MediaProjection.java | 28 +-- .../android/server/display/DisplayDevice.java | 30 ---- .../server/display/DisplayManagerService.java | 41 +---- .../server/display/VirtualDisplayAdapter.java | 25 --- .../com/android/server/wm/DisplayContent.java | 167 ------------------ .../server/wm/DisplayContentTests.java | 113 ------------ 9 files changed, 15 insertions(+), 483 deletions(-) diff --git a/core/java/android/hardware/display/DisplayManagerInternal.java b/core/java/android/hardware/display/DisplayManagerInternal.java index 4f205530ef0d7..abcc33c43c743 100644 --- a/core/java/android/hardware/display/DisplayManagerInternal.java +++ b/core/java/android/hardware/display/DisplayManagerInternal.java @@ -21,7 +21,6 @@ import android.annotation.Nullable; import android.graphics.Point; import android.hardware.SensorManager; import android.os.Handler; -import android.os.IBinder; import android.os.PowerManager; import android.util.IntArray; import android.util.Slog; @@ -340,28 +339,6 @@ public abstract class DisplayManagerInternal { */ public abstract List getRefreshRateLimitations(int displayId); - /** - * Returns the window token of the level of the WindowManager hierarchy to mirror. Returns null - * if layer mirroring by SurfaceFlinger should not be performed for the given displayId. - * For now, only used for mirroring started from MediaProjection. - */ - public abstract IBinder getWindowTokenClientToMirror(int displayId); - - /** - * For the given displayId, updates the window token of the level of the WindowManager hierarchy - * to mirror. If windowToken is null, then SurfaceFlinger performs no layer mirroring to the - * given display. - * For now, only used for mirroring started from MediaProjection. - */ - public abstract void setWindowTokenClientToMirror(int displayId, IBinder windowToken); - - /** - * Returns the default size of the surface associated with the display, or null if the surface - * is not provided for layer mirroring by SurfaceFlinger. - * For now, only used for mirroring started from MediaProjection. - */ - public abstract Point getDisplaySurfaceDefaultSize(int displayId); - /** * Describes the requested power state of the display. * diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java index 0e86f43207aae..71688c7cc7e85 100644 --- a/core/java/android/hardware/display/VirtualDisplayConfig.java +++ b/core/java/android/hardware/display/VirtualDisplayConfig.java @@ -23,7 +23,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.media.projection.MediaProjection; import android.os.Handler; -import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; import android.view.Surface; @@ -92,16 +91,9 @@ public final class VirtualDisplayConfig implements Parcelable { */ private int mDisplayIdToMirror = DEFAULT_DISPLAY; - /** - * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring - * should not be performed. - */ - @Nullable - private IBinder mWindowTokenClientToMirror = null; - - // Code below generated by codegen v1.0.23. + // Code below generated by codegen v1.0.20. // // DO NOT MODIFY! // CHECKSTYLE:OFF Generated code @@ -123,8 +115,7 @@ public final class VirtualDisplayConfig implements Parcelable { int flags, @Nullable Surface surface, @Nullable String uniqueId, - int displayIdToMirror, - @Nullable IBinder windowTokenClientToMirror) { + int displayIdToMirror) { this.mName = name; com.android.internal.util.AnnotationValidations.validate( NonNull.class, null, mName); @@ -144,7 +135,6 @@ public final class VirtualDisplayConfig implements Parcelable { this.mSurface = surface; this.mUniqueId = uniqueId; this.mDisplayIdToMirror = displayIdToMirror; - this.mWindowTokenClientToMirror = windowTokenClientToMirror; // onConstructed(); // You can define this method to get a callback } @@ -222,15 +212,6 @@ public final class VirtualDisplayConfig implements Parcelable { return mDisplayIdToMirror; } - /** - * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring - * should not be performed. - */ - @DataClass.Generated.Member - public @Nullable IBinder getWindowTokenClientToMirror() { - return mWindowTokenClientToMirror; - } - @Override @DataClass.Generated.Member public void writeToParcel(@NonNull Parcel dest, int flags) { @@ -240,7 +221,6 @@ public final class VirtualDisplayConfig implements Parcelable { int flg = 0; if (mSurface != null) flg |= 0x20; if (mUniqueId != null) flg |= 0x40; - if (mWindowTokenClientToMirror != null) flg |= 0x100; dest.writeInt(flg); dest.writeString(mName); dest.writeInt(mWidth); @@ -250,7 +230,6 @@ public final class VirtualDisplayConfig implements Parcelable { if (mSurface != null) dest.writeTypedObject(mSurface, flags); if (mUniqueId != null) dest.writeString(mUniqueId); dest.writeInt(mDisplayIdToMirror); - if (mWindowTokenClientToMirror != null) dest.writeStrongBinder(mWindowTokenClientToMirror); } @Override @@ -273,7 +252,6 @@ public final class VirtualDisplayConfig implements Parcelable { Surface surface = (flg & 0x20) == 0 ? null : (Surface) in.readTypedObject(Surface.CREATOR); String uniqueId = (flg & 0x40) == 0 ? null : in.readString(); int displayIdToMirror = in.readInt(); - IBinder windowTokenClientToMirror = (flg & 0x100) == 0 ? null : (IBinder) in.readStrongBinder(); this.mName = name; com.android.internal.util.AnnotationValidations.validate( @@ -294,7 +272,6 @@ public final class VirtualDisplayConfig implements Parcelable { this.mSurface = surface; this.mUniqueId = uniqueId; this.mDisplayIdToMirror = displayIdToMirror; - this.mWindowTokenClientToMirror = windowTokenClientToMirror; // onConstructed(); // You can define this method to get a callback } @@ -328,7 +305,6 @@ public final class VirtualDisplayConfig implements Parcelable { private @Nullable Surface mSurface; private @Nullable String mUniqueId; private int mDisplayIdToMirror; - private @Nullable IBinder mWindowTokenClientToMirror; private long mBuilderFieldsSet = 0L; @@ -463,22 +439,10 @@ public final class VirtualDisplayConfig implements Parcelable { return this; } - /** - * The window token of the level of the WindowManager hierarchy to mirror, or null if mirroring - * should not be performed. - */ - @DataClass.Generated.Member - public @NonNull Builder setWindowTokenClientToMirror(@NonNull IBinder value) { - checkNotUsed(); - mBuilderFieldsSet |= 0x100; - mWindowTokenClientToMirror = value; - return this; - } - /** Builds the instance. This builder should not be touched after calling this! */ public @NonNull VirtualDisplayConfig build() { checkNotUsed(); - mBuilderFieldsSet |= 0x200; // Mark builder used + mBuilderFieldsSet |= 0x100; // Mark builder used if ((mBuilderFieldsSet & 0x10) == 0) { mFlags = 0; @@ -492,9 +456,6 @@ public final class VirtualDisplayConfig implements Parcelable { if ((mBuilderFieldsSet & 0x80) == 0) { mDisplayIdToMirror = DEFAULT_DISPLAY; } - if ((mBuilderFieldsSet & 0x100) == 0) { - mWindowTokenClientToMirror = null; - } VirtualDisplayConfig o = new VirtualDisplayConfig( mName, mWidth, @@ -503,13 +464,12 @@ public final class VirtualDisplayConfig implements Parcelable { mFlags, mSurface, mUniqueId, - mDisplayIdToMirror, - mWindowTokenClientToMirror); + mDisplayIdToMirror); return o; } private void checkNotUsed() { - if ((mBuilderFieldsSet & 0x200) != 0) { + if ((mBuilderFieldsSet & 0x100) != 0) { throw new IllegalStateException( "This Builder should not be reused. Use a new Builder instance instead"); } @@ -517,10 +477,10 @@ public final class VirtualDisplayConfig implements Parcelable { } @DataClass.Generated( - time = 1620657851981L, - codegenVersion = "1.0.23", + time = 1604456298440L, + codegenVersion = "1.0.20", sourceFile = "frameworks/base/core/java/android/hardware/display/VirtualDisplayConfig.java", - inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate int mDisplayIdToMirror\nprivate @android.annotation.Nullable android.os.IBinder mWindowTokenClientToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)") + inputSignatures = "private @android.annotation.NonNull java.lang.String mName\nprivate @android.annotation.IntRange int mWidth\nprivate @android.annotation.IntRange int mHeight\nprivate @android.annotation.IntRange int mDensityDpi\nprivate int mFlags\nprivate @android.annotation.Nullable android.view.Surface mSurface\nprivate @android.annotation.Nullable java.lang.String mUniqueId\nprivate int mDisplayIdToMirror\nclass VirtualDisplayConfig extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index aaf53ee1cfc10..ff2d2eb3d3345 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -29,7 +29,6 @@ import android.graphics.Canvas; import android.graphics.ColorSpace; import android.graphics.HardwareRenderer; import android.graphics.Matrix; -import android.graphics.Point; import android.graphics.RecordingCanvas; import android.graphics.Rect; import android.graphics.RenderNode; @@ -408,20 +407,6 @@ public class Surface implements Parcelable { } } - /** - * Returns the default size of this Surface provided by the consumer of the surface. - * Should only be used by the producer of the surface. - * - * @hide - */ - @NonNull - public Point getDefaultSize() { - synchronized (mLock) { - checkNotReleasedLocked(); - return new Point(nativeGetWidth(mNativeObject), nativeGetHeight(mNativeObject)); - } - } - /** * Gets a {@link Canvas} for drawing into this surface. * diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java index 72cddc91f436a..37e141537c794 100644 --- a/media/java/android/media/projection/MediaProjection.java +++ b/media/java/android/media/projection/MediaProjection.java @@ -16,14 +16,14 @@ package android.media.projection; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; - import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.hardware.display.VirtualDisplayConfig; +import android.media.projection.IMediaProjection; +import android.media.projection.IMediaProjectionCallback; import android.os.Handler; import android.os.RemoteException; import android.util.ArrayMap; @@ -106,7 +106,7 @@ public final class MediaProjection { if (isSecure) { flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE; } - final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width, + final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width, height, dpi); builder.setFlags(flags); if (surface != null) { @@ -141,7 +141,7 @@ public final class MediaProjection { public VirtualDisplay createVirtualDisplay(@NonNull String name, int width, int height, int dpi, int flags, @Nullable Surface surface, @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) { - final VirtualDisplayConfig.Builder builder = buildMirroredVirtualDisplay(name, width, + final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width, height, dpi); builder.setFlags(flags); if (surface != null) { @@ -150,26 +150,6 @@ public final class MediaProjection { return createVirtualDisplay(builder.build(), callback, handler); } - /** - * Constructs a {@link VirtualDisplayConfig.Builder}, which will mirror the contents of a - * DisplayArea. The DisplayArea to mirror is from the DisplayArea the caller is launched on. - * - * @param name The name of the virtual display, must be non-empty. - * @param width The width of the virtual display in pixels. Must be greater than 0. - * @param height The height of the virtual display in pixels. Must be greater than 0. - * @param dpi The density of the virtual display in dpi. Must be greater than 0. - * @return a config representing a VirtualDisplay - */ - private VirtualDisplayConfig.Builder buildMirroredVirtualDisplay(@NonNull String name, - int width, int height, int dpi) { - Context windowContext = mContext.createWindowContext(mContext.getDisplayNoVerify(), - TYPE_APPLICATION, null /* options */); - final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width, - height, dpi); - builder.setWindowTokenClientToMirror(windowContext.getWindowContextToken()); - return builder; - } - /** * Creates a {@link android.hardware.display.VirtualDisplay} to capture the * contents of the screen. diff --git a/services/core/java/com/android/server/display/DisplayDevice.java b/services/core/java/com/android/server/display/DisplayDevice.java index 806bcc29f3057..9f806af5b444f 100644 --- a/services/core/java/com/android/server/display/DisplayDevice.java +++ b/services/core/java/com/android/server/display/DisplayDevice.java @@ -16,9 +16,7 @@ package com.android.server.display; -import android.annotation.Nullable; import android.content.Context; -import android.graphics.Point; import android.graphics.Rect; import android.hardware.display.DisplayViewport; import android.os.IBinder; @@ -106,34 +104,6 @@ abstract class DisplayDevice { return Display.DEFAULT_DISPLAY; } - /** - * Returns the window token of the level of the WindowManager hierarchy to mirror, or null - * if layer mirroring by SurfaceFlinger should not be performed. - * For now, only used for mirroring started from MediaProjection. - */ - @Nullable - public IBinder getWindowTokenClientToMirrorLocked() { - return null; - } - - /** - * Updates the window token of the level of the level of the WindowManager hierarchy to mirror. - * If windowToken is null, then no layer mirroring by SurfaceFlinger to should be performed. - * For now, only used for mirroring started from MediaProjection. - */ - public void setWindowTokenClientToMirrorLocked(IBinder windowToken) { - } - - /** - * Returns the default size of the surface associated with the display, or null if the surface - * is not provided for layer mirroring by SurfaceFlinger. - * For now, only used for mirroring started from MediaProjection. - */ - @Nullable - public Point getDisplaySurfaceDefaultSize() { - return null; - } - /** * Gets the name of the display device. * diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index 39fd962369bfd..afd18894f5312 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -63,6 +63,8 @@ import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerInternal; import android.hardware.display.DisplayManagerInternal.DisplayGroupListener; import android.hardware.display.DisplayManagerInternal.DisplayTransactionListener; +import android.hardware.display.DisplayManagerInternal.RefreshRateLimitation; +import android.hardware.display.DisplayManagerInternal.RefreshRateRange; import android.hardware.display.DisplayViewport; import android.hardware.display.DisplayedContentSample; import android.hardware.display.DisplayedContentSamplingAttributes; @@ -1747,13 +1749,10 @@ public final class DisplayManagerService extends SystemService { final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked(); final boolean ownContent = (info.flags & DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY) != 0; - // Mirror the part of WM hierarchy that corresponds to the provided window token. - IBinder windowTokenClientToMirror = device.getWindowTokenClientToMirrorLocked(); - // Find the logical display that the display device is showing. // Certain displays only ever show their own content. LogicalDisplay display = mLogicalDisplayMapper.getDisplayLocked(device); - if (!ownContent && windowTokenClientToMirror == null) { + if (!ownContent) { if (display != null && !display.hasContentLocked()) { // If the display does not have any content of its own, then // automatically mirror the requested logical display contents if possible. @@ -3315,40 +3314,6 @@ public final class DisplayManagerService extends SystemService { } return config.getRefreshRateLimitations(); } - - @Override - public IBinder getWindowTokenClientToMirror(int displayId) { - final DisplayDevice device; - synchronized (mSyncRoot) { - device = getDeviceForDisplayLocked(displayId); - if (device == null) { - return null; - } - } - return device.getWindowTokenClientToMirrorLocked(); - } - - @Override - public void setWindowTokenClientToMirror(int displayId, IBinder windowToken) { - synchronized (mSyncRoot) { - final DisplayDevice device = getDeviceForDisplayLocked(displayId); - if (device != null) { - device.setWindowTokenClientToMirrorLocked(windowToken); - } - } - } - - @Override - public Point getDisplaySurfaceDefaultSize(int displayId) { - final DisplayDevice device; - synchronized (mSyncRoot) { - device = getDeviceForDisplayLocked(displayId); - if (device == null) { - return null; - } - } - return device.getDisplaySurfaceDefaultSize(); - } } class DesiredDisplayModeSpecsObserver diff --git a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java index 34d2b0160c3c7..b7931c8a8424f 100644 --- a/services/core/java/com/android/server/display/VirtualDisplayAdapter.java +++ b/services/core/java/com/android/server/display/VirtualDisplayAdapter.java @@ -31,9 +31,7 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUST import static com.android.server.display.DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP; import static com.android.server.display.DisplayDeviceInfo.FLAG_TRUSTED; -import android.annotation.Nullable; import android.content.Context; -import android.graphics.Point; import android.hardware.display.IVirtualDisplayCallback; import android.hardware.display.VirtualDisplayConfig; import android.media.projection.IMediaProjection; @@ -233,7 +231,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter { private Display.Mode mMode; private boolean mIsDisplayOn; private int mDisplayIdToMirror; - private IBinder mWindowTokenClientToMirror; public VirtualDisplayDevice(IBinder displayToken, IBinder appToken, int ownerUid, String ownerPackageName, Surface surface, int flags, @@ -256,7 +253,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter { mUniqueIndex = uniqueIndex; mIsDisplayOn = surface != null; mDisplayIdToMirror = virtualDisplayConfig.getDisplayIdToMirror(); - mWindowTokenClientToMirror = virtualDisplayConfig.getWindowTokenClientToMirror(); } @Override @@ -286,26 +282,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter { return mDisplayIdToMirror; } - @Override - @Nullable - public IBinder getWindowTokenClientToMirrorLocked() { - return mWindowTokenClientToMirror; - } - - @Override - public void setWindowTokenClientToMirrorLocked(IBinder windowToken) { - if (mWindowTokenClientToMirror != windowToken) { - mWindowTokenClientToMirror = windowToken; - sendDisplayDeviceEventLocked(this, DISPLAY_DEVICE_EVENT_CHANGED); - sendTraversalRequestLocked(); - } - } - - @Override - public Point getDisplaySurfaceDefaultSize() { - return mSurface.getDefaultSize(); - } - @VisibleForTesting Surface getSurfaceLocked() { return mSurface; @@ -386,7 +362,6 @@ public class VirtualDisplayAdapter extends DisplayAdapter { pw.println("mDisplayState=" + Display.stateToString(mDisplayState)); pw.println("mStopped=" + mStopped); pw.println("mDisplayIdToMirror=" + mDisplayIdToMirror); - pw.println("mWindowTokenClientToMirror=" + mWindowTokenClientToMirror); } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c6b92c0549c74..e8cb1cc1e1d18 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -294,22 +294,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp */ private final SurfaceControl mWindowingLayer; - /** - * The window token of the layer of the hierarchy to mirror, or null if this DisplayContent - * is not being used for layer mirroring. - */ - @VisibleForTesting IBinder mTokenToMirror = null; - - /** - * The surface for mirroring the contents of this hierarchy. - */ - private SurfaceControl mMirroredSurface = null; - - /** - * The last bounds of the DisplayArea to mirror. - */ - private Rect mLastMirroredDisplayAreaBounds = null; - // Contains all IME window containers. Note that the z-ordering of the IME windows will depend // on the IME target. We mainly have this container grouping so we can keep track of all the IME // window containers together and move them in-sync if/when needed. We use a subclass of @@ -1127,10 +1111,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp if (DEBUG_DISPLAY) Slog.v(TAG_WM, "Creating display=" + display); mWmService.mDisplayWindowSettings.applySettingsToDisplayLocked(this); - - // Check if this DisplayContent is for a new VirtualDisplay, that should use layer mirroring - // to capture the contents of a DisplayArea. - startMirrorIfNeeded(); } boolean isReady() { @@ -2485,25 +2465,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp // Update IME parent if needed. updateImeParent(); - // Update mirroring surface for MediaProjection, if this DisplayContent is being used - // for layer mirroring. - if (mMirroredSurface != null) { - // Retrieve the size of the DisplayArea to mirror, and continue with the update if the - // bounds have changed. - final WindowContainer wc = mWmService.mWindowContextListenerController.getContainer( - mTokenToMirror); - if (wc != null && mLastMirroredDisplayAreaBounds != null) { - // Retrieve the size of the DisplayArea to mirror, and continue with the update - // if the bounds or orientation has changed. - final Rect displayAreaBounds = wc.getDisplayContent().getBounds(); - int displayAreaOrientation = wc.getDisplayContent().getOrientation(); - if (!mLastMirroredDisplayAreaBounds.equals(displayAreaBounds) - || lastOrientation != displayAreaOrientation) { - updateMirroredSurface(mWmService.mTransactionFactory.get(), displayAreaBounds); - } - } - } - if (lastOrientation != getConfiguration().orientation) { getMetricsLogger().write( new LogMaker(MetricsEvent.ACTION_PHONE_ORIENTATION_CHANGED) @@ -4362,7 +4323,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp mTmpApplySurfaceChangesTransactionState.preferMinimalPostProcessing, true /* inTraversal, must call performTraversalInTrans... below */); } - updateMirroring(); final boolean wallpaperVisible = mWallpaperController.isWallpaperVisible(); if (wallpaperVisible != mLastWallpaperVisible) { @@ -5882,133 +5842,6 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp return mSandboxDisplayApis; } - /** - * Start mirroring to this DisplayContent if it does not have its own content. Captures the - * content of a WindowContainer indicated by a WindowToken. If unable to start mirroring, falls - * back to original MediaProjection approach. - */ - private void startMirrorIfNeeded() { - // Only mirror if this display does not have its own content. - if (mLastHasContent) { - return; - } - // Given the WindowToken of the DisplayArea to mirror, retrieve the associated - // SurfaceControl. - IBinder tokenToMirror = mWmService.mDisplayManagerInternal.getWindowTokenClientToMirror( - mDisplayId); - - if (tokenToMirror == null) { - // This DisplayContent instance is not involved in layer mirroring. If the display - // has been created for capturing, fall back to prior MediaProjection approach. - return; - } - final WindowContainer wc = mWmService.mWindowContextListenerController.getContainer( - tokenToMirror); - if (wc == null) { - // Un-set the window token to mirror for this VirtualDisplay, to fall back to the - // original MediaProjection approach. - mWmService.mDisplayManagerInternal.setWindowTokenClientToMirror(mDisplayId, null); - return; - } - SurfaceControl sc = wc.getDisplayContent().getSurfaceControl(); - - // Create a mirrored hierarchy for the SurfaceControl of the DisplayArea to capture. - mMirroredSurface = SurfaceControl.mirrorSurface(sc); - SurfaceControl.Transaction transaction = mWmService.mTransactionFactory.get() - // Set the mMirroredSurface's parent to the root SurfaceControl for this - // DisplayContent. This brings the new mirrored hierarchy under this DisplayContent, - // so SurfaceControl will write the layers of this hierarchy to the output surface - // provided by the app. - .reparent(mMirroredSurface, mSurfaceControl) - // Reparent the SurfaceControl of this DisplayContent to null, to prevent content - // being added to it. This ensures that no app launched explicitly on the - // VirtualDisplay will show up as part of the mirrored content. - .reparent(mWindowingLayer, null); - // Retrieve the size of the DisplayArea to mirror. - updateMirroredSurface(transaction, wc.getDisplayContent().getBounds()); - mTokenToMirror = tokenToMirror; - - // No need to clean up. In SurfaceFlinger, parents hold references to their children. The - // mirrored SurfaceControl is alive since the parent DisplayContent SurfaceControl is - // holding a reference to it. Therefore, the mirrored SurfaceControl will be cleaned up - // when the VirtualDisplay is destroyed - which will clean up this DisplayContent. - } - - /** - * Start or stop mirroring if this DisplayContent now has content, or no longer has content. - */ - private void updateMirroring() { - if (mLastHasContent && mMirroredSurface != null) { - // Display now has content, so stop mirroring to it. - mWmService.mTransactionFactory.get() - // Remove the reference to mMirroredSurface, to clean up associated memory. - .remove(mMirroredSurface) - // Reparent the SurfaceControl of this DisplayContent back to mSurfaceControl, - // to allow content to be added to it. This allows this DisplayContent to stop - // mirroring and show content normally. - .reparent(mWindowingLayer, mSurfaceControl).apply(); - // Stop mirroring by destroying the reference to the mirrored layer. - mMirroredSurface = null; - // Do not un-set the token, in case content is removed and mirroring should begin again. - } else if (!mLastHasContent && mMirroredSurface == null) { - // Display no longer has content, so start mirroring to it. - startMirrorIfNeeded(); - } - } - - /** - * Apply transformations to the mirrored surface to ensure the captured contents are scaled to - * fit and centred in the output surface. - * - * @param transaction the transaction to include transformations of mMirroredSurface - * to. Transaction is not applied before returning. - * @param displayAreaBounds bounds of the DisplayArea to mirror to the surface provided by - * the app. - */ - @VisibleForTesting - void updateMirroredSurface(SurfaceControl.Transaction transaction, - Rect displayAreaBounds) { - // Retrieve the default size of the surface the app provided to - // MediaProjection#createVirtualDisplay. Note the app is the consumer of the surface, - // since it reads out buffers from the surface, and SurfaceFlinger is the producer since - // it writes the mirrored layers to the buffers. - final Point surfaceSize = mWmService.mDisplayManagerInternal.getDisplaySurfaceDefaultSize( - mDisplayId); - - // Calculate the scale to apply to the root mirror SurfaceControl to fit the size of the - // output surface. - float scaleX = surfaceSize.x / (float) displayAreaBounds.width(); - float scaleY = surfaceSize.y / (float) displayAreaBounds.height(); - float scale = Math.min(scaleX, scaleY); - int scaledWidth = Math.round(scale * (float) displayAreaBounds.width()); - int scaledHeight = Math.round(scale * (float) displayAreaBounds.height()); - - // Calculate the shift to apply to the root mirror SurfaceControl to centre the mirrored - // contents in the output surface. - int shiftedX = 0; - if (scaledWidth != surfaceSize.x) { - shiftedX = (surfaceSize.x - scaledWidth) / 2; - } - int shiftedY = 0; - if (scaledHeight != surfaceSize.y) { - shiftedY = (surfaceSize.y - scaledHeight) / 2; - } - - transaction - // Crop the area to capture to exclude the 'extra' wallpaper that is used - // for parallax (b/189930234). - .setWindowCrop(mMirroredSurface, displayAreaBounds.width(), - displayAreaBounds.height()) - // Scale the root mirror SurfaceControl, based upon the size difference between the - // source (DisplayArea to capture) and output (surface the app reads images from). - .setMatrix(mMirroredSurface, scale, 0 /* dtdx */, 0 /* dtdy */, scale) - // Position needs to be updated when the mirrored DisplayArea has changed, since - // the content will no longer be centered in the output surface. - .setPosition(mMirroredSurface, shiftedX /* x */, shiftedY /* y */) - .apply(); - mLastMirroredDisplayAreaBounds = new Rect(displayAreaBounds); - } - /** The entry for proceeding to handle {@link #mFixedRotationLaunchingApp}. */ class FixedRotationTransitionListener extends WindowManagerInternal.AppTransitionListener { diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index 597ad24d743cf..ea203c3a82e3f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -67,7 +67,6 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; import static com.android.dx.mockito.inline.extended.ExtendedMockito.never; import static com.android.dx.mockito.inline.extended.ExtendedMockito.reset; import static com.android.dx.mockito.inline.extended.ExtendedMockito.same; @@ -108,12 +107,9 @@ import android.app.WindowConfiguration; import android.app.servertransaction.FixedRotationAdjustmentsItem; import android.content.res.Configuration; import android.graphics.Insets; -import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.metrics.LogMaker; -import android.os.Binder; -import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.platform.test.annotations.Presubmit; @@ -146,8 +142,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; -import org.mockito.MockitoSession; -import org.mockito.quality.Strictness; import java.util.ArrayList; import java.util.Arrays; @@ -2223,113 +2217,6 @@ public class DisplayContentTests extends WindowTestsBase { assertNotEquals(imeMenuDialog, mDisplayContent.findFocusedWindow()); } - @Test - public void testVirtualDisplayContent() { - MockitoSession mockSession = mockitoSession() - .initMocks(this) - .spyStatic(SurfaceControl.class) - .strictness(Strictness.LENIENT) - .startMocking(); - - // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to - // mirror. - final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken(); - - // GIVEN SurfaceControl can successfully mirror the provided surface. - Point surfaceSize = new Point( - mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), - mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); - surfaceControlMirrors(surfaceSize); - - // WHEN creating the DisplayContent for a new virtual display. - final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm, - mDisplayInfo).build(); - - // THEN mirroring is initiated for the default display's DisplayArea. - assertThat(virtualDisplay.mTokenToMirror).isEqualTo(tokenToMirror); - - mockSession.finishMocking(); - } - - @Test - public void testVirtualDisplayContent_capturedAreaResized() { - MockitoSession mockSession = mockitoSession() - .initMocks(this) - .spyStatic(SurfaceControl.class) - .strictness(Strictness.LENIENT) - .startMocking(); - - // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to - // mirror. - final IBinder tokenToMirror = setUpDefaultTaskDisplayAreaWindowToken(); - - // GIVEN SurfaceControl can successfully mirror the provided surface. - Point surfaceSize = new Point( - mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().width(), - mDefaultDisplay.getDefaultTaskDisplayArea().getBounds().height()); - SurfaceControl mirroredSurface = surfaceControlMirrors(surfaceSize); - - // WHEN creating the DisplayContent for a new virtual display. - final DisplayContent virtualDisplay = new TestDisplayContent.Builder(mAtm, - mDisplayInfo).build(); - - // THEN mirroring is initiated for the default display's DisplayArea. - assertThat(virtualDisplay.mTokenToMirror).isEqualTo(tokenToMirror); - - float xScale = 0.7f; - float yScale = 2f; - Rect displayAreaBounds = new Rect(0, 0, Math.round(surfaceSize.x * xScale), - Math.round(surfaceSize.y * yScale)); - virtualDisplay.updateMirroredSurface(mTransaction, displayAreaBounds); - - // THEN content in the captured DisplayArea is scaled to fit the surface size. - verify(mTransaction, atLeastOnce()).setMatrix(mirroredSurface, 1.0f / yScale, 0, 0, - 1.0f / yScale); - // THEN captured content is positioned in the centre of the output surface. - float scaledWidth = displayAreaBounds.width() / xScale; - float xInset = (surfaceSize.x - scaledWidth) / 2; - verify(mTransaction, atLeastOnce()).setPosition(mirroredSurface, xInset, 0); - - mockSession.finishMocking(); - } - - private class TestToken extends Binder { - } - - /** - * Creates a WindowToken associated with the default task DisplayArea, in order for that - * DisplayArea to be mirrored. - */ - private IBinder setUpDefaultTaskDisplayAreaWindowToken() { - // GIVEN MediaProjection has already initialized the WindowToken of the DisplayArea to - // mirror. - final IBinder tokenToMirror = new TestToken(); - doReturn(tokenToMirror).when(mWm.mDisplayManagerInternal).getWindowTokenClientToMirror( - anyInt()); - - // GIVEN the default task display area is represented by the WindowToken. - spyOn(mWm.mWindowContextListenerController); - doReturn(mDefaultDisplay.getDefaultTaskDisplayArea()).when( - mWm.mWindowContextListenerController).getContainer(any()); - return tokenToMirror; - } - - /** - * SurfaceControl successfully creates a mirrored surface of the given size. - */ - private SurfaceControl surfaceControlMirrors(Point surfaceSize) { - // Do not set the parent, since the mirrored surface is the root of a new surface hierarchy. - SurfaceControl mirroredSurface = new SurfaceControl.Builder() - .setName("mirroredSurface") - .setBufferSize(surfaceSize.x, surfaceSize.y) - .setCallsite("mirrorSurface") - .build(); - doReturn(mirroredSurface).when(() -> SurfaceControl.mirrorSurface(any())); - doReturn(surfaceSize).when(mWm.mDisplayManagerInternal).getDisplaySurfaceDefaultSize( - anyInt()); - return mirroredSurface; - } - private void removeRootTaskTests(Runnable runnable) { final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea(); final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN, From 4d48f9ebe3273cf851d947ca99896ae85a690bdf Mon Sep 17 00:00:00 2001 From: bsears Date: Fri, 6 Aug 2021 15:18:26 +0000 Subject: [PATCH 073/176] Revert "Added crop rect to LayerDrawable to not crop TextureView..." Revert "Adds out parameters for crop rectangle and transform" Revert "Add test to crop TextureView and verify if outer edge ha..." Revert submission 15339442-1texelcrop Reason for revert: Bisection identified these CLs as the likely cause of Droidfood blocking bugs b/195620803 and b/195637414 Bug: 195637414 Bug: 195620803 Reverted Changes: If1f448a94:Added crop rect to LayerDrawable to not crop Textu... Iefde6bdf7:Add test to crop TextureView and verify if outer e... Icf0ee20e8:Adds out parameters for crop rectangle and transfo... Change-Id: I3448ebe193f25de79d186ae705911d99da2cef2b (cherry picked from commit 9df09ccff953f45f1990796e0e558e5ec4e3ccb9) --- libs/hwui/DeferredLayerUpdater.cpp | 21 +++--- libs/hwui/DeferredLayerUpdater.h | 2 +- libs/hwui/Layer.cpp | 2 + libs/hwui/Layer.h | 27 ++------ libs/hwui/Readback.cpp | 5 ++ libs/hwui/pipeline/skia/LayerDrawable.cpp | 66 +++++++++---------- libs/hwui/tests/common/TestUtils.cpp | 2 +- .../tests/unit/DeferredLayerUpdaterTests.cpp | 9 ++- 8 files changed, 63 insertions(+), 71 deletions(-) diff --git a/libs/hwui/DeferredLayerUpdater.cpp b/libs/hwui/DeferredLayerUpdater.cpp index 6cb53206f60b9..8d112d1c64bf6 100644 --- a/libs/hwui/DeferredLayerUpdater.cpp +++ b/libs/hwui/DeferredLayerUpdater.cpp @@ -21,6 +21,7 @@ // TODO: Use public SurfaceTexture APIs once available and include public NDK header file instead. #include #include "AutoBackendTextureRelease.h" +#include "Matrix.h" #include "Properties.h" #include "renderstate/RenderState.h" #include "renderthread/EglManager.h" @@ -144,17 +145,16 @@ void DeferredLayerUpdater::apply() { } if (mUpdateTexImage) { mUpdateTexImage = false; + float transformMatrix[16]; android_dataspace dataspace; int slot; bool newContent = false; - ARect rect; - uint32_t textureTransform; // Note: ASurfaceTexture_dequeueBuffer discards all but the last frame. This // is necessary if the SurfaceTexture queue is in synchronous mode, and we // cannot tell which mode it is in. AHardwareBuffer* hardwareBuffer = ASurfaceTexture_dequeueBuffer( - mSurfaceTexture.get(), &slot, &dataspace, &newContent, createReleaseFence, - fenceWait, this, &rect, &textureTransform); + mSurfaceTexture.get(), &slot, &dataspace, transformMatrix, &newContent, + createReleaseFence, fenceWait, this); if (hardwareBuffer) { mCurrentSlot = slot; @@ -165,12 +165,12 @@ void DeferredLayerUpdater::apply() { // (invoked by createIfNeeded) will add a ref to the AHardwareBuffer. AHardwareBuffer_release(hardwareBuffer); if (layerImage.get()) { + SkMatrix textureTransform; + mat4(transformMatrix).copyTo(textureTransform); // force filtration if buffer size != layer size bool forceFilter = mWidth != layerImage->width() || mHeight != layerImage->height(); - SkRect cropRect = - SkRect::MakeLTRB(rect.left, rect.top, rect.right, rect.bottom); - updateLayer(forceFilter, textureTransform, cropRect, layerImage); + updateLayer(forceFilter, textureTransform, layerImage); } } } @@ -182,13 +182,12 @@ void DeferredLayerUpdater::apply() { } } -void DeferredLayerUpdater::updateLayer(bool forceFilter, const uint32_t textureTransform, - const SkRect cropRect, const sk_sp& layerImage) { +void DeferredLayerUpdater::updateLayer(bool forceFilter, const SkMatrix& textureTransform, + const sk_sp& layerImage) { mLayer->setBlend(mBlend); mLayer->setForceFilter(forceFilter); mLayer->setSize(mWidth, mHeight); - mLayer->setTextureTransform(textureTransform); - mLayer->setCropRect(cropRect); + mLayer->getTexTransform() = textureTransform; mLayer->setImage(layerImage); } diff --git a/libs/hwui/DeferredLayerUpdater.h b/libs/hwui/DeferredLayerUpdater.h index 7a63ccd4250db..8f79c4ec97b86 100644 --- a/libs/hwui/DeferredLayerUpdater.h +++ b/libs/hwui/DeferredLayerUpdater.h @@ -90,7 +90,7 @@ public: void detachSurfaceTexture(); - void updateLayer(bool forceFilter, const uint32_t textureTransform, const SkRect cropRect, + void updateLayer(bool forceFilter, const SkMatrix& textureTransform, const sk_sp& layerImage); void destroyLayer(); diff --git a/libs/hwui/Layer.cpp b/libs/hwui/Layer.cpp index 9053c1240957b..47c47e0427a4d 100644 --- a/libs/hwui/Layer.cpp +++ b/libs/hwui/Layer.cpp @@ -35,6 +35,7 @@ Layer::Layer(RenderState& renderState, sk_sp colorFilter, int alp // preserves the old inc/dec ref locations. This should be changed... incStrong(nullptr); renderState.registerLayer(this); + texTransform.setIdentity(); transform.setIdentity(); } @@ -100,6 +101,7 @@ void Layer::draw(SkCanvas* canvas) { const int layerHeight = getHeight(); if (layerImage) { SkMatrix textureMatrixInv; + textureMatrixInv = getTexTransform(); // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed // use bottom left origin and remove flipV and invert transformations. SkMatrix flipV; diff --git a/libs/hwui/Layer.h b/libs/hwui/Layer.h index 656a817837168..e99e76299317d 100644 --- a/libs/hwui/Layer.h +++ b/libs/hwui/Layer.h @@ -74,18 +74,10 @@ public: void setColorFilter(sk_sp filter) { mColorFilter = filter; }; + inline SkMatrix& getTexTransform() { return texTransform; } + inline SkMatrix& getTransform() { return transform; } - inline SkRect getCropRect() { return mCropRect; } - - inline void setCropRect(const SkRect cropRect) { mCropRect = cropRect; } - - inline void setTextureTransform(uint32_t textureTransform) { - mTextureTransform = textureTransform; - } - - inline uint32_t getTextureTransform() { return mTextureTransform; } - /** * Posts a decStrong call to the appropriate thread. * Thread-safe. @@ -123,21 +115,16 @@ private: */ SkBlendMode mode; + /** + * Optional texture coordinates transform. + */ + SkMatrix texTransform; + /** * Optional transform. */ SkMatrix transform; - /** - * Optional crop - */ - SkRect mCropRect; - - /** - * Optional transform - */ - uint32_t mTextureTransform; - /** * An image backing the layer. */ diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp index 386c88a35d85b..a743d30939d05 100644 --- a/libs/hwui/Readback.cpp +++ b/libs/hwui/Readback.cpp @@ -251,6 +251,8 @@ CopyResult Readback::copyHWBitmapInto(Bitmap* hwBitmap, SkBitmap* bitmap) { Rect srcRect; Matrix4 transform; + transform.loadScale(1, -1, 1); + transform.translate(0, -1); return copyImageInto(hwBitmap->makeImage(), transform, srcRect, bitmap); } @@ -278,6 +280,8 @@ CopyResult Readback::copyLayerInto(DeferredLayerUpdater* deferredLayer, SkBitmap CopyResult Readback::copyImageInto(const sk_sp& image, SkBitmap* bitmap) { Rect srcRect; Matrix4 transform; + transform.loadScale(1, -1, 1); + transform.translate(0, -1); return copyImageInto(image, transform, srcRect, bitmap); } @@ -316,6 +320,7 @@ CopyResult Readback::copyImageInto(const sk_sp& image, Matrix4& texTran Layer layer(mRenderThread.renderState(), nullptr, 255, SkBlendMode::kSrc); layer.setSize(displayedWidth, displayedHeight); + texTransform.copyTo(layer.getTexTransform()); layer.setImage(image); // Scaling filter is not explicitly set here, because it is done inside copyLayerInfo // after checking the necessity based on the src/dest rect size and the transformation. diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp index b28277c42cb58..e32788c9ec515 100644 --- a/libs/hwui/pipeline/skia/LayerDrawable.cpp +++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp @@ -18,11 +18,9 @@ #include #include "GrBackendSurface.h" -#include "Matrix.h" #include "SkColorFilter.h" #include "SkSurface.h" #include "gl/GrGLTypes.h" -#include "system/window.h" namespace android { namespace uirenderer { @@ -31,8 +29,7 @@ namespace skiapipeline { void LayerDrawable::onDraw(SkCanvas* canvas) { Layer* layer = mLayerUpdater->backingLayer(); if (layer) { - SkRect srcRect = layer->getCropRect(); - DrawLayer(canvas->recordingContext(), canvas, layer, &srcRect, nullptr, true); + DrawLayer(canvas->recordingContext(), canvas, layer, nullptr, nullptr, true); } } @@ -82,16 +79,33 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, return false; } // transform the matrix based on the layer - const uint32_t transform = layer->getTextureTransform(); + SkMatrix layerTransform = layer->getTransform(); sk_sp layerImage = layer->getImage(); const int layerWidth = layer->getWidth(); const int layerHeight = layer->getHeight(); - SkMatrix layerTransform = layer->getTransform(); + if (layerImage) { + SkMatrix textureMatrixInv; + textureMatrixInv = layer->getTexTransform(); + // TODO: after skia bug https://bugs.chromium.org/p/skia/issues/detail?id=7075 is fixed + // use bottom left origin and remove flipV and invert transformations. + SkMatrix flipV; + flipV.setAll(1, 0, 0, 0, -1, 1, 0, 0, 1); + textureMatrixInv.preConcat(flipV); + textureMatrixInv.preScale(1.0f / layerWidth, 1.0f / layerHeight); + textureMatrixInv.postScale(layerImage->width(), layerImage->height()); + SkMatrix textureMatrix; + if (!textureMatrixInv.invert(&textureMatrix)) { + textureMatrix = textureMatrixInv; + } + SkMatrix matrix; if (useLayerTransform) { - matrix = layerTransform; + matrix = SkMatrix::Concat(layerTransform, textureMatrix); + } else { + matrix = textureMatrix; } + SkPaint paint; paint.setAlpha(layer->getAlpha()); paint.setBlendMode(layer->getMode()); @@ -101,54 +115,39 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, canvas->save(); canvas->concat(matrix); } - const SkMatrix totalMatrix = canvas->getTotalMatrix(); + const SkMatrix& totalMatrix = canvas->getTotalMatrix(); if (dstRect || srcRect) { SkMatrix matrixInv; if (!matrix.invert(&matrixInv)) { matrixInv = matrix; } SkRect skiaSrcRect; - if (srcRect && !srcRect->isEmpty()) { + if (srcRect) { skiaSrcRect = *srcRect; } else { - skiaSrcRect = (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) - ? SkRect::MakeIWH(layerHeight, layerWidth) - : SkRect::MakeIWH(layerWidth, layerHeight); + skiaSrcRect = SkRect::MakeIWH(layerWidth, layerHeight); } matrixInv.mapRect(&skiaSrcRect); SkRect skiaDestRect; - if (dstRect && !dstRect->isEmpty()) { + if (dstRect) { skiaDestRect = *dstRect; } else { skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight); } matrixInv.mapRect(&skiaDestRect); + // If (matrix is a rect-to-rect transform) + // and (src/dst buffers size match in screen coordinates) + // and (src/dst corners align fractionally), + // then use nearest neighbor, otherwise use bilerp sampling. + // Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works + // only for SrcOver blending and without color filter (readback uses Src blending). SkSamplingOptions sampling(SkFilterMode::kNearest); if (layer->getForceFilter() || shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) { sampling = SkSamplingOptions(SkFilterMode::kLinear); } - - const float px = skiaDestRect.centerX(); - const float py = skiaDestRect.centerY(); - if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) { - matrix.postScale(-1.f, 1.f, px, py); - } - if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) { - matrix.postScale(1.f, -1.f, px, py); - } - if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) { - matrix.postRotate(90, 0, 0); - matrix.postTranslate(skiaDestRect.height(), 0); - } - auto constraint = SkCanvas::kFast_SrcRectConstraint; - if (srcRect && srcRect->isEmpty()) { - constraint = SkCanvas::kStrict_SrcRectConstraint; - } - matrix.postConcat(SkMatrix::MakeRectToRect(skiaSrcRect, skiaDestRect, - SkMatrix::kFill_ScaleToFit)); canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, sampling, &paint, - constraint); + SkCanvas::kFast_SrcRectConstraint); } else { SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height()); SkSamplingOptions sampling(SkFilterMode::kNearest); @@ -162,6 +161,7 @@ bool LayerDrawable::DrawLayer(GrRecordingContext* context, canvas->restore(); } } + return layerImage != nullptr; } diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp index 1bfdc47a1d02b..e8ba15fe92aff 100644 --- a/libs/hwui/tests/common/TestUtils.cpp +++ b/libs/hwui/tests/common/TestUtils.cpp @@ -74,7 +74,7 @@ sp TestUtils::createTextureLayerUpdater( layerUpdater->setTransform(&transform); // updateLayer so it's ready to draw - layerUpdater->updateLayer(true, 0, SkRect::MakeEmpty(), nullptr); + layerUpdater->updateLayer(true, SkMatrix::I(), nullptr); return layerUpdater; } diff --git a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp index ca84aeec96a23..955a5e7d8b3a1 100644 --- a/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp +++ b/libs/hwui/tests/unit/DeferredLayerUpdaterTests.cpp @@ -36,20 +36,19 @@ RENDERTHREAD_TEST(DeferredLayerUpdater, updateLayer) { EXPECT_EQ(0u, layerUpdater->backingLayer()->getHeight()); EXPECT_FALSE(layerUpdater->backingLayer()->getForceFilter()); EXPECT_FALSE(layerUpdater->backingLayer()->isBlend()); + EXPECT_EQ(Matrix4::identity(), layerUpdater->backingLayer()->getTexTransform()); // push the deferred updates to the layer - uint32_t textureTransform = 1; + SkMatrix scaledMatrix = SkMatrix::Scale(0.5, 0.5); SkBitmap bitmap; bitmap.allocN32Pixels(16, 16); - SkRect cropRect = SkRect::MakeIWH(10, 10); sk_sp layerImage = SkImage::MakeFromBitmap(bitmap); - layerUpdater->updateLayer(true, textureTransform, cropRect, layerImage); + layerUpdater->updateLayer(true, scaledMatrix, layerImage); // the backing layer should now have all the properties applied. EXPECT_EQ(100u, layerUpdater->backingLayer()->getWidth()); EXPECT_EQ(100u, layerUpdater->backingLayer()->getHeight()); EXPECT_TRUE(layerUpdater->backingLayer()->getForceFilter()); EXPECT_TRUE(layerUpdater->backingLayer()->isBlend()); - EXPECT_EQ(textureTransform, layerUpdater->backingLayer()->getTextureTransform()); - EXPECT_EQ(cropRect, layerUpdater->backingLayer()->getCropRect()); + EXPECT_EQ(scaledMatrix, layerUpdater->backingLayer()->getTexTransform()); } From aedadb880934401625fdded02500462cfa5b8f24 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Wed, 22 Sep 2021 17:58:34 +0000 Subject: [PATCH 074/176] Revert "Make DreamActivity translucent when waking up dream" This reverts commit 7b024ebd9d19489f6bc5ab8db07e46059555e50e. Reason for revert: Bug: 200760427 Change-Id: I37a68c0abab584f214ebd625a77b21b8eba8caf0 (cherry picked from commit aecd865d065baa802f3f1aafb29c4506edcb1553) --- core/java/android/service/dreams/DreamService.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java index 491a5f9b35dbb..a47c3b188b793 100644 --- a/core/java/android/service/dreams/DreamService.java +++ b/core/java/android/service/dreams/DreamService.java @@ -920,13 +920,6 @@ public class DreamService extends Service implements Window.Callback { if (!mWaking && !mFinished) { mWaking = true; - // During wake up the activity should be translucent to allow the application underneath - // to start drawing. Normally, the WM animation system takes care of this, but here we - // give the dream application some time to perform a custom exit animation. - // If it uses a view animation, the WM doesn't know about it and can't make the activity - // translucent in the normal way. Therefore, here we ensure that the activity is - // translucent during wake up regardless of what animation is used in onWakeUp(). - mActivity.convertToTranslucent(null, null); // As a minor optimization, invoke the callback first in case it simply // calls finish() immediately so there wouldn't be much point in telling From c7dfeac8e876b8b3ee1f4e8593b3c75241b5478a Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Thu, 14 Oct 2021 22:48:33 +0000 Subject: [PATCH 075/176] Revert "Keep FLAG_SHOW_WALLPAPER flag on NotificationShade." This reverts commit 5e48aeeaddb94c7f03213664c227618c80a3060f. Reason for revert: Droidfood blocking bugs bug: 203025772 & bug: 203041994 Change-Id: I768c13d2959fb92d2a5d038df560e1575aea0712 (cherry picked from commit f7ef58461c1bb91c6908bd4b2a9b4e68a1df3ed2) --- .../policy/IKeyguardStateCallback.aidl | 1 + .../keyguard/KeyguardUpdateMonitor.java | 26 +++++++++++++++++++ .../KeyguardUpdateMonitorCallback.java | 5 ++++ .../keyguard/KeyguardViewMediator.java | 23 ++++++++++++++++ .../statusbar/phone/LockscreenWallpaper.java | 2 ++ .../server/policy/PhoneWindowManager.java | 14 +++++++++- .../keyguard/KeyguardServiceDelegate.java | 7 +++++ .../keyguard/KeyguardServiceWrapper.java | 4 +++ .../policy/keyguard/KeyguardStateMonitor.java | 10 +++++++ .../com/android/server/wm/DisplayPolicy.java | 9 +++++++ .../server/wm/WindowManagerService.java | 14 ++++------ 11 files changed, 105 insertions(+), 10 deletions(-) diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl index d69a240b140b7..a8003a1169e9a 100644 --- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl +++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl @@ -20,4 +20,5 @@ interface IKeyguardStateCallback { void onSimSecureStateChanged(boolean simSecure); void onInputRestrictedStateChanged(boolean inputRestricted); void onTrustedChanged(boolean trusted); + void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper); } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 24f367335ad98..5969e9290c9c9 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -277,6 +277,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private boolean mBouncer; // true if bouncerIsOrWillBeShowing private boolean mAuthInterruptActive; private boolean mNeedsSlowUnlockTransition; + private boolean mHasLockscreenWallpaper; private boolean mAssistantVisible; private boolean mKeyguardOccluded; private boolean mOccludingAppRequestingFp; @@ -2577,6 +2578,31 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } + /** + * Update the state whether Keyguard currently has a lockscreen wallpaper. + * + * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper. + */ + public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) { + Assert.isMainThread(); + if (hasLockscreenWallpaper != mHasLockscreenWallpaper) { + mHasLockscreenWallpaper = hasLockscreenWallpaper; + for (int i = 0; i < mCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper); + } + } + } + } + + /** + * @return Whether Keyguard has a lockscreen wallpaper. + */ + public boolean hasLockscreenWallpaper() { + return mHasLockscreenWallpaper; + } + /** * Handle {@link #MSG_DPM_STATE_CHANGED} */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index e970a86c65168..6aa7aaa4d4889 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -291,6 +291,11 @@ public class KeyguardUpdateMonitorCallback { */ public void onStrongAuthStateChanged(int userId) { } + /** + * Called when the state whether we have a lockscreen wallpaper has changed. + */ + public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { } + /** * Called when the dream's window state is changed. * @param dreaming true if the dream's window has been created and is visible diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 78138402184d2..526571861be03 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -670,6 +670,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } } } + + @Override + public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { + synchronized (KeyguardViewMediator.this) { + notifyHasLockscreenWallpaperChanged(hasLockscreenWallpaper); + } + } }; ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { @@ -2866,6 +2873,21 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } } + private void notifyHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { + int size = mKeyguardStateCallbacks.size(); + for (int i = size - 1; i >= 0; i--) { + try { + mKeyguardStateCallbacks.get(i).onHasLockscreenWallpaperChanged( + hasLockscreenWallpaper); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call onHasLockscreenWallpaperChanged", e); + if (e instanceof DeadObjectException) { + mKeyguardStateCallbacks.remove(i); + } + } + } + } + public void addStateMonitorCallback(IKeyguardStateCallback callback) { synchronized (this) { mKeyguardStateCallbacks.add(callback); @@ -2875,6 +2897,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, callback.onInputRestrictedStateChanged(mInputRestricted); callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust( KeyguardUpdateMonitor.getCurrentUser())); + callback.onHasLockscreenWallpaperChanged(mUpdateMonitor.hasLockscreenWallpaper()); } catch (RemoteException e) { Slog.w(TAG, "Failed to call to IKeyguardStateCallback", e); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index 2a13e6bbd37e4..78fcd82dc1f5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -119,6 +119,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen LoaderResult result = loadBitmap(mCurrentUserId, mSelectedUser); if (result.success) { mCached = true; + mUpdateMonitor.setHasLockscreenWallpaper(result.bitmap != null); mCache = result.bitmap; } return mCache; @@ -234,6 +235,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen if (result.success) { mCached = true; mCache = result.bitmap; + mUpdateMonitor.setHasLockscreenWallpaper(result.bitmap != null); mMediaManager.updateMediaMetaData( true /* metaDataChanged */, true /* allowEnterAnimation */); } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 5d34939919851..12e6086d8b012 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -47,6 +47,7 @@ import static android.view.KeyEvent.KEYCODE_VOLUME_UP; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; +import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; @@ -3290,7 +3291,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { final boolean showing = mKeyguardDelegate.isShowing(); final boolean animate = showing && !isOccluded; mKeyguardDelegate.setOccluded(isOccluded, animate); - return showing; + + if (!showing) { + return false; + } + if (mKeyguardCandidate != null) { + if (isOccluded) { + mKeyguardCandidate.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER; + } else if (!mKeyguardDelegate.hasLockscreenWallpaper()) { + mKeyguardCandidate.getAttrs().flags |= FLAG_SHOW_WALLPAPER; + } + } + return true; } /** {@inheritDoc} */ diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index cdd36f7e25dd0..86ff33e8cc423 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -235,6 +235,13 @@ public class KeyguardServiceDelegate { return false; } + public boolean hasLockscreenWallpaper() { + if (mKeyguardService != null) { + return mKeyguardService.hasLockscreenWallpaper(); + } + return false; + } + public boolean hasKeyguard() { return mKeyguardState.deviceHasKeyguard; } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 2029f869802ee..c356fec83fa8c 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -267,6 +267,10 @@ public class KeyguardServiceWrapper implements IKeyguardService { return mKeyguardStateMonitor.isTrusted(); } + public boolean hasLockscreenWallpaper() { + return mKeyguardStateMonitor.hasLockscreenWallpaper(); + } + public boolean isSecure(int userId) { return mKeyguardStateMonitor.isSecure(userId); } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index c0aa8aeff7111..f0f62edf87792 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -44,6 +44,7 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { private volatile boolean mSimSecure = true; private volatile boolean mInputRestricted = true; private volatile boolean mTrusted = false; + private volatile boolean mHasLockscreenWallpaper = false; private int mCurrentUserId; @@ -78,6 +79,10 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { return mTrusted; } + public boolean hasLockscreenWallpaper() { + return mHasLockscreenWallpaper; + } + public int getCurrentUser() { return mCurrentUserId; } @@ -111,6 +116,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mCallback.onTrustedChanged(); } + @Override // Binder interface + public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { + mHasLockscreenWallpaper = hasLockscreenWallpaper; + } + public interface StateCallback { void onTrustedChanged(); void onShowingChanged(); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index c9a8d9428b0e0..881bd353ad469 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -913,6 +913,15 @@ public class DisplayPolicy { // letterboxed. Hence always let them extend under the cutout. attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; break; + case TYPE_NOTIFICATION_SHADE: + // If the Keyguard is in a hidden state (occluded by another window), we force to + // remove the wallpaper and keyguard flag so that any change in-flight after setting + // the keyguard as occluded wouldn't set these flags again. + // See {@link #processKeyguardSetHiddenResultLw}. + if (mService.mPolicy.isKeyguardOccluded()) { + attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; + } + break; case TYPE_TOAST: // While apps should use the dedicated toast APIs to add such windows diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f11fa16557129..438bfaf21d0f4 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2583,17 +2583,13 @@ public class WindowManagerService extends IWindowManager.Stub // an exit. win.mAnimatingExit = true; } else if (win.mDisplayContent.okToAnimate() - && win.mDisplayContent.mWallpaperController.isWallpaperTarget(win) - && win.mAttrs.type == TYPE_NOTIFICATION_SHADE) { - // If the wallpaper is currently behind this app window, we need to change both of them - // inside of a transaction to avoid artifacts. - // For NotificationShade, sysui is in charge of running window animation and it updates - // the client view visibility only after both NotificationShade and the wallpaper are - // hidden. So we don't need to care about exit animation, but can destroy its surface - // immediately. + && win.mDisplayContent.mWallpaperController.isWallpaperTarget(win)) { + // If the wallpaper is currently behind this + // window, we need to change both of them inside + // of a transaction to avoid artifacts. win.mAnimatingExit = true; } else { - boolean stopped = win.mActivityRecord == null || win.mActivityRecord.mAppStopped; + boolean stopped = win.mActivityRecord != null ? win.mActivityRecord.mAppStopped : true; // We set mDestroying=true so ActivityRecord#notifyAppStopped in-to destroy surfaces // will later actually destroy the surface if we do not do so here. Normally we leave // this to the exit animation. From cfe825ebef67f87d06a6c51094835fd2b7b694a9 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Thu, 14 Oct 2021 22:48:33 +0000 Subject: [PATCH 076/176] Revert "Keep FLAG_SHOW_WALLPAPER flag on NotificationShade." This reverts commit 5e48aeeaddb94c7f03213664c227618c80a3060f. Reason for revert: Droidfood blocking bugs bug: 203025772 & bug: 203041994 Change-Id: I768c13d2959fb92d2a5d038df560e1575aea0712 (cherry picked from commit f7ef58461c1bb91c6908bd4b2a9b4e68a1df3ed2) --- .../policy/IKeyguardStateCallback.aidl | 1 + .../keyguard/KeyguardUpdateMonitor.java | 26 +++++++++++++++++++ .../KeyguardUpdateMonitorCallback.java | 5 ++++ .../keyguard/KeyguardViewMediator.java | 23 ++++++++++++++++ .../statusbar/phone/LockscreenWallpaper.java | 2 ++ .../server/policy/PhoneWindowManager.java | 14 +++++++++- .../keyguard/KeyguardServiceDelegate.java | 7 +++++ .../keyguard/KeyguardServiceWrapper.java | 4 +++ .../policy/keyguard/KeyguardStateMonitor.java | 10 +++++++ .../com/android/server/wm/DisplayPolicy.java | 9 +++++++ .../server/wm/WindowManagerService.java | 14 ++++------ 11 files changed, 105 insertions(+), 10 deletions(-) diff --git a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl index d69a240b140b7..a8003a1169e9a 100644 --- a/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl +++ b/core/java/com/android/internal/policy/IKeyguardStateCallback.aidl @@ -20,4 +20,5 @@ interface IKeyguardStateCallback { void onSimSecureStateChanged(boolean simSecure); void onInputRestrictedStateChanged(boolean inputRestricted); void onTrustedChanged(boolean trusted); + void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper); } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index 5707fa7b18d7f..5c0fb5d4257ae 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -271,6 +271,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab private boolean mBouncer; // true if bouncerIsOrWillBeShowing private boolean mAuthInterruptActive; private boolean mNeedsSlowUnlockTransition; + private boolean mHasLockscreenWallpaper; private boolean mAssistantVisible; private boolean mKeyguardOccluded; private boolean mOccludingAppRequestingFp; @@ -2531,6 +2532,31 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab } } + /** + * Update the state whether Keyguard currently has a lockscreen wallpaper. + * + * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper. + */ + public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) { + Assert.isMainThread(); + if (hasLockscreenWallpaper != mHasLockscreenWallpaper) { + mHasLockscreenWallpaper = hasLockscreenWallpaper; + for (int i = 0; i < mCallbacks.size(); i++) { + KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get(); + if (cb != null) { + cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper); + } + } + } + } + + /** + * @return Whether Keyguard has a lockscreen wallpaper. + */ + public boolean hasLockscreenWallpaper() { + return mHasLockscreenWallpaper; + } + /** * Handle {@link #MSG_DPM_STATE_CHANGED} */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java index 12431984c9b92..1e951f923f134 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java @@ -291,6 +291,11 @@ public class KeyguardUpdateMonitorCallback { */ public void onStrongAuthStateChanged(int userId) { } + /** + * Called when the state whether we have a lockscreen wallpaper has changed. + */ + public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { } + /** * Called when the dream's window state is changed. * @param dreaming true if the dream's window has been created and is visible diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 78138402184d2..526571861be03 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -670,6 +670,13 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } } } + + @Override + public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { + synchronized (KeyguardViewMediator.this) { + notifyHasLockscreenWallpaperChanged(hasLockscreenWallpaper); + } + } }; ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() { @@ -2866,6 +2873,21 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, } } + private void notifyHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { + int size = mKeyguardStateCallbacks.size(); + for (int i = size - 1; i >= 0; i--) { + try { + mKeyguardStateCallbacks.get(i).onHasLockscreenWallpaperChanged( + hasLockscreenWallpaper); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call onHasLockscreenWallpaperChanged", e); + if (e instanceof DeadObjectException) { + mKeyguardStateCallbacks.remove(i); + } + } + } + } + public void addStateMonitorCallback(IKeyguardStateCallback callback) { synchronized (this) { mKeyguardStateCallbacks.add(callback); @@ -2875,6 +2897,7 @@ public class KeyguardViewMediator extends SystemUI implements Dumpable, callback.onInputRestrictedStateChanged(mInputRestricted); callback.onTrustedChanged(mUpdateMonitor.getUserHasTrust( KeyguardUpdateMonitor.getCurrentUser())); + callback.onHasLockscreenWallpaperChanged(mUpdateMonitor.hasLockscreenWallpaper()); } catch (RemoteException e) { Slog.w(TAG, "Failed to call to IKeyguardStateCallback", e); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index 2a13e6bbd37e4..78fcd82dc1f5a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -119,6 +119,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen LoaderResult result = loadBitmap(mCurrentUserId, mSelectedUser); if (result.success) { mCached = true; + mUpdateMonitor.setHasLockscreenWallpaper(result.bitmap != null); mCache = result.bitmap; } return mCache; @@ -234,6 +235,7 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen if (result.success) { mCached = true; mCache = result.bitmap; + mUpdateMonitor.setHasLockscreenWallpaper(result.bitmap != null); mMediaManager.updateMediaMetaData( true /* metaDataChanged */, true /* allowEnterAnimation */); } diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 5d34939919851..12e6086d8b012 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -47,6 +47,7 @@ import static android.view.KeyEvent.KEYCODE_VOLUME_UP; import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW; import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; +import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED; import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW; import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW; @@ -3290,7 +3291,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { final boolean showing = mKeyguardDelegate.isShowing(); final boolean animate = showing && !isOccluded; mKeyguardDelegate.setOccluded(isOccluded, animate); - return showing; + + if (!showing) { + return false; + } + if (mKeyguardCandidate != null) { + if (isOccluded) { + mKeyguardCandidate.getAttrs().flags &= ~FLAG_SHOW_WALLPAPER; + } else if (!mKeyguardDelegate.hasLockscreenWallpaper()) { + mKeyguardCandidate.getAttrs().flags |= FLAG_SHOW_WALLPAPER; + } + } + return true; } /** {@inheritDoc} */ diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index cdd36f7e25dd0..86ff33e8cc423 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -235,6 +235,13 @@ public class KeyguardServiceDelegate { return false; } + public boolean hasLockscreenWallpaper() { + if (mKeyguardService != null) { + return mKeyguardService.hasLockscreenWallpaper(); + } + return false; + } + public boolean hasKeyguard() { return mKeyguardState.deviceHasKeyguard; } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 2029f869802ee..c356fec83fa8c 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -267,6 +267,10 @@ public class KeyguardServiceWrapper implements IKeyguardService { return mKeyguardStateMonitor.isTrusted(); } + public boolean hasLockscreenWallpaper() { + return mKeyguardStateMonitor.hasLockscreenWallpaper(); + } + public boolean isSecure(int userId) { return mKeyguardStateMonitor.isSecure(userId); } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index c0aa8aeff7111..f0f62edf87792 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -44,6 +44,7 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { private volatile boolean mSimSecure = true; private volatile boolean mInputRestricted = true; private volatile boolean mTrusted = false; + private volatile boolean mHasLockscreenWallpaper = false; private int mCurrentUserId; @@ -78,6 +79,10 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { return mTrusted; } + public boolean hasLockscreenWallpaper() { + return mHasLockscreenWallpaper; + } + public int getCurrentUser() { return mCurrentUserId; } @@ -111,6 +116,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { mCallback.onTrustedChanged(); } + @Override // Binder interface + public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { + mHasLockscreenWallpaper = hasLockscreenWallpaper; + } + public interface StateCallback { void onTrustedChanged(); void onShowingChanged(); diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index cf7204a8faa97..5a522fc5190b6 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -913,6 +913,15 @@ public class DisplayPolicy { // letterboxed. Hence always let them extend under the cutout. attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; break; + case TYPE_NOTIFICATION_SHADE: + // If the Keyguard is in a hidden state (occluded by another window), we force to + // remove the wallpaper and keyguard flag so that any change in-flight after setting + // the keyguard as occluded wouldn't set these flags again. + // See {@link #processKeyguardSetHiddenResultLw}. + if (mService.mPolicy.isKeyguardOccluded()) { + attrs.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; + } + break; case TYPE_TOAST: // While apps should use the dedicated toast APIs to add such windows diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 80f74f08a5c7b..0fb26d5a5519f 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2584,17 +2584,13 @@ public class WindowManagerService extends IWindowManager.Stub // an exit. win.mAnimatingExit = true; } else if (win.mDisplayContent.okToAnimate() - && win.mDisplayContent.mWallpaperController.isWallpaperTarget(win) - && win.mAttrs.type == TYPE_NOTIFICATION_SHADE) { - // If the wallpaper is currently behind this app window, we need to change both of them - // inside of a transaction to avoid artifacts. - // For NotificationShade, sysui is in charge of running window animation and it updates - // the client view visibility only after both NotificationShade and the wallpaper are - // hidden. So we don't need to care about exit animation, but can destroy its surface - // immediately. + && win.mDisplayContent.mWallpaperController.isWallpaperTarget(win)) { + // If the wallpaper is currently behind this + // window, we need to change both of them inside + // of a transaction to avoid artifacts. win.mAnimatingExit = true; } else { - boolean stopped = win.mActivityRecord == null || win.mActivityRecord.mAppStopped; + boolean stopped = win.mActivityRecord != null ? win.mActivityRecord.mAppStopped : true; // We set mDestroying=true so ActivityRecord#notifyAppStopped in-to destroy surfaces // will later actually destroy the surface if we do not do so here. Normally we leave // this to the exit animation. From 7aceb374939b47a5f958684ade9c561dc67dfaa4 Mon Sep 17 00:00:00 2001 From: Jay Aliomer Date: Wed, 20 Oct 2021 11:17:01 -0400 Subject: [PATCH 077/176] Null check if renderer is null Local colors are added before the renderer is created which is causing crash Fixes: 203613925 Test: switch to user back and forward Change-Id: I2f169434e1cb0e692045050e255d24d1f8fa7c47 (cherry picked from commit e310840dff797f2c3ef25bd7e1ec5ee6f3f70109) --- .../SystemUI/src/com/android/systemui/ImageWallpaper.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index d2566b448ba67..d1739aaccac28 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -238,9 +238,7 @@ public class ImageWallpaper extends WallpaperService { Bitmap bitmap = mMiniBitmap; if (bitmap == null) { mLocalColorsToAdd.addAll(regions); - mRenderer.use(b -> { - updateMiniBitmapAndNotify(b); - }); + if (mRenderer != null) mRenderer.use(this::updateMiniBitmapAndNotify); } else { computeAndNotifyLocalColors(regions, bitmap); } From b23d113a06986b15d875d63b77d4a059b40366ef Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Mon, 8 Nov 2021 17:20:04 +0000 Subject: [PATCH 078/176] Revert "Always check if the view can be recycled." Revert "Add test checking view recycling is always tested" Revert submission 16149646-betterRecycling Reason for revert: Droidfood Blocking Bug: 205503898 Reverted Changes: Ib01c511e4:Always check if the view can be recycled. If11dcd323:Add test checking view recycling is always tested Change-Id: Id08d5ea3602d9d3ca03e148e57a9f97435534e2c (cherry picked from commit 951bc7d8923cbbc90687f8dd19c45975f56e3ca6) --- core/java/android/widget/RemoteViews.java | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index 57b7d618917da..2357d13c8d41d 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -5746,9 +5746,11 @@ public class RemoteViews implements Parcelable, Filter { // persisted across change, and has the RemoteViews re-applied in a different situation // (orientation or size), we throw an exception, since the layouts may be completely // unrelated. - if (!rvToApply.canRecycleView(v)) { - throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" - + " that does not share the same root layout id."); + if (hasMultipleLayouts()) { + if (!rvToApply.canRecycleView(v)) { + throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" + + " that does not share the same root layout id."); + } } rvToApply.performApply(v, (ViewGroup) v.getParent(), handler, colorResources); @@ -5792,9 +5794,11 @@ public class RemoteViews implements Parcelable, Filter { // In the case that a view has this RemoteViews applied in one orientation, is persisted // across orientation change, and has the RemoteViews re-applied in the new orientation, // we throw an exception, since the layouts may be completely unrelated. - if (!rvToApply.canRecycleView(v)) { - throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" - + " that does not share the same root layout id."); + if (hasMultipleLayouts()) { + if (!rvToApply.canRecycleView(v)) { + throw new RuntimeException("Attempting to re-apply RemoteViews to a view that" + + " that does not share the same root layout id."); + } } return new AsyncApplyTask(rvToApply, (ViewGroup) v.getParent(), From fe5cb70918e4d4175b72a50c0959be71b670e4de Mon Sep 17 00:00:00 2001 From: Ben Lin Date: Tue, 16 Nov 2021 18:55:49 +0000 Subject: [PATCH 079/176] Revert "PiP: Recalculate size if too big/small on display change." This reverts commit 4ef153a7970c64f3cb997c408b41465e3e9ef36f. Reason for revert: This fixes a foldable bug and so not really needed anymore for sc-v2. We'll leave it master only. Bug: b/205761901 Bug: b/206644532 Change-Id: Ia50d491d89a4c9faaa49c3e2b9afe38f73bd7f57 (cherry picked from commit 06f8587f412ceddfce8cc676df0dbf92c05cbad2) Merged-In:Ia50d491d89a4c9faaa49c3e2b9afe38f73bd7f57 --- .../wm/shell/pip/phone/PipController.java | 21 ++++--------------- .../wm/shell/pip/phone/PipMotionHelper.java | 9 -------- .../wm/shell/pip/phone/PipControllerTest.java | 2 +- 3 files changed, 5 insertions(+), 27 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index f25cff70e8d54..d18bcfc782c8f 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -491,25 +491,12 @@ public class PipController implements PipTransitionController.PipTransitionCallb if (mPipTaskOrganizer.isInPip() && saveRestoreSnapFraction) { // Calculate the snap fraction of the current stack along the old movement bounds final PipSnapAlgorithm pipSnapAlgorithm = mPipBoundsAlgorithm.getSnapAlgorithm(); - final float snapFraction = pipSnapAlgorithm.getSnapFraction(mPipBoundsState.getBounds(), - mPipBoundsAlgorithm.getMovementBounds(mPipBoundsState.getBounds()), + final Rect postChangeStackBounds = new Rect(mPipBoundsState.getBounds()); + final float snapFraction = pipSnapAlgorithm.getSnapFraction(postChangeStackBounds, + mPipBoundsAlgorithm.getMovementBounds(postChangeStackBounds), mPipBoundsState.getStashedState()); updateDisplayLayout.run(); - final Rect postChangeStackBounds; - if (mPipBoundsState.getBounds() != null - && (mPipBoundsState.getBounds().width() > mPipBoundsState.getMaxSize().x - || mPipBoundsState.getBounds().height() > mPipBoundsState.getMaxSize().y)) { - postChangeStackBounds = new Rect(0, 0, mPipBoundsState.getMaxSize().x, - mPipBoundsState.getMaxSize().y); - } else if (mPipBoundsState.getBounds() != null - && (mPipBoundsState.getBounds().width() < mPipBoundsState.getMinSize().x - || mPipBoundsState.getBounds().height() < mPipBoundsState.getMinSize().y)) { - postChangeStackBounds = new Rect(0, 0, mPipBoundsState.getMinSize().x, - mPipBoundsState.getMinSize().y); - } else { - postChangeStackBounds = new Rect(mPipBoundsState.getBounds()); - } // Calculate the stack bounds in the new orientation based on same fraction along the // rotated movement bounds. @@ -521,7 +508,7 @@ public class PipController implements PipTransitionController.PipTransitionCallb mPipBoundsState.getDisplayBounds(), mPipBoundsState.getDisplayLayout().stableInsets()); - mTouchHandler.getMotionHelper().animateResizedBounds(postChangeStackBounds); + mTouchHandler.getMotionHelper().movePip(postChangeStackBounds); } else { updateDisplayLayout.run(); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java index c634b7f220b05..96fd59f0c9113 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java @@ -69,7 +69,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, private static final int UNSTASH_DURATION = 250; private static final int LEAVE_PIP_DURATION = 300; private static final int SHIFT_DURATION = 300; - private static final int ANIMATE_PIP_RESIZE_ANIMATION = 250; /** Friction to use for PIP when it moves via physics fling animations. */ private static final float DEFAULT_FRICTION = 1.9f; @@ -548,14 +547,6 @@ public class PipMotionHelper implements PipAppOpsListener.Callback, resizeAndAnimatePipUnchecked(unstashedBounds, UNSTASH_DURATION); } - /** - * Animates the PiP from an old bound to a new bound. This is mostly used when display - * has changed and PiP bounds needs to be changed. - */ - void animateResizedBounds(Rect newBounds) { - resizeAndAnimatePipUnchecked(newBounds, ANIMATE_PIP_RESIZE_ANIMATION); - } - /** * Animates the PiP to offset it from the IME or shelf. */ diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java index c2f58b8b62662..935f6695538de 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java @@ -191,7 +191,7 @@ public class PipControllerTest extends ShellTestCase { mPipController.mDisplaysChangedListener.onDisplayConfigurationChanged( displayId, new Configuration()); - verify(mMockPipMotionHelper).animateResizedBounds(any(Rect.class)); + verify(mMockPipMotionHelper).movePip(any(Rect.class)); } @Test From ebc1a84f12d9031d6396fd8dd23fa15bcd88dc83 Mon Sep 17 00:00:00 2001 From: Patrick Baumann Date: Thu, 18 Nov 2021 17:43:42 +0000 Subject: [PATCH 080/176] Reintroduce internal variant of getComponentEnabledSetting The *Internal variant of the getComponentEnabledSetting call was removed in ag/16176950, which was an oversight. This change adds it back to avoid unnecessary permission checks on calls to PackageManagerInternal#getComponentEnabledSetting. Fixes: 206734531 Change-Id: Ifab64bb18960cc504c97a63f46d621bdb812732a (cherry picked from commit 5fe47535521cfa840779fd7da2ac9015043385ae) Merged-In:Ifab64bb18960cc504c97a63f46d621bdb812732a --- .../java/com/android/server/pm/Computer.java | 5 ++++ .../com/android/server/pm/ComputerEngine.java | 24 ++++++++++++------- .../com/android/server/pm/ComputerLocked.java | 8 +++++++ .../android/server/pm/ComputerTracker.java | 9 +++++++ .../server/pm/PackageManagerService.java | 4 ++-- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java index 6f619583b876e..7a301d411d2f2 100644 --- a/services/core/java/com/android/server/pm/Computer.java +++ b/services/core/java/com/android/server/pm/Computer.java @@ -514,6 +514,11 @@ public interface Computer { int getComponentEnabledSetting(@NonNull ComponentName component, int callingUid, @UserIdInt int userId); + @Computer.LiveImplementation(override = LiveImplementation.MANDATORY) + @PackageManager.EnabledState + int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid, + @UserIdInt int userId); + /** * @return true if the runtime app user enabled state, runtime component user enabled state, * install-time app manifest enabled state, and install-time component manifest enabled state diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java index 996509788637c..887dfff413840 100644 --- a/services/core/java/com/android/server/pm/ComputerEngine.java +++ b/services/core/java/com/android/server/pm/ComputerEngine.java @@ -5015,20 +5015,26 @@ public class ComputerEngine implements Computer { @UserIdInt int userId) { enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled"); + return getComponentEnabledSettingInternal(component, callingUid, userId); + } + @PackageManager.EnabledState + @Override + public int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid, + @UserIdInt int userId) { if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT; if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; - try { - if (shouldFilterApplication( - mSettings.getPackage(component.getPackageName()), callingUid, - component, TYPE_UNKNOWN, userId)) { - throw new PackageManager.NameNotFoundException(component.getPackageName()); - } - return mSettings.getComponentEnabledSetting(component, userId); - } catch (PackageManager.NameNotFoundException e) { - throw new IllegalArgumentException("Unknown component: " + component); + try { + if (shouldFilterApplication( + mSettings.getPackage(component.getPackageName()), callingUid, + component, TYPE_UNKNOWN, userId)) { + throw new PackageManager.NameNotFoundException(component.getPackageName()); } + return mSettings.getComponentEnabledSetting(component, userId); + } catch (PackageManager.NameNotFoundException e) { + throw new IllegalArgumentException("Unknown component: " + component); + } } @Override diff --git a/services/core/java/com/android/server/pm/ComputerLocked.java b/services/core/java/com/android/server/pm/ComputerLocked.java index d234d4dde3f98..801aaeff8ada7 100644 --- a/services/core/java/com/android/server/pm/ComputerLocked.java +++ b/services/core/java/com/android/server/pm/ComputerLocked.java @@ -649,6 +649,14 @@ public final class ComputerLocked extends ComputerEngine { } } + @Override + public int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid, + @UserIdInt int userId) { + synchronized (mLock) { + return super.getComponentEnabledSettingInternal(component, callingUid, userId); + } + } + @Override public boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo, @UserIdInt int userId) { diff --git a/services/core/java/com/android/server/pm/ComputerTracker.java b/services/core/java/com/android/server/pm/ComputerTracker.java index 37298cd52f751..ca17d66f4e25e 100644 --- a/services/core/java/com/android/server/pm/ComputerTracker.java +++ b/services/core/java/com/android/server/pm/ComputerTracker.java @@ -1089,6 +1089,15 @@ public final class ComputerTracker implements Computer { } } + @Override + public int getComponentEnabledSettingInternal(@NonNull ComponentName component, int callingUid, + @UserIdInt int userId) { + try (ThreadComputer current = snapshot()) { + return current.mComputer.getComponentEnabledSettingInternal( + component, callingUid, userId); + } + } + @Override public boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo, @UserIdInt int userId) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 5f56d4e100369..ab01961517f4b 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -8195,8 +8195,8 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @PackageManager.EnabledState int getComponentEnabledSetting( @NonNull ComponentName componentName, int callingUid, int userId) { - return PackageManagerService.this.mComputer.getComponentEnabledSetting(componentName, - callingUid, userId); + return PackageManagerService.this.mComputer.getComponentEnabledSettingInternal( + componentName, callingUid, userId); } @Override From f441d412a0b8d567b340d0498aeda018e890dad4 Mon Sep 17 00:00:00 2001 From: Alice Kuo Date: Mon, 22 Nov 2021 18:06:05 +0800 Subject: [PATCH 081/176] Fix settingLib couldn't receive the broadcast issue. Bug: 207311784 Test: scan device normal Change-Id: I3bb628871b4921f87c92e03386bcb6f66d90ae9f (cherry picked from commit f634234fca006e10ec31cae4a788e0ced4554c57) Merged-In:I3bb628871b4921f87c92e03386bcb6f66d90ae9f --- .../settingslib/bluetooth/BluetoothEventManager.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index 58d2185ea9e9e..1df1bce014cbb 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -160,10 +160,12 @@ public class BluetoothEventManager { private void registerIntentReceiver(BroadcastReceiver receiver, IntentFilter filter) { if (mUserHandle == null) { // If userHandle has not been provided, simply call registerReceiver. - mContext.registerReceiver(receiver, filter, null, mReceiverHandler); + mContext.registerReceiver(receiver, filter, null, mReceiverHandler, + Context.RECEIVER_EXPORTED); } else { // userHandle was explicitly specified, so need to call multi-user aware API. - mContext.registerReceiverAsUser(receiver, mUserHandle, filter, null, mReceiverHandler); + mContext.registerReceiverAsUser(receiver, mUserHandle, filter, null, mReceiverHandler, + Context.RECEIVER_EXPORTED); } } From 53fa17ef7d380c12e9e66f4826b6fde0d9362a9b Mon Sep 17 00:00:00 2001 From: Rick Yiu Date: Thu, 2 Dec 2021 04:23:16 +0000 Subject: [PATCH 082/176] Revert "SDK libraries." This reverts commit 8d0ec8faa8eb44dd8bfb4b507faa209edcc77f8e. Reason for revert: DroidMonitor: Potential culprit for Bug 208710019 - verifying through Forrest before revert submission. This is part of the standard investigation process, and does not mean your CL will be reverted Change-Id: Ic1ff41e7648afc0fa50081de9b7d538a49c6468a (cherry picked from commit a22b7e05d4ee2dddb6e89726102b10f0d8257381) Merged-In:Ic1ff41e7648afc0fa50081de9b7d538a49c6468a --- core/api/current.txt | 1 - .../android/content/pm/PackageManager.java | 10 +- .../android/content/pm/SharedLibraryInfo.java | 17 --- .../content/pm/parsing/ParsingPackage.java | 14 +- .../pm/parsing/ParsingPackageImpl.java | 120 +++--------------- .../pm/parsing/ParsingPackageRead.java | 31 ----- .../pm/parsing/ParsingPackageUtils.java | 111 +--------------- .../pm/parsing/PkgWithoutStateAppInfo.java | 7 +- core/res/res/values/attrs_manifest.xml | 30 ----- .../com/android/server/pm/ComputerEngine.java | 93 ++------------ .../server/pm/DeletePackageHelper.java | 18 +-- .../server/pm/InstallPackageHelper.java | 8 +- .../server/pm/PackageInstallerService.java | 2 +- .../server/pm/PackageInstallerSession.java | 2 +- .../server/pm/PackageManagerService.java | 84 ++++-------- .../server/pm/PackageManagerShellCommand.java | 86 ++++--------- .../com/android/server/pm/PackageSetting.java | 57 ++------- .../server/pm/RemovePackageHelper.java | 14 +- .../android/server/pm/ScanPackageHelper.java | 16 +-- .../com/android/server/pm/ScanResult.java | 4 - .../java/com/android/server/pm/Settings.java | 111 +++------------- .../server/pm/SharedLibraryHelper.java | 65 ++++------ .../pm/parsing/pkg/AndroidPackageUtils.java | 14 +- .../android/server/pm/pkg/PackageState.java | 13 +- .../server/pm/pkg/PackageStateImpl.java | 31 +---- ...geManagerComponentLabelIconOverrideTest.kt | 2 +- .../parsing/parcelling/AndroidPackageTest.kt | 58 ++++----- .../src/com/android/server/pm/MockSystem.kt | 2 +- .../pm/PackageManagerSettingsTests.java | 108 ---------------- .../android/server/pm/PackageParserTest.java | 7 +- .../server/pm/PackageSettingBuilder.java | 18 ++- .../src/com/android/server/pm/ScanTests.java | 43 +------ tools/aapt2/dump/DumpManifest.cpp | 62 --------- tools/aapt2/link/ManifestFixer.cpp | 10 -- 34 files changed, 210 insertions(+), 1059 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 2501c0281952d..56b6800fba13b 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -13223,7 +13223,6 @@ package android.content.pm { field @NonNull public static final android.os.Parcelable.Creator CREATOR; field public static final int TYPE_BUILTIN = 0; // 0x0 field public static final int TYPE_DYNAMIC = 1; // 0x1 - field public static final int TYPE_SDK = 3; // 0x3 field public static final int TYPE_STATIC = 2; // 0x2 field public static final int VERSION_UNDEFINED = -1; // 0xffffffff } diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index a7f38016fb48e..c777bf5427066 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -697,7 +697,7 @@ public abstract class PackageManager { MATCH_DISABLED_COMPONENTS, MATCH_DISABLED_UNTIL_USED_COMPONENTS, MATCH_INSTANT, - MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, + MATCH_STATIC_SHARED_LIBRARIES, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS, @@ -721,7 +721,7 @@ public abstract class PackageManager { MATCH_SYSTEM_ONLY, MATCH_UNINSTALLED_PACKAGES, MATCH_INSTANT, - MATCH_STATIC_SHARED_AND_SDK_LIBRARIES, + MATCH_STATIC_SHARED_LIBRARIES, GET_DISABLED_COMPONENTS, GET_DISABLED_UNTIL_USED_COMPONENTS, GET_UNINSTALLED_PACKAGES, @@ -1038,14 +1038,14 @@ public abstract class PackageManager { public static final int MATCH_EXPLICITLY_VISIBLE_ONLY = 0x02000000; /** - * Internal {@link PackageInfo} flag: include static shared and SDK libraries. - * Apps that depend on static shared/SDK libs can always access the version + * Internal {@link PackageInfo} flag: include static shared libraries. + * Apps that depend on static shared libs can always access the version * of the lib they depend on. System/shell/root can access all shared * libs regardless of dependency but need to explicitly ask for them * via this flag. * @hide */ - public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 0x04000000; + public static final int MATCH_STATIC_SHARED_LIBRARIES = 0x04000000; /** * {@link PackageInfo} flag: return the signing certificates associated with diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index 4ba2ee65f2217..7abb6947095f9 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -69,13 +69,6 @@ public final class SharedLibraryInfo implements Parcelable { */ public static final int TYPE_STATIC = 2; - /** - * SDK library type: this library is not backwards - * -compatible, can be updated and updates can be uninstalled. Clients - * depend on a specific version of the library. - */ - public static final int TYPE_SDK = 3; - /** * Constant for referring to an undefined version. */ @@ -295,13 +288,6 @@ public final class SharedLibraryInfo implements Parcelable { return mType == TYPE_STATIC; } - /** - * @hide - */ - public boolean isSdk() { - return mType == TYPE_SDK; - } - /** * Gets the package that declares the library. * @@ -365,9 +351,6 @@ public final class SharedLibraryInfo implements Parcelable { case TYPE_STATIC: { return "static"; } - case TYPE_SDK: { - return "sdk"; - } default: { return "unknown"; } diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 63332e79c88b9..056f99fcc004e 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -103,11 +103,11 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage addUsesOptionalNativeLibrary(String libraryName); - ParsingPackage addUsesSdkLibrary(String libraryName, long versionMajor, - String[] certSha256Digests); + ParsingPackage addUsesStaticLibrary(String libraryName); - ParsingPackage addUsesStaticLibrary(String libraryName, long version, - String[] certSha256Digests); + ParsingPackage addUsesStaticLibraryCertDigests(String[] certSha256Digests); + + ParsingPackage addUsesStaticLibraryVersion(long version); ParsingPackage addQueriesIntent(Intent intent); @@ -212,12 +212,6 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage setRestoreAnyVersion(boolean restoreAnyVersion); - ParsingPackage setSdkLibName(String sdkLibName); - - ParsingPackage setSdkLibVersionMajor(int sdkLibVersionMajor); - - ParsingPackage setSdkLibrary(boolean sdkLibrary); - ParsingPackage setSplitHasCode(int splitIndex, boolean splitHasCode); ParsingPackage setStaticSharedLibrary(boolean staticSharedLibrary); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index 19a8ce92373da..d5957a2b69243 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -177,10 +177,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, @DataClass.ParcelWith(ForInternedStringValueMap.class) private Map overlayables = emptyMap(); - @Nullable - @DataClass.ParcelWith(ForInternedString.class) - private String sdkLibName; - private int sdkLibVersionMajor; @Nullable @DataClass.ParcelWith(ForInternedString.class) private String staticSharedLibName; @@ -207,17 +203,10 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private List usesStaticLibraries = emptyList(); @Nullable private long[] usesStaticLibrariesVersions; + @Nullable private String[][] usesStaticLibrariesCertDigests; - @NonNull - @DataClass.ParcelWith(ForInternedStringList.class) - private List usesSdkLibraries = emptyList(); - @Nullable - private long[] usesSdkLibrariesVersionsMajor; - @Nullable - private String[][] usesSdkLibrariesCertDigests; - @Nullable @DataClass.ParcelWith(ForInternedString.class) private String sharedUserId; @@ -529,7 +518,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private static final long REQUEST_FOREGROUND_SERVICE_EXEMPTION = 1L << 46; private static final long ATTRIBUTIONS_ARE_USER_VISIBLE = 1L << 47; private static final long RESET_ENABLED_SETTINGS_ON_APP_DATA_CLEARED = 1L << 48; - private static final long SDK_LIBRARY = 1L << 49; } private ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) { @@ -840,24 +828,21 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, } @Override - public ParsingPackageImpl addUsesSdkLibrary(String libraryName, long versionMajor, - String[] certSha256Digests) { - this.usesSdkLibraries = CollectionUtils.add(this.usesSdkLibraries, + public ParsingPackageImpl addUsesStaticLibrary(String libraryName) { + this.usesStaticLibraries = CollectionUtils.add(this.usesStaticLibraries, TextUtils.safeIntern(libraryName)); - this.usesSdkLibrariesVersionsMajor = ArrayUtils.appendLong( - this.usesSdkLibrariesVersionsMajor, versionMajor, true); - this.usesSdkLibrariesCertDigests = ArrayUtils.appendElement(String[].class, - this.usesSdkLibrariesCertDigests, certSha256Digests, true); return this; } @Override - public ParsingPackageImpl addUsesStaticLibrary(String libraryName, long version, - String[] certSha256Digests) { - this.usesStaticLibraries = CollectionUtils.add(this.usesStaticLibraries, - TextUtils.safeIntern(libraryName)); + public ParsingPackageImpl addUsesStaticLibraryVersion(long version) { this.usesStaticLibrariesVersions = ArrayUtils.appendLong(this.usesStaticLibrariesVersions, version, true); + return this; + } + + @Override + public ParsingPackageImpl addUsesStaticLibraryCertDigests(String[] certSha256Digests) { this.usesStaticLibrariesCertDigests = ArrayUtils.appendElement(String[].class, this.usesStaticLibrariesCertDigests, certSha256Digests, true); return this; @@ -1151,8 +1136,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, dest.writeString(this.overlayCategory); dest.writeInt(this.overlayPriority); sForInternedStringValueMap.parcel(this.overlayables, dest, flags); - sForInternedString.parcel(this.sdkLibName, dest, flags); - dest.writeInt(this.sdkLibVersionMajor); sForInternedString.parcel(this.staticSharedLibName, dest, flags); dest.writeLong(this.staticSharedLibVersion); sForInternedStringList.parcel(this.libraryNames, dest, flags); @@ -1160,9 +1143,9 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, sForInternedStringList.parcel(this.usesOptionalLibraries, dest, flags); sForInternedStringList.parcel(this.usesNativeLibraries, dest, flags); sForInternedStringList.parcel(this.usesOptionalNativeLibraries, dest, flags); - sForInternedStringList.parcel(this.usesStaticLibraries, dest, flags); dest.writeLongArray(this.usesStaticLibrariesVersions); + if (this.usesStaticLibrariesCertDigests == null) { dest.writeInt(-1); } else { @@ -1172,17 +1155,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, } } - sForInternedStringList.parcel(this.usesSdkLibraries, dest, flags); - dest.writeLongArray(this.usesSdkLibrariesVersionsMajor); - if (this.usesSdkLibrariesCertDigests == null) { - dest.writeInt(-1); - } else { - dest.writeInt(this.usesSdkLibrariesCertDigests.length); - for (int index = 0; index < this.usesSdkLibrariesCertDigests.length; index++) { - dest.writeStringArray(this.usesSdkLibrariesCertDigests[index]); - } - } - sForInternedString.parcel(this.sharedUserId, dest, flags); dest.writeInt(this.sharedUserLabel); dest.writeTypedList(this.configPreferences); @@ -1287,8 +1259,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.overlayCategory = in.readString(); this.overlayPriority = in.readInt(); this.overlayables = sForInternedStringValueMap.unparcel(in); - this.sdkLibName = sForInternedString.unparcel(in); - this.sdkLibVersionMajor = in.readInt(); this.staticSharedLibName = sForInternedString.unparcel(in); this.staticSharedLibVersion = in.readLong(); this.libraryNames = sForInternedStringList.unparcel(in); @@ -1296,29 +1266,14 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.usesOptionalLibraries = sForInternedStringList.unparcel(in); this.usesNativeLibraries = sForInternedStringList.unparcel(in); this.usesOptionalNativeLibraries = sForInternedStringList.unparcel(in); - this.usesStaticLibraries = sForInternedStringList.unparcel(in); this.usesStaticLibrariesVersions = in.createLongArray(); - { - int digestsSize = in.readInt(); - if (digestsSize >= 0) { - this.usesStaticLibrariesCertDigests = new String[digestsSize][]; - for (int index = 0; index < digestsSize; index++) { - this.usesStaticLibrariesCertDigests[index] = sForInternedStringArray.unparcel( - in); - } - } - } - this.usesSdkLibraries = sForInternedStringList.unparcel(in); - this.usesSdkLibrariesVersionsMajor = in.createLongArray(); - { - int digestsSize = in.readInt(); - if (digestsSize >= 0) { - this.usesSdkLibrariesCertDigests = new String[digestsSize][]; - for (int index = 0; index < digestsSize; index++) { - this.usesSdkLibrariesCertDigests[index] = sForInternedStringArray.unparcel(in); - } + int digestsSize = in.readInt(); + if (digestsSize >= 0) { + this.usesStaticLibrariesCertDigests = new String[digestsSize][]; + for (int index = 0; index < digestsSize; index++) { + this.usesStaticLibrariesCertDigests[index] = sForInternedStringArray.unparcel(in); } } @@ -1522,17 +1477,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return overlayables; } - @Nullable - @Override - public String getSdkLibName() { - return sdkLibName; - } - - @Override - public int getSdkLibVersionMajor() { - return sdkLibVersionMajor; - } - @Nullable @Override public String getStaticSharedLibName() { @@ -1592,18 +1536,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return usesStaticLibrariesCertDigests; } - @NonNull - @Override - public List getUsesSdkLibraries() { return usesSdkLibraries; } - - @Nullable - @Override - public long[] getUsesSdkLibrariesVersionsMajor() { return usesSdkLibrariesVersionsMajor; } - - @Nullable - @Override - public String[][] getUsesSdkLibrariesCertDigests() { return usesSdkLibrariesCertDigests; } - @Nullable @Override public String getSharedUserId() { @@ -2150,11 +2082,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return getBoolean(Booleans.STATIC_SHARED_LIBRARY); } - @Override - public boolean isSdkLibrary() { - return getBoolean(Booleans.SDK_LIBRARY); - } - @Override public boolean isOverlay() { return getBoolean(Booleans.OVERLAY); @@ -2630,23 +2557,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return this; } - @Override - public ParsingPackageImpl setSdkLibName(String sdkLibName) { - this.sdkLibName = TextUtils.safeIntern(sdkLibName); - return this; - } - - @Override - public ParsingPackageImpl setSdkLibVersionMajor(int sdkLibVersionMajor) { - this.sdkLibVersionMajor = sdkLibVersionMajor; - return this; - } - - @Override - public ParsingPackageImpl setSdkLibrary(boolean value) { - return setBoolean(Booleans.SDK_LIBRARY, value); - } - @Override public ParsingPackageImpl setStaticSharedLibrary(boolean value) { return setBoolean(Booleans.STATIC_SHARED_LIBRARY, value); diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 49b3b08ec5dbe..2933f955bb8cd 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -195,17 +195,6 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt @Nullable int[] getSplitFlags(); - /** - * @see R.styleable#AndroidManifestSdkLibrary_name - */ - @Nullable - String getSdkLibName(); - - /** - * @see R.styleable#AndroidManifestSdkLibrary_versionMajor - */ - int getSdkLibVersionMajor(); - /** * @see R.styleable#AndroidManifestStaticLibrary_name */ @@ -278,26 +267,6 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt @Nullable long[] getUsesStaticLibrariesVersions(); - /** - * TODO(b/135203078): Move SDK library stuff to an inner data class - * - * @see R.styleable#AndroidManifestUsesSdkLibrary - */ - @NonNull - List getUsesSdkLibraries(); - - /** - * @see R.styleable#AndroidManifestUsesSdkLibrary_certDigest - */ - @Nullable - String[][] getUsesSdkLibrariesCertDigests(); - - /** - * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor - */ - @Nullable - long[] getUsesSdkLibrariesVersionsMajor(); - boolean hasPreserveLegacyExternalStorage(); /** diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 3e537c8741377..d2ac87395f628 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -117,7 +117,6 @@ import com.android.internal.util.XmlUtils; import libcore.io.IoUtils; import libcore.util.EmptyArray; -import libcore.util.HexEncoding; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -849,8 +848,6 @@ public class ParsingPackageUtils { pkg.addProperty(propertyResult.getResult()); } return propertyResult; - case "uses-sdk-library": - return parseUsesSdkLibrary(input, pkg, res, parser); case "uses-static-library": return parseUsesStaticLibrary(input, pkg, res, parser); case "uses-library": @@ -2215,8 +2212,7 @@ public class ParsingPackageUtils { } } - if (TextUtils.isEmpty(pkg.getStaticSharedLibName()) && TextUtils.isEmpty( - pkg.getSdkLibName())) { + if (TextUtils.isEmpty(pkg.getStaticSharedLibName())) { // Add a hidden app detail activity to normal apps which forwards user to App Details // page. ParseResult a = generateAppDetailsHiddenActivity(input, pkg); @@ -2355,14 +2351,10 @@ public class ParsingPackageUtils { pkg.addProperty(propertyResult.getResult()); } return propertyResult; - case "sdk-library": - return parseSdkLibrary(pkg, res, parser, input); case "static-library": return parseStaticLibrary(pkg, res, parser, input); case "library": return parseLibrary(pkg, res, parser, input); - case "uses-sdk-library": - return parseUsesSdkLibrary(input, pkg, res, parser); case "uses-static-library": return parseUsesStaticLibrary(input, pkg, res, parser); case "uses-library": @@ -2382,41 +2374,6 @@ public class ParsingPackageUtils { } } - @NonNull - private static ParseResult parseSdkLibrary( - ParsingPackage pkg, Resources res, - XmlResourceParser parser, ParseInput input) { - TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestSdkLibrary); - try { - // Note: don't allow this value to be a reference to a resource that may change. - String lname = sa.getNonResourceString( - R.styleable.AndroidManifestSdkLibrary_name); - final int versionMajor = sa.getInt( - R.styleable.AndroidManifestSdkLibrary_versionMajor, - -1); - - // Fail if malformed. - if (lname == null || versionMajor < 0) { - return input.error("Bad sdk-library declaration name: " + lname - + " version: " + versionMajor); - } else if (pkg.getSharedUserId() != null) { - return input.error( - PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID, - "sharedUserId not allowed in SDK library" - ); - } else if (pkg.getSdkLibName() != null) { - return input.error("Multiple SDKs for package " - + pkg.getPackageName()); - } - - return input.success(pkg.setSdkLibName(lname.intern()) - .setSdkLibVersionMajor(versionMajor) - .setSdkLibrary(true)); - } finally { - sa.recycle(); - } - } - @NonNull private static ParseResult parseStaticLibrary( ParsingPackage pkg, Resources res, @@ -2478,68 +2435,6 @@ public class ParsingPackageUtils { } } - @NonNull - private static ParseResult parseUsesSdkLibrary(ParseInput input, - ParsingPackage pkg, Resources res, XmlResourceParser parser) - throws XmlPullParserException, IOException { - TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdkLibrary); - try { - // Note: don't allow this value to be a reference to a resource that may change. - String lname = sa.getNonResourceString( - R.styleable.AndroidManifestUsesSdkLibrary_name); - final int versionMajor = sa.getInt( - R.styleable.AndroidManifestUsesSdkLibrary_versionMajor, -1); - String certSha256Digest = sa.getNonResourceString(R.styleable - .AndroidManifestUsesSdkLibrary_certDigest); - - // Since an APK providing a static shared lib can only provide the lib - fail if - // malformed - if (lname == null || versionMajor < 0 || certSha256Digest == null) { - return input.error("Bad uses-sdk-library declaration name: " + lname - + " version: " + versionMajor + " certDigest" + certSha256Digest); - } - - // Can depend only on one version of the same library - List usesSdkLibraries = pkg.getUsesSdkLibraries(); - if (usesSdkLibraries.contains(lname)) { - return input.error( - "Depending on multiple versions of SDK library " + lname); - } - - lname = lname.intern(); - // We allow ":" delimiters in the SHA declaration as this is the format - // emitted by the certtool making it easy for developers to copy/paste. - certSha256Digest = certSha256Digest.replace(":", "").toLowerCase(); - - if ("".equals(certSha256Digest)) { - // Test-only uses-sdk-library empty certificate digest override. - certSha256Digest = SystemProperties.get( - "debug.pm.uses_sdk_library_default_cert_digest", ""); - // Validate the overridden digest. - try { - HexEncoding.decode(certSha256Digest, false); - } catch (IllegalArgumentException e) { - certSha256Digest = ""; - } - } - - ParseResult certResult = parseAdditionalCertificates(input, res, parser); - if (certResult.isError()) { - return input.error(certResult); - } - String[] additionalCertSha256Digests = certResult.getResult(); - - final String[] certSha256Digests = new String[additionalCertSha256Digests.length + 1]; - certSha256Digests[0] = certSha256Digest; - System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests, - 1, additionalCertSha256Digests.length); - - return input.success(pkg.addUsesSdkLibrary(lname, versionMajor, certSha256Digests)); - } finally { - sa.recycle(); - } - } - @NonNull private static ParseResult parseUsesStaticLibrary(ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser) @@ -2588,7 +2483,9 @@ public class ParsingPackageUtils { System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests, 1, additionalCertSha256Digests.length); - return input.success(pkg.addUsesStaticLibrary(lname, version, certSha256Digests)); + return input.success(pkg.addUsesStaticLibrary(lname) + .addUsesStaticLibraryVersion(version) + .addUsesStaticLibraryCertDigests(certSha256Digests)); } finally { sa.recycle(); } diff --git a/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java b/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java index 625b9d1bb4794..fcad10c767c3e 100644 --- a/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java +++ b/core/java/android/content/pm/parsing/PkgWithoutStateAppInfo.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.content.pm.ApplicationInfo; import android.util.SparseArray; +import com.android.internal.R; + /** * Container for fields that are eventually exposed through {@link ApplicationInfo}. *

    @@ -573,11 +575,6 @@ public interface PkgWithoutStateAppInfo { */ boolean isStaticSharedLibrary(); - /** - * True means that this package/app contains an SDK library. - */ - boolean isSdkLibrary(); - /** * If omitted from manifest, returns true if {@link #getTargetSdkVersion()} >= {@link * android.os.Build.VERSION_CODES#GINGERBREAD}. diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index fe5811463a722..94717b11deb26 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -2303,36 +2303,6 @@ - - - - - - - - - - - - - - - - - - - * - * - * - * - * - * @param uci Bearer Unique Client Identifier - * @param uriSchemes URI Schemes supported list - * @param capabilities bearer capabilities - * @param provider Network provider name - * @param technology Network technology - * @param executor {@link Executor} object on which callback will be - * executed. The Executor object is required. - * @param callback {@link Callback} object to which callback messages will - * be sent. The Callback object is required. - * @return true on success, false otherwise - * @hide - */ - @SuppressLint("ExecutorRegistration") - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public boolean registerBearer(@Nullable String uci, - @NonNull List uriSchemes, int capabilities, - @NonNull String provider, int technology, - @NonNull Executor executor, @NonNull Callback callback) { - if (DBG) { - Log.d(TAG, "registerBearer"); - } - if (callback == null) { - throw new IllegalArgumentException("null parameter: " + callback); - } - if (mCcid != 0) { - return false; - } - - mToken = uci; - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - synchronized (mServerIfLock) { - if (mCallback != null) { - Log.e(TAG, "Bearer can be opened only once"); - return false; - } - - mCallback = callback; - try { - CallbackWrapper callbackWrapper = new CallbackWrapper(executor, callback); - service.registerBearer(mToken, callbackWrapper, uci, uriSchemes, capabilities, - provider, technology); - } catch (RemoteException e) { - Log.e(TAG, "", e); - mCallback = null; - return false; - } - - try { - mServerIfLock.wait(REG_TIMEOUT); - } catch (InterruptedException e) { - Log.e(TAG, "" + e); - mCallback = null; - } - - if (mCcid == 0) { - mCallback = null; - return false; - } - - return true; - } - } - if (service == null) { - Log.w(TAG, "Proxy not attached to service"); - } - - return false; - } - - /** - * Unregister Telephone Bearer Service and destroy all the associated data. - * - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void unregisterBearer() { - if (DBG) { - Log.d(TAG, "unregisterBearer"); - } - if (mCcid == 0) { - return; - } - - int ccid = mCcid; - mCcid = 0; - mCallback = null; - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.unregisterBearer(mToken); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - if (service == null) { - Log.w(TAG, "Proxy not attached to service"); - } - } - - /** - * Get the Content Control ID (CCID) value. - * - * @return ccid Content Control ID value - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public int getContentControlId() { - return mCcid; - } - - /** - * Notify about the newly added call. - * - *

    - * This shall be called as early as possible after the call has been added. - * - *

    - * Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param call Newly added call - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void onCallAdded(@NonNull BluetoothLeCall call) { - if (DBG) { - Log.d(TAG, "onCallAdded: call=" + call); - } - if (mCcid == 0) { - return; - } - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.callAdded(mCcid, call); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - if (service == null) { - Log.w(TAG, "Proxy not attached to service"); - } - } - - /** - * Notify about the removed call. - * - *

    - * This shall be called as early as possible after the call has been removed. - * - *

    - * Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param callId The Id of a call that has been removed - * @param reason Call termination reason - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void onCallRemoved(@NonNull UUID callId, @TerminationReason int reason) { - if (DBG) { - Log.d(TAG, "callRemoved: callId=" + callId); - } - if (mCcid == 0) { - return; - } - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.callRemoved(mCcid, new ParcelUuid(callId), reason); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - if (service == null) { - Log.w(TAG, "Proxy not attached to service"); - } - } - - /** - * Notify the call state change - * - *

    - * This shall be called as early as possible after the state of the call has - * changed. - * - *

    - * Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * @param callId The call Id that state has been changed - * @param state Call state - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void onCallStateChanged(@NonNull UUID callId, @BluetoothLeCall.State int state) { - if (DBG) { - Log.d(TAG, "callStateChanged: callId=" + callId + " state=" + state); - } - if (mCcid == 0) { - return; - } - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.callStateChanged(mCcid, new ParcelUuid(callId), state); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - if (service == null) { - Log.w(TAG, "Proxy not attached to service"); - } - } - - /** - * Provide the current calls list - * - *

    - * This function must be invoked after registration if application has any - * calls. - * - * @param calls current calls list - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void currentCallsList(@NonNull List calls) { - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.currentCallsList(mCcid, calls); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - } - - /** - * Provide the network current status - * - *

    - * This function must be invoked on change of network state. - * - *

    - * Requires {@link android.Manifest.permission#BLUETOOTH} permission. - * - * - * - * @param provider Network provider name - * @param technology Network technology - * @hide - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void networkStateChanged(@NonNull String provider, int technology) { - if (DBG) { - Log.d(TAG, "networkStateChanged: provider=" + provider + ", technology=" + technology); - } - if (mCcid == 0) { - return; - } - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.networkStateChanged(mCcid, provider, technology); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - if (service == null) { - Log.w(TAG, "Proxy not attached to service"); - } - } - - /** - * Send a response to a call control request to a remote device. - * - *

    - * This function must be invoked in when a request is received by one of these - * callback methods: - * - *

      - *
    • {@link Callback#onAcceptCall} - *
    • {@link Callback#onTerminateCall} - *
    • {@link Callback#onHoldCall} - *
    • {@link Callback#onUnholdCall} - *
    • {@link Callback#onPlaceCall} - *
    • {@link Callback#onJoinCalls} - *
    - * - * @param requestId The ID of the request that was received with the callback - * @param result The result of the request to be sent to the remote devices - */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - public void requestResult(int requestId, @Result int result) { - if (DBG) { - Log.d(TAG, "requestResult: requestId=" + requestId + " result=" + result); - } - if (mCcid == 0) { - return; - } - - final IBluetoothLeCallControl service = getService(); - if (service != null) { - try { - service.requestResult(mCcid, requestId, result); - } catch (RemoteException e) { - Log.e(TAG, "", e); - } - } - } - - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) - private static boolean isValidDevice(@Nullable BluetoothDevice device) { - return device != null && BluetoothAdapter.checkBluetoothAddress(device.getAddress()); - } - - private static void log(String msg) { - Log.d(TAG, msg); - } - - private final IBluetoothProfileServiceConnection mConnection = - new IBluetoothProfileServiceConnection.Stub() { - @Override - public void onServiceConnected(ComponentName className, IBinder service) { - if (DBG) { - Log.d(TAG, "Proxy object connected"); - } - mService = IBluetoothLeCallControl.Stub.asInterface(Binder.allowBlocking(service)); - mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_TBS_SERVICE_CONNECTED)); - } - - @Override - public void onServiceDisconnected(ComponentName className) { - if (DBG) { - Log.d(TAG, "Proxy object disconnected"); - } - doUnbind(); - mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_TBS_SERVICE_DISCONNECTED)); - } - }; - - private final Handler mHandler = new Handler(Looper.getMainLooper()) { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case MESSAGE_TBS_SERVICE_CONNECTED: { - if (mServiceListener != null) { - mServiceListener.onServiceConnected(BluetoothProfile.LE_CALL_CONTROL, - BluetoothLeCallControl.this); - } - break; - } - case MESSAGE_TBS_SERVICE_DISCONNECTED: { - if (mServiceListener != null) { - mServiceListener.onServiceDisconnected(BluetoothProfile.LE_CALL_CONTROL); - } - break; - } - } - } - }; -} diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java index d0f74e9857290..e047e5d81a9df 100644 --- a/core/java/android/bluetooth/BluetoothProfile.java +++ b/core/java/android/bluetooth/BluetoothProfile.java @@ -239,20 +239,13 @@ public interface BluetoothProfile { */ int LE_AUDIO_BROADCAST = 26; - /** - * @hide - * Telephone Bearer Service from Call Control Profile - * - */ - int LE_CALL_CONTROL = 27; - /** * Max profile ID. This value should be updated whenever a new profile is added to match * the largest value assigned to a profile. * * @hide */ - int MAX_PROFILE_ID = 27; + int MAX_PROFILE_ID = 26; /** * Default priority for devices that we try to auto-connect to and diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 262933dea27fc..bc8da8443a7d2 100644 --- a/services/core/java/com/android/server/BluetoothManagerService.java +++ b/services/core/java/com/android/server/BluetoothManagerService.java @@ -45,7 +45,6 @@ import android.bluetooth.IBluetoothManager; import android.bluetooth.IBluetoothManagerCallback; import android.bluetooth.IBluetoothProfileServiceConnection; import android.bluetooth.IBluetoothStateChangeCallback; -import android.bluetooth.IBluetoothLeCallControl; import android.content.ActivityNotFoundException; import android.content.AttributionSource; import android.content.BroadcastReceiver; @@ -1324,15 +1323,11 @@ class BluetoothManagerService extends IBluetoothManager.Stub { + bluetoothProfile); } - Intent intent; - if (bluetoothProfile == BluetoothProfile.HEADSET) { - intent = new Intent(IBluetoothHeadset.class.getName()); - } else if (bluetoothProfile== BluetoothProfile.LE_CALL_CONTROL) { - intent = new Intent(IBluetoothLeCallControl.class.getName()); - } else { + if (bluetoothProfile != BluetoothProfile.HEADSET) { return false; } + Intent intent = new Intent(IBluetoothHeadset.class.getName()); psc = new ProfileServiceConnections(intent); if (!psc.bindService()) { return false; From 3dd1d1d9e2b4056ca6ea079c0e0be76edf086ad4 Mon Sep 17 00:00:00 2001 From: Jacob Hobbie Date: Thu, 6 Jan 2022 17:53:32 +0000 Subject: [PATCH 089/176] Revert "Adding client side logging for receivers." This reverts commit 2c34dcd95606389ba8b9f9f88de244d640312db1. Reason for revert: Not WAI, logging on user-debug builds (not just eng) and not logging across the binder appropriately Droidfood blocking bug:213406883 Change-Id: Ifff533d280cce22fbf877dd265e4910ab9230943 (cherry picked from commit e9482d775fb486964c81fb8b0ef987f9534a229e) Merged-In:Ifff533d280cce22fbf877dd265e4910ab9230943 --- core/java/android/app/ContextImpl.java | 4 -- core/java/android/app/WtfException.java | 66 ------------------- .../server/am/ActivityManagerService.java | 19 ++---- 3 files changed, 6 insertions(+), 83 deletions(-) delete mode 100644 core/java/android/app/WtfException.java diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index c895636ddc824..f3e9f105500e9 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1796,7 +1796,6 @@ class ContextImpl extends Context { && ((flags & Context.RECEIVER_NOT_EXPORTED) == 0)) { flags = flags | Context.RECEIVER_EXPORTED; } - final Intent intent = ActivityManager.getService().registerReceiverWithFeature( mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), AppOpsManager.toReceiverId(receiver), rd, filter, broadcastPermission, userId, @@ -1811,9 +1810,6 @@ class ContextImpl extends Context { return intent; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } catch (WtfException e) { - Log.wtf(TAG, e.getMessage()); - return null; } } diff --git a/core/java/android/app/WtfException.java b/core/java/android/app/WtfException.java deleted file mode 100644 index ba8dbefad160e..0000000000000 --- a/core/java/android/app/WtfException.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.app; - -import android.os.Parcel; -import android.os.Parcelable; - -/** - * Exception meant to be thrown instead of calling Log.wtf() such that server side code can - * throw this exception, and it will carry across the binder to do client side logging. - * {@hide} - */ -public final class WtfException extends RuntimeException implements Parcelable { - public static final @android.annotation.NonNull - Creator CREATOR = new Creator() { - @Override - public WtfException createFromParcel(Parcel source) { - return new WtfException(source.readString8()); - } - - @Override - public WtfException[] newArray(int size) { - return new WtfException[size]; - } - }; - - public WtfException(@android.annotation.NonNull String message) { - super(message); - } - - /** {@hide} */ - public static Throwable readFromParcel(Parcel in) { - final String msg = in.readString8(); - return new WtfException(msg); - } - - /** {@hide} */ - public static void writeToParcel(Parcel out, Throwable t) { - out.writeString8(t.getMessage()); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(@android.annotation.NonNull Parcel dest, int flags) { - dest.writeString8(getMessage()); - } -} - diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 9d2b4e7a570f3..da8c407a501d4 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -189,7 +189,6 @@ import android.app.ProfilerInfo; import android.app.PropertyInvalidatedCache; import android.app.SyncNotedAppOp; import android.app.WaitResult; -import android.app.WtfException; import android.app.backup.BackupManager.OperationType; import android.app.backup.IBackupManager; import android.app.compat.CompatChanges; @@ -12635,7 +12634,6 @@ public class ActivityManagerService extends IActivityManager.Stub int callingUid; int callingPid; boolean instantApp; - boolean throwWtfException = false; synchronized(this) { if (caller != null) { callerApp = getRecordForAppLOSP(caller); @@ -12730,9 +12728,13 @@ public class ActivityManagerService extends IActivityManager.Stub + "RECEIVER_NOT_EXPORTED be specified when registering a " + "receiver"); } else { - // will be removed when enforcement is required + Slog.wtf(TAG, + callerPackage + ": Targeting T+ (version " + + Build.VERSION_CODES.TIRAMISU + + " and above) requires that one of RECEIVER_EXPORTED or " + + "RECEIVER_NOT_EXPORTED be specified when registering a " + + "receiver"); // Assume default behavior-- flag check is not enforced - throwWtfException = true; flags |= Context.RECEIVER_EXPORTED; } } else if (!requireExplicitFlagForDynamicReceivers) { @@ -12863,15 +12865,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - if (throwWtfException) { - throw new WtfException( - callerPackage + ": Targeting T+ (version " - + Build.VERSION_CODES.TIRAMISU - + " and above) requires that one of RECEIVER_EXPORTED or " - + "RECEIVER_NOT_EXPORTED be specified when registering a " - + "receiver"); - } - return sticky; } } From 97fd58f609e6a19a71c2788fb5023a3e8f25df41 Mon Sep 17 00:00:00 2001 From: Shubham Dubey Date: Mon, 10 Jan 2022 05:17:52 +0000 Subject: [PATCH 090/176] Revert "Implement fallback line spacing for BoringLayout" Revert "Add font extent calculation" Revert "Add test case for fallback line spacing" Revert submission 16486662-fallback_line_spacing Reason for revert: Investigate test failures on master BUGID: b/213826416 BUGID: b/213829920 Reverted Changes: I06cd7ab71:Add font extent calculation I6214d52cd:Implement fallback line spacing for BoringLayout Ia5825c474:Add test case for fallback line spacing Change-Id: Ia6d6f9f44e73ddaf5e8fe9a8aead7a53efbddd44 (cherry picked from commit da511945c380b24dfcb4257e192d3b700d70751b) Merged-In:Ia6d6f9f44e73ddaf5e8fe9a8aead7a53efbddd44 --- core/api/current.txt | 7 - core/java/android/text/BoringLayout.java | 171 +++--------------- core/java/android/text/Layout.java | 33 +--- core/java/android/text/StaticLayout.java | 14 +- core/java/android/text/TextLine.java | 37 +--- core/java/android/text/TextShaper.java | 3 +- core/java/android/widget/Editor.java | 2 +- core/java/android/widget/TextView.java | 81 ++------- .../src/android/text/TextLineTest.java | 13 +- graphics/java/android/graphics/Paint.java | 136 +------------- libs/hwui/hwui/MinikinUtils.cpp | 10 - libs/hwui/hwui/MinikinUtils.h | 4 - libs/hwui/jni/Paint.cpp | 87 ++------- 13 files changed, 80 insertions(+), 518 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index edf69449f4e9d..06f82e0c50a53 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -15977,8 +15977,6 @@ package android.graphics { method public String getFontFeatureSettings(); method public float getFontMetrics(android.graphics.Paint.FontMetrics); method public android.graphics.Paint.FontMetrics getFontMetrics(); - method public void getFontMetricsInt(@NonNull CharSequence, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, boolean, @NonNull android.graphics.Paint.FontMetricsInt); - method public void getFontMetricsInt(@NonNull char[], @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, @IntRange(from=0) int, boolean, @NonNull android.graphics.Paint.FontMetricsInt); method public int getFontMetricsInt(android.graphics.Paint.FontMetricsInt); method public android.graphics.Paint.FontMetricsInt getFontMetricsInt(); method public float getFontSpacing(); @@ -44656,7 +44654,6 @@ package android.text { public class BoringLayout extends android.text.Layout implements android.text.TextUtils.EllipsizeCallback { ctor public BoringLayout(CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean); ctor public BoringLayout(CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean, android.text.TextUtils.TruncateAt, int); - ctor public BoringLayout(@NonNull CharSequence, @NonNull android.text.TextPaint, @IntRange(from=0) int, @NonNull android.text.Layout.Alignment, float, float, @NonNull android.text.BoringLayout.Metrics, boolean, @NonNull android.text.TextUtils.TruncateAt, @IntRange(from=0) int, boolean); method public void ellipsized(int, int); method public int getBottomPadding(); method public int getEllipsisCount(int); @@ -44671,12 +44668,9 @@ package android.text { method public int getTopPadding(); method public static android.text.BoringLayout.Metrics isBoring(CharSequence, android.text.TextPaint); method public static android.text.BoringLayout.Metrics isBoring(CharSequence, android.text.TextPaint, android.text.BoringLayout.Metrics); - method @Nullable public static android.text.BoringLayout.Metrics isBoring(@NonNull CharSequence, @NonNull android.text.TextPaint, @NonNull android.text.TextDirectionHeuristic, boolean, @Nullable android.text.BoringLayout.Metrics); method public static android.text.BoringLayout make(CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean); method public static android.text.BoringLayout make(CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean, android.text.TextUtils.TruncateAt, int); - method @NonNull public static android.text.BoringLayout make(@NonNull CharSequence, @NonNull android.text.TextPaint, @IntRange(from=0) int, @NonNull android.text.Layout.Alignment, @NonNull android.text.BoringLayout.Metrics, boolean, @NonNull android.text.TextUtils.TruncateAt, @IntRange(from=0) int, boolean); method public android.text.BoringLayout replaceOrMake(CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean); - method @NonNull public android.text.BoringLayout replaceOrMake(@NonNull CharSequence, @NonNull android.text.TextPaint, @IntRange(from=0) int, @NonNull android.text.Layout.Alignment, @NonNull android.text.BoringLayout.Metrics, boolean, @NonNull android.text.TextUtils.TruncateAt, @IntRange(from=0) int, boolean); method public android.text.BoringLayout replaceOrMake(CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean, android.text.TextUtils.TruncateAt, int); } @@ -44885,7 +44879,6 @@ package android.text { method public abstract int getTopPadding(); method public final int getWidth(); method public final void increaseWidthTo(int); - method public boolean isFallbackLineSpacingEnabled(); method public boolean isRtlCharAt(int); method protected final boolean isSpanned(); field public static final int BREAK_STRATEGY_BALANCED = 2; // 0x2 diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java index 4ee02f01f330d..3ee1a9000188e 100644 --- a/core/java/android/text/BoringLayout.java +++ b/core/java/android/text/BoringLayout.java @@ -16,9 +16,6 @@ package android.text; -import android.annotation.IntRange; -import android.annotation.NonNull; -import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Canvas; import android.graphics.Paint; @@ -87,37 +84,6 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback includePad, ellipsize, ellipsizedWidth); } - /** - * Utility function to construct a BoringLayout instance. - * - * The spacing multiplier and additional amount spacing are not used by BoringLayout. - * {@link Layout#getSpacingMultiplier()} will return 1.0 and {@link Layout#getSpacingAdd()} will - * return 0.0. - * - * @param source the text to render - * @param paint the default paint for the layout - * @param outerWidth the wrapping width for the text - * @param align whether to left, right, or center the text - * @param metrics {@code #Metrics} instance that contains information about FontMetrics and - * line width - * @param includePad set whether to include extra space beyond font ascent and descent which is - * needed to avoid clipping in some scripts - * @param ellipsize whether to ellipsize the text if width of the text is longer than the - * requested width - * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is - * {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is - * not used, {@code outerWidth} is used instead - */ - public static @NonNull BoringLayout make( - @NonNull CharSequence source, @NonNull TextPaint paint, - @IntRange(from = 0) int outerWidth, - @NonNull Alignment align, @NonNull BoringLayout.Metrics metrics, - boolean includePad, @NonNull TextUtils.TruncateAt ellipsize, - @IntRange(from = 0) int ellipsizedWidth, boolean useFallbackLineSpacing) { - return new BoringLayout(source, paint, outerWidth, align, 1f, 0f, metrics, includePad, - ellipsize, ellipsizedWidth, useFallbackLineSpacing); - } - /** * Returns a BoringLayout for the specified text, potentially reusing * this one if it is already suitable. The caller must make sure that @@ -143,57 +109,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback mEllipsizedStart = 0; mEllipsizedCount = 0; - init(source, paint, align, metrics, includePad, true, false /* useFallbackLineSpacing */); - return this; - } - - /** - * Returns a BoringLayout for the specified text, potentially reusing - * this one if it is already suitable. The caller must make sure that - * no one is still using this Layout. - * - * The spacing multiplier and additional amount spacing are not used by BoringLayout. - * {@link Layout#getSpacingMultiplier()} will return 1.0 and {@link Layout#getSpacingAdd()} will - * return 0.0. - * - * @param source the text to render - * @param paint the default paint for the layout - * @param outerWidth the wrapping width for the text - * @param align whether to left, right, or center the text - * @param metrics {@code #Metrics} instance that contains information about FontMetrics and - * line width - * @param includePad set whether to include extra space beyond font ascent and descent which is - * needed to avoid clipping in some scripts - * @param ellipsize whether to ellipsize the text if width of the text is longer than the - * requested width - * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is - * {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is - * not used, {@code outerwidth} is used instead - */ - public @NonNull BoringLayout replaceOrMake(@NonNull CharSequence source, - @NonNull TextPaint paint, @IntRange(from = 0) int outerWidth, - @NonNull Alignment align, @NonNull BoringLayout.Metrics metrics, boolean includePad, - @NonNull TextUtils.TruncateAt ellipsize, @IntRange(from = 0) int ellipsizedWidth, - boolean useFallbackLineSpacing) { - boolean trust; - - if (ellipsize == null || ellipsize == TextUtils.TruncateAt.MARQUEE) { - replaceWith(source, paint, outerWidth, align, 1f, 0f); - - mEllipsizedWidth = outerWidth; - mEllipsizedStart = 0; - mEllipsizedCount = 0; - trust = true; - } else { - replaceWith(TextUtils.ellipsize(source, paint, ellipsizedWidth, ellipsize, true, this), - paint, outerWidth, align, 1f, 0f); - - mEllipsizedWidth = ellipsizedWidth; - trust = false; - } - - init(getText(), paint, align, metrics, includePad, trust, - useFallbackLineSpacing); + init(source, paint, align, metrics, includePad, true); return this; } @@ -221,8 +137,25 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback public BoringLayout replaceOrMake(CharSequence source, TextPaint paint, int outerWidth, Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) { - return replaceOrMake(source, paint, outerWidth, align, metrics, - includePad, ellipsize, ellipsizedWidth, false /* useFallbackLineSpacing */); + boolean trust; + + if (ellipsize == null || ellipsize == TextUtils.TruncateAt.MARQUEE) { + replaceWith(source, paint, outerWidth, align, spacingMult, spacingAdd); + + mEllipsizedWidth = outerWidth; + mEllipsizedStart = 0; + mEllipsizedCount = 0; + trust = true; + } else { + replaceWith(TextUtils.ellipsize(source, paint, ellipsizedWidth, ellipsize, true, this), + paint, outerWidth, align, spacingMult, spacingAdd); + + mEllipsizedWidth = ellipsizedWidth; + trust = false; + } + + init(getText(), paint, align, metrics, includePad, trust); + return this; } /** @@ -245,7 +178,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback mEllipsizedStart = 0; mEllipsizedCount = 0; - init(source, paint, align, metrics, includePad, true, false /* useFallbackLineSpacing */); + init(source, paint, align, metrics, includePad, true); } /** @@ -269,34 +202,6 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback public BoringLayout(CharSequence source, TextPaint paint, int outerWidth, Alignment align, float spacingMult, float spacingAdd, BoringLayout.Metrics metrics, boolean includePad, TextUtils.TruncateAt ellipsize, int ellipsizedWidth) { - this(source, paint, outerWidth, align, spacingMult, spacingAdd, metrics, includePad, - ellipsize, ellipsizedWidth, false /* fallbackLineSpacing */); - } - - /** - * - * @param source the text to render - * @param paint the default paint for the layout - * @param outerWidth the wrapping width for the text - * @param align whether to left, right, or center the text - * @param spacingMult this value is no longer used by BoringLayout - * @param spacingAdd this value is no longer used by BoringLayout - * @param metrics {@code #Metrics} instance that contains information about FontMetrics and - * line width - * @param includePad set whether to include extra space beyond font ascent and descent which is - * needed to avoid clipping in some scripts - * @param ellipsize whether to ellipsize the text if width of the text is longer than the - * requested {@code outerwidth} - * @param ellipsizedWidth the width to which this Layout is ellipsizing. If {@code ellipsize} is - * {@code null}, or is {@link TextUtils.TruncateAt#MARQUEE} this value is - * not used, {@code outerwidth} is used instead - */ - public BoringLayout( - @NonNull CharSequence source, @NonNull TextPaint paint, - @IntRange(from = 0) int outerWidth, @NonNull Alignment align, float spacingMult, - float spacingAdd, @NonNull BoringLayout.Metrics metrics, boolean includePad, - @NonNull TextUtils.TruncateAt ellipsize, @IntRange(from = 0) int ellipsizedWidth, - boolean useFallbackLineSpacing) { /* * It is silly to have to call super() and then replaceWith(), * but we can't use "this" for the callback until the call to @@ -319,12 +224,11 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback trust = false; } - init(getText(), paint, align, metrics, includePad, trust, useFallbackLineSpacing); + init(getText(), paint, align, metrics, includePad, trust); } /* package */ void init(CharSequence source, TextPaint paint, Alignment align, - BoringLayout.Metrics metrics, boolean includePad, boolean trustWidth, - boolean useFallbackLineSpacing) { + BoringLayout.Metrics metrics, boolean includePad, boolean trustWidth) { int spacing; if (source instanceof String && align == Layout.Alignment.ALIGN_NORMAL) { @@ -356,7 +260,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback TextLine line = TextLine.obtain(); line.set(paint, source, 0, source.length(), Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null, - mEllipsizedStart, mEllipsizedStart + mEllipsizedCount, useFallbackLineSpacing); + mEllipsizedStart, mEllipsizedStart + mEllipsizedCount); mMax = (int) Math.ceil(line.metrics(null)); TextLine.recycle(line); } @@ -432,24 +336,6 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback @UnsupportedAppUsage public static Metrics isBoring(CharSequence text, TextPaint paint, TextDirectionHeuristic textDir, Metrics metrics) { - return isBoring(text, paint, textDir, false /* useFallbackLineSpacing */, metrics); - } - - /** - * Returns null if not boring; the width, ascent, and descent in the - * provided Metrics object (or a new one if the provided one was null) - * if boring. - * - * @param text a text to be calculated text layout. - * @param paint a paint object used for styling. - * @param textDir a text direction. - * @param useFallbackLineSpacing true if use fallback line spacing, otherwise false. - * @param metrics the out metrics. - * @return metrics on success. null if text cannot be rendered by BoringLayout. - */ - public static @Nullable Metrics isBoring(@NonNull CharSequence text, @NonNull TextPaint paint, - @NonNull TextDirectionHeuristic textDir, boolean useFallbackLineSpacing, - @Nullable Metrics metrics) { final int textLength = text.length(); if (hasAnyInterestingChars(text, textLength)) { return null; // There are some interesting characters. Not boring. @@ -476,8 +362,7 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback line.set(paint, text, 0, textLength, Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false, null, 0 /* ellipsisStart, 0 since text has not been ellipsized at this point */, - 0 /* ellipsisEnd, 0 since text has not been ellipsized at this point */, - useFallbackLineSpacing); + 0 /* ellipsisEnd, 0 since text has not been ellipsized at this point */); fm.width = (int) Math.ceil(line.metrics(fm)); TextLine.recycle(line); @@ -565,11 +450,6 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback return mEllipsizedWidth; } - @Override - public boolean isFallbackLineSpacingEnabled() { - return mUseFallbackLineSpacing; - } - // Override draw so it will be faster. @Override public void draw(Canvas c, Path highlight, Paint highlightpaint, @@ -591,7 +471,6 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback private String mDirect; private Paint mPaint; - private boolean mUseFallbackLineSpacing; /* package */ int mBottom, mDesc; // for Direct private int mTopPadding, mBottomPadding; diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 95adb7765f1ec..da3e9b6d509c5 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -591,8 +591,7 @@ public abstract class Layout { } else { tl.set(paint, buf, start, end, dir, directions, hasTab, tabStops, getEllipsisStart(lineNum), - getEllipsisStart(lineNum) + getEllipsisCount(lineNum), - isFallbackLineSpacingEnabled()); + getEllipsisStart(lineNum) + getEllipsisCount(lineNum)); if (justify) { tl.justify(right - left - indentWidth); } @@ -960,15 +959,6 @@ public abstract class Layout { return 0; } - /** - * Return true if the fallback line space is enabled in this Layout. - * - * @return true if the fallback line space is enabled. Otherwise returns false. - */ - public boolean isFallbackLineSpacingEnabled() { - return false; - } - /** * Returns true if the character at offset and the preceding character * are at different run levels (and thus there's a split caret). @@ -1241,8 +1231,7 @@ public abstract class Layout { TextLine tl = TextLine.obtain(); tl.set(mPaint, mText, start, end, dir, directions, hasTab, tabStops, - getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), - isFallbackLineSpacingEnabled()); + getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line)); float wid = tl.measure(offset - start, trailing, null); TextLine.recycle(tl); @@ -1282,8 +1271,7 @@ public abstract class Layout { TextLine tl = TextLine.obtain(); tl.set(mPaint, mText, start, end, dir, directions, hasTab, tabStops, - getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), - isFallbackLineSpacingEnabled()); + getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line)); boolean[] trailings = primaryIsTrailingPreviousAllLineOffsets(line); if (!primary) { for (int offset = 0; offset < trailings.length; ++offset) { @@ -1468,8 +1456,7 @@ public abstract class Layout { paint.setStartHyphenEdit(getStartHyphenEdit(line)); paint.setEndHyphenEdit(getEndHyphenEdit(line)); tl.set(paint, mText, start, end, dir, directions, hasTabs, tabStops, - getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), - isFallbackLineSpacingEnabled()); + getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line)); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); } @@ -1499,8 +1486,7 @@ public abstract class Layout { paint.setStartHyphenEdit(getStartHyphenEdit(line)); paint.setEndHyphenEdit(getEndHyphenEdit(line)); tl.set(paint, mText, start, end, dir, directions, hasTabs, tabStops, - getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), - isFallbackLineSpacingEnabled()); + getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line)); if (isJustificationRequired(line)) { tl.justify(getJustifyWidth(line)); } @@ -1586,8 +1572,7 @@ public abstract class Layout { // XXX: we don't care about tabs as we just use TextLine#getOffsetToLeftRightOf here. tl.set(mPaint, mText, lineStartOffset, lineEndOffset, getParagraphDirection(line), dirs, false, null, - getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), - isFallbackLineSpacingEnabled()); + getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line)); final HorizontalMeasurementProvider horizontal = new HorizontalMeasurementProvider(line, primary); @@ -1843,8 +1828,7 @@ public abstract class Layout { TextLine tl = TextLine.obtain(); // XXX: we don't care about tabs tl.set(mPaint, mText, lineStart, lineEnd, lineDir, directions, false, null, - getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line), - isFallbackLineSpacingEnabled()); + getEllipsisStart(line), getEllipsisStart(line) + getEllipsisCount(line)); caret = lineStart + tl.getOffsetToLeftRightOf(caret - lineStart, toLeft); TextLine.recycle(tl); return caret; @@ -2218,8 +2202,7 @@ public abstract class Layout { } } tl.set(paint, text, start, end, dir, directions, hasTabs, tabStops, - 0 /* ellipsisStart */, 0 /* ellipsisEnd */, - false /* use fallback line spacing. unused */); + 0 /* ellipsisStart */, 0 /* ellipsisEnd */); return margin + Math.abs(tl.metrics(null)); } finally { TextLine.recycle(tl); diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index b1bc7667da165..4789231b04045 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -612,6 +612,7 @@ public class StaticLayout extends Layout { TextPaint paint = b.mPaint; int outerWidth = b.mWidth; TextDirectionHeuristic textDir = b.mTextDir; + final boolean fallbackLineSpacing = b.mFallbackLineSpacing; float spacingmult = b.mSpacingMult; float spacingadd = b.mSpacingAdd; float ellipsizedWidth = b.mEllipsizedWidth; @@ -629,7 +630,6 @@ public class StaticLayout extends Layout { mLineCount = 0; mEllipsized = false; mMaxLineHeight = mMaximumVisibleLineCount < 1 ? 0 : DEFAULT_MAX_LINE_HEIGHT; - mFallbackLineSpacing = b.mFallbackLineSpacing; int v = 0; boolean needMultiply = (spacingmult != 1 || spacingadd != 0); @@ -867,17 +867,17 @@ public class StaticLayout extends Layout { boolean moreChars = (endPos < bufEnd); - final int ascent = mFallbackLineSpacing + final int ascent = fallbackLineSpacing ? Math.min(fmAscent, Math.round(ascents[breakIndex])) : fmAscent; - final int descent = mFallbackLineSpacing + final int descent = fallbackLineSpacing ? Math.max(fmDescent, Math.round(descents[breakIndex])) : fmDescent; // The fallback ascent/descent may be larger than top/bottom of the default font // metrics. Adjust top/bottom with ascent/descent for avoiding unexpected // clipping. - if (mFallbackLineSpacing) { + if (fallbackLineSpacing) { if (ascent < fmTop) { fmTop = ascent; } @@ -1381,11 +1381,6 @@ public class StaticLayout extends Layout { return mEllipsizedWidth; } - @Override - public boolean isFallbackLineSpacingEnabled() { - return mFallbackLineSpacing; - } - /** * Return the total height of this layout. * @@ -1412,7 +1407,6 @@ public class StaticLayout extends Layout { @UnsupportedAppUsage private int mColumns; private int mEllipsizedWidth; - private boolean mFallbackLineSpacing; /** * Keeps track if ellipsize is applied to the text. diff --git a/core/java/android/text/TextLine.java b/core/java/android/text/TextLine.java index 2b396612cf3c7..1a7ec7f99c954 100644 --- a/core/java/android/text/TextLine.java +++ b/core/java/android/text/TextLine.java @@ -71,8 +71,6 @@ public class TextLine { private Spanned mSpanned; private PrecomputedText mComputed; - private boolean mUseFallbackExtent = false; - // The start and end of a potentially existing ellipsis on this text line. // We use them to filter out replacement and metric affecting spans on ellipsized away chars. private int mEllipsisStart; @@ -143,7 +141,6 @@ public class TextLine { tl.mTabs = null; tl.mChars = null; tl.mComputed = null; - tl.mUseFallbackExtent = false; tl.mMetricAffectingSpanSpanSet.recycle(); tl.mCharacterStyleSpanSet.recycle(); @@ -174,20 +171,17 @@ public class TextLine { * @param ellipsisStart the start of the ellipsis relative to the line * @param ellipsisEnd the end of the ellipsis relative to the line. When there * is no ellipsis, this should be equal to ellipsisStart. - * @param useFallbackLineSpacing true for enabling fallback line spacing. false for disabling - * fallback line spacing. */ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) public void set(TextPaint paint, CharSequence text, int start, int limit, int dir, Directions directions, boolean hasTabs, TabStops tabStops, - int ellipsisStart, int ellipsisEnd, boolean useFallbackLineSpacing) { + int ellipsisStart, int ellipsisEnd) { mPaint = paint; mText = text; mStart = start; mLen = limit - start; mDir = dir; mDirections = directions; - mUseFallbackExtent = useFallbackLineSpacing; if (mDirections == null) { throw new IllegalArgumentException("Directions cannot be null"); } @@ -851,31 +845,6 @@ public class TextLine { previousLeading); } - private void expandMetricsFromPaint(TextPaint wp, int start, int end, - int contextStart, int contextEnd, boolean runIsRtl, FontMetricsInt fmi) { - - final int previousTop = fmi.top; - final int previousAscent = fmi.ascent; - final int previousDescent = fmi.descent; - final int previousBottom = fmi.bottom; - final int previousLeading = fmi.leading; - - if (mCharsValid) { - int count = end - start; - int contextCount = contextEnd - contextStart; - wp.getFontMetricsInt(mChars, start, count, contextStart, contextCount, runIsRtl, - fmi); - } else { - int delta = mStart; - wp.getFontMetricsInt(mText, delta + start, delta + end, - delta + contextStart, delta + contextEnd, runIsRtl, fmi); - } - - updateMetrics(fmi, previousTop, previousAscent, previousDescent, previousBottom, - previousLeading); - } - - static void updateMetrics(FontMetricsInt fmi, int previousTop, int previousAscent, int previousDescent, int previousBottom, int previousLeading) { fmi.top = Math.min(fmi.top, previousTop); @@ -980,10 +949,6 @@ public class TextLine { shapeTextRun(consumer, wp, start, end, contextStart, contextEnd, runIsRtl, leftX); } - if (mUseFallbackExtent && fmi != null) { - expandMetricsFromPaint(wp, start, end, contextStart, contextEnd, runIsRtl, fmi); - } - if (c != null) { if (wp.bgColor != 0) { int previousColor = wp.getColor(); diff --git a/core/java/android/text/TextShaper.java b/core/java/android/text/TextShaper.java index a1d6cc8e283a1..02fd7b4470f0a 100644 --- a/core/java/android/text/TextShaper.java +++ b/core/java/android/text/TextShaper.java @@ -222,8 +222,7 @@ public class TextShaper { mp.getDirections(0, count), false /* tabstop is not supported */, null, - -1, -1, // ellipsis is not supported. - false /* fallback line spacing is not used */ + -1, -1 // ellipsis is not supported. ); tl.shape(consumer); } finally { diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 6284bc2f3513b..60ce651538900 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1073,7 +1073,7 @@ public class Editor { com.android.internal.R.dimen.textview_error_popup_default_width); final StaticLayout l = StaticLayout.Builder.obtain(text, 0, text.length(), tv.getPaint(), defaultWidthInPixels) - .setUseLineSpacingFromFallbacks(tv.isFallbackLineSpacingForStaticLayout()) + .setUseLineSpacingFromFallbacks(tv.mUseFallbackLineSpacing) .build(); float max = 0; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 7327214c5389b..014340197393c 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -48,9 +48,6 @@ import android.annotation.XmlRes; import android.app.Activity; import android.app.PendingIntent; import android.app.assist.AssistStructure; -import android.app.compat.CompatChanges; -import android.compat.annotation.ChangeId; -import android.compat.annotation.EnabledSince; import android.compat.annotation.UnsupportedAppUsage; import android.content.ClipData; import android.content.ClipDescription; @@ -456,22 +453,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private static final int FLOATING_TOOLBAR_SELECT_ALL_REFRESH_DELAY = 500; - /** - * This change ID enables the fallback text line spacing (line height) for BoringLayout. - * @hide - */ - @ChangeId - @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU) - public static final long BORINGLAYOUT_FALLBACK_LINESPACING = 210923482L; // buganizer id - - /** - * This change ID enables the fallback text line spacing (line height) for StaticLayout. - * @hide - */ - @ChangeId - @EnabledSince(targetSdkVersion = Build.VERSION_CODES.P) - public static final long STATICLAYOUT_FALLBACK_LINESPACING = 37756858; // buganizer id - // System wide time for last cut, copy or text changed action. static long sLastCutCopyOrTextChangedTime; @@ -785,13 +766,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private boolean mListenerChanged = false; // True if internationalized input should be used for numbers and date and time. private final boolean mUseInternationalizedInput; - - // Fallback fonts that end up getting used should be allowed to affect line spacing. - private static final int FALLBACK_LINE_SPACING_NONE = 0; - private static final int FALLBACK_LINE_SPACING_STATIC_LAYOUT_ONLY = 1; - private static final int FALLBACK_LINE_SPACING_ALL = 2; - - private int mUseFallbackLineSpacing; + // True if fallback fonts that end up getting used should be allowed to affect line spacing. + /* package */ boolean mUseFallbackLineSpacing; // True if the view text can be padded for compat reasons, when the view is translated. private final boolean mUseTextPaddingForUiTranslation; @@ -1503,13 +1479,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; mUseInternationalizedInput = targetSdkVersion >= VERSION_CODES.O; - if (CompatChanges.isChangeEnabled(BORINGLAYOUT_FALLBACK_LINESPACING)) { - mUseFallbackLineSpacing = FALLBACK_LINE_SPACING_ALL; - } else if (CompatChanges.isChangeEnabled(STATICLAYOUT_FALLBACK_LINESPACING)) { - mUseFallbackLineSpacing = FALLBACK_LINE_SPACING_STATIC_LAYOUT_ONLY; - } else { - mUseFallbackLineSpacing = FALLBACK_LINE_SPACING_NONE; - } + mUseFallbackLineSpacing = targetSdkVersion >= VERSION_CODES.P; // TODO(b/179693024): Use a ChangeId instead. mUseTextPaddingForUiTranslation = targetSdkVersion <= Build.VERSION_CODES.R; @@ -4571,18 +4541,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @attr ref android.R.styleable#TextView_fallbackLineSpacing */ public void setFallbackLineSpacing(boolean enabled) { - int fallbackStrategy; - if (enabled) { - if (CompatChanges.isChangeEnabled(BORINGLAYOUT_FALLBACK_LINESPACING)) { - fallbackStrategy = FALLBACK_LINE_SPACING_ALL; - } else { - fallbackStrategy = FALLBACK_LINE_SPACING_STATIC_LAYOUT_ONLY; - } - } else { - fallbackStrategy = FALLBACK_LINE_SPACING_NONE; - } - if (mUseFallbackLineSpacing != fallbackStrategy) { - mUseFallbackLineSpacing = fallbackStrategy; + if (mUseFallbackLineSpacing != enabled) { + mUseFallbackLineSpacing = enabled; if (mLayout != null) { nullLayouts(); requestLayout(); @@ -4600,17 +4560,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @InspectableProperty public boolean isFallbackLineSpacing() { - return mUseFallbackLineSpacing != FALLBACK_LINE_SPACING_NONE; - } - - private boolean isFallbackLineSpacingForBoringLayout() { - return mUseFallbackLineSpacing == FALLBACK_LINE_SPACING_ALL; - } - - // Package privte for accessing from Editor.java - /* package */ boolean isFallbackLineSpacingForStaticLayout() { - return mUseFallbackLineSpacing == FALLBACK_LINE_SPACING_ALL - || mUseFallbackLineSpacing == FALLBACK_LINE_SPACING_STATIC_LAYOUT_ONLY; + return mUseFallbackLineSpacing; } /** @@ -9198,7 +9148,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (hintBoring == UNKNOWN_BORING) { hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, - isFallbackLineSpacingForBoringLayout(), mHintBoring); + mHintBoring); if (hintBoring != null) { mHintBoring = hintBoring; } @@ -9240,7 +9190,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setTextDirection(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) - .setUseLineSpacingFromFallbacks(isFallbackLineSpacingForStaticLayout()) + .setUseLineSpacingFromFallbacks(mUseFallbackLineSpacing) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency) .setJustificationMode(mJustificationMode) @@ -9300,7 +9250,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setTextDirection(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) - .setUseLineSpacingFromFallbacks(isFallbackLineSpacingForStaticLayout()) + .setUseLineSpacingFromFallbacks(mUseFallbackLineSpacing) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency) .setJustificationMode(mJustificationMode) @@ -9309,8 +9259,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener result = builder.build(); } else { if (boring == UNKNOWN_BORING) { - boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, - isFallbackLineSpacingForBoringLayout(), mBoring); + boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring); if (boring != null) { mBoring = boring; } @@ -9354,7 +9303,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener .setTextDirection(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) - .setUseLineSpacingFromFallbacks(isFallbackLineSpacingForStaticLayout()) + .setUseLineSpacingFromFallbacks(mUseFallbackLineSpacing) .setBreakStrategy(mBreakStrategy) .setHyphenationFrequency(mHyphenationFrequency) .setJustificationMode(mJustificationMode) @@ -9481,8 +9430,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } if (des < 0) { - boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, - isFallbackLineSpacingForBoringLayout(), mBoring); + boring = BoringLayout.isBoring(mTransformed, mTextPaint, mTextDir, mBoring); if (boring != null) { mBoring = boring; } @@ -9515,8 +9463,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } if (hintDes < 0) { - hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, - isFallbackLineSpacingForBoringLayout(), mHintBoring); + hintBoring = BoringLayout.isBoring(mHint, mTextPaint, mTextDir, mHintBoring); if (hintBoring != null) { mHintBoring = hintBoring; } @@ -9720,7 +9667,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener layoutBuilder.setAlignment(getLayoutAlignment()) .setLineSpacing(getLineSpacingExtra(), getLineSpacingMultiplier()) .setIncludePad(getIncludeFontPadding()) - .setUseLineSpacingFromFallbacks(isFallbackLineSpacingForStaticLayout()) + .setUseLineSpacingFromFallbacks(mUseFallbackLineSpacing) .setBreakStrategy(getBreakStrategy()) .setHyphenationFrequency(getHyphenationFrequency()) .setJustificationMode(getJustificationMode()) diff --git a/core/tests/coretests/src/android/text/TextLineTest.java b/core/tests/coretests/src/android/text/TextLineTest.java index 412d6ec975ac1..90ce305b3dab7 100644 --- a/core/tests/coretests/src/android/text/TextLineTest.java +++ b/core/tests/coretests/src/android/text/TextLineTest.java @@ -48,7 +48,7 @@ public class TextLineTest { final TextLine tl = TextLine.obtain(); tl.set(paint, line, 0, line.length(), Layout.DIR_LEFT_TO_RIGHT, Layout.DIRS_ALL_LEFT_TO_RIGHT, false /* hasTabs */, null /* tabStops */, - 0, 0 /* no ellipsis */, false /* useFallbackLinespace */); + 0, 0 /* no ellipsis */); final float originalWidth = tl.metrics(null); final float expandedWidth = 2 * originalWidth; @@ -105,7 +105,7 @@ public class TextLineTest { tl.set(paint, str, 0, str.length(), TextDirectionHeuristics.FIRSTSTRONG_LTR.isRtl(str, 0, str.length()) ? -1 : 1, layout.getLineDirections(0), tabStops != null, tabStops, - 0, 0 /* no ellipsis */, false /* useFallbackLineSpacing */); + 0, 0 /* no ellipsis */); return tl; } @@ -276,8 +276,7 @@ public class TextLineTest { final TextLine tl = TextLine.obtain(); tl.set(new TextPaint(), text, 0, text.length(), 1, Layout.DIRS_ALL_LEFT_TO_RIGHT, - false /* hasTabs */, null /* tabStops */, 9, 12, - false /* useFallbackLineSpacing */); + false /* hasTabs */, null /* tabStops */, 9, 12); tl.measure(text.length(), false /* trailing */, null /* fmi */); assertFalse(span.mIsUsed); @@ -293,8 +292,7 @@ public class TextLineTest { final TextLine tl = TextLine.obtain(); tl.set(new TextPaint(), text, 0, text.length(), 1, Layout.DIRS_ALL_LEFT_TO_RIGHT, - false /* hasTabs */, null /* tabStops */, 9, 12, - false /* useFallbackLineSpacing */); + false /* hasTabs */, null /* tabStops */, 9, 12); tl.measure(text.length(), false /* trailing */, null /* fmi */); assertTrue(span.mIsUsed); @@ -310,8 +308,7 @@ public class TextLineTest { final TextLine tl = TextLine.obtain(); tl.set(new TextPaint(), text, 0, text.length(), 1, Layout.DIRS_ALL_LEFT_TO_RIGHT, - false /* hasTabs */, null /* tabStops */, 9, 12, - false /* useFallbackLineSpacing */); + false /* hasTabs */, null /* tabStops */, 9, 12); tl.measure(text.length(), false /* trailing */, null /* fmi */); assertTrue(span.mIsUsed); } diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java index eefad8d0e4de2..42e470b7f660a 100644 --- a/graphics/java/android/graphics/Paint.java +++ b/graphics/java/android/graphics/Paint.java @@ -46,7 +46,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Locale; -import java.util.Objects; /** * The Paint class holds the style and color information about how to draw @@ -2131,116 +2130,6 @@ public class Paint { return fm; } - /** - * Returns the font metrics value for the given text. - * - * If the text is rendered with multiple font files, this function returns the large ascent and - * descent that are enough for drawing all font files. - * - * The context range is used for shaping context. Some script, e.g. Arabic or Devanagari, - * changes letter shape based on its location or surrounding characters. - * - * @param text a text to be measured. - * @param start a starting offset in the text. - * @param count a length of the text to be measured. - * @param contextStart a context starting offset in the text. - * @param contextCount a length of the context to be used. - * @param isRtl true if measuring on RTL context, otherwise false. - * @param outMetrics the output font metrics. - */ - public void getFontMetricsInt( - @NonNull CharSequence text, - @IntRange(from = 0) int start, @IntRange(from = 0) int count, - @IntRange(from = 0) int contextStart, @IntRange(from = 0) int contextCount, - boolean isRtl, - @NonNull FontMetricsInt outMetrics) { - - if (text == null) { - throw new IllegalArgumentException("text must not be null"); - } - if (start < 0 || start >= text.length()) { - throw new IllegalArgumentException("start argument is out of bounds."); - } - if (count < 0 || start + count > text.length()) { - throw new IllegalArgumentException("count argument is out of bounds."); - } - if (contextStart < 0 || contextStart >= text.length()) { - throw new IllegalArgumentException("ctxStart argument is out of bounds."); - } - if (contextCount < 0 || contextStart + contextCount > text.length()) { - throw new IllegalArgumentException("ctxCount argument is out of bounds."); - } - if (outMetrics == null) { - throw new IllegalArgumentException("outMetrics must not be null."); - } - - if (count == 0) { - getFontMetricsInt(outMetrics); - return; - } - - if (text instanceof String) { - nGetFontMetricsIntForText(mNativePaint, (String) text, start, count, contextStart, - contextCount, isRtl, outMetrics); - } else { - char[] buf = TemporaryBuffer.obtain(contextCount); - TextUtils.getChars(text, contextStart, contextStart + contextCount, buf, 0); - nGetFontMetricsIntForText(mNativePaint, buf, start - contextStart, count, 0, - contextCount, isRtl, outMetrics); - } - - } - - /** - * Returns the font metrics value for the given text. - * - * If the text is rendered with multiple font files, this function returns the large ascent and - * descent that are enough for drawing all font files. - * - * The context range is used for shaping context. Some script, e.g. Arabic or Devanagari, - * changes letter shape based on its location or surrounding characters. - * - * @param text a text to be measured. - * @param start a starting offset in the text. - * @param count a length of the text to be measured. - * @param contextStart a context starting offset in the text. - * @param contextCount a length of the context to be used. - * @param isRtl true if measuring on RTL context, otherwise false. - * @param outMetrics the output font metrics. - */ - public void getFontMetricsInt(@NonNull char[] text, - @IntRange(from = 0) int start, @IntRange(from = 0) int count, - @IntRange(from = 0) int contextStart, @IntRange(from = 0) int contextCount, - boolean isRtl, - @NonNull FontMetricsInt outMetrics) { - if (text == null) { - throw new IllegalArgumentException("text must not be null"); - } - if (start < 0 || start >= text.length) { - throw new IllegalArgumentException("start argument is out of bounds."); - } - if (count < 0 || start + count > text.length) { - throw new IllegalArgumentException("count argument is out of bounds."); - } - if (contextStart < 0 || contextStart >= text.length) { - throw new IllegalArgumentException("ctxStart argument is out of bounds."); - } - if (contextCount < 0 || contextStart + contextCount > text.length) { - throw new IllegalArgumentException("ctxCount argument is out of bounds."); - } - if (outMetrics == null) { - throw new IllegalArgumentException("outMetrics must not be null."); - } - - if (count == 0) { - getFontMetricsInt(outMetrics); - return; - } - - nGetFontMetricsIntForText(mNativePaint, text, start, count, contextStart, contextCount, - isRtl, outMetrics); - } - /** * Convenience method for callers that want to have FontMetrics values as * integers. @@ -2274,23 +2163,6 @@ public class Paint { " descent=" + descent + " bottom=" + bottom + " leading=" + leading; } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof FontMetricsInt)) return false; - FontMetricsInt that = (FontMetricsInt) o; - return top == that.top - && ascent == that.ascent - && descent == that.descent - && bottom == that.bottom - && leading == that.leading; - } - - @Override - public int hashCode() { - return Objects.hash(top, ascent, descent, bottom, leading); - } } /** @@ -3245,13 +3117,6 @@ public class Paint { int contextStart, int contextEnd, boolean isRtl, int offset); private static native int nGetOffsetForAdvance(long paintPtr, char[] text, int start, int end, int contextStart, int contextEnd, boolean isRtl, float advance); - private static native void nGetFontMetricsIntForText(long paintPtr, char[] text, - int start, int count, int ctxStart, int ctxCount, boolean isRtl, - FontMetricsInt outMetrics); - private static native void nGetFontMetricsIntForText(long paintPtr, String text, - int start, int count, int ctxStart, int ctxCount, boolean isRtl, - FontMetricsInt outMetrics); - // ---------------- @FastNative ------------------------ @@ -3265,6 +3130,7 @@ public class Paint { @FastNative private static native int nGetFontMetricsInt(long paintPtr, FontMetricsInt fmi); + // ---------------- @CriticalNative ------------------------ @CriticalNative diff --git a/libs/hwui/hwui/MinikinUtils.cpp b/libs/hwui/hwui/MinikinUtils.cpp index e359145feef7c..b8029087cb4f8 100644 --- a/libs/hwui/hwui/MinikinUtils.cpp +++ b/libs/hwui/hwui/MinikinUtils.cpp @@ -95,16 +95,6 @@ float MinikinUtils::measureText(const Paint* paint, minikin::Bidi bidiFlags, endHyphen, advances); } -minikin::MinikinExtent MinikinUtils::getFontExtent(const Paint* paint, minikin::Bidi bidiFlags, - const Typeface* typeface, const uint16_t* buf, - size_t start, size_t count, size_t bufSize) { - minikin::MinikinPaint minikinPaint = prepareMinikinPaint(paint, typeface); - const minikin::U16StringPiece textBuf(buf, bufSize); - const minikin::Range range(start, start + count); - - return minikin::getFontExtent(textBuf, range, bidiFlags, minikinPaint); -} - bool MinikinUtils::hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs) { const Typeface* resolvedFace = Typeface::resolveDefault(typeface); return resolvedFace->fFontCollection->hasVariationSelector(codepoint, vs); diff --git a/libs/hwui/hwui/MinikinUtils.h b/libs/hwui/hwui/MinikinUtils.h index 009b84b140ea7..a15803ad2dcaa 100644 --- a/libs/hwui/hwui/MinikinUtils.h +++ b/libs/hwui/hwui/MinikinUtils.h @@ -56,10 +56,6 @@ public: size_t start, size_t count, size_t bufSize, float* advances); - static minikin::MinikinExtent getFontExtent(const Paint* paint, minikin::Bidi bidiFlags, - const Typeface* typeface, const uint16_t* buf, - size_t start, size_t count, size_t bufSize); - static bool hasVariationSelector(const Typeface* typeface, uint32_t codepoint, uint32_t vs); diff --git a/libs/hwui/jni/Paint.cpp b/libs/hwui/jni/Paint.cpp index f76863255153b..22a1e1fd94b94 100644 --- a/libs/hwui/jni/Paint.cpp +++ b/libs/hwui/jni/Paint.cpp @@ -541,6 +541,26 @@ namespace PaintGlue { return result; } + // ------------------ @FastNative --------------------------- + + static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) { + Paint* obj = reinterpret_cast(objHandle); + ScopedUtfChars localesChars(env, locales); + jint minikinLocaleListId = minikin::registerLocaleList(localesChars.c_str()); + obj->setMinikinLocaleListId(minikinLocaleListId); + return minikinLocaleListId; + } + + static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, jstring settings) { + Paint* paint = reinterpret_cast(paintHandle); + if (!settings) { + paint->setFontFeatureSettings(std::string()); + } else { + ScopedUtfChars settingsChars(env, settings); + paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); + } + } + static SkScalar getMetricsInternal(jlong paintHandle, SkFontMetrics *metrics) { const int kElegantTop = 2500; const int kElegantBottom = -1000; @@ -573,67 +593,6 @@ namespace PaintGlue { return spacing; } - static void doFontExtent(JNIEnv* env, jlong paintHandle, const jchar buf[], jint start, - jint count, jint bufSize, jboolean isRtl, jobject fmi) { - const Paint* paint = reinterpret_cast(paintHandle); - const Typeface* typeface = paint->getAndroidTypeface(); - minikin::Bidi bidiFlags = isRtl ? minikin::Bidi::FORCE_RTL : minikin::Bidi::FORCE_LTR; - minikin::MinikinExtent extent = - MinikinUtils::getFontExtent(paint, bidiFlags, typeface, buf, start, count, bufSize); - - SkFontMetrics metrics; - getMetricsInternal(paintHandle, &metrics); - - metrics.fAscent = extent.ascent; - metrics.fDescent = extent.descent; - - // If top/bottom is narrower than ascent/descent, adjust top/bottom to ascent/descent. - metrics.fTop = std::min(metrics.fAscent, metrics.fTop); - metrics.fBottom = std::max(metrics.fDescent, metrics.fBottom); - - GraphicsJNI::set_metrics_int(env, fmi, metrics); - } - - static void getFontMetricsIntForText___C(JNIEnv* env, jclass, jlong paintHandle, - jcharArray text, jint start, jint count, jint ctxStart, - jint ctxCount, jboolean isRtl, jobject fmi) { - ScopedCharArrayRO textArray(env, text); - - doFontExtent(env, paintHandle, textArray.get() + ctxStart, start - ctxStart, count, - ctxCount, isRtl, fmi); - } - - static void getFontMetricsIntForText___String(JNIEnv* env, jclass, jlong paintHandle, - jstring text, jint start, jint count, - jint ctxStart, jint ctxCount, jboolean isRtl, - jobject fmi) { - ScopedStringChars textChars(env, text); - - doFontExtent(env, paintHandle, textChars.get() + ctxStart, start - ctxStart, count, - ctxCount, isRtl, fmi); - } - - // ------------------ @FastNative --------------------------- - - static jint setTextLocales(JNIEnv* env, jobject clazz, jlong objHandle, jstring locales) { - Paint* obj = reinterpret_cast(objHandle); - ScopedUtfChars localesChars(env, locales); - jint minikinLocaleListId = minikin::registerLocaleList(localesChars.c_str()); - obj->setMinikinLocaleListId(minikinLocaleListId); - return minikinLocaleListId; - } - - static void setFontFeatureSettings(JNIEnv* env, jobject clazz, jlong paintHandle, - jstring settings) { - Paint* paint = reinterpret_cast(paintHandle); - if (!settings) { - paint->setFontFeatureSettings(std::string()); - } else { - ScopedUtfChars settingsChars(env, settings); - paint->setFontFeatureSettings(std::string(settingsChars.c_str(), settingsChars.size())); - } - } - static jfloat getFontMetrics(JNIEnv* env, jobject, jlong paintHandle, jobject metricsObj) { SkFontMetrics metrics; SkScalar spacing = getMetricsInternal(paintHandle, &metrics); @@ -1056,11 +1015,6 @@ static const JNINativeMethod methods[] = { {"nGetRunAdvance", "(J[CIIIIZI)F", (void*) PaintGlue::getRunAdvance___CIIIIZI_F}, {"nGetOffsetForAdvance", "(J[CIIIIZF)I", (void*) PaintGlue::getOffsetForAdvance___CIIIIZF_I}, - {"nGetFontMetricsIntForText", "(J[CIIIIZLandroid/graphics/Paint$FontMetricsInt;)V", - (void*)PaintGlue::getFontMetricsIntForText___C}, - {"nGetFontMetricsIntForText", - "(JLjava/lang/String;IIIIZLandroid/graphics/Paint$FontMetricsInt;)V", - (void*)PaintGlue::getFontMetricsIntForText___String}, // --------------- @FastNative ---------------------- @@ -1139,7 +1093,6 @@ static const JNINativeMethod methods[] = { {"nEqualsForTextMeasurement", "(JJ)Z", (void*)PaintGlue::equalsForTextMeasurement}, }; - int register_android_graphics_Paint(JNIEnv* env) { return RegisterMethodsOrDie(env, "android/graphics/Paint", methods, NELEM(methods)); } From 541f591ae99b53be16e6ef1d284c392790a97f6e Mon Sep 17 00:00:00 2001 From: Selim Cinek Date: Wed, 12 Jan 2022 11:48:52 +0100 Subject: [PATCH 091/176] Fixed a crash when dragging down on the NotificationShelf The logging code was wrongly casting an ExpandableView to a row, but it can also be a Shelf. Fixes: 213969909 Tests: atest SystemUITests Change-Id: Id5847d44d313d57cade46a6ccb9109d86145499b (cherry picked from commit 05ee93d30f6cf1199f492eb3cbaacf38d589c1d4) Merged-In:Id5847d44d313d57cade46a6ccb9109d86145499b --- .../phone/LSShadeTransitionLogger.kt | 8 ++-- .../statusbar/LSShadeTransitionLoggerTest.kt | 44 +++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt index 4de78f5d6190d..868efa027f409 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt @@ -34,7 +34,7 @@ class LSShadeTransitionLogger @Inject constructor( private val displayMetrics: DisplayMetrics ) { fun logUnSuccessfulDragDown(startingChild: View?) { - val entry = (startingChild as ExpandableNotificationRow?)?.entry + val entry = (startingChild as? ExpandableNotificationRow)?.entry buffer.log(TAG, LogLevel.INFO, { str1 = entry?.key ?: "no entry" }, { @@ -49,7 +49,7 @@ class LSShadeTransitionLogger @Inject constructor( } fun logDragDownStarted(startingChild: ExpandableView?) { - val entry = (startingChild as ExpandableNotificationRow?)?.entry + val entry = (startingChild as? ExpandableNotificationRow)?.entry buffer.log(TAG, LogLevel.INFO, { str1 = entry?.key ?: "no entry" }, { @@ -58,7 +58,7 @@ class LSShadeTransitionLogger @Inject constructor( } fun logDraggedDownLockDownShade(startingChild: View?) { - val entry = (startingChild as ExpandableNotificationRow?)?.entry + val entry = (startingChild as? ExpandableNotificationRow)?.entry buffer.log(TAG, LogLevel.INFO, { str1 = entry?.key ?: "no entry" }, { @@ -67,7 +67,7 @@ class LSShadeTransitionLogger @Inject constructor( } fun logDraggedDown(startingChild: View?, dragLengthY: Int) { - val entry = (startingChild as ExpandableNotificationRow?)?.entry + val entry = (startingChild as? ExpandableNotificationRow)?.entry buffer.log(TAG, LogLevel.INFO, { str1 = entry?.key ?: "no entry" }, { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt new file mode 100644 index 0000000000000..6971c63ed6d49 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt @@ -0,0 +1,44 @@ +package com.android.systemui.statusbar + +import android.testing.AndroidTestingRunner +import android.util.DisplayMetrics +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.log.LogBuffer +import com.android.systemui.statusbar.notification.row.ExpandableView +import com.android.systemui.statusbar.phone.LSShadeTransitionLogger +import com.android.systemui.statusbar.phone.LockscreenGestureLogger +import com.android.systemui.util.mockito.mock +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.junit.MockitoJUnit + +@RunWith(AndroidTestingRunner::class) +@SmallTest +class LSShadeTransitionLoggerTest : SysuiTestCase() { + lateinit var logger: LSShadeTransitionLogger + @Mock + lateinit var gestureLogger: LockscreenGestureLogger + @Mock + lateinit var displayMetrics: DisplayMetrics + @JvmField @Rule + val mockito = MockitoJUnit.rule() + + @Before + fun setup() { + logger = LSShadeTransitionLogger( + LogBuffer("Test", 10, 10, mock()), + gestureLogger, + displayMetrics) + } + + @Test + fun testLogDragDownStarted() { + val view: ExpandableView = mock() + // log a non-null, non row, ensure no crash + logger.logDragDownStarted(view) + } +} \ No newline at end of file From f3005426a3657b1e033e8291a08b575a90bfb338 Mon Sep 17 00:00:00 2001 From: Bernardo Rufino Date: Wed, 12 Jan 2022 17:44:44 +0000 Subject: [PATCH 092/176] Revert "Migrate unsafe parcel APIs in framework-minus-apex" This reverts commit 90bb3709dc75f7e44914222114752de5bce133d4. Reason for revert: b/214053959 Change-Id: Ic271bab1d3eaf677a5989dda9deb944ee2ad6850 (cherry picked from commit 331be9a6431d6489f8d1e1b80cb510d0ee073c50) Merged-In:Ic271bab1d3eaf677a5989dda9deb944ee2ad6850 --- .../java/android/app/blob/BlobInfo.java | 1 - .../java/android/app/AlarmManager.java | 1 - .../java/android/app/job/JobInfo.java | 1 - .../AccessibilityGestureEvent.java | 2 +- .../AccessibilityServiceInfo.java | 4 +- core/java/android/app/ActivityManager.java | 2 +- core/java/android/app/AppOpsManager.java | 6 +-- core/java/android/app/AutomaticZenRule.java | 8 ++-- .../android/app/GrantedUriPermission.java | 2 +- .../android/app/NotificationChannelGroup.java | 2 +- .../android/app/RemoteInputHistoryItem.java | 2 +- .../android/app/assist/AssistStructure.java | 6 +-- .../app/people/ConversationChannel.java | 8 ++-- .../app/people/ConversationStatus.java | 2 +- .../android/app/people/PeopleSpaceTile.java | 12 ++--- .../app/prediction/AppTargetEvent.java | 2 +- .../servertransaction/ClientTransaction.java | 4 +- .../app/smartspace/SmartspaceTargetEvent.java | 2 +- .../app/time/ExternalTimeSuggestion.java | 4 +- .../app/time/TimeCapabilitiesAndConfig.java | 4 +- .../time/TimeZoneCapabilitiesAndConfig.java | 4 +- .../app/timedetector/GnssTimeSuggestion.java | 4 +- .../timedetector/ManualTimeSuggestion.java | 4 +- .../timedetector/NetworkTimeSuggestion.java | 4 +- .../timedetector/TelephonyTimeSuggestion.java | 4 +- .../java/android/app/timezone/RulesState.java | 6 +-- .../ManualTimeZoneSuggestion.java | 2 +- .../TelephonyTimeZoneSuggestion.java | 2 +- .../android/app/usage/CacheQuotaHint.java | 2 +- .../BluetoothGattCharacteristic.java | 2 +- .../bluetooth/BluetoothGattDescriptor.java | 2 +- .../BluetoothGattIncludedService.java | 2 +- .../bluetooth/BluetoothGattService.java | 2 +- .../bluetooth/BluetoothHeadsetClientCall.java | 2 +- .../android/bluetooth/BufferConstraints.java | 2 +- .../java/android/bluetooth/le/ScanFilter.java | 10 ++--- .../android/companion/AssociationRequest.java | 2 +- .../companion/BluetoothDeviceFilter.java | 2 +- .../companion/BluetoothLeDeviceFilter.java | 2 +- .../content/ContentProviderOperation.java | 2 +- core/java/android/content/PeriodicSync.java | 2 +- core/java/android/content/SyncInfo.java | 2 +- core/java/android/content/SyncRequest.java | 2 +- core/java/android/content/UndoManager.java | 2 +- core/java/android/content/UriPermission.java | 2 +- .../content/om/OverlayManagerTransaction.java | 2 +- .../android/content/pm/InstallSourceInfo.java | 2 +- .../android/content/pm/InstantAppInfo.java | 2 +- .../content/pm/InstantAppIntentFilter.java | 2 +- .../content/pm/InstantAppResolveInfo.java | 2 +- .../pm/LauncherActivityInfoInternal.java | 4 +- .../android/content/pm/PackageInstaller.java | 14 +++--- .../android/content/pm/PackageParser.java | 44 +++++++++---------- .../android/content/pm/SharedLibraryInfo.java | 4 +- .../java/android/content/pm/ShortcutInfo.java | 8 ++-- .../android/content/pm/ShortcutManager.java | 4 +- .../content/pm/ShortcutQueryWrapper.java | 2 +- .../java/android/content/pm/VerifierInfo.java | 2 +- .../pm/parsing/ParsingPackageImpl.java | 2 +- .../pm/parsing/ParsingPackageUtils.java | 2 +- .../content/pm/parsing/ParsingUtils.java | 2 +- .../component/ParsedPermissionImpl.java | 2 +- .../graphics/fonts/FontUpdateRequest.java | 6 +-- .../hardware/biometrics/PromptInfo.java | 2 +- .../biometrics/SensorPropertiesInternal.java | 2 +- .../face/FaceAuthenticationFrame.java | 2 +- .../hardware/face/FaceEnrollFrame.java | 4 +- .../GeofenceHardwareMonitorEvent.java | 2 +- .../android/net/InterfaceConfiguration.java | 1 - core/java/android/net/NetworkPolicy.java | 4 +- core/java/android/net/vcn/VcnConfig.java | 2 +- .../net/vcn/VcnNetworkPolicyResult.java | 2 +- .../android/net/vcn/VcnTransportInfo.java | 2 +- .../net/vcn/VcnUnderlyingNetworkPolicy.java | 2 +- core/java/android/nfc/BeamShareData.java | 4 +- core/java/android/os/Message.java | 2 +- core/java/android/os/StrictMode.java | 2 +- core/java/android/os/VibrationEffect.java | 2 +- core/java/android/os/VibratorInfo.java | 2 +- core/java/android/os/WorkSource.java | 2 +- .../android/os/storage/StorageVolume.java | 2 +- core/java/android/print/PrintJobInfo.java | 8 ++-- core/java/android/print/PrinterId.java | 2 +- core/java/android/print/PrinterInfo.java | 6 +-- .../printservice/PrintServiceInfo.java | 2 +- .../service/autofill/BatchUpdates.java | 2 +- .../service/autofill/CompositeUserData.java | 4 +- .../service/autofill/CustomDescription.java | 2 +- .../android/service/autofill/Dataset.java | 12 ++--- .../service/autofill/DateTransformation.java | 4 +- .../service/autofill/DateValueSanitizer.java | 2 +- .../android/service/autofill/FillRequest.java | 2 +- .../service/autofill/FillResponse.java | 20 ++++----- .../service/autofill/ImageTransformation.java | 2 +- .../service/autofill/NegationValidator.java | 2 +- .../service/autofill/RegexValidator.java | 4 +- .../android/service/autofill/SaveInfo.java | 8 ++-- .../service/autofill/TextValueSanitizer.java | 2 +- .../service/contentcapture/ActivityEvent.java | 2 +- .../service/contentcapture/SnapshotData.java | 4 +- .../service/notification/Condition.java | 2 +- .../ConversationChannelWrapper.java | 4 +- .../NotificationListenerService.java | 4 +- .../NotificationRankingUpdate.java | 2 +- .../service/notification/ZenModeConfig.java | 12 ++--- .../service/notification/ZenPolicy.java | 4 +- .../GetWalletCardsResponse.java | 2 +- .../settings/suggestions/Suggestion.java | 4 +- .../timezone/TimeZoneProviderEvent.java | 2 +- .../timezone/TimeZoneProviderSuggestion.java | 2 +- core/java/android/speech/tts/Voice.java | 2 +- .../android/telephony/SubscriptionPlan.java | 2 +- core/java/android/text/FontConfig.java | 6 +-- .../java/android/text/style/EasyEditSpan.java | 2 +- .../text/style/TextAppearanceSpan.java | 2 +- core/java/android/util/MemoryIntArray.java | 2 +- core/java/android/view/DisplayInfo.java | 6 +-- .../android/view/KeyboardShortcutInfo.java | 2 +- .../accessibility/AccessibilityEvent.java | 2 +- .../AccessibilityWindowInfo.java | 2 +- .../android/view/autofill/ParcelableMap.java | 4 +- .../ContentCaptureCondition.java | 2 +- .../contentcapture/ContentCaptureContext.java | 4 +- .../contentcapture/ContentCaptureEvent.java | 8 ++-- .../android/view/contentcapture/ViewNode.java | 8 ++-- .../view/inputmethod/CursorAnchorInfo.java | 2 +- .../android/view/inputmethod/EditorInfo.java | 2 +- .../inputmethod/InlineSuggestionsRequest.java | 2 +- .../InlineSuggestionsResponse.java | 2 +- .../textclassifier/ConversationAction.java | 2 +- .../textclassifier/ConversationActions.java | 8 ++-- .../view/textclassifier/SelectionEvent.java | 2 +- .../textclassifier/TextClassification.java | 4 +- .../TextClassificationContext.java | 2 +- .../textclassifier/TextClassifierEvent.java | 2 +- .../view/textclassifier/TextLanguage.java | 2 +- .../view/textclassifier/TextLinks.java | 6 +-- .../view/textclassifier/TextSelection.java | 6 +-- .../view/translation/TranslationRequest.java | 4 +- .../view/translation/TranslationSpec.java | 2 +- .../android/widget/ExpandableListView.java | 2 +- core/java/android/widget/RemoteViews.java | 2 +- .../internal/uce/options/OptionsCapInfo.java | 2 +- .../uce/options/OptionsCmdStatus.java | 6 +-- .../uce/options/OptionsSipResponse.java | 2 +- .../internal/uce/presence/PresCapInfo.java | 2 +- .../internal/uce/presence/PresCmdStatus.java | 4 +- .../internal/uce/presence/PresResInfo.java | 2 +- .../internal/uce/presence/PresRlmiInfo.java | 2 +- .../uce/presence/PresSipResponse.java | 2 +- .../app/chooser/DisplayResolveInfo.java | 4 +- .../android/internal/net/LegacyVpnInfo.java | 2 +- .../com/android/internal/net/VpnConfig.java | 4 +- .../com/android/internal/net/VpnProfile.java | 4 +- .../com/android/internal/os/AppFuseMount.java | 2 +- .../internal/statusbar/StatusBarIcon.java | 4 +- .../internal/util/ScreenshotHelper.java | 6 +-- .../android/location/GnssMeasurement.java | 2 +- .../location/GnssMeasurementsEvent.java | 2 +- .../location/GpsMeasurementsEvent.java | 2 +- .../location/GpsNavigationMessageEvent.java | 2 +- .../java/android/location/SatellitePvt.java | 6 +-- .../java/android/media/MediaDescription.java | 6 +-- media/java/android/media/MediaRoute2Info.java | 2 +- .../android/media/midi/MidiDeviceStatus.java | 2 +- .../musicrecognition/RecognitionRequest.java | 4 +- .../media/session/MediaController.java | 2 +- .../media/tv/TvContentRatingSystemInfo.java | 4 +- media/java/android/media/tv/TvInputInfo.java | 10 ++--- .../src/android/net/DataUsageRequest.java | 2 +- .../src/android/net/IpSecConfig.java | 8 ++-- .../android/net/IpSecUdpEncapResponse.java | 2 +- .../src/android/net/NetworkStateSnapshot.java | 6 +-- .../android/net/UnderlyingNetworkInfo.java | 2 +- .../java/android/telecom/CallAudioState.java | 4 +- telecomm/java/android/telecom/Connection.java | 4 +- .../android/telecom/ConnectionRequest.java | 12 ++--- .../java/android/telecom/DisconnectCause.java | 2 +- .../java/android/telecom/ParcelableCall.java | 16 +++---- .../android/telecom/ParcelableConference.java | 10 ++--- .../android/telecom/ParcelableConnection.java | 8 ++-- .../android/telecom/ParcelableRttCall.java | 4 +- .../telecom/PhoneAccountSuggestion.java | 2 +- .../java/android/telecom/StatusHints.java | 4 +- .../telephony/AvailableNetworkInfo.java | 4 +- .../java/android/telephony/BarringInfo.java | 4 +- .../android/telephony/CallAttributes.java | 4 +- .../android/telephony/CellIdentityLte.java | 2 +- .../telephony/CellIdentityTdscdma.java | 2 +- .../android/telephony/CellIdentityWcdma.java | 2 +- .../telephony/CellSignalStrengthNr.java | 2 +- .../DataSpecificRegistrationInfo.java | 2 +- .../telephony/NetworkRegistrationInfo.java | 8 ++-- .../android/telephony/PhoneCapability.java | 2 +- .../telephony/PreciseDataConnectionState.java | 4 +- .../java/android/telephony/ServiceState.java | 2 +- .../android/telephony/SignalStrength.java | 12 ++--- .../telephony/ThermalMitigationRequest.java | 2 +- .../android/telephony/VisualVoicemailSms.java | 2 +- .../android/telephony/data/ApnSetting.java | 2 +- .../telephony/data/DataCallResponse.java | 16 +++---- .../android/telephony/data/DataProfile.java | 4 +- .../java/android/telephony/data/Qos.java | 4 +- .../telephony/data/QosBearerFilter.java | 8 ++-- .../telephony/data/QosBearerSession.java | 4 +- .../android/telephony/gba/GbaAuthRequest.java | 2 +- .../telephony/ims/DelegateRequest.java | 2 +- .../android/telephony/ims/ImsCallProfile.java | 2 +- .../telephony/ims/ImsConferenceState.java | 2 +- .../telephony/ims/ImsExternalCallState.java | 4 +- .../ims/ImsRegistrationAttributes.java | 2 +- .../java/android/telephony/ims/ImsSsData.java | 4 +- .../ims/RcsContactPresenceTuple.java | 4 +- .../ims/RcsContactTerminatedReason.java | 2 +- .../ims/RcsContactUceCapability.java | 4 +- .../telephony/ims/RtpHeaderExtensionType.java | 2 +- .../ims/SipDelegateConfiguration.java | 2 +- .../telephony/mbms/DownloadRequest.java | 4 +- .../java/android/telephony/mbms/FileInfo.java | 2 +- .../telephony/mbms/FileServiceInfo.java | 2 +- .../android/telephony/mbms/ServiceInfo.java | 8 ++-- .../android/telephony/mbms/UriPathPair.java | 4 +- .../internal/telephony/NetworkScanResult.java | 2 +- .../internal/telephony/OperatorInfo.java | 2 +- 224 files changed, 425 insertions(+), 429 deletions(-) diff --git a/apex/blobstore/framework/java/android/app/blob/BlobInfo.java b/apex/blobstore/framework/java/android/app/blob/BlobInfo.java index 73ef310c7b40e..ba92d95b483ed 100644 --- a/apex/blobstore/framework/java/android/app/blob/BlobInfo.java +++ b/apex/blobstore/framework/java/android/app/blob/BlobInfo.java @@ -48,7 +48,6 @@ public final class BlobInfo implements Parcelable { mLeaseInfos = leaseInfos; } - @SuppressWarnings("UnsafeParcelApi") private BlobInfo(Parcel in) { mId = in.readLong(); mExpiryTimeMs = in.readLong(); diff --git a/apex/jobscheduler/framework/java/android/app/AlarmManager.java b/apex/jobscheduler/framework/java/android/app/AlarmManager.java index 66767e21a2e70..9c0c3657bff33 100644 --- a/apex/jobscheduler/framework/java/android/app/AlarmManager.java +++ b/apex/jobscheduler/framework/java/android/app/AlarmManager.java @@ -1408,7 +1408,6 @@ public class AlarmManager { * Use the {@link #CREATOR} * @hide */ - @SuppressWarnings("UnsafeParcelApi") AlarmClockInfo(Parcel in) { mTriggerTime = in.readLong(); mShowIntent = in.readParcelable(PendingIntent.class.getClassLoader()); diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java index b9673f25d680f..0e6006a62397b 100644 --- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java +++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java @@ -881,7 +881,6 @@ public class JobInfo implements Parcelable { return hashCode; } - @SuppressWarnings("UnsafeParcelApi") private JobInfo(Parcel in) { jobId = in.readInt(); extras = in.readPersistableBundle(); diff --git a/core/java/android/accessibilityservice/AccessibilityGestureEvent.java b/core/java/android/accessibilityservice/AccessibilityGestureEvent.java index 8e01779c6fac6..3c9b232511915 100644 --- a/core/java/android/accessibilityservice/AccessibilityGestureEvent.java +++ b/core/java/android/accessibilityservice/AccessibilityGestureEvent.java @@ -172,7 +172,7 @@ public final class AccessibilityGestureEvent implements Parcelable { private AccessibilityGestureEvent(@NonNull Parcel parcel) { mGestureId = parcel.readInt(); mDisplayId = parcel.readInt(); - ParceledListSlice slice = parcel.readParcelable(getClass().getClassLoader(), android.content.pm.ParceledListSlice.class); + ParceledListSlice slice = parcel.readParcelable(getClass().getClassLoader()); mMotionEvents = slice.getList(); } diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 1167d0b1034f8..04c784ea1c170 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -1094,8 +1094,8 @@ public class AccessibilityServiceInfo implements Parcelable { mInteractiveUiTimeout = parcel.readInt(); flags = parcel.readInt(); crashed = parcel.readInt() != 0; - mComponentName = parcel.readParcelable(this.getClass().getClassLoader(), android.content.ComponentName.class); - mResolveInfo = parcel.readParcelable(null, android.content.pm.ResolveInfo.class); + mComponentName = parcel.readParcelable(this.getClass().getClassLoader()); + mResolveInfo = parcel.readParcelable(null); mSettingsActivityName = parcel.readString(); mCapabilities = parcel.readInt(); mSummaryResId = parcel.readInt(); diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index a1409839ff63d..9f8d24662c8d2 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -1903,7 +1903,7 @@ public class ActivityManager { public void readFromParcel(Parcel source) { id = source.readInt(); persistentId = source.readInt(); - childrenTaskInfos = source.readArrayList(RecentTaskInfo.class.getClassLoader(), android.app.ActivityManager.RecentTaskInfo.class); + childrenTaskInfos = source.readArrayList(RecentTaskInfo.class.getClassLoader()); lastSnapshotData.taskSize = source.readTypedObject(Point.CREATOR); lastSnapshotData.contentInsets = source.readTypedObject(Rect.CREATOR); lastSnapshotData.bufferSize = source.readTypedObject(Point.CREATOR); diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 68c69e555bda9..565f69090c6b0 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -4058,7 +4058,7 @@ public class AppOpsManager { LongSparseArray array = new LongSparseArray<>(numEntries); for (int i = 0; i < numEntries; i++) { - array.put(source.readLong(), source.readParcelable(null, android.app.AppOpsManager.NoteOpEvent.class)); + array.put(source.readLong(), source.readParcelable(null)); } return array; @@ -5178,7 +5178,7 @@ public class AppOpsManager { final int[] uids = parcel.createIntArray(); if (!ArrayUtils.isEmpty(uids)) { final ParceledListSlice listSlice = parcel.readParcelable( - HistoricalOps.class.getClassLoader(), android.content.pm.ParceledListSlice.class); + HistoricalOps.class.getClassLoader()); final List uidOps = (listSlice != null) ? listSlice.getList() : null; if (uidOps == null) { @@ -10000,7 +10000,7 @@ public class AppOpsManager { private static @Nullable List readDiscreteAccessArrayFromParcel( @NonNull Parcel parcel) { - final ParceledListSlice listSlice = parcel.readParcelable(null, android.content.pm.ParceledListSlice.class); + final ParceledListSlice listSlice = parcel.readParcelable(null); return listSlice == null ? null : listSlice.getList(); } diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java index c0aebeed596a6..7a806bdf473dd 100644 --- a/core/java/android/app/AutomaticZenRule.java +++ b/core/java/android/app/AutomaticZenRule.java @@ -118,11 +118,11 @@ public final class AutomaticZenRule implements Parcelable { name = source.readString(); } interruptionFilter = source.readInt(); - conditionId = source.readParcelable(null, android.net.Uri.class); - owner = source.readParcelable(null, android.content.ComponentName.class); - configurationActivity = source.readParcelable(null, android.content.ComponentName.class); + conditionId = source.readParcelable(null); + owner = source.readParcelable(null); + configurationActivity = source.readParcelable(null); creationTime = source.readLong(); - mZenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class); + mZenPolicy = source.readParcelable(null); mModified = source.readInt() == ENABLED; mPkg = source.readString(); } diff --git a/core/java/android/app/GrantedUriPermission.java b/core/java/android/app/GrantedUriPermission.java index a71cb4a11af81..48d5b8cc126ba 100644 --- a/core/java/android/app/GrantedUriPermission.java +++ b/core/java/android/app/GrantedUriPermission.java @@ -68,7 +68,7 @@ public class GrantedUriPermission implements Parcelable { }; private GrantedUriPermission(Parcel in) { - uri = in.readParcelable(null, android.net.Uri.class); + uri = in.readParcelable(null); packageName = in.readString(); } } diff --git a/core/java/android/app/NotificationChannelGroup.java b/core/java/android/app/NotificationChannelGroup.java index f97415ca20c8a..cd6df0b231d91 100644 --- a/core/java/android/app/NotificationChannelGroup.java +++ b/core/java/android/app/NotificationChannelGroup.java @@ -100,7 +100,7 @@ public final class NotificationChannelGroup implements Parcelable { } else { mDescription = null; } - in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class); + in.readParcelableList(mChannels, NotificationChannel.class.getClassLoader()); mBlocked = in.readBoolean(); mUserLockedFields = in.readInt(); } diff --git a/core/java/android/app/RemoteInputHistoryItem.java b/core/java/android/app/RemoteInputHistoryItem.java index 32f89819fb1fd..091db3f142aec 100644 --- a/core/java/android/app/RemoteInputHistoryItem.java +++ b/core/java/android/app/RemoteInputHistoryItem.java @@ -48,7 +48,7 @@ public class RemoteInputHistoryItem implements Parcelable { protected RemoteInputHistoryItem(Parcel in) { mText = in.readCharSequence(); mMimeType = in.readStringNoHelper(); - mUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mUri = in.readParcelable(Uri.class.getClassLoader()); } public static final Creator CREATOR = diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index 6e49e956fe7e2..e1f6af0cc1282 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -815,13 +815,13 @@ public class AssistStructure implements Parcelable { mAutofillHints = in.readStringArray(); } if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_VALUE) != 0) { - mAutofillValue = in.readParcelable(null, android.view.autofill.AutofillValue.class); + mAutofillValue = in.readParcelable(null); } if ((autofillFlags & AUTOFILL_FLAGS_HAS_AUTOFILL_OPTIONS) != 0) { mAutofillOptions = in.readCharSequenceArray(); } if ((autofillFlags & AUTOFILL_FLAGS_HAS_HTML_INFO) != 0) { - mHtmlInfo = in.readParcelable(null, android.view.ViewStructure.HtmlInfo.class); + mHtmlInfo = in.readParcelable(null); } if ((autofillFlags & AUTOFILL_FLAGS_HAS_MIN_TEXT_EMS) != 0) { mMinEms = in.readInt(); @@ -886,7 +886,7 @@ public class AssistStructure implements Parcelable { mWebDomain = in.readString(); } if ((flags&FLAGS_HAS_LOCALE_LIST) != 0) { - mLocaleList = in.readParcelable(null, android.os.LocaleList.class); + mLocaleList = in.readParcelable(null); } if ((flags & FLAGS_HAS_MIME_TYPES) != 0) { mReceiveContentMimeTypes = in.readStringArray(); diff --git a/core/java/android/app/people/ConversationChannel.java b/core/java/android/app/people/ConversationChannel.java index ab350f225e52f..2bf71b0183c60 100644 --- a/core/java/android/app/people/ConversationChannel.java +++ b/core/java/android/app/people/ConversationChannel.java @@ -83,16 +83,16 @@ public final class ConversationChannel implements Parcelable { } public ConversationChannel(Parcel in) { - mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader(), android.content.pm.ShortcutInfo.class); + mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader()); mUid = in.readInt(); - mNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class); + mNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader()); mNotificationChannelGroup = - in.readParcelable(NotificationChannelGroup.class.getClassLoader(), android.app.NotificationChannelGroup.class); + in.readParcelable(NotificationChannelGroup.class.getClassLoader()); mLastEventTimestamp = in.readLong(); mHasActiveNotifications = in.readBoolean(); mHasBirthdayToday = in.readBoolean(); mStatuses = new ArrayList<>(); - in.readParcelableList(mStatuses, ConversationStatus.class.getClassLoader(), android.app.people.ConversationStatus.class); + in.readParcelableList(mStatuses, ConversationStatus.class.getClassLoader()); } @Override diff --git a/core/java/android/app/people/ConversationStatus.java b/core/java/android/app/people/ConversationStatus.java index a7b61b37d14e1..8038158b1f97a 100644 --- a/core/java/android/app/people/ConversationStatus.java +++ b/core/java/android/app/people/ConversationStatus.java @@ -126,7 +126,7 @@ public final class ConversationStatus implements Parcelable { mActivity = p.readInt(); mAvailability = p.readInt(); mDescription = p.readCharSequence(); - mIcon = p.readParcelable(Icon.class.getClassLoader(), android.graphics.drawable.Icon.class); + mIcon = p.readParcelable(Icon.class.getClassLoader()); mStartTimeMs = p.readLong(); mEndTimeMs = p.readLong(); } diff --git a/core/java/android/app/people/PeopleSpaceTile.java b/core/java/android/app/people/PeopleSpaceTile.java index 4337111636a0c..e11861f49be89 100644 --- a/core/java/android/app/people/PeopleSpaceTile.java +++ b/core/java/android/app/people/PeopleSpaceTile.java @@ -472,9 +472,9 @@ public class PeopleSpaceTile implements Parcelable { public PeopleSpaceTile(Parcel in) { mId = in.readString(); mUserName = in.readCharSequence(); - mUserIcon = in.readParcelable(Icon.class.getClassLoader(), android.graphics.drawable.Icon.class); - mContactUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); - mUserHandle = in.readParcelable(UserHandle.class.getClassLoader(), android.os.UserHandle.class); + mUserIcon = in.readParcelable(Icon.class.getClassLoader()); + mContactUri = in.readParcelable(Uri.class.getClassLoader()); + mUserHandle = in.readParcelable(UserHandle.class.getClassLoader()); mPackageName = in.readString(); mBirthdayText = in.readString(); mLastInteractionTimestamp = in.readLong(); @@ -483,12 +483,12 @@ public class PeopleSpaceTile implements Parcelable { mNotificationContent = in.readCharSequence(); mNotificationSender = in.readCharSequence(); mNotificationCategory = in.readString(); - mNotificationDataUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mNotificationDataUri = in.readParcelable(Uri.class.getClassLoader()); mMessagesCount = in.readInt(); - mIntent = in.readParcelable(Intent.class.getClassLoader(), android.content.Intent.class); + mIntent = in.readParcelable(Intent.class.getClassLoader()); mNotificationTimestamp = in.readLong(); mStatuses = new ArrayList<>(); - in.readParcelableList(mStatuses, ConversationStatus.class.getClassLoader(), android.app.people.ConversationStatus.class); + in.readParcelableList(mStatuses, ConversationStatus.class.getClassLoader()); mCanBypassDnd = in.readBoolean(); mIsPackageSuspended = in.readBoolean(); mIsUserQuieted = in.readBoolean(); diff --git a/core/java/android/app/prediction/AppTargetEvent.java b/core/java/android/app/prediction/AppTargetEvent.java index 51e3953ead4fa..963e750e4fd15 100644 --- a/core/java/android/app/prediction/AppTargetEvent.java +++ b/core/java/android/app/prediction/AppTargetEvent.java @@ -72,7 +72,7 @@ public final class AppTargetEvent implements Parcelable { } private AppTargetEvent(Parcel parcel) { - mTarget = parcel.readParcelable(null, android.app.prediction.AppTarget.class); + mTarget = parcel.readParcelable(null); mLocation = parcel.readString(); mAction = parcel.readInt(); } diff --git a/core/java/android/app/servertransaction/ClientTransaction.java b/core/java/android/app/servertransaction/ClientTransaction.java index 30a6c311bd1e1..fbb37db52014a 100644 --- a/core/java/android/app/servertransaction/ClientTransaction.java +++ b/core/java/android/app/servertransaction/ClientTransaction.java @@ -197,11 +197,11 @@ public class ClientTransaction implements Parcelable, ObjectPoolItem { if (readActivityToken) { mActivityToken = in.readStrongBinder(); } - mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader(), android.app.servertransaction.ActivityLifecycleItem.class); + mLifecycleStateRequest = in.readParcelable(getClass().getClassLoader()); final boolean readActivityCallbacks = in.readBoolean(); if (readActivityCallbacks) { mActivityCallbacks = new ArrayList<>(); - in.readParcelableList(mActivityCallbacks, getClass().getClassLoader(), android.app.servertransaction.ClientTransactionItem.class); + in.readParcelableList(mActivityCallbacks, getClass().getClassLoader()); } } diff --git a/core/java/android/app/smartspace/SmartspaceTargetEvent.java b/core/java/android/app/smartspace/SmartspaceTargetEvent.java index 89caab764591a..61f8723ca393b 100644 --- a/core/java/android/app/smartspace/SmartspaceTargetEvent.java +++ b/core/java/android/app/smartspace/SmartspaceTargetEvent.java @@ -96,7 +96,7 @@ public final class SmartspaceTargetEvent implements Parcelable { } private SmartspaceTargetEvent(Parcel parcel) { - mSmartspaceTarget = parcel.readParcelable(null, android.app.smartspace.SmartspaceTarget.class); + mSmartspaceTarget = parcel.readParcelable(null); mSmartspaceActionId = parcel.readString(); mEventType = parcel.readInt(); } diff --git a/core/java/android/app/time/ExternalTimeSuggestion.java b/core/java/android/app/time/ExternalTimeSuggestion.java index 0f98b44519838..8e281c07c45d1 100644 --- a/core/java/android/app/time/ExternalTimeSuggestion.java +++ b/core/java/android/app/time/ExternalTimeSuggestion.java @@ -101,11 +101,11 @@ public final class ExternalTimeSuggestion implements Parcelable { } private static ExternalTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue utcTime = in.readParcelable(null /* classLoader */, android.os.TimestampedValue.class); + TimestampedValue utcTime = in.readParcelable(null /* classLoader */); ExternalTimeSuggestion suggestion = new ExternalTimeSuggestion(utcTime.getReferenceTimeMillis(), utcTime.getValue()); @SuppressWarnings("unchecked") - ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; return suggestion; } diff --git a/core/java/android/app/time/TimeCapabilitiesAndConfig.java b/core/java/android/app/time/TimeCapabilitiesAndConfig.java index 71fce14a80b14..4a10447600648 100644 --- a/core/java/android/app/time/TimeCapabilitiesAndConfig.java +++ b/core/java/android/app/time/TimeCapabilitiesAndConfig.java @@ -59,8 +59,8 @@ public final class TimeCapabilitiesAndConfig implements Parcelable { @NonNull private static TimeCapabilitiesAndConfig readFromParcel(Parcel in) { - TimeCapabilities capabilities = in.readParcelable(null, android.app.time.TimeCapabilities.class); - TimeConfiguration configuration = in.readParcelable(null, android.app.time.TimeConfiguration.class); + TimeCapabilities capabilities = in.readParcelable(null); + TimeConfiguration configuration = in.readParcelable(null); return new TimeCapabilitiesAndConfig(capabilities, configuration); } diff --git a/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java b/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java index cd91b0431b28e..a9ea76f779589 100644 --- a/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java +++ b/core/java/android/app/time/TimeZoneCapabilitiesAndConfig.java @@ -61,8 +61,8 @@ public final class TimeZoneCapabilitiesAndConfig implements Parcelable { @NonNull private static TimeZoneCapabilitiesAndConfig createFromParcel(Parcel in) { - TimeZoneCapabilities capabilities = in.readParcelable(null, android.app.time.TimeZoneCapabilities.class); - TimeZoneConfiguration configuration = in.readParcelable(null, android.app.time.TimeZoneConfiguration.class); + TimeZoneCapabilities capabilities = in.readParcelable(null); + TimeZoneConfiguration configuration = in.readParcelable(null); return new TimeZoneCapabilitiesAndConfig(capabilities, configuration); } diff --git a/core/java/android/app/timedetector/GnssTimeSuggestion.java b/core/java/android/app/timedetector/GnssTimeSuggestion.java index 8ccff6227c79f..6478a2dd2aa9c 100644 --- a/core/java/android/app/timedetector/GnssTimeSuggestion.java +++ b/core/java/android/app/timedetector/GnssTimeSuggestion.java @@ -66,10 +66,10 @@ public final class GnssTimeSuggestion implements Parcelable { } private static GnssTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue utcTime = in.readParcelable(null /* classLoader */, android.os.TimestampedValue.class); + TimestampedValue utcTime = in.readParcelable(null /* classLoader */); GnssTimeSuggestion suggestion = new GnssTimeSuggestion(utcTime); @SuppressWarnings("unchecked") - ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; return suggestion; } diff --git a/core/java/android/app/timedetector/ManualTimeSuggestion.java b/core/java/android/app/timedetector/ManualTimeSuggestion.java index 1699a5f8c8ae9..299e9518e329c 100644 --- a/core/java/android/app/timedetector/ManualTimeSuggestion.java +++ b/core/java/android/app/timedetector/ManualTimeSuggestion.java @@ -66,10 +66,10 @@ public final class ManualTimeSuggestion implements Parcelable { } private static ManualTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue utcTime = in.readParcelable(null /* classLoader */, android.os.TimestampedValue.class); + TimestampedValue utcTime = in.readParcelable(null /* classLoader */); ManualTimeSuggestion suggestion = new ManualTimeSuggestion(utcTime); @SuppressWarnings("unchecked") - ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; return suggestion; } diff --git a/core/java/android/app/timedetector/NetworkTimeSuggestion.java b/core/java/android/app/timedetector/NetworkTimeSuggestion.java index 20300832d2fc1..a5259c27ec421 100644 --- a/core/java/android/app/timedetector/NetworkTimeSuggestion.java +++ b/core/java/android/app/timedetector/NetworkTimeSuggestion.java @@ -66,10 +66,10 @@ public final class NetworkTimeSuggestion implements Parcelable { } private static NetworkTimeSuggestion createFromParcel(Parcel in) { - TimestampedValue utcTime = in.readParcelable(null /* classLoader */, android.os.TimestampedValue.class); + TimestampedValue utcTime = in.readParcelable(null /* classLoader */); NetworkTimeSuggestion suggestion = new NetworkTimeSuggestion(utcTime); @SuppressWarnings("unchecked") - ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; return suggestion; } diff --git a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java index 52d0bbea701e1..6c3a304ed3a7b 100644 --- a/core/java/android/app/timedetector/TelephonyTimeSuggestion.java +++ b/core/java/android/app/timedetector/TelephonyTimeSuggestion.java @@ -77,10 +77,10 @@ public final class TelephonyTimeSuggestion implements Parcelable { private static TelephonyTimeSuggestion createFromParcel(Parcel in) { int slotIndex = in.readInt(); TelephonyTimeSuggestion suggestion = new TelephonyTimeSuggestion.Builder(slotIndex) - .setUtcTime(in.readParcelable(null /* classLoader */, android.os.TimestampedValue.class)) + .setUtcTime(in.readParcelable(null /* classLoader */)) .build(); @SuppressWarnings("unchecked") - ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */); if (debugInfo != null) { suggestion.addDebugInfo(debugInfo); } diff --git a/core/java/android/app/timezone/RulesState.java b/core/java/android/app/timezone/RulesState.java index 516ad033a936a..ee88ec54d08f6 100644 --- a/core/java/android/app/timezone/RulesState.java +++ b/core/java/android/app/timezone/RulesState.java @@ -195,12 +195,12 @@ public final class RulesState implements Parcelable { private static RulesState createFromParcel(Parcel in) { String baseRulesVersion = in.readString(); - DistroFormatVersion distroFormatVersionSupported = in.readParcelable(null, android.app.timezone.DistroFormatVersion.class); + DistroFormatVersion distroFormatVersionSupported = in.readParcelable(null); boolean operationInProgress = in.readByte() == BYTE_TRUE; int distroStagedState = in.readByte(); - DistroRulesVersion stagedDistroRulesVersion = in.readParcelable(null, android.app.timezone.DistroRulesVersion.class); + DistroRulesVersion stagedDistroRulesVersion = in.readParcelable(null); int installedDistroStatus = in.readByte(); - DistroRulesVersion installedDistroRulesVersion = in.readParcelable(null, android.app.timezone.DistroRulesVersion.class); + DistroRulesVersion installedDistroRulesVersion = in.readParcelable(null); return new RulesState(baseRulesVersion, distroFormatVersionSupported, operationInProgress, distroStagedState, stagedDistroRulesVersion, installedDistroStatus, installedDistroRulesVersion); diff --git a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java index 387319edc5e7c..01a60b1fa025c 100644 --- a/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java +++ b/core/java/android/app/timezonedetector/ManualTimeZoneSuggestion.java @@ -65,7 +65,7 @@ public final class ManualTimeZoneSuggestion implements Parcelable { String zoneId = in.readString(); ManualTimeZoneSuggestion suggestion = new ManualTimeZoneSuggestion(zoneId); @SuppressWarnings("unchecked") - ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + ArrayList debugInfo = (ArrayList) in.readArrayList(null /* classLoader */); suggestion.mDebugInfo = debugInfo; return suggestion; } diff --git a/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java b/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java index e5b4e46ba2851..eb6750f06d251 100644 --- a/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java +++ b/core/java/android/app/timezonedetector/TelephonyTimeZoneSuggestion.java @@ -165,7 +165,7 @@ public final class TelephonyTimeZoneSuggestion implements Parcelable { .setQuality(in.readInt()) .build(); List debugInfo = - in.readArrayList(TelephonyTimeZoneSuggestion.class.getClassLoader(), java.lang.String.class); + in.readArrayList(TelephonyTimeZoneSuggestion.class.getClassLoader()); if (debugInfo != null) { suggestion.addDebugInfo(debugInfo); } diff --git a/core/java/android/app/usage/CacheQuotaHint.java b/core/java/android/app/usage/CacheQuotaHint.java index ba6bcdc936ba1..0ccb058d11cfa 100644 --- a/core/java/android/app/usage/CacheQuotaHint.java +++ b/core/java/android/app/usage/CacheQuotaHint.java @@ -148,7 +148,7 @@ public final class CacheQuotaHint implements Parcelable { return builder.setVolumeUuid(in.readString()) .setUid(in.readInt()) .setQuota(in.readLong()) - .setUsageStats(in.readParcelable(UsageStats.class.getClassLoader(), android.app.usage.UsageStats.class)) + .setUsageStats(in.readParcelable(UsageStats.class.getClassLoader())) .build(); } diff --git a/core/java/android/bluetooth/BluetoothGattCharacteristic.java b/core/java/android/bluetooth/BluetoothGattCharacteristic.java index 053e0db3d8a6f..c5e986e895b25 100644 --- a/core/java/android/bluetooth/BluetoothGattCharacteristic.java +++ b/core/java/android/bluetooth/BluetoothGattCharacteristic.java @@ -313,7 +313,7 @@ public class BluetoothGattCharacteristic implements Parcelable { }; private BluetoothGattCharacteristic(Parcel in) { - mUuid = ((ParcelUuid) in.readParcelable(null, android.os.ParcelUuid.class)).getUuid(); + mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid(); mInstance = in.readInt(); mProperties = in.readInt(); mPermissions = in.readInt(); diff --git a/core/java/android/bluetooth/BluetoothGattDescriptor.java b/core/java/android/bluetooth/BluetoothGattDescriptor.java index 6ed4706b5fbad..a35d5b99fd7b2 100644 --- a/core/java/android/bluetooth/BluetoothGattDescriptor.java +++ b/core/java/android/bluetooth/BluetoothGattDescriptor.java @@ -187,7 +187,7 @@ public class BluetoothGattDescriptor implements Parcelable { }; private BluetoothGattDescriptor(Parcel in) { - mUuid = ((ParcelUuid) in.readParcelable(null, android.os.ParcelUuid.class)).getUuid(); + mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid(); mInstance = in.readInt(); mPermissions = in.readInt(); } diff --git a/core/java/android/bluetooth/BluetoothGattIncludedService.java b/core/java/android/bluetooth/BluetoothGattIncludedService.java index 1ae2ca0a92e16..5580619033a65 100644 --- a/core/java/android/bluetooth/BluetoothGattIncludedService.java +++ b/core/java/android/bluetooth/BluetoothGattIncludedService.java @@ -76,7 +76,7 @@ public class BluetoothGattIncludedService implements Parcelable { }; private BluetoothGattIncludedService(Parcel in) { - mUuid = ((ParcelUuid) in.readParcelable(null, android.os.ParcelUuid.class)).getUuid(); + mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid(); mInstanceId = in.readInt(); mServiceType = in.readInt(); } diff --git a/core/java/android/bluetooth/BluetoothGattService.java b/core/java/android/bluetooth/BluetoothGattService.java index 36bc4772e0161..f64d09fc30d93 100644 --- a/core/java/android/bluetooth/BluetoothGattService.java +++ b/core/java/android/bluetooth/BluetoothGattService.java @@ -180,7 +180,7 @@ public class BluetoothGattService implements Parcelable { }; private BluetoothGattService(Parcel in) { - mUuid = ((ParcelUuid) in.readParcelable(null, android.os.ParcelUuid.class)).getUuid(); + mUuid = ((ParcelUuid) in.readParcelable(null)).getUuid(); mInstanceId = in.readInt(); mServiceType = in.readInt(); diff --git a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java index e9dd761efdf62..032b507f5d3cf 100644 --- a/core/java/android/bluetooth/BluetoothHeadsetClientCall.java +++ b/core/java/android/bluetooth/BluetoothHeadsetClientCall.java @@ -292,7 +292,7 @@ public final class BluetoothHeadsetClientCall implements Parcelable, Attributabl new Parcelable.Creator() { @Override public BluetoothHeadsetClientCall createFromParcel(Parcel in) { - return new BluetoothHeadsetClientCall((BluetoothDevice) in.readParcelable(null, android.bluetooth.BluetoothDevice.class), + return new BluetoothHeadsetClientCall((BluetoothDevice) in.readParcelable(null), in.readInt(), UUID.fromString(in.readString()), in.readInt(), in.readString(), in.readInt() == 1, in.readInt() == 1, in.readInt() == 1); diff --git a/core/java/android/bluetooth/BufferConstraints.java b/core/java/android/bluetooth/BufferConstraints.java index 06b45ee5c8b57..97d97232b7a68 100644 --- a/core/java/android/bluetooth/BufferConstraints.java +++ b/core/java/android/bluetooth/BufferConstraints.java @@ -55,7 +55,7 @@ public final class BufferConstraints implements Parcelable { BufferConstraints(Parcel in) { mBufferConstraintList = new ArrayList(); mBufferConstraints = new HashMap(); - in.readList(mBufferConstraintList, BufferConstraint.class.getClassLoader(), android.bluetooth.BufferConstraint.class); + in.readList(mBufferConstraintList, BufferConstraint.class.getClassLoader()); for (int i = 0; i < mBufferConstraintList.size(); i++) { mBufferConstraints.put(i, mBufferConstraintList.get(i)); } diff --git a/core/java/android/bluetooth/le/ScanFilter.java b/core/java/android/bluetooth/le/ScanFilter.java index 675fe05a7dec0..b059193ae03fd 100644 --- a/core/java/android/bluetooth/le/ScanFilter.java +++ b/core/java/android/bluetooth/le/ScanFilter.java @@ -200,28 +200,28 @@ public final class ScanFilter implements Parcelable { address = in.readString(); } if (in.readInt() == 1) { - ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader(), android.os.ParcelUuid.class); + ParcelUuid uuid = in.readParcelable(ParcelUuid.class.getClassLoader()); builder.setServiceUuid(uuid); if (in.readInt() == 1) { ParcelUuid uuidMask = in.readParcelable( - ParcelUuid.class.getClassLoader(), android.os.ParcelUuid.class); + ParcelUuid.class.getClassLoader()); builder.setServiceUuid(uuid, uuidMask); } } if (in.readInt() == 1) { ParcelUuid solicitationUuid = in.readParcelable( - ParcelUuid.class.getClassLoader(), android.os.ParcelUuid.class); + ParcelUuid.class.getClassLoader()); builder.setServiceSolicitationUuid(solicitationUuid); if (in.readInt() == 1) { ParcelUuid solicitationUuidMask = in.readParcelable( - ParcelUuid.class.getClassLoader(), android.os.ParcelUuid.class); + ParcelUuid.class.getClassLoader()); builder.setServiceSolicitationUuid(solicitationUuid, solicitationUuidMask); } } if (in.readInt() == 1) { ParcelUuid servcieDataUuid = - in.readParcelable(ParcelUuid.class.getClassLoader(), android.os.ParcelUuid.class); + in.readParcelable(ParcelUuid.class.getClassLoader()); if (in.readInt() == 1) { int serviceDataLength = in.readInt(); byte[] serviceData = new byte[serviceDataLength]; diff --git a/core/java/android/companion/AssociationRequest.java b/core/java/android/companion/AssociationRequest.java index 1d2f06d34c8c7..18a59d863c467 100644 --- a/core/java/android/companion/AssociationRequest.java +++ b/core/java/android/companion/AssociationRequest.java @@ -595,7 +595,7 @@ public final class AssociationRequest implements Parcelable { boolean forceConfirmation = (flg & 0x20) != 0; boolean skipPrompt = (flg & 0x400) != 0; List> deviceFilters = new ArrayList<>(); - in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader(), (Class>) (Class) android.companion.DeviceFilter.class); + in.readParcelableList(deviceFilters, DeviceFilter.class.getClassLoader()); String deviceProfile = (flg & 0x4) == 0 ? null : in.readString(); CharSequence displayName = (flg & 0x8) == 0 ? null : (CharSequence) in.readCharSequence(); String packageName = (flg & 0x40) == 0 ? null : in.readString(); diff --git a/core/java/android/companion/BluetoothDeviceFilter.java b/core/java/android/companion/BluetoothDeviceFilter.java index e0018f4bad42d..be663f7bdc1dd 100644 --- a/core/java/android/companion/BluetoothDeviceFilter.java +++ b/core/java/android/companion/BluetoothDeviceFilter.java @@ -70,7 +70,7 @@ public final class BluetoothDeviceFilter implements DeviceFilter readUuids(Parcel in) { - return in.readParcelableList(new ArrayList<>(), ParcelUuid.class.getClassLoader(), android.os.ParcelUuid.class); + return in.readParcelableList(new ArrayList<>(), ParcelUuid.class.getClassLoader()); } /** @hide */ diff --git a/core/java/android/companion/BluetoothLeDeviceFilter.java b/core/java/android/companion/BluetoothLeDeviceFilter.java index e6091f04a72a6..58898cc095bec 100644 --- a/core/java/android/companion/BluetoothLeDeviceFilter.java +++ b/core/java/android/companion/BluetoothLeDeviceFilter.java @@ -252,7 +252,7 @@ public final class BluetoothLeDeviceFilter implements DeviceFilter { public BluetoothLeDeviceFilter createFromParcel(Parcel in) { Builder builder = new Builder() .setNamePattern(patternFromString(in.readString())) - .setScanFilter(in.readParcelable(null, android.bluetooth.le.ScanFilter.class)); + .setScanFilter(in.readParcelable(null)); byte[] rawDataFilter = in.createByteArray(); byte[] rawDataFilterMask = in.createByteArray(); if (rawDataFilter != null) { diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index 0c065d9bd4022..30775b19ab00c 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -108,7 +108,7 @@ public class ContentProviderOperation implements Parcelable { mExtras = null; } mSelection = source.readInt() != 0 ? source.readString8() : null; - mSelectionArgs = source.readSparseArray(null, java.lang.Object.class); + mSelectionArgs = source.readSparseArray(null); mExpectedCount = source.readInt() != 0 ? source.readInt() : null; mYieldAllowed = source.readInt() != 0; mExceptionAllowed = source.readInt() != 0; diff --git a/core/java/android/content/PeriodicSync.java b/core/java/android/content/PeriodicSync.java index 6830f5f34e753..432e81bad0195 100644 --- a/core/java/android/content/PeriodicSync.java +++ b/core/java/android/content/PeriodicSync.java @@ -84,7 +84,7 @@ public class PeriodicSync implements Parcelable { } private PeriodicSync(Parcel in) { - this.account = in.readParcelable(null, android.accounts.Account.class); + this.account = in.readParcelable(null); this.authority = in.readString(); this.extras = in.readBundle(); this.period = in.readLong(); diff --git a/core/java/android/content/SyncInfo.java b/core/java/android/content/SyncInfo.java index 57101be6507e4..017a92b1e8bbc 100644 --- a/core/java/android/content/SyncInfo.java +++ b/core/java/android/content/SyncInfo.java @@ -99,7 +99,7 @@ public class SyncInfo implements Parcelable { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) SyncInfo(Parcel parcel) { authorityId = parcel.readInt(); - account = parcel.readParcelable(Account.class.getClassLoader(), android.accounts.Account.class); + account = parcel.readParcelable(Account.class.getClassLoader()); authority = parcel.readString(); startTime = parcel.readLong(); } diff --git a/core/java/android/content/SyncRequest.java b/core/java/android/content/SyncRequest.java index 83ce84e7a5cb2..e1e6f75d152f1 100644 --- a/core/java/android/content/SyncRequest.java +++ b/core/java/android/content/SyncRequest.java @@ -174,7 +174,7 @@ public class SyncRequest implements Parcelable { mIsAuthority = (in.readInt() != 0); mIsExpedited = (in.readInt() != 0); mIsScheduledAsExpeditedJob = (in.readInt() != 0); - mAccountToSync = in.readParcelable(null, android.accounts.Account.class); + mAccountToSync = in.readParcelable(null); mAuthority = in.readString(); } diff --git a/core/java/android/content/UndoManager.java b/core/java/android/content/UndoManager.java index b2979f36e01b2..87afbf874b378 100644 --- a/core/java/android/content/UndoManager.java +++ b/core/java/android/content/UndoManager.java @@ -777,7 +777,7 @@ public class UndoManager { final int N = p.readInt(); for (int i=0; i(size); for (int i = 0; i < size; i++) { final int request = source.readInt(); - final OverlayIdentifier overlay = source.readParcelable(null, android.content.om.OverlayIdentifier.class); + final OverlayIdentifier overlay = source.readParcelable(null); final int userId = source.readInt(); final Bundle extras = source.readBundle(null); mRequests.add(new Request(request, overlay, userId, extras)); diff --git a/core/java/android/content/pm/InstallSourceInfo.java b/core/java/android/content/pm/InstallSourceInfo.java index 84d2ca389611b..a45bf79305090 100644 --- a/core/java/android/content/pm/InstallSourceInfo.java +++ b/core/java/android/content/pm/InstallSourceInfo.java @@ -61,7 +61,7 @@ public final class InstallSourceInfo implements Parcelable { private InstallSourceInfo(Parcel source) { mInitiatingPackageName = source.readString(); - mInitiatingPackageSigningInfo = source.readParcelable(SigningInfo.class.getClassLoader(), android.content.pm.SigningInfo.class); + mInitiatingPackageSigningInfo = source.readParcelable(SigningInfo.class.getClassLoader()); mOriginatingPackageName = source.readString(); mInstallingPackageName = source.readString(); } diff --git a/core/java/android/content/pm/InstantAppInfo.java b/core/java/android/content/pm/InstantAppInfo.java index d6cfb0e70693e..24d6a07ec4e85 100644 --- a/core/java/android/content/pm/InstantAppInfo.java +++ b/core/java/android/content/pm/InstantAppInfo.java @@ -65,7 +65,7 @@ public final class InstantAppInfo implements Parcelable { mLabelText = parcel.readCharSequence(); mRequestedPermissions = parcel.readStringArray(); mGrantedPermissions = parcel.createStringArray(); - mApplicationInfo = parcel.readParcelable(null, android.content.pm.ApplicationInfo.class); + mApplicationInfo = parcel.readParcelable(null); } /** diff --git a/core/java/android/content/pm/InstantAppIntentFilter.java b/core/java/android/content/pm/InstantAppIntentFilter.java index 721b2616fbfd2..123d2ba5aa8d1 100644 --- a/core/java/android/content/pm/InstantAppIntentFilter.java +++ b/core/java/android/content/pm/InstantAppIntentFilter.java @@ -46,7 +46,7 @@ public final class InstantAppIntentFilter implements Parcelable { InstantAppIntentFilter(Parcel in) { mSplitName = in.readString(); - in.readList(mFilters, getClass().getClassLoader(), android.content.IntentFilter.class); + in.readList(mFilters, getClass().getClassLoader()); } public String getSplitName() { diff --git a/core/java/android/content/pm/InstantAppResolveInfo.java b/core/java/android/content/pm/InstantAppResolveInfo.java index 6124638ccbcbd..98815647f0c36 100644 --- a/core/java/android/content/pm/InstantAppResolveInfo.java +++ b/core/java/android/content/pm/InstantAppResolveInfo.java @@ -140,7 +140,7 @@ public final class InstantAppResolveInfo implements Parcelable { mFilters = Collections.emptyList(); mVersionCode = -1; } else { - mDigest = in.readParcelable(null /*loader*/, android.content.pm.InstantAppResolveInfo.InstantAppDigest.class); + mDigest = in.readParcelable(null /*loader*/); mPackageName = in.readString(); mFilters = new ArrayList<>(); in.readTypedList(mFilters, InstantAppIntentFilter.CREATOR); diff --git a/core/java/android/content/pm/LauncherActivityInfoInternal.java b/core/java/android/content/pm/LauncherActivityInfoInternal.java index 46c415df75256..417f168940b6f 100644 --- a/core/java/android/content/pm/LauncherActivityInfoInternal.java +++ b/core/java/android/content/pm/LauncherActivityInfoInternal.java @@ -43,10 +43,10 @@ public class LauncherActivityInfoInternal implements Parcelable { } public LauncherActivityInfoInternal(Parcel source) { - mActivityInfo = source.readParcelable(ActivityInfo.class.getClassLoader(), android.content.pm.ActivityInfo.class); + mActivityInfo = source.readParcelable(ActivityInfo.class.getClassLoader()); mComponentName = new ComponentName(mActivityInfo.packageName, mActivityInfo.name); mIncrementalStatesInfo = source.readParcelable( - IncrementalStatesInfo.class.getClassLoader(), android.content.pm.IncrementalStatesInfo.class); + IncrementalStatesInfo.class.getClassLoader()); } public ComponentName getComponentName() { diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 495100b0ae52b..730a26c0eeb33 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1754,11 +1754,11 @@ public class PackageInstaller { installScenario = source.readInt(); sizeBytes = source.readLong(); appPackageName = source.readString(); - appIcon = source.readParcelable(null, android.graphics.Bitmap.class); + appIcon = source.readParcelable(null); appLabel = source.readString(); - originatingUri = source.readParcelable(null, android.net.Uri.class); + originatingUri = source.readParcelable(null); originatingUid = source.readInt(); - referrerUri = source.readParcelable(null, android.net.Uri.class); + referrerUri = source.readParcelable(null); abiOverride = source.readString(); volumeUuid = source.readString(); grantedRuntimePermissions = source.readStringArray(); @@ -1770,7 +1770,7 @@ public class PackageInstaller { forceQueryableOverride = source.readBoolean(); requiredInstalledVersionCode = source.readLong(); DataLoaderParamsParcel dataLoaderParamsParcel = source.readParcelable( - DataLoaderParamsParcel.class.getClassLoader(), android.content.pm.DataLoaderParamsParcel.class); + DataLoaderParamsParcel.class.getClassLoader()); if (dataLoaderParamsParcel != null) { dataLoaderParams = new DataLoaderParams(dataLoaderParamsParcel); } @@ -2533,13 +2533,13 @@ public class PackageInstaller { installScenario = source.readInt(); sizeBytes = source.readLong(); appPackageName = source.readString(); - appIcon = source.readParcelable(null, android.graphics.Bitmap.class); + appIcon = source.readParcelable(null); appLabel = source.readString(); installLocation = source.readInt(); - originatingUri = source.readParcelable(null, android.net.Uri.class); + originatingUri = source.readParcelable(null); originatingUid = source.readInt(); - referrerUri = source.readParcelable(null, android.net.Uri.class); + referrerUri = source.readParcelable(null); grantedRuntimePermissions = source.readStringArray(); whitelistedRestrictedPermissions = source.createStringArrayList(); autoRevokePermissionsMode = source.readInt(); diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index f31f78fb81f3d..e2c91a4b1bea5 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -7297,7 +7297,7 @@ public class PackageParser { splitFlags = dest.createIntArray(); splitPrivateFlags = dest.createIntArray(); baseHardwareAccelerated = (dest.readInt() == 1); - applicationInfo = dest.readParcelable(boot, android.content.pm.ApplicationInfo.class); + applicationInfo = dest.readParcelable(boot); if (applicationInfo.permission != null) { applicationInfo.permission = applicationInfo.permission.intern(); } @@ -7305,19 +7305,19 @@ public class PackageParser { // We don't serialize the "owner" package and the application info object for each of // these components, in order to save space and to avoid circular dependencies while // serialization. We need to fix them all up here. - dest.readParcelableList(permissions, boot, android.content.pm.PackageParser.Permission.class); + dest.readParcelableList(permissions, boot); fixupOwner(permissions); - dest.readParcelableList(permissionGroups, boot, android.content.pm.PackageParser.PermissionGroup.class); + dest.readParcelableList(permissionGroups, boot); fixupOwner(permissionGroups); - dest.readParcelableList(activities, boot, android.content.pm.PackageParser.Activity.class); + dest.readParcelableList(activities, boot); fixupOwner(activities); - dest.readParcelableList(receivers, boot, android.content.pm.PackageParser.Activity.class); + dest.readParcelableList(receivers, boot); fixupOwner(receivers); - dest.readParcelableList(providers, boot, android.content.pm.PackageParser.Provider.class); + dest.readParcelableList(providers, boot); fixupOwner(providers); - dest.readParcelableList(services, boot, android.content.pm.PackageParser.Service.class); + dest.readParcelableList(services, boot); fixupOwner(services); - dest.readParcelableList(instrumentation, boot, android.content.pm.PackageParser.Instrumentation.class); + dest.readParcelableList(instrumentation, boot); fixupOwner(instrumentation); dest.readStringList(requestedPermissions); @@ -7327,10 +7327,10 @@ public class PackageParser { protectedBroadcasts = dest.createStringArrayList(); internStringArrayList(protectedBroadcasts); - parentPackage = dest.readParcelable(boot, android.content.pm.PackageParser.Package.class); + parentPackage = dest.readParcelable(boot); childPackages = new ArrayList<>(); - dest.readParcelableList(childPackages, boot, android.content.pm.PackageParser.Package.class); + dest.readParcelableList(childPackages, boot); if (childPackages.size() == 0) { childPackages = null; } @@ -7364,7 +7364,7 @@ public class PackageParser { } preferredActivityFilters = new ArrayList<>(); - dest.readParcelableList(preferredActivityFilters, boot, android.content.pm.PackageParser.ActivityIntentInfo.class); + dest.readParcelableList(preferredActivityFilters, boot); if (preferredActivityFilters.size() == 0) { preferredActivityFilters = null; } @@ -7385,7 +7385,7 @@ public class PackageParser { } mSharedUserLabel = dest.readInt(); - mSigningDetails = dest.readParcelable(boot, android.content.pm.PackageParser.SigningDetails.class); + mSigningDetails = dest.readParcelable(boot); mPreferredOrder = dest.readInt(); @@ -7397,19 +7397,19 @@ public class PackageParser { configPreferences = new ArrayList<>(); - dest.readParcelableList(configPreferences, boot, android.content.pm.ConfigurationInfo.class); + dest.readParcelableList(configPreferences, boot); if (configPreferences.size() == 0) { configPreferences = null; } reqFeatures = new ArrayList<>(); - dest.readParcelableList(reqFeatures, boot, android.content.pm.FeatureInfo.class); + dest.readParcelableList(reqFeatures, boot); if (reqFeatures.size() == 0) { reqFeatures = null; } featureGroups = new ArrayList<>(); - dest.readParcelableList(featureGroups, boot, android.content.pm.FeatureGroupInfo.class); + dest.readParcelableList(featureGroups, boot); if (featureGroups.size() == 0) { featureGroups = null; } @@ -7806,13 +7806,13 @@ public class PackageParser { private Permission(Parcel in) { super(in); final ClassLoader boot = Object.class.getClassLoader(); - info = in.readParcelable(boot, android.content.pm.PermissionInfo.class); + info = in.readParcelable(boot); if (info.group != null) { info.group = info.group.intern(); } tree = (in.readInt() == 1); - group = in.readParcelable(boot, android.content.pm.PackageParser.PermissionGroup.class); + group = in.readParcelable(boot); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -7867,7 +7867,7 @@ public class PackageParser { private PermissionGroup(Parcel in) { super(in); - info = in.readParcelable(Object.class.getClassLoader(), android.content.pm.PermissionGroupInfo.class); + info = in.readParcelable(Object.class.getClassLoader()); } public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { @@ -8160,7 +8160,7 @@ public class PackageParser { private Activity(Parcel in) { super(in); - info = in.readParcelable(Object.class.getClassLoader(), android.content.pm.ActivityInfo.class); + info = in.readParcelable(Object.class.getClassLoader()); mHasMaxAspectRatio = in.readBoolean(); mHasMinAspectRatio = in.readBoolean(); @@ -8254,7 +8254,7 @@ public class PackageParser { private Service(Parcel in) { super(in); - info = in.readParcelable(Object.class.getClassLoader(), android.content.pm.ServiceInfo.class); + info = in.readParcelable(Object.class.getClassLoader()); for (ServiceIntentInfo aii : intents) { aii.service = this; @@ -8344,7 +8344,7 @@ public class PackageParser { private Provider(Parcel in) { super(in); - info = in.readParcelable(Object.class.getClassLoader(), android.content.pm.ProviderInfo.class); + info = in.readParcelable(Object.class.getClassLoader()); syncable = (in.readInt() == 1); for (ProviderIntentInfo aii : intents) { @@ -8436,7 +8436,7 @@ public class PackageParser { private Instrumentation(Parcel in) { super(in); - info = in.readParcelable(Object.class.getClassLoader(), android.content.pm.InstrumentationInfo.class); + info = in.readParcelable(Object.class.getClassLoader()); if (info.targetPackage != null) { info.targetPackage = info.targetPackage.intern(); diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index 43a4b17e51722..f153566bf61ac 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -136,8 +136,8 @@ public final class SharedLibraryInfo implements Parcelable { mName = parcel.readString8(); mVersion = parcel.readLong(); mType = parcel.readInt(); - mDeclaringPackage = parcel.readParcelable(null, android.content.pm.VersionedPackage.class); - mDependentPackages = parcel.readArrayList(null, android.content.pm.VersionedPackage.class); + mDeclaringPackage = parcel.readParcelable(null); + mDependentPackages = parcel.readArrayList(null); mDependencies = parcel.createTypedArrayList(SharedLibraryInfo.CREATOR); mIsNative = parcel.readBoolean(); } diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index 7d4f7ecef29c2..613fb84812f8f 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -2182,7 +2182,7 @@ public final class ShortcutInfo implements Parcelable { mUserId = source.readInt(); mId = source.readString8(); mPackageName = source.readString8(); - mActivity = source.readParcelable(cl, android.content.ComponentName.class); + mActivity = source.readParcelable(cl); mFlags = source.readInt(); mIconResId = source.readInt(); mLastChangedTimestamp = source.readLong(); @@ -2192,7 +2192,7 @@ public final class ShortcutInfo implements Parcelable { return; // key information only. } - mIcon = source.readParcelable(cl, android.graphics.drawable.Icon.class); + mIcon = source.readParcelable(cl); mTitle = source.readCharSequence(); mTitleResId = source.readInt(); mText = source.readCharSequence(); @@ -2202,7 +2202,7 @@ public final class ShortcutInfo implements Parcelable { mIntents = source.readParcelableArray(cl, Intent.class); mIntentPersistableExtrases = source.readParcelableArray(cl, PersistableBundle.class); mRank = source.readInt(); - mExtras = source.readParcelable(cl, android.os.PersistableBundle.class); + mExtras = source.readParcelable(cl); mBitmapPath = source.readString8(); mIconResName = source.readString8(); @@ -2221,7 +2221,7 @@ public final class ShortcutInfo implements Parcelable { } mPersons = source.readParcelableArray(cl, Person.class); - mLocusId = source.readParcelable(cl, android.content.LocusId.class); + mLocusId = source.readParcelable(cl); mIconUri = source.readString8(); mStartingThemeResName = source.readString8(); mExcludedSurfaces = source.readInt(); diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index 7dbfd08310bef..be0d934f51333 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -704,8 +704,8 @@ public class ShortcutManager { } private ShareShortcutInfo(@NonNull Parcel in) { - mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader(), android.content.pm.ShortcutInfo.class); - mTargetComponent = in.readParcelable(ComponentName.class.getClassLoader(), android.content.ComponentName.class); + mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader()); + mTargetComponent = in.readParcelable(ComponentName.class.getClassLoader()); } @NonNull diff --git a/core/java/android/content/pm/ShortcutQueryWrapper.java b/core/java/android/content/pm/ShortcutQueryWrapper.java index 64337d86f7ecb..c6134416adbc2 100644 --- a/core/java/android/content/pm/ShortcutQueryWrapper.java +++ b/core/java/android/content/pm/ShortcutQueryWrapper.java @@ -143,7 +143,7 @@ public final class ShortcutQueryWrapper extends LauncherApps.ShortcutQuery imple List locusIds = null; if ((flg & 0x8) != 0) { locusIds = new ArrayList<>(); - in.readParcelableList(locusIds, LocusId.class.getClassLoader(), android.content.LocusId.class); + in.readParcelableList(locusIds, LocusId.class.getClassLoader()); } ComponentName activity = (flg & 0x10) == 0 ? null : (ComponentName) in.readTypedObject(ComponentName.CREATOR); diff --git a/core/java/android/content/pm/VerifierInfo.java b/core/java/android/content/pm/VerifierInfo.java index 868bb9cb995ce..3e69ff555946d 100644 --- a/core/java/android/content/pm/VerifierInfo.java +++ b/core/java/android/content/pm/VerifierInfo.java @@ -59,7 +59,7 @@ public class VerifierInfo implements Parcelable { private VerifierInfo(Parcel source) { packageName = source.readString(); - publicKey = (PublicKey) source.readSerializable(java.security.PublicKey.class.getClassLoader(), java.security.PublicKey.class); + publicKey = (PublicKey) source.readSerializable(); } @Override diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index 23cae4c044679..ddab207437c2e 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -1408,7 +1408,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.processes = in.readHashMap(boot); this.metaData = in.readBundle(boot); this.volumeUuid = sForInternedString.unparcel(in); - this.signingDetails = in.readParcelable(boot, android.content.pm.SigningDetails.class); + this.signingDetails = in.readParcelable(boot); this.mPath = in.readString(); this.queriesIntents = in.createTypedArrayList(Intent.CREATOR); this.queriesPackages = sForInternedStringList.unparcel(in); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index f336672ffefae..e02eb7cca0909 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -3519,7 +3519,7 @@ public class ParsingPackageUtils { ArraySet keys = new ArraySet<>(M); for (int j = 0; j < M; ++j) { - PublicKey pk = (PublicKey) in.readSerializable(java.security.PublicKey.class.getClassLoader(), java.security.PublicKey.class); + PublicKey pk = (PublicKey) in.readSerializable(); keys.add(pk); } diff --git a/core/java/android/content/pm/parsing/ParsingUtils.java b/core/java/android/content/pm/parsing/ParsingUtils.java index 6dfb268c3d648..cce984eb93a76 100644 --- a/core/java/android/content/pm/parsing/ParsingUtils.java +++ b/core/java/android/content/pm/parsing/ParsingUtils.java @@ -138,7 +138,7 @@ public class ParsingUtils { final List> list = new ArrayList<>(size); for (int i = 0; i < size; ++i) { list.add(Pair.create(source.readString(), source.readParcelable( - ParsedIntentInfoImpl.class.getClassLoader(), android.content.pm.parsing.component.ParsedIntentInfo.class))); + ParsedIntentInfoImpl.class.getClassLoader()))); } return list; diff --git a/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java b/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java index 45038cf225fb6..2145e441553ac 100644 --- a/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java +++ b/core/java/android/content/pm/parsing/component/ParsedPermissionImpl.java @@ -116,7 +116,7 @@ public class ParsedPermissionImpl extends ParsedComponentImpl implements ParsedP this.requestRes = in.readInt(); this.protectionLevel = in.readInt(); this.tree = in.readBoolean(); - this.parsedPermissionGroup = in.readParcelable(boot, android.content.pm.parsing.component.ParsedPermissionGroup.class); + this.parsedPermissionGroup = in.readParcelable(boot); this.knownCerts = sForStringSet.unparcel(in); } diff --git a/core/java/android/graphics/fonts/FontUpdateRequest.java b/core/java/android/graphics/fonts/FontUpdateRequest.java index dae09f0977a46..cda1638a24dcb 100644 --- a/core/java/android/graphics/fonts/FontUpdateRequest.java +++ b/core/java/android/graphics/fonts/FontUpdateRequest.java @@ -235,7 +235,7 @@ public final class FontUpdateRequest implements Parcelable { public Family createFromParcel(Parcel source) { String familyName = source.readString8(); List fonts = source.readParcelableList( - new ArrayList<>(), Font.class.getClassLoader(), android.graphics.fonts.FontUpdateRequest.Font.class); + new ArrayList<>(), Font.class.getClassLoader()); return new Family(familyName, fonts); } @@ -379,9 +379,9 @@ public final class FontUpdateRequest implements Parcelable { protected FontUpdateRequest(Parcel in) { mType = in.readInt(); - mFd = in.readParcelable(ParcelFileDescriptor.class.getClassLoader(), android.os.ParcelFileDescriptor.class); + mFd = in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); mSignature = in.readBlob(); - mFontFamily = in.readParcelable(FontConfig.FontFamily.class.getClassLoader(), android.graphics.fonts.FontUpdateRequest.Family.class); + mFontFamily = in.readParcelable(FontConfig.FontFamily.class.getClassLoader()); } public @Type int getType() { diff --git a/core/java/android/hardware/biometrics/PromptInfo.java b/core/java/android/hardware/biometrics/PromptInfo.java index 0c03948e5368a..e6b762a64384d 100644 --- a/core/java/android/hardware/biometrics/PromptInfo.java +++ b/core/java/android/hardware/biometrics/PromptInfo.java @@ -65,7 +65,7 @@ public class PromptInfo implements Parcelable { mAuthenticators = in.readInt(); mDisallowBiometricsIfPolicyExists = in.readBoolean(); mReceiveSystemEvents = in.readBoolean(); - mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class); + mAllowedSensorIds = in.readArrayList(Integer.class.getClassLoader()); mAllowBackgroundAuthentication = in.readBoolean(); mIgnoreEnrollmentState = in.readBoolean(); } diff --git a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java index 1490ea1592a58..f365ee6066d08 100644 --- a/core/java/android/hardware/biometrics/SensorPropertiesInternal.java +++ b/core/java/android/hardware/biometrics/SensorPropertiesInternal.java @@ -60,7 +60,7 @@ public class SensorPropertiesInternal implements Parcelable { sensorStrength = in.readInt(); maxEnrollmentsPerUser = in.readInt(); componentInfo = new ArrayList<>(); - in.readList(componentInfo, ComponentInfoInternal.class.getClassLoader(), android.hardware.biometrics.ComponentInfoInternal.class); + in.readList(componentInfo, ComponentInfoInternal.class.getClassLoader()); resetLockoutRequiresHardwareAuthToken = in.readBoolean(); resetLockoutRequiresChallenge = in.readBoolean(); } diff --git a/core/java/android/hardware/face/FaceAuthenticationFrame.java b/core/java/android/hardware/face/FaceAuthenticationFrame.java index a53aad74d4e08..f39d63411825e 100644 --- a/core/java/android/hardware/face/FaceAuthenticationFrame.java +++ b/core/java/android/hardware/face/FaceAuthenticationFrame.java @@ -46,7 +46,7 @@ public final class FaceAuthenticationFrame implements Parcelable { } private FaceAuthenticationFrame(@NonNull Parcel source) { - mData = source.readParcelable(FaceDataFrame.class.getClassLoader(), android.hardware.face.FaceDataFrame.class); + mData = source.readParcelable(FaceDataFrame.class.getClassLoader()); } @Override diff --git a/core/java/android/hardware/face/FaceEnrollFrame.java b/core/java/android/hardware/face/FaceEnrollFrame.java index bbccee2e2c3d9..822a57944449a 100644 --- a/core/java/android/hardware/face/FaceEnrollFrame.java +++ b/core/java/android/hardware/face/FaceEnrollFrame.java @@ -73,9 +73,9 @@ public final class FaceEnrollFrame implements Parcelable { } private FaceEnrollFrame(@NonNull Parcel source) { - mCell = source.readParcelable(FaceEnrollCell.class.getClassLoader(), android.hardware.face.FaceEnrollCell.class); + mCell = source.readParcelable(FaceEnrollCell.class.getClassLoader()); mStage = source.readInt(); - mData = source.readParcelable(FaceDataFrame.class.getClassLoader(), android.hardware.face.FaceDataFrame.class); + mData = source.readParcelable(FaceDataFrame.class.getClassLoader()); } @Override diff --git a/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java b/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java index 310ebe9ac093e..78cca9601a2df 100644 --- a/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java +++ b/core/java/android/hardware/location/GeofenceHardwareMonitorEvent.java @@ -81,7 +81,7 @@ public class GeofenceHardwareMonitorEvent implements Parcelable { int monitoringType = source.readInt(); int monitoringStatus = source.readInt(); int sourceTechnologies = source.readInt(); - Location location = source.readParcelable(classLoader, android.location.Location.class); + Location location = source.readParcelable(classLoader); return new GeofenceHardwareMonitorEvent( monitoringType, diff --git a/core/java/android/net/InterfaceConfiguration.java b/core/java/android/net/InterfaceConfiguration.java index 1c4089c0f366f..37425ffc18aae 100644 --- a/core/java/android/net/InterfaceConfiguration.java +++ b/core/java/android/net/InterfaceConfiguration.java @@ -160,7 +160,6 @@ public class InterfaceConfiguration implements Parcelable { } } - @SuppressWarnings("UnsafeParcelApi") public static final @android.annotation.NonNull Creator CREATOR = new Creator< InterfaceConfiguration>() { public InterfaceConfiguration createFromParcel(Parcel in) { diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java index 596f4317dce30..ab1f5420fb3fe 100644 --- a/core/java/android/net/NetworkPolicy.java +++ b/core/java/android/net/NetworkPolicy.java @@ -142,8 +142,8 @@ public class NetworkPolicy implements Parcelable, Comparable { } private NetworkPolicy(Parcel source) { - template = source.readParcelable(null, android.net.NetworkTemplate.class); - cycleRule = source.readParcelable(null, android.util.RecurrenceRule.class); + template = source.readParcelable(null); + cycleRule = source.readParcelable(null); warningBytes = source.readLong(); limitBytes = source.readLong(); lastWarningSnooze = source.readLong(); diff --git a/core/java/android/net/vcn/VcnConfig.java b/core/java/android/net/vcn/VcnConfig.java index fd3fe3731b74f..caab15251f58f 100644 --- a/core/java/android/net/vcn/VcnConfig.java +++ b/core/java/android/net/vcn/VcnConfig.java @@ -173,7 +173,7 @@ public final class VcnConfig implements Parcelable { new Parcelable.Creator() { @NonNull public VcnConfig createFromParcel(Parcel in) { - return new VcnConfig((PersistableBundle) in.readParcelable(null, android.os.PersistableBundle.class)); + return new VcnConfig((PersistableBundle) in.readParcelable(null)); } @NonNull diff --git a/core/java/android/net/vcn/VcnNetworkPolicyResult.java b/core/java/android/net/vcn/VcnNetworkPolicyResult.java index fca084a00a798..14e70cfeb18a4 100644 --- a/core/java/android/net/vcn/VcnNetworkPolicyResult.java +++ b/core/java/android/net/vcn/VcnNetworkPolicyResult.java @@ -114,7 +114,7 @@ public final class VcnNetworkPolicyResult implements Parcelable { public static final @NonNull Creator CREATOR = new Creator() { public VcnNetworkPolicyResult createFromParcel(Parcel in) { - return new VcnNetworkPolicyResult(in.readBoolean(), in.readParcelable(null, android.net.NetworkCapabilities.class)); + return new VcnNetworkPolicyResult(in.readBoolean(), in.readParcelable(null)); } public VcnNetworkPolicyResult[] newArray(int size) { diff --git a/core/java/android/net/vcn/VcnTransportInfo.java b/core/java/android/net/vcn/VcnTransportInfo.java index 5c47b28a7c741..25a257423ce2a 100644 --- a/core/java/android/net/vcn/VcnTransportInfo.java +++ b/core/java/android/net/vcn/VcnTransportInfo.java @@ -146,7 +146,7 @@ public class VcnTransportInfo implements TransportInfo, Parcelable { new Creator() { public VcnTransportInfo createFromParcel(Parcel in) { final int subId = in.readInt(); - final WifiInfo wifiInfo = in.readParcelable(null, android.net.wifi.WifiInfo.class); + final WifiInfo wifiInfo = in.readParcelable(null); // If all fields are their null values, return null TransportInfo to avoid // leaking information about this being a VCN Network (instead of macro diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java index 2b5305d05dcd5..b0d4f3be248f5 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java +++ b/core/java/android/net/vcn/VcnUnderlyingNetworkPolicy.java @@ -106,7 +106,7 @@ public final class VcnUnderlyingNetworkPolicy implements Parcelable { public static final @NonNull Creator CREATOR = new Creator() { public VcnUnderlyingNetworkPolicy createFromParcel(Parcel in) { - return new VcnUnderlyingNetworkPolicy(in.readParcelable(null, android.net.vcn.VcnNetworkPolicyResult.class)); + return new VcnUnderlyingNetworkPolicy(in.readParcelable(null)); } public VcnUnderlyingNetworkPolicy[] newArray(int size) { diff --git a/core/java/android/nfc/BeamShareData.java b/core/java/android/nfc/BeamShareData.java index 6a40f98fe21c4..ed3b74ab6308c 100644 --- a/core/java/android/nfc/BeamShareData.java +++ b/core/java/android/nfc/BeamShareData.java @@ -47,13 +47,13 @@ public final class BeamShareData implements Parcelable { @Override public BeamShareData createFromParcel(Parcel source) { Uri[] uris = null; - NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader(), android.nfc.NdefMessage.class); + NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader()); int numUris = source.readInt(); if (numUris > 0) { uris = new Uri[numUris]; source.readTypedArray(uris, Uri.CREATOR); } - UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader(), android.os.UserHandle.class); + UserHandle userHandle = source.readParcelable(UserHandle.class.getClassLoader()); int flags = source.readInt(); return new BeamShareData(msg, uris, userHandle, flags); diff --git a/core/java/android/os/Message.java b/core/java/android/os/Message.java index 72fb4ae03a637..c62df407ca77c 100644 --- a/core/java/android/os/Message.java +++ b/core/java/android/os/Message.java @@ -654,7 +654,7 @@ public final class Message implements Parcelable { arg1 = source.readInt(); arg2 = source.readInt(); if (source.readInt() != 0) { - obj = source.readParcelable(getClass().getClassLoader(), java.lang.Object.class); + obj = source.readParcelable(getClass().getClassLoader()); } when = source.readLong(); data = source.readBundle(); diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 70aaa5e52c444..ebbfe47c44177 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -2993,7 +2993,7 @@ public final class StrictMode { * should be removed. */ public ViolationInfo(Parcel in, boolean unsetGatheringBit) { - mViolation = (Violation) in.readSerializable(android.os.strictmode.Violation.class.getClassLoader(), android.os.strictmode.Violation.class); + mViolation = (Violation) in.readSerializable(); int binderStackSize = in.readInt(); for (int i = 0; i < binderStackSize; i++) { StackTraceElement[] traceElements = new StackTraceElement[in.readInt()]; diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java index ae37a714e0c8f..5de455695c018 100644 --- a/core/java/android/os/VibrationEffect.java +++ b/core/java/android/os/VibrationEffect.java @@ -576,7 +576,7 @@ public abstract class VibrationEffect implements Parcelable { private final int mRepeatIndex; Composed(@NonNull Parcel in) { - this(in.readArrayList(VibrationEffectSegment.class.getClassLoader(), android.os.vibrator.VibrationEffectSegment.class), in.readInt()); + this(in.readArrayList(VibrationEffectSegment.class.getClassLoader()), in.readInt()); } Composed(@NonNull VibrationEffectSegment segment) { diff --git a/core/java/android/os/VibratorInfo.java b/core/java/android/os/VibratorInfo.java index 5271c4df11ef0..189e454f14885 100644 --- a/core/java/android/os/VibratorInfo.java +++ b/core/java/android/os/VibratorInfo.java @@ -69,7 +69,7 @@ public class VibratorInfo implements Parcelable { mPwlePrimitiveDurationMax = in.readInt(); mPwleSizeMax = in.readInt(); mQFactor = in.readFloat(); - mFrequencyMapping = in.readParcelable(VibratorInfo.class.getClassLoader(), android.os.VibratorInfo.FrequencyMapping.class); + mFrequencyMapping = in.readParcelable(VibratorInfo.class.getClassLoader()); } /** diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java index e899f7729efa7..6588b5748d096 100644 --- a/core/java/android/os/WorkSource.java +++ b/core/java/android/os/WorkSource.java @@ -130,7 +130,7 @@ public class WorkSource implements Parcelable { int numChains = in.readInt(); if (numChains > 0) { mChains = new ArrayList<>(numChains); - in.readParcelableList(mChains, WorkChain.class.getClassLoader(), android.os.WorkSource.WorkChain.class); + in.readParcelableList(mChains, WorkChain.class.getClassLoader()); } else { mChains = null; } diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java index 8ee52c21e869a..b78bb253bcf78 100644 --- a/core/java/android/os/storage/StorageVolume.java +++ b/core/java/android/os/storage/StorageVolume.java @@ -168,7 +168,7 @@ public final class StorageVolume implements Parcelable { mExternallyManaged = in.readInt() != 0; mAllowMassStorage = in.readInt() != 0; mMaxFileSize = in.readLong(); - mOwner = in.readParcelable(null, android.os.UserHandle.class); + mOwner = in.readParcelable(null); if (in.readInt() != 0) { mUuid = StorageManager.convert(in.readString8()); } else { diff --git a/core/java/android/print/PrintJobInfo.java b/core/java/android/print/PrintJobInfo.java index 9d0c8d82ed0d5..67249be2b8064 100644 --- a/core/java/android/print/PrintJobInfo.java +++ b/core/java/android/print/PrintJobInfo.java @@ -231,9 +231,9 @@ public final class PrintJobInfo implements Parcelable { } private PrintJobInfo(@NonNull Parcel parcel) { - mId = parcel.readParcelable(null, android.print.PrintJobId.class); + mId = parcel.readParcelable(null); mLabel = parcel.readString(); - mPrinterId = parcel.readParcelable(null, android.print.PrinterId.class); + mPrinterId = parcel.readParcelable(null); mPrinterName = parcel.readString(); mState = parcel.readInt(); mAppId = parcel.readInt(); @@ -247,8 +247,8 @@ public final class PrintJobInfo implements Parcelable { mPageRanges[i] = (PageRange) parcelables[i]; } } - mAttributes = (PrintAttributes) parcel.readParcelable(null, android.print.PrintAttributes.class); - mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null, android.print.PrintDocumentInfo.class); + mAttributes = (PrintAttributes) parcel.readParcelable(null); + mDocumentInfo = (PrintDocumentInfo) parcel.readParcelable(null); mProgress = parcel.readFloat(); mStatus = parcel.readCharSequence(); mStatusRes = parcel.readInt(); diff --git a/core/java/android/print/PrinterId.java b/core/java/android/print/PrinterId.java index 284e122fc1038..25260c473709b 100644 --- a/core/java/android/print/PrinterId.java +++ b/core/java/android/print/PrinterId.java @@ -48,7 +48,7 @@ public final class PrinterId implements Parcelable { } private PrinterId(@NonNull Parcel parcel) { - mServiceName = Preconditions.checkNotNull((ComponentName) parcel.readParcelable(null, android.content.ComponentName.class)); + mServiceName = Preconditions.checkNotNull((ComponentName) parcel.readParcelable(null)); mLocalId = Preconditions.checkNotNull(parcel.readString()); } diff --git a/core/java/android/print/PrinterInfo.java b/core/java/android/print/PrinterInfo.java index 2f93e404a2112..8e03e3eb3f221 100644 --- a/core/java/android/print/PrinterInfo.java +++ b/core/java/android/print/PrinterInfo.java @@ -270,15 +270,15 @@ public final class PrinterInfo implements Parcelable { private PrinterInfo(Parcel parcel) { // mName can be null due to unchecked set in Builder.setName and status can be invalid // due to unchecked set in Builder.setStatus, hence we can only check mId for a valid state - mId = checkPrinterId((PrinterId) parcel.readParcelable(null, android.print.PrinterId.class)); + mId = checkPrinterId((PrinterId) parcel.readParcelable(null)); mName = checkName(parcel.readString()); mStatus = checkStatus(parcel.readInt()); mDescription = parcel.readString(); - mCapabilities = parcel.readParcelable(null, android.print.PrinterCapabilitiesInfo.class); + mCapabilities = parcel.readParcelable(null); mIconResourceId = parcel.readInt(); mHasCustomPrinterIcon = parcel.readByte() != 0; mCustomPrinterIconGen = parcel.readInt(); - mInfoIntent = parcel.readParcelable(null, android.app.PendingIntent.class); + mInfoIntent = parcel.readParcelable(null); } @Override diff --git a/core/java/android/printservice/PrintServiceInfo.java b/core/java/android/printservice/PrintServiceInfo.java index 347955718f78d..0c1b61d583b3d 100644 --- a/core/java/android/printservice/PrintServiceInfo.java +++ b/core/java/android/printservice/PrintServiceInfo.java @@ -76,7 +76,7 @@ public final class PrintServiceInfo implements Parcelable { public PrintServiceInfo(Parcel parcel) { mId = parcel.readString(); mIsEnabled = parcel.readByte() != 0; - mResolveInfo = parcel.readParcelable(null, android.content.pm.ResolveInfo.class); + mResolveInfo = parcel.readParcelable(null); mSettingsActivityName = parcel.readString(); mAddPrintersActivityName = parcel.readString(); mAdvancedPrintOptionsActivityName = parcel.readString(); diff --git a/core/java/android/service/autofill/BatchUpdates.java b/core/java/android/service/autofill/BatchUpdates.java index c996cc088d66c..8eeecc2931043 100644 --- a/core/java/android/service/autofill/BatchUpdates.java +++ b/core/java/android/service/autofill/BatchUpdates.java @@ -205,7 +205,7 @@ public final class BatchUpdates implements Parcelable { builder.transformChild(ids[i], values[i]); } } - final RemoteViews updates = parcel.readParcelable(null, android.widget.RemoteViews.class); + final RemoteViews updates = parcel.readParcelable(null); if (updates != null) { builder.updateTemplate(updates); } diff --git a/core/java/android/service/autofill/CompositeUserData.java b/core/java/android/service/autofill/CompositeUserData.java index 55ac5a5e92f09..92952cb7dc24d 100644 --- a/core/java/android/service/autofill/CompositeUserData.java +++ b/core/java/android/service/autofill/CompositeUserData.java @@ -197,8 +197,8 @@ public final class CompositeUserData implements FieldClassificationUserData, Par // Always go through the builder to ensure the data ingested by // the system obeys the contract of the builder to avoid attacks // using specially crafted parcels. - final UserData genericUserData = parcel.readParcelable(null, android.service.autofill.UserData.class); - final UserData packageUserData = parcel.readParcelable(null, android.service.autofill.UserData.class); + final UserData genericUserData = parcel.readParcelable(null); + final UserData packageUserData = parcel.readParcelable(null); return new CompositeUserData(genericUserData, packageUserData); } diff --git a/core/java/android/service/autofill/CustomDescription.java b/core/java/android/service/autofill/CustomDescription.java index 690cd06916313..f3f912bb3a5b6 100644 --- a/core/java/android/service/autofill/CustomDescription.java +++ b/core/java/android/service/autofill/CustomDescription.java @@ -437,7 +437,7 @@ public final class CustomDescription implements Parcelable { // Always go through the builder to ensure the data ingested by // the system obeys the contract of the builder to avoid attacks // using specially crafted parcels. - final RemoteViews parentPresentation = parcel.readParcelable(null, android.widget.RemoteViews.class); + final RemoteViews parentPresentation = parcel.readParcelable(null); if (parentPresentation == null) return null; final Builder builder = new Builder(parentPresentation); diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java index 86341a908ad78..8539bf58da278 100644 --- a/core/java/android/service/autofill/Dataset.java +++ b/core/java/android/service/autofill/Dataset.java @@ -913,10 +913,10 @@ public final class Dataset implements Parcelable { public static final @NonNull Creator CREATOR = new Creator() { @Override public Dataset createFromParcel(Parcel parcel) { - final RemoteViews presentation = parcel.readParcelable(null, android.widget.RemoteViews.class); - final InlinePresentation inlinePresentation = parcel.readParcelable(null, android.service.autofill.InlinePresentation.class); + final RemoteViews presentation = parcel.readParcelable(null); + final InlinePresentation inlinePresentation = parcel.readParcelable(null); final InlinePresentation inlineTooltipPresentation = - parcel.readParcelable(null, android.service.autofill.InlinePresentation.class); + parcel.readParcelable(null); final ArrayList ids = parcel.createTypedArrayList(AutofillId.CREATOR); final ArrayList values = @@ -929,8 +929,8 @@ public final class Dataset implements Parcelable { parcel.createTypedArrayList(InlinePresentation.CREATOR); final ArrayList filters = parcel.createTypedArrayList(DatasetFieldFilter.CREATOR); - final ClipData fieldContent = parcel.readParcelable(null, android.content.ClipData.class); - final IntentSender authentication = parcel.readParcelable(null, android.content.IntentSender.class); + final ClipData fieldContent = parcel.readParcelable(null); + final IntentSender authentication = parcel.readParcelable(null); final String datasetId = parcel.readString(); // Always go through the builder to ensure the data ingested by @@ -1014,7 +1014,7 @@ public final class Dataset implements Parcelable { @Override public DatasetFieldFilter createFromParcel(Parcel parcel) { - return new DatasetFieldFilter((Pattern) parcel.readSerializable(java.util.regex.Pattern.class.getClassLoader(), java.util.regex.Pattern.class)); + return new DatasetFieldFilter((Pattern) parcel.readSerializable()); } @Override diff --git a/core/java/android/service/autofill/DateTransformation.java b/core/java/android/service/autofill/DateTransformation.java index df5ed4dace554..734085737159e 100644 --- a/core/java/android/service/autofill/DateTransformation.java +++ b/core/java/android/service/autofill/DateTransformation.java @@ -114,8 +114,8 @@ public final class DateTransformation extends InternalTransformation implements new Parcelable.Creator() { @Override public DateTransformation createFromParcel(Parcel parcel) { - return new DateTransformation(parcel.readParcelable(null, android.view.autofill.AutofillId.class), - (DateFormat) parcel.readSerializable(android.icu.text.DateFormat.class.getClassLoader(), android.icu.text.DateFormat.class)); + return new DateTransformation(parcel.readParcelable(null), + (DateFormat) parcel.readSerializable()); } @Override diff --git a/core/java/android/service/autofill/DateValueSanitizer.java b/core/java/android/service/autofill/DateValueSanitizer.java index c7d5b79ae4840..6f7808ee181a0 100644 --- a/core/java/android/service/autofill/DateValueSanitizer.java +++ b/core/java/android/service/autofill/DateValueSanitizer.java @@ -111,7 +111,7 @@ public final class DateValueSanitizer extends InternalSanitizer implements Sanit new Parcelable.Creator() { @Override public DateValueSanitizer createFromParcel(Parcel parcel) { - return new DateValueSanitizer((DateFormat) parcel.readSerializable(android.icu.text.DateFormat.class.getClassLoader(), android.icu.text.DateFormat.class)); + return new DateValueSanitizer((DateFormat) parcel.readSerializable()); } @Override diff --git a/core/java/android/service/autofill/FillRequest.java b/core/java/android/service/autofill/FillRequest.java index 43bd4102ffb5e..af846b62ae2c1 100644 --- a/core/java/android/service/autofill/FillRequest.java +++ b/core/java/android/service/autofill/FillRequest.java @@ -384,7 +384,7 @@ public final class FillRequest implements Parcelable { byte flg = in.readByte(); int id = in.readInt(); List fillContexts = new ArrayList<>(); - in.readParcelableList(fillContexts, FillContext.class.getClassLoader(), android.service.autofill.FillContext.class); + in.readParcelableList(fillContexts, FillContext.class.getClassLoader()); Bundle clientState = (flg & 0x4) == 0 ? null : in.readBundle(); int flags = in.readInt(); InlineSuggestionsRequest inlineSuggestionsRequest = (flg & 0x10) == 0 ? null : (InlineSuggestionsRequest) in.readTypedObject(InlineSuggestionsRequest.CREATOR); diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java index d94988ebea669..970cb18883172 100644 --- a/core/java/android/service/autofill/FillResponse.java +++ b/core/java/android/service/autofill/FillResponse.java @@ -834,35 +834,35 @@ public final class FillResponse implements Parcelable { // the system obeys the contract of the builder to avoid attacks // using specially crafted parcels. final Builder builder = new Builder(); - final ParceledListSlice datasetSlice = parcel.readParcelable(null, android.content.pm.ParceledListSlice.class); + final ParceledListSlice datasetSlice = parcel.readParcelable(null); final List datasets = (datasetSlice != null) ? datasetSlice.getList() : null; final int datasetCount = (datasets != null) ? datasets.size() : 0; for (int i = 0; i < datasetCount; i++) { builder.addDataset(datasets.get(i)); } - builder.setSaveInfo(parcel.readParcelable(null, android.service.autofill.SaveInfo.class)); - builder.setClientState(parcel.readParcelable(null, android.os.Bundle.class)); + builder.setSaveInfo(parcel.readParcelable(null)); + builder.setClientState(parcel.readParcelable(null)); // Sets authentication state. final AutofillId[] authenticationIds = parcel.readParcelableArray(null, AutofillId.class); - final IntentSender authentication = parcel.readParcelable(null, android.content.IntentSender.class); - final RemoteViews presentation = parcel.readParcelable(null, android.widget.RemoteViews.class); - final InlinePresentation inlinePresentation = parcel.readParcelable(null, android.service.autofill.InlinePresentation.class); - final InlinePresentation inlineTooltipPresentation = parcel.readParcelable(null, android.service.autofill.InlinePresentation.class); + final IntentSender authentication = parcel.readParcelable(null); + final RemoteViews presentation = parcel.readParcelable(null); + final InlinePresentation inlinePresentation = parcel.readParcelable(null); + final InlinePresentation inlineTooltipPresentation = parcel.readParcelable(null); if (authenticationIds != null) { builder.setAuthentication(authenticationIds, authentication, presentation, inlinePresentation, inlineTooltipPresentation); } - final RemoteViews header = parcel.readParcelable(null, android.widget.RemoteViews.class); + final RemoteViews header = parcel.readParcelable(null); if (header != null) { builder.setHeader(header); } - final RemoteViews footer = parcel.readParcelable(null, android.widget.RemoteViews.class); + final RemoteViews footer = parcel.readParcelable(null); if (footer != null) { builder.setFooter(footer); } - final UserData userData = parcel.readParcelable(null, android.service.autofill.UserData.class); + final UserData userData = parcel.readParcelable(null); if (userData != null) { builder.setUserData(userData); } diff --git a/core/java/android/service/autofill/ImageTransformation.java b/core/java/android/service/autofill/ImageTransformation.java index af82205b77b9b..e3171594c39e0 100644 --- a/core/java/android/service/autofill/ImageTransformation.java +++ b/core/java/android/service/autofill/ImageTransformation.java @@ -247,7 +247,7 @@ public final class ImageTransformation extends InternalTransformation implements new Parcelable.Creator() { @Override public ImageTransformation createFromParcel(Parcel parcel) { - final AutofillId id = parcel.readParcelable(null, android.view.autofill.AutofillId.class); + final AutofillId id = parcel.readParcelable(null); final Pattern[] regexs = (Pattern[]) parcel.readSerializable(); final int[] resIds = parcel.createIntArray(); diff --git a/core/java/android/service/autofill/NegationValidator.java b/core/java/android/service/autofill/NegationValidator.java index 85cd981e31526..d626845b3b3ed 100644 --- a/core/java/android/service/autofill/NegationValidator.java +++ b/core/java/android/service/autofill/NegationValidator.java @@ -68,7 +68,7 @@ final class NegationValidator extends InternalValidator { new Parcelable.Creator() { @Override public NegationValidator createFromParcel(Parcel parcel) { - return new NegationValidator(parcel.readParcelable(null, android.service.autofill.InternalValidator.class)); + return new NegationValidator(parcel.readParcelable(null)); } @Override diff --git a/core/java/android/service/autofill/RegexValidator.java b/core/java/android/service/autofill/RegexValidator.java index 4c58590ab7cf8..00c43473ce7f6 100644 --- a/core/java/android/service/autofill/RegexValidator.java +++ b/core/java/android/service/autofill/RegexValidator.java @@ -96,8 +96,8 @@ public final class RegexValidator extends InternalValidator implements Validator new Parcelable.Creator() { @Override public RegexValidator createFromParcel(Parcel parcel) { - return new RegexValidator(parcel.readParcelable(null, android.view.autofill.AutofillId.class), - (Pattern) parcel.readSerializable(java.util.regex.Pattern.class.getClassLoader(), java.util.regex.Pattern.class)); + return new RegexValidator(parcel.readParcelable(null), + (Pattern) parcel.readSerializable()); } @Override diff --git a/core/java/android/service/autofill/SaveInfo.java b/core/java/android/service/autofill/SaveInfo.java index 5fe1d4f5ca5fe..8edfde8c3914a 100644 --- a/core/java/android/service/autofill/SaveInfo.java +++ b/core/java/android/service/autofill/SaveInfo.java @@ -888,14 +888,14 @@ public final class SaveInfo implements Parcelable { builder.setOptionalIds(optionalIds); } - builder.setNegativeAction(parcel.readInt(), parcel.readParcelable(null, android.content.IntentSender.class)); + builder.setNegativeAction(parcel.readInt(), parcel.readParcelable(null)); builder.setPositiveAction(parcel.readInt()); builder.setDescription(parcel.readCharSequence()); - final CustomDescription customDescripton = parcel.readParcelable(null, android.service.autofill.CustomDescription.class); + final CustomDescription customDescripton = parcel.readParcelable(null); if (customDescripton != null) { builder.setCustomDescription(customDescripton); } - final InternalValidator validator = parcel.readParcelable(null, android.service.autofill.InternalValidator.class); + final InternalValidator validator = parcel.readParcelable(null); if (validator != null) { builder.setValidator(validator); } @@ -909,7 +909,7 @@ public final class SaveInfo implements Parcelable { builder.addSanitizer(sanitizers[i], autofillIds); } } - final AutofillId triggerId = parcel.readParcelable(null, android.view.autofill.AutofillId.class); + final AutofillId triggerId = parcel.readParcelable(null); if (triggerId != null) { builder.setTriggerId(triggerId); } diff --git a/core/java/android/service/autofill/TextValueSanitizer.java b/core/java/android/service/autofill/TextValueSanitizer.java index 46c18b23a74d9..5bafa7a1ff546 100644 --- a/core/java/android/service/autofill/TextValueSanitizer.java +++ b/core/java/android/service/autofill/TextValueSanitizer.java @@ -119,7 +119,7 @@ public final class TextValueSanitizer extends InternalSanitizer implements new Parcelable.Creator() { @Override public TextValueSanitizer createFromParcel(Parcel parcel) { - return new TextValueSanitizer((Pattern) parcel.readSerializable(java.util.regex.Pattern.class.getClassLoader(), java.util.regex.Pattern.class), parcel.readString()); + return new TextValueSanitizer((Pattern) parcel.readSerializable(), parcel.readString()); } @Override diff --git a/core/java/android/service/contentcapture/ActivityEvent.java b/core/java/android/service/contentcapture/ActivityEvent.java index d286942c74fa8..74a7355181201 100644 --- a/core/java/android/service/contentcapture/ActivityEvent.java +++ b/core/java/android/service/contentcapture/ActivityEvent.java @@ -149,7 +149,7 @@ public final class ActivityEvent implements Parcelable { @Override @NonNull public ActivityEvent createFromParcel(@NonNull Parcel parcel) { - final ComponentName componentName = parcel.readParcelable(null, android.content.ComponentName.class); + final ComponentName componentName = parcel.readParcelable(null); final int eventType = parcel.readInt(); return new ActivityEvent(componentName, eventType); } diff --git a/core/java/android/service/contentcapture/SnapshotData.java b/core/java/android/service/contentcapture/SnapshotData.java index f72624d000615..bf469b4b3ad8f 100644 --- a/core/java/android/service/contentcapture/SnapshotData.java +++ b/core/java/android/service/contentcapture/SnapshotData.java @@ -51,8 +51,8 @@ public final class SnapshotData implements Parcelable { SnapshotData(@NonNull Parcel parcel) { mAssistData = parcel.readBundle(); - mAssistStructure = parcel.readParcelable(null, android.app.assist.AssistStructure.class); - mAssistContent = parcel.readParcelable(null, android.app.assist.AssistContent.class); + mAssistStructure = parcel.readParcelable(null); + mAssistContent = parcel.readParcelable(null); } /** diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java index 267b2ff818a69..4f324f9e35bff 100644 --- a/core/java/android/service/notification/Condition.java +++ b/core/java/android/service/notification/Condition.java @@ -114,7 +114,7 @@ public final class Condition implements Parcelable { } public Condition(Parcel source) { - this((Uri)source.readParcelable(Condition.class.getClassLoader(), android.net.Uri.class), + this((Uri)source.readParcelable(Condition.class.getClassLoader()), source.readString(), source.readString(), source.readString(), diff --git a/core/java/android/service/notification/ConversationChannelWrapper.java b/core/java/android/service/notification/ConversationChannelWrapper.java index 35b6bad4e40b2..3d0984ca80eea 100644 --- a/core/java/android/service/notification/ConversationChannelWrapper.java +++ b/core/java/android/service/notification/ConversationChannelWrapper.java @@ -40,10 +40,10 @@ public final class ConversationChannelWrapper implements Parcelable { public ConversationChannelWrapper() {} protected ConversationChannelWrapper(Parcel in) { - mNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader(), android.app.NotificationChannel.class); + mNotificationChannel = in.readParcelable(NotificationChannel.class.getClassLoader()); mGroupLabel = in.readCharSequence(); mParentChannelLabel = in.readCharSequence(); - mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader(), android.content.pm.ShortcutInfo.class); + mShortcutInfo = in.readParcelable(ShortcutInfo.class.getClassLoader()); mPkg = in.readStringNoHelper(); mUid = in.readInt(); } diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index ae39d3d3c2dab..c94595468aec2 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -1763,7 +1763,7 @@ public abstract class NotificationListenerService extends Service { mImportanceExplanation = in.readCharSequence(); // may be null mRankingScore = in.readFloat(); mOverrideGroupKey = in.readString(); // may be null - mChannel = in.readParcelable(cl, android.app.NotificationChannel.class); // may be null + mChannel = in.readParcelable(cl); // may be null mOverridePeople = in.createStringArrayList(); mSnoozeCriteria = in.createTypedArrayList(SnoozeCriterion.CREATOR); mShowBadge = in.readBoolean(); @@ -1776,7 +1776,7 @@ public abstract class NotificationListenerService extends Service { mCanBubble = in.readBoolean(); mIsTextChanged = in.readBoolean(); mIsConversation = in.readBoolean(); - mShortcutInfo = in.readParcelable(cl, android.content.pm.ShortcutInfo.class); + mShortcutInfo = in.readParcelable(cl); mRankingAdjustment = in.readInt(); mIsBubble = in.readBoolean(); } diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java index a853714c0e9da..c64f4c46a769d 100644 --- a/core/java/android/service/notification/NotificationRankingUpdate.java +++ b/core/java/android/service/notification/NotificationRankingUpdate.java @@ -30,7 +30,7 @@ public class NotificationRankingUpdate implements Parcelable { } public NotificationRankingUpdate(Parcel in) { - mRankingMap = in.readParcelable(getClass().getClassLoader(), android.service.notification.NotificationListenerService.RankingMap.class); + mRankingMap = in.readParcelable(getClass().getClassLoader()); } public NotificationListenerService.RankingMap getRankingMap() { diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index 8834ceea74532..c1d5a28aa349b 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -211,7 +211,7 @@ public class ZenModeConfig implements Parcelable { allowCallsFrom = source.readInt(); allowMessagesFrom = source.readInt(); user = source.readInt(); - manualRule = source.readParcelable(null, android.service.notification.ZenModeConfig.ZenRule.class); + manualRule = source.readParcelable(null); final int len = source.readInt(); if (len > 0) { final String[] ids = new String[len]; @@ -1800,10 +1800,10 @@ public class ZenModeConfig implements Parcelable { name = source.readString(); } zenMode = source.readInt(); - conditionId = source.readParcelable(null, android.net.Uri.class); - condition = source.readParcelable(null, android.service.notification.Condition.class); - component = source.readParcelable(null, android.content.ComponentName.class); - configurationActivity = source.readParcelable(null, android.content.ComponentName.class); + conditionId = source.readParcelable(null); + condition = source.readParcelable(null); + component = source.readParcelable(null); + configurationActivity = source.readParcelable(null); if (source.readInt() == 1) { id = source.readString(); } @@ -1811,7 +1811,7 @@ public class ZenModeConfig implements Parcelable { if (source.readInt() == 1) { enabler = source.readString(); } - zenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class); + zenPolicy = source.readParcelable(null); modified = source.readInt() == 1; pkg = source.readString(); } diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java index a04f07380ce87..ed3a9ac33738a 100644 --- a/core/java/android/service/notification/ZenPolicy.java +++ b/core/java/android/service/notification/ZenPolicy.java @@ -804,8 +804,8 @@ public final class ZenPolicy implements Parcelable { @Override public ZenPolicy createFromParcel(Parcel source) { ZenPolicy policy = new ZenPolicy(); - policy.mPriorityCategories = source.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class); - policy.mVisualEffects = source.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class); + policy.mPriorityCategories = source.readArrayList(Integer.class.getClassLoader()); + policy.mVisualEffects = source.readArrayList(Integer.class.getClassLoader()); policy.mPriorityCalls = source.readInt(); policy.mPriorityMessages = source.readInt(); policy.mConversationSenders = source.readInt(); diff --git a/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java index 7471a4f399a59..0551e2709de6f 100644 --- a/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java +++ b/core/java/android/service/quickaccesswallet/GetWalletCardsResponse.java @@ -63,7 +63,7 @@ public final class GetWalletCardsResponse implements Parcelable { private static GetWalletCardsResponse readFromParcel(Parcel source) { int size = source.readInt(); List walletCards = - source.readParcelableList(new ArrayList<>(size), WalletCard.class.getClassLoader(), android.service.quickaccesswallet.WalletCard.class); + source.readParcelableList(new ArrayList<>(size), WalletCard.class.getClassLoader()); int selectedIndex = source.readInt(); return new GetWalletCardsResponse(walletCards, selectedIndex); } diff --git a/core/java/android/service/settings/suggestions/Suggestion.java b/core/java/android/service/settings/suggestions/Suggestion.java index 16622d70065fe..3e63efbda9c01 100644 --- a/core/java/android/service/settings/suggestions/Suggestion.java +++ b/core/java/android/service/settings/suggestions/Suggestion.java @@ -120,9 +120,9 @@ public final class Suggestion implements Parcelable { mId = in.readString(); mTitle = in.readCharSequence(); mSummary = in.readCharSequence(); - mIcon = in.readParcelable(Icon.class.getClassLoader(), android.graphics.drawable.Icon.class); + mIcon = in.readParcelable(Icon.class.getClassLoader()); mFlags = in.readInt(); - mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader(), android.app.PendingIntent.class); + mPendingIntent = in.readParcelable(PendingIntent.class.getClassLoader()); } public static final @android.annotation.NonNull Creator CREATOR = new Creator() { diff --git a/core/java/android/service/timezone/TimeZoneProviderEvent.java b/core/java/android/service/timezone/TimeZoneProviderEvent.java index f6433b7f371e3..700528116a8f0 100644 --- a/core/java/android/service/timezone/TimeZoneProviderEvent.java +++ b/core/java/android/service/timezone/TimeZoneProviderEvent.java @@ -141,7 +141,7 @@ public final class TimeZoneProviderEvent implements Parcelable { int type = in.readInt(); long creationElapsedMillis = in.readLong(); TimeZoneProviderSuggestion suggestion = - in.readParcelable(getClass().getClassLoader(), android.service.timezone.TimeZoneProviderSuggestion.class); + in.readParcelable(getClass().getClassLoader()); String failureCause = in.readString8(); return new TimeZoneProviderEvent( type, creationElapsedMillis, suggestion, failureCause); diff --git a/core/java/android/service/timezone/TimeZoneProviderSuggestion.java b/core/java/android/service/timezone/TimeZoneProviderSuggestion.java index 4841ac1890340..229fa268a47c5 100644 --- a/core/java/android/service/timezone/TimeZoneProviderSuggestion.java +++ b/core/java/android/service/timezone/TimeZoneProviderSuggestion.java @@ -100,7 +100,7 @@ public final class TimeZoneProviderSuggestion implements Parcelable { public TimeZoneProviderSuggestion createFromParcel(Parcel in) { @SuppressWarnings("unchecked") ArrayList timeZoneIds = - (ArrayList) in.readArrayList(null /* classLoader */, java.lang.String.class); + (ArrayList) in.readArrayList(null /* classLoader */); long elapsedRealtimeMillis = in.readLong(); return new TimeZoneProviderSuggestion(timeZoneIds, elapsedRealtimeMillis); } diff --git a/core/java/android/speech/tts/Voice.java b/core/java/android/speech/tts/Voice.java index 0d98a6ca5f14b..7ffe5eb7893d3 100644 --- a/core/java/android/speech/tts/Voice.java +++ b/core/java/android/speech/tts/Voice.java @@ -84,7 +84,7 @@ public class Voice implements Parcelable { private Voice(Parcel in) { this.mName = in.readString(); - this.mLocale = (Locale)in.readSerializable(java.util.Locale.class.getClassLoader(), java.util.Locale.class); + this.mLocale = (Locale)in.readSerializable(); this.mQuality = in.readInt(); this.mLatency = in.readInt(); this.mRequiresNetworkConnection = (in.readByte() == 1); diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java index fb2d7714d4024..d5ac4368aa97f 100644 --- a/core/java/android/telephony/SubscriptionPlan.java +++ b/core/java/android/telephony/SubscriptionPlan.java @@ -99,7 +99,7 @@ public final class SubscriptionPlan implements Parcelable { } private SubscriptionPlan(Parcel source) { - cycleRule = source.readParcelable(null, android.util.RecurrenceRule.class); + cycleRule = source.readParcelable(null); title = source.readCharSequence(); summary = source.readCharSequence(); dataLimitBytes = source.readLong(); diff --git a/core/java/android/text/FontConfig.java b/core/java/android/text/FontConfig.java index 32b3bc62a8cd0..2f7fb2f0ab9d1 100644 --- a/core/java/android/text/FontConfig.java +++ b/core/java/android/text/FontConfig.java @@ -143,9 +143,9 @@ public final class FontConfig implements Parcelable { @Override public FontConfig createFromParcel(Parcel source) { List families = source.readParcelableList(new ArrayList<>(), - FontFamily.class.getClassLoader(), android.text.FontConfig.FontFamily.class); + FontFamily.class.getClassLoader()); List aliases = source.readParcelableList(new ArrayList<>(), - Alias.class.getClassLoader(), android.text.FontConfig.Alias.class); + Alias.class.getClassLoader()); long lastModifiedDate = source.readLong(); int configVersion = source.readInt(); return new FontConfig(families, aliases, lastModifiedDate, configVersion); @@ -617,7 +617,7 @@ public final class FontConfig implements Parcelable { @Override public FontFamily createFromParcel(Parcel source) { List fonts = source.readParcelableList( - new ArrayList<>(), Font.class.getClassLoader(), android.text.FontConfig.Font.class); + new ArrayList<>(), Font.class.getClassLoader()); String name = source.readString8(); String langTags = source.readString8(); int variant = source.readInt(); diff --git a/core/java/android/text/style/EasyEditSpan.java b/core/java/android/text/style/EasyEditSpan.java index 3da83332d62e8..ccccdcf88b695 100644 --- a/core/java/android/text/style/EasyEditSpan.java +++ b/core/java/android/text/style/EasyEditSpan.java @@ -82,7 +82,7 @@ public class EasyEditSpan implements ParcelableSpan { * Constructor called from {@link TextUtils} to restore the span. */ public EasyEditSpan(@NonNull Parcel source) { - mPendingIntent = source.readParcelable(null, android.app.PendingIntent.class); + mPendingIntent = source.readParcelable(null); mDeleteEnabled = (source.readByte() == 1); } diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java index adb379a397b74..23557694a48dd 100644 --- a/core/java/android/text/style/TextAppearanceSpan.java +++ b/core/java/android/text/style/TextAppearanceSpan.java @@ -249,7 +249,7 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl mTypeface = LeakyTypefaceStorage.readTypefaceFromParcel(src); mTextFontWeight = src.readInt(); - mTextLocales = src.readParcelable(LocaleList.class.getClassLoader(), android.os.LocaleList.class); + mTextLocales = src.readParcelable(LocaleList.class.getClassLoader()); mShadowRadius = src.readFloat(); mShadowDx = src.readFloat(); diff --git a/core/java/android/util/MemoryIntArray.java b/core/java/android/util/MemoryIntArray.java index 5cbbbef2cf884..42181c3c1722e 100644 --- a/core/java/android/util/MemoryIntArray.java +++ b/core/java/android/util/MemoryIntArray.java @@ -80,7 +80,7 @@ public final class MemoryIntArray implements Parcelable, Closeable { private MemoryIntArray(Parcel parcel) throws IOException { mIsOwner = false; - ParcelFileDescriptor pfd = parcel.readParcelable(null, android.os.ParcelFileDescriptor.class); + ParcelFileDescriptor pfd = parcel.readParcelable(null); if (pfd == null) { throw new IOException("No backing file descriptor"); } diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index 678c80a2094b0..b8614ccde6fd1 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -449,8 +449,8 @@ public final class DisplayInfo implements Parcelable { type = source.readInt(); displayId = source.readInt(); displayGroupId = source.readInt(); - address = source.readParcelable(null, android.view.DisplayAddress.class); - deviceProductInfo = source.readParcelable(null, android.hardware.display.DeviceProductInfo.class); + address = source.readParcelable(null); + deviceProductInfo = source.readParcelable(null); name = source.readString8(); appWidth = source.readInt(); appHeight = source.readInt(); @@ -475,7 +475,7 @@ public final class DisplayInfo implements Parcelable { for (int i = 0; i < nColorModes; i++) { supportedColorModes[i] = source.readInt(); } - hdrCapabilities = source.readParcelable(null, android.view.Display.HdrCapabilities.class); + hdrCapabilities = source.readParcelable(null); minimalPostProcessingSupported = source.readBoolean(); logicalDensityDpi = source.readInt(); physicalXDpi = source.readFloat(); diff --git a/core/java/android/view/KeyboardShortcutInfo.java b/core/java/android/view/KeyboardShortcutInfo.java index 118b03ce5504a..2660e74dcb205 100644 --- a/core/java/android/view/KeyboardShortcutInfo.java +++ b/core/java/android/view/KeyboardShortcutInfo.java @@ -91,7 +91,7 @@ public final class KeyboardShortcutInfo implements Parcelable { private KeyboardShortcutInfo(Parcel source) { mLabel = source.readCharSequence(); - mIcon = source.readParcelable(null, android.graphics.drawable.Icon.class); + mIcon = source.readParcelable(null); mBaseCharacter = (char) source.readInt(); mKeycode = source.readInt(); mModifiers = source.readInt(); diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index a427ab8fe8374..6ad2d9a7adb1c 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -1315,7 +1315,7 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par record.mContentDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); record.mBeforeText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel); record.mParcelableData = parcel.readParcelable(null); - parcel.readList(record.mText, null, java.lang.CharSequence.class); + parcel.readList(record.mText, null); record.mSourceWindowId = parcel.readInt(); record.mSourceNodeId = parcel.readLong(); record.mSourceDisplayId = parcel.readInt(); diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java index 540f5dc27f7e1..67e6d3f2aec36 100644 --- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java +++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java @@ -917,7 +917,7 @@ public final class AccessibilityWindowInfo implements Parcelable { final int count = source.readInt(); for (int i = 0; i < count; i++) { List windows = new ArrayList<>(); - source.readParcelableList(windows, loader, android.view.accessibility.AccessibilityWindowInfo.class); + source.readParcelableList(windows, loader); array.put(source.readInt(), windows); } return array; diff --git a/core/java/android/view/autofill/ParcelableMap.java b/core/java/android/view/autofill/ParcelableMap.java index 3fa7734e56fce..d8459aa22fa1e 100644 --- a/core/java/android/view/autofill/ParcelableMap.java +++ b/core/java/android/view/autofill/ParcelableMap.java @@ -56,8 +56,8 @@ class ParcelableMap extends HashMap implements Parcel ParcelableMap map = new ParcelableMap(size); for (int i = 0; i < size; i++) { - AutofillId key = source.readParcelable(null, android.view.autofill.AutofillId.class); - AutofillValue value = source.readParcelable(null, android.view.autofill.AutofillValue.class); + AutofillId key = source.readParcelable(null); + AutofillValue value = source.readParcelable(null); map.put(key, value); } diff --git a/core/java/android/view/contentcapture/ContentCaptureCondition.java b/core/java/android/view/contentcapture/ContentCaptureCondition.java index 685ea1aeaba80..027c8d20ccc61 100644 --- a/core/java/android/view/contentcapture/ContentCaptureCondition.java +++ b/core/java/android/view/contentcapture/ContentCaptureCondition.java @@ -133,7 +133,7 @@ public final class ContentCaptureCondition implements Parcelable { @Override public ContentCaptureCondition createFromParcel(@NonNull Parcel parcel) { - return new ContentCaptureCondition(parcel.readParcelable(null, android.content.LocusId.class), + return new ContentCaptureCondition(parcel.readParcelable(null), parcel.readInt()); } diff --git a/core/java/android/view/contentcapture/ContentCaptureContext.java b/core/java/android/view/contentcapture/ContentCaptureContext.java index 59b5286f6fc54..3bc9a967ea207 100644 --- a/core/java/android/view/contentcapture/ContentCaptureContext.java +++ b/core/java/android/view/contentcapture/ContentCaptureContext.java @@ -419,7 +419,7 @@ public final class ContentCaptureContext implements Parcelable { final ContentCaptureContext clientContext; if (hasClientContext) { // Must reconstruct the client context using the Builder API - final LocusId id = parcel.readParcelable(null, android.content.LocusId.class); + final LocusId id = parcel.readParcelable(null); final Bundle extras = parcel.readBundle(); final Builder builder = new Builder(id); if (extras != null) builder.setExtras(extras); @@ -427,7 +427,7 @@ public final class ContentCaptureContext implements Parcelable { } else { clientContext = null; } - final ComponentName componentName = parcel.readParcelable(null, android.content.ComponentName.class); + final ComponentName componentName = parcel.readParcelable(null); if (componentName == null) { // Client-state only return clientContext; diff --git a/core/java/android/view/contentcapture/ContentCaptureEvent.java b/core/java/android/view/contentcapture/ContentCaptureEvent.java index ba4176faa2835..0f4bc191fe4eb 100644 --- a/core/java/android/view/contentcapture/ContentCaptureEvent.java +++ b/core/java/android/view/contentcapture/ContentCaptureEvent.java @@ -620,7 +620,7 @@ public final class ContentCaptureEvent implements Parcelable { final int type = parcel.readInt(); final long eventTime = parcel.readLong(); final ContentCaptureEvent event = new ContentCaptureEvent(sessionId, type, eventTime); - final AutofillId id = parcel.readParcelable(null, android.view.autofill.AutofillId.class); + final AutofillId id = parcel.readParcelable(null); if (id != null) { event.setAutofillId(id); } @@ -637,13 +637,13 @@ public final class ContentCaptureEvent implements Parcelable { event.setParentSessionId(parcel.readInt()); } if (type == TYPE_SESSION_STARTED || type == TYPE_CONTEXT_UPDATED) { - event.setClientContext(parcel.readParcelable(null, android.view.contentcapture.ContentCaptureContext.class)); + event.setClientContext(parcel.readParcelable(null)); } if (type == TYPE_VIEW_INSETS_CHANGED) { - event.setInsets(parcel.readParcelable(null, android.graphics.Insets.class)); + event.setInsets(parcel.readParcelable(null)); } if (type == TYPE_WINDOW_BOUNDS_CHANGED) { - event.setBounds(parcel.readParcelable(null, android.graphics.Rect.class)); + event.setBounds(parcel.readParcelable(null)); } if (type == TYPE_VIEW_TEXT_CHANGED) { event.setComposingIndex(parcel.readInt(), parcel.readInt()); diff --git a/core/java/android/view/contentcapture/ViewNode.java b/core/java/android/view/contentcapture/ViewNode.java index 1762a5817aaf2..1b4a00f81e443 100644 --- a/core/java/android/view/contentcapture/ViewNode.java +++ b/core/java/android/view/contentcapture/ViewNode.java @@ -124,10 +124,10 @@ public final class ViewNode extends AssistStructure.ViewNode { mFlags = nodeFlags; if ((nodeFlags & FLAGS_HAS_AUTOFILL_ID) != 0) { - mAutofillId = parcel.readParcelable(null, android.view.autofill.AutofillId.class); + mAutofillId = parcel.readParcelable(null); } if ((nodeFlags & FLAGS_HAS_AUTOFILL_PARENT_ID) != 0) { - mParentAutofillId = parcel.readParcelable(null, android.view.autofill.AutofillId.class); + mParentAutofillId = parcel.readParcelable(null); } if ((nodeFlags & FLAGS_HAS_TEXT) != 0) { mText = new ViewNodeText(parcel, (nodeFlags & FLAGS_HAS_COMPLEX_TEXT) == 0); @@ -169,7 +169,7 @@ public final class ViewNode extends AssistStructure.ViewNode { mExtras = parcel.readBundle(); } if ((nodeFlags & FLAGS_HAS_LOCALE_LIST) != 0) { - mLocaleList = parcel.readParcelable(null, android.os.LocaleList.class); + mLocaleList = parcel.readParcelable(null); } if ((nodeFlags & FLAGS_HAS_MIME_TYPES) != 0) { mReceiveContentMimeTypes = parcel.readStringArray(); @@ -196,7 +196,7 @@ public final class ViewNode extends AssistStructure.ViewNode { mAutofillHints = parcel.readStringArray(); } if ((nodeFlags & FLAGS_HAS_AUTOFILL_VALUE) != 0) { - mAutofillValue = parcel.readParcelable(null, android.view.autofill.AutofillValue.class); + mAutofillValue = parcel.readParcelable(null); } if ((nodeFlags & FLAGS_HAS_AUTOFILL_OPTIONS) != 0) { mAutofillOptions = parcel.readCharSequenceArray(); diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java index 437e54f635ee4..fbc947071c990 100644 --- a/core/java/android/view/inputmethod/CursorAnchorInfo.java +++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java @@ -140,7 +140,7 @@ public final class CursorAnchorInfo implements Parcelable { mInsertionMarkerTop = source.readFloat(); mInsertionMarkerBaseline = source.readFloat(); mInsertionMarkerBottom = source.readFloat(); - mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader(), android.view.inputmethod.SparseRectFArray.class); + mCharacterBoundsArray = source.readParcelable(SparseRectFArray.class.getClassLoader()); mMatrixValues = source.createFloatArray(); } diff --git a/core/java/android/view/inputmethod/EditorInfo.java b/core/java/android/view/inputmethod/EditorInfo.java index 09a14484095e0..4cbd477d807a7 100644 --- a/core/java/android/view/inputmethod/EditorInfo.java +++ b/core/java/android/view/inputmethod/EditorInfo.java @@ -1067,7 +1067,7 @@ public class EditorInfo implements InputType, Parcelable { res.hintText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); res.label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); res.packageName = source.readString(); - res.autofillId = source.readParcelable(AutofillId.class.getClassLoader(), android.view.autofill.AutofillId.class); + res.autofillId = source.readParcelable(AutofillId.class.getClassLoader()); res.fieldId = source.readInt(); res.fieldName = source.readString(); res.extras = source.readBundle(); diff --git a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java index 70279cc8e8452..e1e175512edc9 100644 --- a/core/java/android/view/inputmethod/InlineSuggestionsRequest.java +++ b/core/java/android/view/inputmethod/InlineSuggestionsRequest.java @@ -490,7 +490,7 @@ public final class InlineSuggestionsRequest implements Parcelable { boolean clientSupported = (flg & 0x200) != 0; int maxSuggestionCount = in.readInt(); List inlinePresentationSpecs = new ArrayList<>(); - in.readParcelableList(inlinePresentationSpecs, InlinePresentationSpec.class.getClassLoader(), android.widget.inline.InlinePresentationSpec.class); + in.readParcelableList(inlinePresentationSpecs, InlinePresentationSpec.class.getClassLoader()); String hostPackageName = in.readString(); LocaleList supportedLocales = (LocaleList) in.readTypedObject(LocaleList.CREATOR); Bundle extras = in.readBundle(); diff --git a/core/java/android/view/inputmethod/InlineSuggestionsResponse.java b/core/java/android/view/inputmethod/InlineSuggestionsResponse.java index 532fc85dcc448..b393c67d7876d 100644 --- a/core/java/android/view/inputmethod/InlineSuggestionsResponse.java +++ b/core/java/android/view/inputmethod/InlineSuggestionsResponse.java @@ -170,7 +170,7 @@ public final class InlineSuggestionsResponse implements Parcelable { // static FieldType unparcelFieldName(Parcel in) { ... } List inlineSuggestions = new ArrayList<>(); - in.readParcelableList(inlineSuggestions, InlineSuggestion.class.getClassLoader(), android.view.inputmethod.InlineSuggestion.class); + in.readParcelableList(inlineSuggestions, InlineSuggestion.class.getClassLoader()); this.mInlineSuggestions = inlineSuggestions; com.android.internal.util.AnnotationValidations.validate( diff --git a/core/java/android/view/textclassifier/ConversationAction.java b/core/java/android/view/textclassifier/ConversationAction.java index a4a5a1ed0ac9f..bf0409dfc9190 100644 --- a/core/java/android/view/textclassifier/ConversationAction.java +++ b/core/java/android/view/textclassifier/ConversationAction.java @@ -141,7 +141,7 @@ public final class ConversationAction implements Parcelable { private ConversationAction(Parcel in) { mType = in.readString(); - mAction = in.readParcelable(null, android.app.RemoteAction.class); + mAction = in.readParcelable(null); mTextReply = in.readCharSequence(); mScore = in.readFloat(); mExtras = in.readBundle(); diff --git a/core/java/android/view/textclassifier/ConversationActions.java b/core/java/android/view/textclassifier/ConversationActions.java index 7a6a3cd026fd3..6ad5cb9135532 100644 --- a/core/java/android/view/textclassifier/ConversationActions.java +++ b/core/java/android/view/textclassifier/ConversationActions.java @@ -149,7 +149,7 @@ public final class ConversationActions implements Parcelable { } private Message(Parcel in) { - mAuthor = in.readParcelable(null, android.app.Person.class); + mAuthor = in.readParcelable(null); mReferenceTime = in.readInt() == 0 ? null @@ -331,13 +331,13 @@ public final class ConversationActions implements Parcelable { private static Request readFromParcel(Parcel in) { List conversation = new ArrayList<>(); - in.readParcelableList(conversation, null, android.view.textclassifier.ConversationActions.Message.class); - TextClassifier.EntityConfig typeConfig = in.readParcelable(null, android.view.textclassifier.TextClassifier.EntityConfig.class); + in.readParcelableList(conversation, null); + TextClassifier.EntityConfig typeConfig = in.readParcelable(null); int maxSuggestions = in.readInt(); List hints = new ArrayList<>(); in.readStringList(hints); Bundle extras = in.readBundle(); - SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null); Request request = new Request( conversation, diff --git a/core/java/android/view/textclassifier/SelectionEvent.java b/core/java/android/view/textclassifier/SelectionEvent.java index b34701082b80e..858825b1d5acc 100644 --- a/core/java/android/view/textclassifier/SelectionEvent.java +++ b/core/java/android/view/textclassifier/SelectionEvent.java @@ -172,7 +172,7 @@ public final class SelectionEvent implements Parcelable { mEnd = in.readInt(); mSmartStart = in.readInt(); mSmartEnd = in.readInt(); - mSystemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + mSystemTcMetadata = in.readParcelable(null); } @Override diff --git a/core/java/android/view/textclassifier/TextClassification.java b/core/java/android/view/textclassifier/TextClassification.java index 8b04d35734eca..7db35d4bf8b5d 100644 --- a/core/java/android/view/textclassifier/TextClassification.java +++ b/core/java/android/view/textclassifier/TextClassification.java @@ -713,12 +713,12 @@ public final class TextClassification implements Parcelable { final CharSequence text = in.readCharSequence(); final int startIndex = in.readInt(); final int endIndex = in.readInt(); - final LocaleList defaultLocales = in.readParcelable(null, android.os.LocaleList.class); + final LocaleList defaultLocales = in.readParcelable(null); final String referenceTimeString = in.readString(); final ZonedDateTime referenceTime = referenceTimeString == null ? null : ZonedDateTime.parse(referenceTimeString); final Bundle extras = in.readBundle(); - final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null); final Request request = new Request(text, startIndex, endIndex, defaultLocales, referenceTime, extras); diff --git a/core/java/android/view/textclassifier/TextClassificationContext.java b/core/java/android/view/textclassifier/TextClassificationContext.java index 3a50809ea8b4e..5d5683f7110ec 100644 --- a/core/java/android/view/textclassifier/TextClassificationContext.java +++ b/core/java/android/view/textclassifier/TextClassificationContext.java @@ -159,7 +159,7 @@ public final class TextClassificationContext implements Parcelable { mPackageName = in.readString(); mWidgetType = in.readString(); mWidgetVersion = in.readString(); - mSystemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + mSystemTcMetadata = in.readParcelable(null); } public static final @android.annotation.NonNull Parcelable.Creator CREATOR = diff --git a/core/java/android/view/textclassifier/TextClassifierEvent.java b/core/java/android/view/textclassifier/TextClassifierEvent.java index 195565c5bc09d..90667cf54f930 100644 --- a/core/java/android/view/textclassifier/TextClassifierEvent.java +++ b/core/java/android/view/textclassifier/TextClassifierEvent.java @@ -189,7 +189,7 @@ public abstract class TextClassifierEvent implements Parcelable { mEventCategory = in.readInt(); mEventType = in.readInt(); mEntityTypes = in.readStringArray(); - mEventContext = in.readParcelable(null, android.view.textclassifier.TextClassificationContext.class); + mEventContext = in.readParcelable(null); mResultId = in.readString(); mEventIndex = in.readInt(); int scoresLength = in.readInt(); diff --git a/core/java/android/view/textclassifier/TextLanguage.java b/core/java/android/view/textclassifier/TextLanguage.java index 67167c6d3e65f..604979b1ac78b 100644 --- a/core/java/android/view/textclassifier/TextLanguage.java +++ b/core/java/android/view/textclassifier/TextLanguage.java @@ -295,7 +295,7 @@ public final class TextLanguage implements Parcelable { private static Request readFromParcel(Parcel in) { final CharSequence text = in.readCharSequence(); final Bundle extra = in.readBundle(); - final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null); final Request request = new Request(text, extra); request.setSystemTextClassifierMetadata(systemTcMetadata); diff --git a/core/java/android/view/textclassifier/TextLinks.java b/core/java/android/view/textclassifier/TextLinks.java index 445e9ecff54fd..dea3a9010b186 100644 --- a/core/java/android/view/textclassifier/TextLinks.java +++ b/core/java/android/view/textclassifier/TextLinks.java @@ -558,13 +558,13 @@ public final class TextLinks implements Parcelable { private static Request readFromParcel(Parcel in) { final String text = in.readString(); - final LocaleList defaultLocales = in.readParcelable(null, android.os.LocaleList.class); - final EntityConfig entityConfig = in.readParcelable(null, android.view.textclassifier.TextClassifier.EntityConfig.class); + final LocaleList defaultLocales = in.readParcelable(null); + final EntityConfig entityConfig = in.readParcelable(null); final Bundle extras = in.readBundle(); final String referenceTimeString = in.readString(); final ZonedDateTime referenceTime = referenceTimeString == null ? null : ZonedDateTime.parse(referenceTimeString); - final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null); final Request request = new Request(text, defaultLocales, entityConfig, /* legacyFallback= */ true, referenceTime, extras); diff --git a/core/java/android/view/textclassifier/TextSelection.java b/core/java/android/view/textclassifier/TextSelection.java index dda0fcdd44fd9..c1913f69546cb 100644 --- a/core/java/android/view/textclassifier/TextSelection.java +++ b/core/java/android/view/textclassifier/TextSelection.java @@ -489,9 +489,9 @@ public final class TextSelection implements Parcelable { final CharSequence text = in.readCharSequence(); final int startIndex = in.readInt(); final int endIndex = in.readInt(); - final LocaleList defaultLocales = in.readParcelable(null, android.os.LocaleList.class); + final LocaleList defaultLocales = in.readParcelable(null); final Bundle extras = in.readBundle(); - final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null, android.view.textclassifier.SystemTextClassifierMetadata.class); + final SystemTextClassifierMetadata systemTcMetadata = in.readParcelable(null); final boolean includeTextClassification = in.readBoolean(); final Request request = new Request(text, startIndex, endIndex, defaultLocales, @@ -548,6 +548,6 @@ public final class TextSelection implements Parcelable { mEntityConfidence = EntityConfidence.CREATOR.createFromParcel(in); mId = in.readString(); mExtras = in.readBundle(); - mTextClassification = in.readParcelable(TextClassification.class.getClassLoader(), android.view.textclassifier.TextClassification.class); + mTextClassification = in.readParcelable(TextClassification.class.getClassLoader()); } } diff --git a/core/java/android/view/translation/TranslationRequest.java b/core/java/android/view/translation/TranslationRequest.java index 027edc21389fe..0d41851ca7044 100644 --- a/core/java/android/view/translation/TranslationRequest.java +++ b/core/java/android/view/translation/TranslationRequest.java @@ -255,9 +255,9 @@ public final class TranslationRequest implements Parcelable { int flags = in.readInt(); List translationRequestValues = new ArrayList<>(); - in.readParcelableList(translationRequestValues, TranslationRequestValue.class.getClassLoader(), android.view.translation.TranslationRequestValue.class); + in.readParcelableList(translationRequestValues, TranslationRequestValue.class.getClassLoader()); List viewTranslationRequests = new ArrayList<>(); - in.readParcelableList(viewTranslationRequests, ViewTranslationRequest.class.getClassLoader(), android.view.translation.ViewTranslationRequest.class); + in.readParcelableList(viewTranslationRequests, ViewTranslationRequest.class.getClassLoader()); this.mFlags = flags; diff --git a/core/java/android/view/translation/TranslationSpec.java b/core/java/android/view/translation/TranslationSpec.java index 76dda5fbe83b7..efc3d8ba8096c 100644 --- a/core/java/android/view/translation/TranslationSpec.java +++ b/core/java/android/view/translation/TranslationSpec.java @@ -64,7 +64,7 @@ public final class TranslationSpec implements Parcelable { } static ULocale unparcelLocale(Parcel in) { - return (ULocale) in.readSerializable(android.icu.util.ULocale.class.getClassLoader(), android.icu.util.ULocale.class); + return (ULocale) in.readSerializable(); } /** diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java index e243aae81da4e..51869d4e04d51 100644 --- a/core/java/android/widget/ExpandableListView.java +++ b/core/java/android/widget/ExpandableListView.java @@ -1309,7 +1309,7 @@ public class ExpandableListView extends ListView { private SavedState(Parcel in) { super(in); expandedGroupMetadataList = new ArrayList(); - in.readList(expandedGroupMetadataList, ExpandableListConnector.class.getClassLoader(), android.widget.ExpandableListConnector.GroupMetadata.class); + in.readList(expandedGroupMetadataList, ExpandableListConnector.class.getClassLoader()); } @Override diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java index b21d08c8e6648..e60f9a6487308 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -1489,7 +1489,7 @@ public class RemoteViews implements Parcelable, Filter { SetRippleDrawableColor(Parcel parcel) { viewId = parcel.readInt(); - mColorStateList = parcel.readParcelable(null, android.content.res.ColorStateList.class); + mColorStateList = parcel.readParcelable(null); } public void writeToParcel(Parcel dest, int flags) { diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java b/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java index d709acfc28721..6f83bf3224a88 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCapInfo.java @@ -89,6 +89,6 @@ public class OptionsCapInfo implements Parcelable { public void readFromParcel(Parcel source) { mSdp = source.readString(); - mCapInfo = source.readParcelable(CapInfo.class.getClassLoader(), com.android.ims.internal.uce.common.CapInfo.class); + mCapInfo = source.readParcelable(CapInfo.class.getClassLoader()); } } \ No newline at end of file diff --git a/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java b/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java index 559d61b20d8ca..461f8bfb48c85 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsCmdStatus.java @@ -147,8 +147,8 @@ public class OptionsCmdStatus implements Parcelable { /** @hide */ public void readFromParcel(Parcel source) { mUserData = source.readInt(); - mCmdId = source.readParcelable(OptionsCmdId.class.getClassLoader(), com.android.ims.internal.uce.options.OptionsCmdId.class); - mStatus = source.readParcelable(StatusCode.class.getClassLoader(), com.android.ims.internal.uce.common.StatusCode.class); - mCapInfo = source.readParcelable(CapInfo.class.getClassLoader(), com.android.ims.internal.uce.common.CapInfo.class); + mCmdId = source.readParcelable(OptionsCmdId.class.getClassLoader()); + mStatus = source.readParcelable(StatusCode.class.getClassLoader()); + mCapInfo = source.readParcelable(CapInfo.class.getClassLoader()); } } \ No newline at end of file diff --git a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java index 160f9ebaebc8d..32420816f5ab2 100644 --- a/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java +++ b/core/java/com/android/ims/internal/uce/options/OptionsSipResponse.java @@ -180,7 +180,7 @@ public class OptionsSipResponse implements Parcelable { mRequestId = source.readInt(); mSipResponseCode = source.readInt(); mReasonPhrase = source.readString(); - mCmdId = source.readParcelable(OptionsCmdId.class.getClassLoader(), com.android.ims.internal.uce.options.OptionsCmdId.class); + mCmdId = source.readParcelable(OptionsCmdId.class.getClassLoader()); mRetryAfter = source.readInt(); mReasonHeader = source.readString(); } diff --git a/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java b/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java index f0ee5f3bb77d7..ec8b6bfa4ef30 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCapInfo.java @@ -105,6 +105,6 @@ public class PresCapInfo implements Parcelable { /** @hide */ public void readFromParcel(Parcel source) { mContactUri = source.readString(); - mCapInfo = source.readParcelable(CapInfo.class.getClassLoader(), com.android.ims.internal.uce.common.CapInfo.class); + mCapInfo = source.readParcelable(CapInfo.class.getClassLoader()); } } diff --git a/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java b/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java index 8fbb000c20f5e..7e22106f3be3f 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java +++ b/core/java/com/android/ims/internal/uce/presence/PresCmdStatus.java @@ -146,8 +146,8 @@ public class PresCmdStatus implements Parcelable{ public void readFromParcel(Parcel source) { mUserData = source.readInt(); mRequestId = source.readInt(); - mCmdId = source.readParcelable(PresCmdId.class.getClassLoader(), com.android.ims.internal.uce.presence.PresCmdId.class); - mStatus = source.readParcelable(StatusCode.class.getClassLoader(), com.android.ims.internal.uce.common.StatusCode.class); + mCmdId = source.readParcelable(PresCmdId.class.getClassLoader()); + mStatus = source.readParcelable(StatusCode.class.getClassLoader()); } } \ No newline at end of file diff --git a/core/java/com/android/ims/internal/uce/presence/PresResInfo.java b/core/java/com/android/ims/internal/uce/presence/PresResInfo.java index 954c2b61c286d..2f797b41b14fd 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresResInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresResInfo.java @@ -122,6 +122,6 @@ public class PresResInfo implements Parcelable { public void readFromParcel(Parcel source) { mResUri = source.readString(); mDisplayName = source.readString(); - mInstanceInfo = source.readParcelable(PresResInstanceInfo.class.getClassLoader(), com.android.ims.internal.uce.presence.PresResInstanceInfo.class); + mInstanceInfo = source.readParcelable(PresResInstanceInfo.class.getClassLoader()); } } \ No newline at end of file diff --git a/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java b/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java index 63247dbd81722..e33aa1303886d 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java +++ b/core/java/com/android/ims/internal/uce/presence/PresRlmiInfo.java @@ -236,7 +236,7 @@ public class PresRlmiInfo implements Parcelable { mListName = source.readString(); mRequestId = source.readInt(); mPresSubscriptionState = source.readParcelable( - PresSubscriptionState.class.getClassLoader(), com.android.ims.internal.uce.presence.PresSubscriptionState.class); + PresSubscriptionState.class.getClassLoader()); mSubscriptionExpireTime = source.readInt(); mSubscriptionTerminatedReason = source.readString(); } diff --git a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java index 8097a3797556c..5e394efed2946 100644 --- a/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java +++ b/core/java/com/android/ims/internal/uce/presence/PresSipResponse.java @@ -185,7 +185,7 @@ public class PresSipResponse implements Parcelable { mRequestId = source.readInt(); mSipResponseCode = source.readInt(); mReasonPhrase = source.readString(); - mCmdId = source.readParcelable(PresCmdId.class.getClassLoader(), com.android.ims.internal.uce.presence.PresCmdId.class); + mCmdId = source.readParcelable(PresCmdId.class.getClassLoader()); mRetryAfter = source.readInt(); mReasonHeader = source.readString(); } diff --git a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java index 301de2d3529e9..9c3c22451c5a3 100644 --- a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java +++ b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java @@ -237,12 +237,12 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable { private DisplayResolveInfo(Parcel in) { mDisplayLabel = in.readCharSequence(); mExtendedInfo = in.readCharSequence(); - mResolvedIntent = in.readParcelable(null /* ClassLoader */, android.content.Intent.class); + mResolvedIntent = in.readParcelable(null /* ClassLoader */); mSourceIntents.addAll( Arrays.asList((Intent[]) in.readParcelableArray(null /* ClassLoader */, Intent.class))); mIsSuspended = in.readBoolean(); mPinned = in.readBoolean(); - mResolveInfo = in.readParcelable(null /* ClassLoader */, android.content.pm.ResolveInfo.class); + mResolveInfo = in.readParcelable(null /* ClassLoader */); } } diff --git a/core/java/com/android/internal/net/LegacyVpnInfo.java b/core/java/com/android/internal/net/LegacyVpnInfo.java index b3bc93a058cf6..43984b59378cb 100644 --- a/core/java/com/android/internal/net/LegacyVpnInfo.java +++ b/core/java/com/android/internal/net/LegacyVpnInfo.java @@ -69,7 +69,7 @@ public class LegacyVpnInfo implements Parcelable { LegacyVpnInfo info = new LegacyVpnInfo(); info.key = in.readString(); info.state = in.readInt(); - info.intent = in.readParcelable(null, android.app.PendingIntent.class); + info.intent = in.readParcelable(null); return info; } diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java index b579be03acbd2..2ae56f8089727 100644 --- a/core/java/com/android/internal/net/VpnConfig.java +++ b/core/java/com/android/internal/net/VpnConfig.java @@ -208,7 +208,7 @@ public class VpnConfig implements Parcelable { config.searchDomains = in.createStringArrayList(); config.allowedApplications = in.createStringArrayList(); config.disallowedApplications = in.createStringArrayList(); - config.configureIntent = in.readParcelable(null, android.app.PendingIntent.class); + config.configureIntent = in.readParcelable(null); config.startTime = in.readLong(); config.legacy = in.readInt() != 0; config.blocking = in.readInt() != 0; @@ -217,7 +217,7 @@ public class VpnConfig implements Parcelable { config.allowIPv6 = in.readInt() != 0; config.isMetered = in.readInt() != 0; config.underlyingNetworks = in.createTypedArray(Network.CREATOR); - config.proxyInfo = in.readParcelable(null, android.net.ProxyInfo.class); + config.proxyInfo = in.readParcelable(null); return config; } diff --git a/core/java/com/android/internal/net/VpnProfile.java b/core/java/com/android/internal/net/VpnProfile.java index 519faa8456ccc..d8dc1436128e3 100644 --- a/core/java/com/android/internal/net/VpnProfile.java +++ b/core/java/com/android/internal/net/VpnProfile.java @@ -182,9 +182,9 @@ public final class VpnProfile implements Cloneable, Parcelable { ipsecCaCert = in.readString(); ipsecServerCert = in.readString(); saveLogin = in.readInt() != 0; - proxy = in.readParcelable(null, android.net.ProxyInfo.class); + proxy = in.readParcelable(null); mAllowedAlgorithms = new ArrayList<>(); - in.readList(mAllowedAlgorithms, null, java.lang.String.class); + in.readList(mAllowedAlgorithms, null); isBypassable = in.readBoolean(); isMetered = in.readBoolean(); maxMtu = in.readInt(); diff --git a/core/java/com/android/internal/os/AppFuseMount.java b/core/java/com/android/internal/os/AppFuseMount.java index 5404fea686720..04d72117d28ad 100644 --- a/core/java/com/android/internal/os/AppFuseMount.java +++ b/core/java/com/android/internal/os/AppFuseMount.java @@ -57,7 +57,7 @@ public class AppFuseMount implements Parcelable { new Parcelable.Creator() { @Override public AppFuseMount createFromParcel(Parcel in) { - return new AppFuseMount(in.readInt(), in.readParcelable(null, android.os.ParcelFileDescriptor.class)); + return new AppFuseMount(in.readInt(), in.readParcelable(null)); } @Override diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java index 4f80afaab6960..1d626235c4d2b 100644 --- a/core/java/com/android/internal/statusbar/StatusBarIcon.java +++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java @@ -81,9 +81,9 @@ public class StatusBarIcon implements Parcelable { } public void readFromParcel(Parcel in) { - this.icon = (Icon) in.readParcelable(null, android.graphics.drawable.Icon.class); + this.icon = (Icon) in.readParcelable(null); this.pkg = in.readString(); - this.user = (UserHandle) in.readParcelable(null, android.os.UserHandle.class); + this.user = (UserHandle) in.readParcelable(null); this.iconLevel = in.readInt(); this.visible = in.readInt() != 0; this.number = in.readInt(); diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java index d3c3917cd7910..f46223ac8769c 100644 --- a/core/java/com/android/internal/util/ScreenshotHelper.java +++ b/core/java/com/android/internal/util/ScreenshotHelper.java @@ -71,11 +71,11 @@ public class ScreenshotHelper { if (in.readInt() == 1) { mBitmapBundle = in.readBundle(getClass().getClassLoader()); - mBoundsInScreen = in.readParcelable(Rect.class.getClassLoader(), android.graphics.Rect.class); - mInsets = in.readParcelable(Insets.class.getClassLoader(), android.graphics.Insets.class); + mBoundsInScreen = in.readParcelable(Rect.class.getClassLoader()); + mInsets = in.readParcelable(Insets.class.getClassLoader()); mTaskId = in.readInt(); mUserId = in.readInt(); - mTopComponent = in.readParcelable(ComponentName.class.getClassLoader(), android.content.ComponentName.class); + mTopComponent = in.readParcelable(ComponentName.class.getClassLoader()); } } diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java index 2c94820d50c10..ecdd4b616e0fd 100644 --- a/location/java/android/location/GnssMeasurement.java +++ b/location/java/android/location/GnssMeasurement.java @@ -1860,7 +1860,7 @@ public final class GnssMeasurement implements Parcelable { gnssMeasurement.mSatelliteInterSignalBiasUncertaintyNanos = parcel.readDouble(); if (gnssMeasurement.hasSatellitePvt()) { ClassLoader classLoader = getClass().getClassLoader(); - gnssMeasurement.mSatellitePvt = parcel.readParcelable(classLoader, android.location.SatellitePvt.class); + gnssMeasurement.mSatellitePvt = parcel.readParcelable(classLoader); } if (gnssMeasurement.hasCorrelationVectors()) { CorrelationVector[] correlationVectorsArray = diff --git a/location/java/android/location/GnssMeasurementsEvent.java b/location/java/android/location/GnssMeasurementsEvent.java index b744017027b76..a07a64acb6e66 100644 --- a/location/java/android/location/GnssMeasurementsEvent.java +++ b/location/java/android/location/GnssMeasurementsEvent.java @@ -156,7 +156,7 @@ public final class GnssMeasurementsEvent implements Parcelable { public GnssMeasurementsEvent createFromParcel(Parcel in) { ClassLoader classLoader = getClass().getClassLoader(); - GnssClock clock = in.readParcelable(classLoader, android.location.GnssClock.class); + GnssClock clock = in.readParcelable(classLoader); int measurementsLength = in.readInt(); GnssMeasurement[] measurementsArray = new GnssMeasurement[measurementsLength]; diff --git a/location/java/android/location/GpsMeasurementsEvent.java b/location/java/android/location/GpsMeasurementsEvent.java index 6b834f324839a..f3feb7a4c7b67 100644 --- a/location/java/android/location/GpsMeasurementsEvent.java +++ b/location/java/android/location/GpsMeasurementsEvent.java @@ -112,7 +112,7 @@ public class GpsMeasurementsEvent implements Parcelable { public GpsMeasurementsEvent createFromParcel(Parcel in) { ClassLoader classLoader = getClass().getClassLoader(); - GpsClock clock = in.readParcelable(classLoader, android.location.GpsClock.class); + GpsClock clock = in.readParcelable(classLoader); int measurementsLength = in.readInt(); GpsMeasurement[] measurementsArray = new GpsMeasurement[measurementsLength]; diff --git a/location/java/android/location/GpsNavigationMessageEvent.java b/location/java/android/location/GpsNavigationMessageEvent.java index b37fe3dfb7921..2d5d6ebd59900 100644 --- a/location/java/android/location/GpsNavigationMessageEvent.java +++ b/location/java/android/location/GpsNavigationMessageEvent.java @@ -92,7 +92,7 @@ public class GpsNavigationMessageEvent implements Parcelable { @Override public GpsNavigationMessageEvent createFromParcel(Parcel in) { ClassLoader classLoader = getClass().getClassLoader(); - GpsNavigationMessage navigationMessage = in.readParcelable(classLoader, android.location.GpsNavigationMessage.class); + GpsNavigationMessage navigationMessage = in.readParcelable(classLoader); return new GpsNavigationMessageEvent(navigationMessage); } diff --git a/location/java/android/location/SatellitePvt.java b/location/java/android/location/SatellitePvt.java index aa43cfd8711cc..794a8d0731f9b 100644 --- a/location/java/android/location/SatellitePvt.java +++ b/location/java/android/location/SatellitePvt.java @@ -465,9 +465,9 @@ public final class SatellitePvt implements Parcelable { public SatellitePvt createFromParcel(Parcel in) { int flags = in.readInt(); ClassLoader classLoader = getClass().getClassLoader(); - PositionEcef positionEcef = in.readParcelable(classLoader, android.location.SatellitePvt.PositionEcef.class); - VelocityEcef velocityEcef = in.readParcelable(classLoader, android.location.SatellitePvt.VelocityEcef.class); - ClockInfo clockInfo = in.readParcelable(classLoader, android.location.SatellitePvt.ClockInfo.class); + PositionEcef positionEcef = in.readParcelable(classLoader); + VelocityEcef velocityEcef = in.readParcelable(classLoader); + ClockInfo clockInfo = in.readParcelable(classLoader); double ionoDelayMeters = in.readDouble(); double tropoDelayMeters = in.readDouble(); diff --git a/media/java/android/media/MediaDescription.java b/media/java/android/media/MediaDescription.java index dece6bdbb35f2..458562afb6eff 100644 --- a/media/java/android/media/MediaDescription.java +++ b/media/java/android/media/MediaDescription.java @@ -142,10 +142,10 @@ public class MediaDescription implements Parcelable { mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); - mIcon = in.readParcelable(null, android.graphics.Bitmap.class); - mIconUri = in.readParcelable(null, android.net.Uri.class); + mIcon = in.readParcelable(null); + mIconUri = in.readParcelable(null); mExtras = in.readBundle(); - mMediaUri = in.readParcelable(null, android.net.Uri.class); + mMediaUri = in.readParcelable(null); } /** diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java index 2427fa64562d3..9c9e83b0987d8 100644 --- a/media/java/android/media/MediaRoute2Info.java +++ b/media/java/android/media/MediaRoute2Info.java @@ -371,7 +371,7 @@ public final class MediaRoute2Info implements Parcelable { mFeatures = in.createStringArrayList(); mType = in.readInt(); mIsSystem = in.readBoolean(); - mIconUri = in.readParcelable(null, android.net.Uri.class); + mIconUri = in.readParcelable(null); mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); mConnectionState = in.readInt(); mClientPackageName = in.readString(); diff --git a/media/java/android/media/midi/MidiDeviceStatus.java b/media/java/android/media/midi/MidiDeviceStatus.java index aa0626742ac2d..b11827966b1a4 100644 --- a/media/java/android/media/midi/MidiDeviceStatus.java +++ b/media/java/android/media/midi/MidiDeviceStatus.java @@ -115,7 +115,7 @@ public final class MidiDeviceStatus implements Parcelable { new Parcelable.Creator() { public MidiDeviceStatus createFromParcel(Parcel in) { ClassLoader classLoader = MidiDeviceInfo.class.getClassLoader(); - MidiDeviceInfo deviceInfo = in.readParcelable(classLoader, android.media.midi.MidiDeviceInfo.class); + MidiDeviceInfo deviceInfo = in.readParcelable(classLoader); boolean[] inputPortOpen = in.createBooleanArray(); int[] outputPortOpenCount = in.createIntArray(); return new MidiDeviceStatus(deviceInfo, inputPortOpen, outputPortOpenCount); diff --git a/media/java/android/media/musicrecognition/RecognitionRequest.java b/media/java/android/media/musicrecognition/RecognitionRequest.java index b8757a351e246..3298d634d3426 100644 --- a/media/java/android/media/musicrecognition/RecognitionRequest.java +++ b/media/java/android/media/musicrecognition/RecognitionRequest.java @@ -152,8 +152,8 @@ public final class RecognitionRequest implements Parcelable { } private RecognitionRequest(Parcel in) { - mAudioFormat = in.readParcelable(AudioFormat.class.getClassLoader(), android.media.AudioFormat.class); - mAudioAttributes = in.readParcelable(AudioAttributes.class.getClassLoader(), android.media.AudioAttributes.class); + mAudioFormat = in.readParcelable(AudioFormat.class.getClassLoader()); + mAudioAttributes = in.readParcelable(AudioAttributes.class.getClassLoader()); mCaptureSession = in.readInt(); mMaxAudioLengthSeconds = in.readInt(); mIgnoreBeginningFrames = in.readInt(); diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java index 955ae3ca28fb4..1da41fb87b402 100644 --- a/media/java/android/media/session/MediaController.java +++ b/media/java/android/media/session/MediaController.java @@ -1022,7 +1022,7 @@ public final class MediaController { mVolumeControl = in.readInt(); mMaxVolume = in.readInt(); mCurrentVolume = in.readInt(); - mAudioAttrs = in.readParcelable(null, android.media.AudioAttributes.class); + mAudioAttrs = in.readParcelable(null); mVolumeControlId = in.readString(); } diff --git a/media/java/android/media/tv/TvContentRatingSystemInfo.java b/media/java/android/media/tv/TvContentRatingSystemInfo.java index 947b2d67bfce4..f44ded3dbd37a 100644 --- a/media/java/android/media/tv/TvContentRatingSystemInfo.java +++ b/media/java/android/media/tv/TvContentRatingSystemInfo.java @@ -94,8 +94,8 @@ public final class TvContentRatingSystemInfo implements Parcelable { }; private TvContentRatingSystemInfo(Parcel in) { - mXmlUri = in.readParcelable(null, android.net.Uri.class); - mApplicationInfo = in.readParcelable(null, android.content.pm.ApplicationInfo.class); + mXmlUri = in.readParcelable(null); + mApplicationInfo = in.readParcelable(null); } @Override diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index e60d5378f88c4..54cb2bff55662 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -653,16 +653,16 @@ public final class TvInputInfo implements Parcelable { mType = in.readInt(); mIsHardwareInput = in.readByte() == 1; mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); - mIconUri = in.readParcelable(null, android.net.Uri.class); + mIconUri = in.readParcelable(null); mLabelResId = in.readInt(); - mIcon = in.readParcelable(null, android.graphics.drawable.Icon.class); - mIconStandby = in.readParcelable(null, android.graphics.drawable.Icon.class); - mIconDisconnected = in.readParcelable(null, android.graphics.drawable.Icon.class); + mIcon = in.readParcelable(null); + mIconStandby = in.readParcelable(null); + mIconDisconnected = in.readParcelable(null); mSetupActivity = in.readString(); mCanRecord = in.readByte() == 1; mCanPauseRecording = in.readByte() == 1; mTunerCount = in.readInt(); - mHdmiDeviceInfo = in.readParcelable(null, android.hardware.hdmi.HdmiDeviceInfo.class); + mHdmiDeviceInfo = in.readParcelable(null); mIsConnectedToHdmiSwitch = in.readByte() == 1; mHdmiConnectionRelativePosition = in.readInt(); mParentId = in.readString(); diff --git a/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java b/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java index f0ff46522d150..b06d515b3acff 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java +++ b/packages/ConnectivityT/framework-t/src/android/net/DataUsageRequest.java @@ -75,7 +75,7 @@ public final class DataUsageRequest implements Parcelable { @Override public DataUsageRequest createFromParcel(Parcel in) { int requestId = in.readInt(); - NetworkTemplate template = in.readParcelable(null, android.net.NetworkTemplate.class); + NetworkTemplate template = in.readParcelable(null); long thresholdInBytes = in.readLong(); DataUsageRequest result = new DataUsageRequest(requestId, template, thresholdInBytes); diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java index 03bb187f119f9..575c5ed968f8f 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java +++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecConfig.java @@ -267,14 +267,14 @@ public final class IpSecConfig implements Parcelable { mMode = in.readInt(); mSourceAddress = in.readString(); mDestinationAddress = in.readString(); - mNetwork = (Network) in.readParcelable(Network.class.getClassLoader(), android.net.Network.class); + mNetwork = (Network) in.readParcelable(Network.class.getClassLoader()); mSpiResourceId = in.readInt(); mEncryption = - (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class); + (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); mAuthentication = - (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class); + (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); mAuthenticatedEncryption = - (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader(), android.net.IpSecAlgorithm.class); + (IpSecAlgorithm) in.readParcelable(IpSecAlgorithm.class.getClassLoader()); mEncapType = in.readInt(); mEncapSocketResourceId = in.readInt(); mEncapRemotePort = in.readInt(); diff --git a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java b/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java index 390af82366962..732cf198a9cc1 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java +++ b/packages/ConnectivityT/framework-t/src/android/net/IpSecUdpEncapResponse.java @@ -81,7 +81,7 @@ public final class IpSecUdpEncapResponse implements Parcelable { status = in.readInt(); resourceId = in.readInt(); port = in.readInt(); - fileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader(), android.os.ParcelFileDescriptor.class); + fileDescriptor = in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); } @android.annotation.NonNull diff --git a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java b/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java index d577aa8fba541..39156343924db 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java +++ b/packages/ConnectivityT/framework-t/src/android/net/NetworkStateSnapshot.java @@ -73,9 +73,9 @@ public final class NetworkStateSnapshot implements Parcelable { /** @hide */ public NetworkStateSnapshot(@NonNull Parcel in) { - mNetwork = in.readParcelable(null, android.net.Network.class); - mNetworkCapabilities = in.readParcelable(null, android.net.NetworkCapabilities.class); - mLinkProperties = in.readParcelable(null, android.net.LinkProperties.class); + mNetwork = in.readParcelable(null); + mNetworkCapabilities = in.readParcelable(null); + mLinkProperties = in.readParcelable(null); mSubscriberId = in.readString(); mLegacyType = in.readInt(); } diff --git a/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java b/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java index 7ab53b1da8567..33f9375c03bfb 100644 --- a/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java +++ b/packages/ConnectivityT/framework-t/src/android/net/UnderlyingNetworkInfo.java @@ -60,7 +60,7 @@ public final class UnderlyingNetworkInfo implements Parcelable { mOwnerUid = in.readInt(); mIface = in.readString(); List underlyingIfaces = new ArrayList<>(); - in.readList(underlyingIfaces, null /*classLoader*/, java.lang.String.class); + in.readList(underlyingIfaces, null /*classLoader*/); mUnderlyingIfaces = Collections.unmodifiableList(underlyingIfaces); } diff --git a/telecomm/java/android/telecom/CallAudioState.java b/telecomm/java/android/telecom/CallAudioState.java index 389df80497df2..55957bd85eaac 100644 --- a/telecomm/java/android/telecom/CallAudioState.java +++ b/telecomm/java/android/telecom/CallAudioState.java @@ -259,10 +259,10 @@ public final class CallAudioState implements Parcelable { int route = source.readInt(); int supportedRouteMask = source.readInt(); BluetoothDevice activeBluetoothDevice = source.readParcelable( - ClassLoader.getSystemClassLoader(), android.bluetooth.BluetoothDevice.class); + ClassLoader.getSystemClassLoader()); List supportedBluetoothDevices = new ArrayList<>(); source.readParcelableList(supportedBluetoothDevices, - ClassLoader.getSystemClassLoader(), android.bluetooth.BluetoothDevice.class); + ClassLoader.getSystemClassLoader()); return new CallAudioState(isMuted, route, supportedRouteMask, activeBluetoothDevice, supportedBluetoothDevices); } diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 30d495942ecef..d63cdc004a3d2 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -3546,9 +3546,9 @@ public abstract class Connection extends Conferenceable { mIsBlocked = in.readByte() != 0; mIsInContacts = in.readByte() != 0; CallScreeningService.ParcelableCallResponse response - = in.readParcelable(CallScreeningService.class.getClassLoader(), android.telecom.CallScreeningService.ParcelableCallResponse.class); + = in.readParcelable(CallScreeningService.class.getClassLoader()); mCallResponse = response == null ? null : response.toCallResponse(); - mCallScreeningComponent = in.readParcelable(ComponentName.class.getClassLoader(), android.content.ComponentName.class); + mCallScreeningComponent = in.readParcelable(ComponentName.class.getClassLoader()); } @NonNull diff --git a/telecomm/java/android/telecom/ConnectionRequest.java b/telecomm/java/android/telecom/ConnectionRequest.java index 1172e1392ef82..be5fae488d5e3 100644 --- a/telecomm/java/android/telecom/ConnectionRequest.java +++ b/telecomm/java/android/telecom/ConnectionRequest.java @@ -272,17 +272,17 @@ public final class ConnectionRequest implements Parcelable { } private ConnectionRequest(Parcel in) { - mAccountHandle = in.readParcelable(getClass().getClassLoader(), android.telecom.PhoneAccountHandle.class); - mAddress = in.readParcelable(getClass().getClassLoader(), android.net.Uri.class); - mExtras = in.readParcelable(getClass().getClassLoader(), android.os.Bundle.class); + mAccountHandle = in.readParcelable(getClass().getClassLoader()); + mAddress = in.readParcelable(getClass().getClassLoader()); + mExtras = in.readParcelable(getClass().getClassLoader()); mVideoState = in.readInt(); mTelecomCallId = in.readString(); mShouldShowIncomingCallUi = in.readInt() == 1; - mRttPipeFromInCall = in.readParcelable(getClass().getClassLoader(), android.os.ParcelFileDescriptor.class); - mRttPipeToInCall = in.readParcelable(getClass().getClassLoader(), android.os.ParcelFileDescriptor.class); + mRttPipeFromInCall = in.readParcelable(getClass().getClassLoader()); + mRttPipeToInCall = in.readParcelable(getClass().getClassLoader()); mParticipants = new ArrayList(); - in.readList(mParticipants, getClass().getClassLoader(), android.net.Uri.class); + in.readList(mParticipants, getClass().getClassLoader()); mIsAdhocConference = in.readInt() == 1; } diff --git a/telecomm/java/android/telecom/DisconnectCause.java b/telecomm/java/android/telecom/DisconnectCause.java index 0f034ad6a45ee..ed7b79f627531 100644 --- a/telecomm/java/android/telecom/DisconnectCause.java +++ b/telecomm/java/android/telecom/DisconnectCause.java @@ -287,7 +287,7 @@ public final class DisconnectCause implements Parcelable { int tone = source.readInt(); int telephonyDisconnectCause = source.readInt(); int telephonyPreciseDisconnectCause = source.readInt(); - ImsReasonInfo imsReasonInfo = source.readParcelable(null, android.telephony.ims.ImsReasonInfo.class); + ImsReasonInfo imsReasonInfo = source.readParcelable(null); return new DisconnectCause(code, label, description, reason, tone, telephonyDisconnectCause, telephonyPreciseDisconnectCause, imsReasonInfo); } diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java index f412a1825e2aa..320308c9e9267 100644 --- a/telecomm/java/android/telecom/ParcelableCall.java +++ b/telecomm/java/android/telecom/ParcelableCall.java @@ -623,9 +623,9 @@ public final class ParcelableCall implements Parcelable { ClassLoader classLoader = ParcelableCall.class.getClassLoader(); String id = source.readString(); int state = source.readInt(); - DisconnectCause disconnectCause = source.readParcelable(classLoader, android.telecom.DisconnectCause.class); + DisconnectCause disconnectCause = source.readParcelable(classLoader); List cannedSmsResponses = new ArrayList<>(); - source.readList(cannedSmsResponses, classLoader, java.lang.String.class); + source.readList(cannedSmsResponses, classLoader); int capabilities = source.readInt(); int properties = source.readInt(); long connectTimeMillis = source.readLong(); @@ -633,23 +633,23 @@ public final class ParcelableCall implements Parcelable { int handlePresentation = source.readInt(); String callerDisplayName = source.readString(); int callerDisplayNamePresentation = source.readInt(); - GatewayInfo gatewayInfo = source.readParcelable(classLoader, android.telecom.GatewayInfo.class); - PhoneAccountHandle accountHandle = source.readParcelable(classLoader, android.telecom.PhoneAccountHandle.class); + GatewayInfo gatewayInfo = source.readParcelable(classLoader); + PhoneAccountHandle accountHandle = source.readParcelable(classLoader); boolean isVideoCallProviderChanged = source.readByte() == 1; IVideoProvider videoCallProvider = IVideoProvider.Stub.asInterface(source.readStrongBinder()); String parentCallId = source.readString(); List childCallIds = new ArrayList<>(); - source.readList(childCallIds, classLoader, java.lang.String.class); - StatusHints statusHints = source.readParcelable(classLoader, android.telecom.StatusHints.class); + source.readList(childCallIds, classLoader); + StatusHints statusHints = source.readParcelable(classLoader); int videoState = source.readInt(); List conferenceableCallIds = new ArrayList<>(); - source.readList(conferenceableCallIds, classLoader, java.lang.String.class); + source.readList(conferenceableCallIds, classLoader); Bundle intentExtras = source.readBundle(classLoader); Bundle extras = source.readBundle(classLoader); int supportedAudioRoutes = source.readInt(); boolean isRttCallChanged = source.readByte() == 1; - ParcelableRttCall rttCall = source.readParcelable(classLoader, android.telecom.ParcelableRttCall.class); + ParcelableRttCall rttCall = source.readParcelable(classLoader); long creationTimeMillis = source.readLong(); int callDirection = source.readInt(); int callerNumberVerificationStatus = source.readInt(); diff --git a/telecomm/java/android/telecom/ParcelableConference.java b/telecomm/java/android/telecom/ParcelableConference.java index e57c833e930e9..1f8aafbca4769 100644 --- a/telecomm/java/android/telecom/ParcelableConference.java +++ b/telecomm/java/android/telecom/ParcelableConference.java @@ -292,24 +292,24 @@ public final class ParcelableConference implements Parcelable { @Override public ParcelableConference createFromParcel(Parcel source) { ClassLoader classLoader = ParcelableConference.class.getClassLoader(); - PhoneAccountHandle phoneAccount = source.readParcelable(classLoader, android.telecom.PhoneAccountHandle.class); + PhoneAccountHandle phoneAccount = source.readParcelable(classLoader); int state = source.readInt(); int capabilities = source.readInt(); List connectionIds = new ArrayList<>(2); - source.readList(connectionIds, classLoader, java.lang.String.class); + source.readList(connectionIds, classLoader); long connectTimeMillis = source.readLong(); IVideoProvider videoCallProvider = IVideoProvider.Stub.asInterface(source.readStrongBinder()); int videoState = source.readInt(); - StatusHints statusHints = source.readParcelable(classLoader, android.telecom.StatusHints.class); + StatusHints statusHints = source.readParcelable(classLoader); Bundle extras = source.readBundle(classLoader); int properties = source.readInt(); long connectElapsedTimeMillis = source.readLong(); - Uri address = source.readParcelable(classLoader, android.net.Uri.class); + Uri address = source.readParcelable(classLoader); int addressPresentation = source.readInt(); String callerDisplayName = source.readString(); int callerDisplayNamePresentation = source.readInt(); - DisconnectCause disconnectCause = source.readParcelable(classLoader, android.telecom.DisconnectCause.class); + DisconnectCause disconnectCause = source.readParcelable(classLoader); boolean isRingbackRequested = source.readInt() == 1; int callDirection = source.readInt(); diff --git a/telecomm/java/android/telecom/ParcelableConnection.java b/telecomm/java/android/telecom/ParcelableConnection.java index 7b8333870eaf1..2b9ce9b46ad70 100644 --- a/telecomm/java/android/telecom/ParcelableConnection.java +++ b/telecomm/java/android/telecom/ParcelableConnection.java @@ -261,10 +261,10 @@ public final class ParcelableConnection implements Parcelable { public ParcelableConnection createFromParcel(Parcel source) { ClassLoader classLoader = ParcelableConnection.class.getClassLoader(); - PhoneAccountHandle phoneAccount = source.readParcelable(classLoader, android.telecom.PhoneAccountHandle.class); + PhoneAccountHandle phoneAccount = source.readParcelable(classLoader); int state = source.readInt(); int capabilities = source.readInt(); - Uri address = source.readParcelable(classLoader, android.net.Uri.class); + Uri address = source.readParcelable(classLoader); int addressPresentation = source.readInt(); String callerDisplayName = source.readString(); int callerDisplayNamePresentation = source.readInt(); @@ -274,8 +274,8 @@ public final class ParcelableConnection implements Parcelable { boolean ringbackRequested = source.readByte() == 1; boolean audioModeIsVoip = source.readByte() == 1; long connectTimeMillis = source.readLong(); - StatusHints statusHints = source.readParcelable(classLoader, android.telecom.StatusHints.class); - DisconnectCause disconnectCause = source.readParcelable(classLoader, android.telecom.DisconnectCause.class); + StatusHints statusHints = source.readParcelable(classLoader); + DisconnectCause disconnectCause = source.readParcelable(classLoader); List conferenceableConnectionIds = new ArrayList<>(); source.readStringList(conferenceableConnectionIds); Bundle extras = Bundle.setDefusable(source.readBundle(classLoader), true); diff --git a/telecomm/java/android/telecom/ParcelableRttCall.java b/telecomm/java/android/telecom/ParcelableRttCall.java index b88473a8a63bd..fbcf486151f95 100644 --- a/telecomm/java/android/telecom/ParcelableRttCall.java +++ b/telecomm/java/android/telecom/ParcelableRttCall.java @@ -46,8 +46,8 @@ public class ParcelableRttCall implements Parcelable { protected ParcelableRttCall(Parcel in) { mRttMode = in.readInt(); - mTransmitStream = in.readParcelable(ParcelFileDescriptor.class.getClassLoader(), android.os.ParcelFileDescriptor.class); - mReceiveStream = in.readParcelable(ParcelFileDescriptor.class.getClassLoader(), android.os.ParcelFileDescriptor.class); + mTransmitStream = in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); + mReceiveStream = in.readParcelable(ParcelFileDescriptor.class.getClassLoader()); } public static final @android.annotation.NonNull Creator CREATOR = new Creator() { diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.java b/telecomm/java/android/telecom/PhoneAccountSuggestion.java index d9f89d544f407..2589d9504f6de 100644 --- a/telecomm/java/android/telecom/PhoneAccountSuggestion.java +++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java @@ -84,7 +84,7 @@ public final class PhoneAccountSuggestion implements Parcelable { } private PhoneAccountSuggestion(Parcel in) { - mHandle = in.readParcelable(PhoneAccountHandle.class.getClassLoader(), android.telecom.PhoneAccountHandle.class); + mHandle = in.readParcelable(PhoneAccountHandle.class.getClassLoader()); mReason = in.readInt(); mShouldAutoSelect = in.readByte() != 0; } diff --git a/telecomm/java/android/telecom/StatusHints.java b/telecomm/java/android/telecom/StatusHints.java index 2faecc2e3468d..762c93a49022a 100644 --- a/telecomm/java/android/telecom/StatusHints.java +++ b/telecomm/java/android/telecom/StatusHints.java @@ -132,8 +132,8 @@ public final class StatusHints implements Parcelable { private StatusHints(Parcel in) { mLabel = in.readCharSequence(); - mIcon = in.readParcelable(getClass().getClassLoader(), android.graphics.drawable.Icon.class); - mExtras = in.readParcelable(getClass().getClassLoader(), android.os.Bundle.class); + mIcon = in.readParcelable(getClass().getClassLoader()); + mExtras = in.readParcelable(getClass().getClassLoader()); } @Override diff --git a/telephony/java/android/telephony/AvailableNetworkInfo.java b/telephony/java/android/telephony/AvailableNetworkInfo.java index 6d673fbc7305d..2b355ae216e37 100644 --- a/telephony/java/android/telephony/AvailableNetworkInfo.java +++ b/telephony/java/android/telephony/AvailableNetworkInfo.java @@ -185,9 +185,9 @@ public final class AvailableNetworkInfo implements Parcelable { mMccMncs = new ArrayList<>(); in.readStringList(mMccMncs); mBands = new ArrayList<>(); - in.readList(mBands, Integer.class.getClassLoader(), java.lang.Integer.class); + in.readList(mBands, Integer.class.getClassLoader()); mRadioAccessSpecifiers = new ArrayList<>(); - in.readList(mRadioAccessSpecifiers, RadioAccessSpecifier.class.getClassLoader(), android.telephony.RadioAccessSpecifier.class); + in.readList(mRadioAccessSpecifiers, RadioAccessSpecifier.class.getClassLoader()); } public AvailableNetworkInfo(int subId, int priority, @NonNull List mccMncs, diff --git a/telephony/java/android/telephony/BarringInfo.java b/telephony/java/android/telephony/BarringInfo.java index 29152f19d17d9..0aa4b5805cd68 100644 --- a/telephony/java/android/telephony/BarringInfo.java +++ b/telephony/java/android/telephony/BarringInfo.java @@ -294,8 +294,8 @@ public final class BarringInfo implements Parcelable { /** @hide */ public BarringInfo(Parcel p) { - mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader(), android.telephony.CellIdentity.class); - mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader(), android.telephony.BarringInfo.BarringServiceInfo.class); + mCellIdentity = p.readParcelable(CellIdentity.class.getClassLoader()); + mBarringServiceInfos = p.readSparseArray(BarringServiceInfo.class.getClassLoader()); } @Override diff --git a/telephony/java/android/telephony/CallAttributes.java b/telephony/java/android/telephony/CallAttributes.java index b7bef39aa2757..0c258f4b64352 100644 --- a/telephony/java/android/telephony/CallAttributes.java +++ b/telephony/java/android/telephony/CallAttributes.java @@ -53,9 +53,9 @@ public final class CallAttributes implements Parcelable { } private CallAttributes(Parcel in) { - this.mPreciseCallState = in.readParcelable(PreciseCallState.class.getClassLoader(), android.telephony.PreciseCallState.class); + this.mPreciseCallState = in.readParcelable(PreciseCallState.class.getClassLoader()); this.mNetworkType = in.readInt(); - this.mCallQuality = in.readParcelable(CallQuality.class.getClassLoader(), android.telephony.CallQuality.class); + this.mCallQuality = in.readParcelable(CallQuality.class.getClassLoader()); } // getters diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java index b4b8aee31b546..4db00cf258e5a 100644 --- a/telephony/java/android/telephony/CellIdentityLte.java +++ b/telephony/java/android/telephony/CellIdentityLte.java @@ -379,7 +379,7 @@ public final class CellIdentityLte extends CellIdentity { mBands = in.createIntArray(); mBandwidth = in.readInt(); mAdditionalPlmns = (ArraySet) in.readArraySet(null); - mCsgInfo = in.readParcelable(null, android.telephony.ClosedSubscriberGroupInfo.class); + mCsgInfo = in.readParcelable(null); updateGlobalCellId(); if (DBG) log(toString()); diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java index 90e6295abda85..13d93737f751c 100644 --- a/telephony/java/android/telephony/CellIdentityTdscdma.java +++ b/telephony/java/android/telephony/CellIdentityTdscdma.java @@ -297,7 +297,7 @@ public final class CellIdentityTdscdma extends CellIdentity { mCpid = in.readInt(); mUarfcn = in.readInt(); mAdditionalPlmns = (ArraySet) in.readArraySet(null); - mCsgInfo = in.readParcelable(null, android.telephony.ClosedSubscriberGroupInfo.class); + mCsgInfo = in.readParcelable(null); updateGlobalCellId(); if (DBG) log(toString()); diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java index 72282cdb344b4..9b463da14f162 100644 --- a/telephony/java/android/telephony/CellIdentityWcdma.java +++ b/telephony/java/android/telephony/CellIdentityWcdma.java @@ -313,7 +313,7 @@ public final class CellIdentityWcdma extends CellIdentity { mPsc = in.readInt(); mUarfcn = in.readInt(); mAdditionalPlmns = (ArraySet) in.readArraySet(null); - mCsgInfo = in.readParcelable(null, android.telephony.ClosedSubscriberGroupInfo.class); + mCsgInfo = in.readParcelable(null); updateGlobalCellId(); if (DBG) log(toString()); diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java index f5ba3abf53a5f..cd22abddd3a7e 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -326,7 +326,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa mCsiRsrq = in.readInt(); mCsiSinr = in.readInt(); mCsiCqiTableIndex = in.readInt(); - mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class); + mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader()); mSsRsrp = in.readInt(); mSsRsrq = in.readInt(); mSsSinr = in.readInt(); diff --git a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java index 837124fe89de4..957f683292f78 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationInfo.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationInfo.java @@ -105,7 +105,7 @@ public final class DataSpecificRegistrationInfo implements Parcelable { isDcNrRestricted = source.readBoolean(); isNrAvailable = source.readBoolean(); isEnDcAvailable = source.readBoolean(); - mVopsSupportInfo = source.readParcelable(VopsSupportInfo.class.getClassLoader(), android.telephony.VopsSupportInfo.class); + mVopsSupportInfo = source.readParcelable(VopsSupportInfo.class.getClassLoader()); } @Override diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java index c18443e81affe..6a807665a1034 100644 --- a/telephony/java/android/telephony/NetworkRegistrationInfo.java +++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java @@ -311,12 +311,12 @@ public final class NetworkRegistrationInfo implements Parcelable { mRejectCause = source.readInt(); mEmergencyOnly = source.readBoolean(); mAvailableServices = new ArrayList<>(); - source.readList(mAvailableServices, Integer.class.getClassLoader(), java.lang.Integer.class); - mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader(), android.telephony.CellIdentity.class); + source.readList(mAvailableServices, Integer.class.getClassLoader()); + mCellIdentity = source.readParcelable(CellIdentity.class.getClassLoader()); mVoiceSpecificInfo = source.readParcelable( - VoiceSpecificRegistrationInfo.class.getClassLoader(), android.telephony.VoiceSpecificRegistrationInfo.class); + VoiceSpecificRegistrationInfo.class.getClassLoader()); mDataSpecificInfo = source.readParcelable( - DataSpecificRegistrationInfo.class.getClassLoader(), android.telephony.DataSpecificRegistrationInfo.class); + DataSpecificRegistrationInfo.class.getClassLoader()); mNrState = source.readInt(); mRplmn = source.readString(); mIsUsingCarrierAggregation = source.readBoolean(); diff --git a/telephony/java/android/telephony/PhoneCapability.java b/telephony/java/android/telephony/PhoneCapability.java index 63e3468ac19b8..a3aaf61a6fecf 100644 --- a/telephony/java/android/telephony/PhoneCapability.java +++ b/telephony/java/android/telephony/PhoneCapability.java @@ -150,7 +150,7 @@ public final class PhoneCapability implements Parcelable { mMaxActiveDataSubscriptions = in.readInt(); mNetworkValidationBeforeSwitchSupported = in.readBoolean(); mLogicalModemList = new ArrayList<>(); - in.readList(mLogicalModemList, ModemInfo.class.getClassLoader(), android.telephony.ModemInfo.class); + in.readList(mLogicalModemList, ModemInfo.class.getClassLoader()); mDeviceNrCapabilities = in.createIntArray(); } diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index 2670b03ca8ac1..ce2f3f9245546 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -125,9 +125,9 @@ public final class PreciseDataConnectionState implements Parcelable { mId = in.readInt(); mState = in.readInt(); mNetworkType = in.readInt(); - mLinkProperties = in.readParcelable(LinkProperties.class.getClassLoader(), android.net.LinkProperties.class); + mLinkProperties = in.readParcelable(LinkProperties.class.getClassLoader()); mFailCause = in.readInt(); - mApnSetting = in.readParcelable(ApnSetting.class.getClassLoader(), android.telephony.data.ApnSetting.class); + mApnSetting = in.readParcelable(ApnSetting.class.getClassLoader()); } /** diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 70da9b95410ae..5affb62ae5cdf 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -479,7 +479,7 @@ public class ServiceState implements Parcelable { mIsEmergencyOnly = in.readInt() != 0; mArfcnRsrpBoost = in.readInt(); synchronized (mNetworkRegistrationInfos) { - in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader(), android.telephony.NetworkRegistrationInfo.class); + in.readList(mNetworkRegistrationInfos, NetworkRegistrationInfo.class.getClassLoader()); } mChannelNumber = in.readInt(); mCellBandwidths = in.createIntArray(); diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java index f74ef0fe764a1..b7bc46736e185 100644 --- a/telephony/java/android/telephony/SignalStrength.java +++ b/telephony/java/android/telephony/SignalStrength.java @@ -275,12 +275,12 @@ public class SignalStrength implements Parcelable { public SignalStrength(Parcel in) { if (DBG) log("Size of signalstrength parcel:" + in.dataSize()); - mCdma = in.readParcelable(CellSignalStrengthCdma.class.getClassLoader(), android.telephony.CellSignalStrengthCdma.class); - mGsm = in.readParcelable(CellSignalStrengthGsm.class.getClassLoader(), android.telephony.CellSignalStrengthGsm.class); - mWcdma = in.readParcelable(CellSignalStrengthWcdma.class.getClassLoader(), android.telephony.CellSignalStrengthWcdma.class); - mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader(), android.telephony.CellSignalStrengthTdscdma.class); - mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader(), android.telephony.CellSignalStrengthLte.class); - mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader(), android.telephony.CellSignalStrengthNr.class); + mCdma = in.readParcelable(CellSignalStrengthCdma.class.getClassLoader()); + mGsm = in.readParcelable(CellSignalStrengthGsm.class.getClassLoader()); + mWcdma = in.readParcelable(CellSignalStrengthWcdma.class.getClassLoader()); + mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader()); + mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader()); + mNr = in.readParcelable(CellSignalStrengthLte.class.getClassLoader()); mTimestampMillis = in.readLong(); } diff --git a/telephony/java/android/telephony/ThermalMitigationRequest.java b/telephony/java/android/telephony/ThermalMitigationRequest.java index a0676ea63711b..91ad9c3e1f515 100644 --- a/telephony/java/android/telephony/ThermalMitigationRequest.java +++ b/telephony/java/android/telephony/ThermalMitigationRequest.java @@ -100,7 +100,7 @@ public final class ThermalMitigationRequest implements Parcelable { private ThermalMitigationRequest(Parcel in) { mThermalMitigationAction = in.readInt(); - mDataThrottlingRequest = in.readParcelable(DataThrottlingRequest.class.getClassLoader(), android.telephony.DataThrottlingRequest.class); + mDataThrottlingRequest = in.readParcelable(DataThrottlingRequest.class.getClassLoader()); } /** diff --git a/telephony/java/android/telephony/VisualVoicemailSms.java b/telephony/java/android/telephony/VisualVoicemailSms.java index bec715e3b81a9..085f8823b840c 100644 --- a/telephony/java/android/telephony/VisualVoicemailSms.java +++ b/telephony/java/android/telephony/VisualVoicemailSms.java @@ -121,7 +121,7 @@ public final class VisualVoicemailSms implements Parcelable { @Override public VisualVoicemailSms createFromParcel(Parcel in) { return new Builder() - .setPhoneAccountHandle((PhoneAccountHandle) in.readParcelable(null, android.telecom.PhoneAccountHandle.class)) + .setPhoneAccountHandle((PhoneAccountHandle) in.readParcelable(null)) .setPrefix(in.readString()) .setFields(in.readBundle()) .setMessageBody(in.readString()) diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 4ff59b5686573..977fe33988d6f 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -1629,7 +1629,7 @@ public class ApnSetting implements Parcelable { .setApnName(in.readString()) .setProxyAddress(in.readString()) .setProxyPort(in.readInt()) - .setMmsc(in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class)) + .setMmsc(in.readParcelable(Uri.class.getClassLoader())) .setMmsProxyAddress(in.readString()) .setMmsProxyPort(in.readInt()) .setUser(in.readString()) diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index ae0d4e7e3b4eb..ef02589abaf81 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -241,24 +241,24 @@ public final class DataCallResponse implements Parcelable { mProtocolType = source.readInt(); mInterfaceName = source.readString(); mAddresses = new ArrayList<>(); - source.readList(mAddresses, LinkAddress.class.getClassLoader(), android.net.LinkAddress.class); + source.readList(mAddresses, LinkAddress.class.getClassLoader()); mDnsAddresses = new ArrayList<>(); - source.readList(mDnsAddresses, InetAddress.class.getClassLoader(), java.net.InetAddress.class); + source.readList(mDnsAddresses, InetAddress.class.getClassLoader()); mGatewayAddresses = new ArrayList<>(); - source.readList(mGatewayAddresses, InetAddress.class.getClassLoader(), java.net.InetAddress.class); + source.readList(mGatewayAddresses, InetAddress.class.getClassLoader()); mPcscfAddresses = new ArrayList<>(); - source.readList(mPcscfAddresses, InetAddress.class.getClassLoader(), java.net.InetAddress.class); + source.readList(mPcscfAddresses, InetAddress.class.getClassLoader()); mMtu = source.readInt(); mMtuV4 = source.readInt(); mMtuV6 = source.readInt(); mHandoverFailureMode = source.readInt(); mPduSessionId = source.readInt(); - mDefaultQos = source.readParcelable(Qos.class.getClassLoader(), android.telephony.data.Qos.class); + mDefaultQos = source.readParcelable(Qos.class.getClassLoader()); mQosBearerSessions = new ArrayList<>(); - source.readList(mQosBearerSessions, QosBearerSession.class.getClassLoader(), android.telephony.data.QosBearerSession.class); - mSliceInfo = source.readParcelable(NetworkSliceInfo.class.getClassLoader(), android.telephony.data.NetworkSliceInfo.class); + source.readList(mQosBearerSessions, QosBearerSession.class.getClassLoader()); + mSliceInfo = source.readParcelable(NetworkSliceInfo.class.getClassLoader()); mTrafficDescriptors = new ArrayList<>(); - source.readList(mTrafficDescriptors, TrafficDescriptor.class.getClassLoader(), android.telephony.data.TrafficDescriptor.class); + source.readList(mTrafficDescriptors, TrafficDescriptor.class.getClassLoader()); } /** diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java index a166a5d6404c0..ec04c1ae95227 100644 --- a/telephony/java/android/telephony/data/DataProfile.java +++ b/telephony/java/android/telephony/data/DataProfile.java @@ -107,8 +107,8 @@ public final class DataProfile implements Parcelable { private DataProfile(Parcel source) { mType = source.readInt(); - mApnSetting = source.readParcelable(ApnSetting.class.getClassLoader(), android.telephony.data.ApnSetting.class); - mTrafficDescriptor = source.readParcelable(TrafficDescriptor.class.getClassLoader(), android.telephony.data.TrafficDescriptor.class); + mApnSetting = source.readParcelable(ApnSetting.class.getClassLoader()); + mTrafficDescriptor = source.readParcelable(TrafficDescriptor.class.getClassLoader()); mPreferred = source.readBoolean(); mSetupTimestamp = source.readLong(); } diff --git a/telephony/java/android/telephony/data/Qos.java b/telephony/java/android/telephony/data/Qos.java index 9c2a3bb1e15c1..8c437c83e196d 100644 --- a/telephony/java/android/telephony/data/Qos.java +++ b/telephony/java/android/telephony/data/Qos.java @@ -136,8 +136,8 @@ public abstract class Qos { protected Qos(@NonNull Parcel source) { type = source.readInt(); - downlink = source.readParcelable(QosBandwidth.class.getClassLoader(), android.telephony.data.Qos.QosBandwidth.class); - uplink = source.readParcelable(QosBandwidth.class.getClassLoader(), android.telephony.data.Qos.QosBandwidth.class); + downlink = source.readParcelable(QosBandwidth.class.getClassLoader()); + uplink = source.readParcelable(QosBandwidth.class.getClassLoader()); } /** diff --git a/telephony/java/android/telephony/data/QosBearerFilter.java b/telephony/java/android/telephony/data/QosBearerFilter.java index 0ab7b61bd73d2..d6f0cb02f0aad 100644 --- a/telephony/java/android/telephony/data/QosBearerFilter.java +++ b/telephony/java/android/telephony/data/QosBearerFilter.java @@ -256,11 +256,11 @@ public final class QosBearerFilter implements Parcelable { private QosBearerFilter(Parcel source) { localAddresses = new ArrayList<>(); - source.readList(localAddresses, LinkAddress.class.getClassLoader(), android.net.LinkAddress.class); + source.readList(localAddresses, LinkAddress.class.getClassLoader()); remoteAddresses = new ArrayList<>(); - source.readList(remoteAddresses, LinkAddress.class.getClassLoader(), android.net.LinkAddress.class); - localPort = source.readParcelable(PortRange.class.getClassLoader(), android.telephony.data.QosBearerFilter.PortRange.class); - remotePort = source.readParcelable(PortRange.class.getClassLoader(), android.telephony.data.QosBearerFilter.PortRange.class); + source.readList(remoteAddresses, LinkAddress.class.getClassLoader()); + localPort = source.readParcelable(PortRange.class.getClassLoader()); + remotePort = source.readParcelable(PortRange.class.getClassLoader()); protocol = source.readInt(); typeOfServiceMask = source.readInt(); flowLabel = source.readLong(); diff --git a/telephony/java/android/telephony/data/QosBearerSession.java b/telephony/java/android/telephony/data/QosBearerSession.java index dd080856d450b..ffeb08a17584f 100644 --- a/telephony/java/android/telephony/data/QosBearerSession.java +++ b/telephony/java/android/telephony/data/QosBearerSession.java @@ -46,9 +46,9 @@ public final class QosBearerSession implements Parcelable{ private QosBearerSession(Parcel source) { qosBearerSessionId = source.readInt(); - qos = source.readParcelable(Qos.class.getClassLoader(), android.telephony.data.Qos.class); + qos = source.readParcelable(Qos.class.getClassLoader()); qosBearerFilterList = new ArrayList<>(); - source.readList(qosBearerFilterList, QosBearerFilter.class.getClassLoader(), android.telephony.data.QosBearerFilter.class); + source.readList(qosBearerFilterList, QosBearerFilter.class.getClassLoader()); } public int getQosBearerSessionId() { diff --git a/telephony/java/android/telephony/gba/GbaAuthRequest.java b/telephony/java/android/telephony/gba/GbaAuthRequest.java index 2c6021a18ea29..5366e9af3147f 100644 --- a/telephony/java/android/telephony/gba/GbaAuthRequest.java +++ b/telephony/java/android/telephony/gba/GbaAuthRequest.java @@ -120,7 +120,7 @@ public final class GbaAuthRequest implements Parcelable { int token = in.readInt(); int subId = in.readInt(); int appType = in.readInt(); - Uri nafUrl = in.readParcelable(GbaAuthRequest.class.getClassLoader(), android.net.Uri.class); + Uri nafUrl = in.readParcelable(GbaAuthRequest.class.getClassLoader()); int len = in.readInt(); byte[] protocol = new byte[len]; in.readByteArray(protocol); diff --git a/telephony/java/android/telephony/ims/DelegateRequest.java b/telephony/java/android/telephony/ims/DelegateRequest.java index c5c92009ee329..c322d924182a8 100644 --- a/telephony/java/android/telephony/ims/DelegateRequest.java +++ b/telephony/java/android/telephony/ims/DelegateRequest.java @@ -63,7 +63,7 @@ public final class DelegateRequest implements Parcelable { */ private DelegateRequest(Parcel in) { mFeatureTags = new ArrayList<>(); - in.readList(mFeatureTags, null /*classLoader*/, java.lang.String.class); + in.readList(mFeatureTags, null /*classLoader*/); } @Override diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java index e6d7df34f7551..8a665dc924215 100644 --- a/telephony/java/android/telephony/ims/ImsCallProfile.java +++ b/telephony/java/android/telephony/ims/ImsCallProfile.java @@ -843,7 +843,7 @@ public final class ImsCallProfile implements Parcelable { mServiceType = in.readInt(); mCallType = in.readInt(); mCallExtras = in.readBundle(); - mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader(), android.telephony.ims.ImsStreamMediaProfile.class); + mMediaProfile = in.readParcelable(ImsStreamMediaProfile.class.getClassLoader()); mEmergencyServiceCategories = in.readInt(); mEmergencyUrns = in.createStringArrayList(); mEmergencyCallRouting = in.readInt(); diff --git a/telephony/java/android/telephony/ims/ImsConferenceState.java b/telephony/java/android/telephony/ims/ImsConferenceState.java index d4d8c44196d5c..1fa5f52968e59 100644 --- a/telephony/java/android/telephony/ims/ImsConferenceState.java +++ b/telephony/java/android/telephony/ims/ImsConferenceState.java @@ -133,7 +133,7 @@ public final class ImsConferenceState implements Parcelable { for (int i = 0; i < size; ++i) { String user = in.readString(); - Bundle state = in.readParcelable(null, android.os.Bundle.class); + Bundle state = in.readParcelable(null); mParticipants.put(user, state); } } diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java index d45110772ce4c..c663e393fe061 100644 --- a/telephony/java/android/telephony/ims/ImsExternalCallState.java +++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java @@ -141,8 +141,8 @@ public final class ImsExternalCallState implements Parcelable { public ImsExternalCallState(Parcel in) { mCallId = in.readInt(); ClassLoader classLoader = ImsExternalCallState.class.getClassLoader(); - mAddress = in.readParcelable(classLoader, android.net.Uri.class); - mLocalAddress = in.readParcelable(classLoader, android.net.Uri.class); + mAddress = in.readParcelable(classLoader); + mLocalAddress = in.readParcelable(classLoader); mIsPullable = (in.readInt() != 0); mCallState = in.readInt(); mCallType = in.readInt(); diff --git a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java index b77d3063e2ccc..ccb3231526ddc 100644 --- a/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java +++ b/telephony/java/android/telephony/ims/ImsRegistrationAttributes.java @@ -153,7 +153,7 @@ public final class ImsRegistrationAttributes implements Parcelable { mTransportType = source.readInt(); mImsAttributeFlags = source.readInt(); mFeatureTags = new ArrayList<>(); - source.readList(mFeatureTags, null /*classloader*/, java.lang.String.class); + source.readList(mFeatureTags, null /*classloader*/); } /** diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java index 9f4b77e22dd72..868dea6a31218 100644 --- a/telephony/java/android/telephony/ims/ImsSsData.java +++ b/telephony/java/android/telephony/ims/ImsSsData.java @@ -365,8 +365,8 @@ public final class ImsSsData implements Parcelable { serviceClass = in.readInt(); result = in.readInt(); mSsInfo = in.createIntArray(); - mCfInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader(), android.telephony.ims.ImsCallForwardInfo.class); - mImsSsInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader(), android.telephony.ims.ImsSsInfo.class); + mCfInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader()); + mImsSsInfo = in.readParcelableList(new ArrayList<>(), this.getClass().getClassLoader()); } public static final @android.annotation.NonNull Creator CREATOR = new Creator() { diff --git a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java index 6a6c3063483e0..9c28c36521f5b 100644 --- a/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java +++ b/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java @@ -439,13 +439,13 @@ public final class RcsContactPresenceTuple implements Parcelable { } private RcsContactPresenceTuple(Parcel in) { - mContactUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mContactUri = in.readParcelable(Uri.class.getClassLoader()); mTimestamp = convertStringFormatTimeToInstant(in.readString()); mStatus = in.readString(); mServiceId = in.readString(); mServiceVersion = in.readString(); mServiceDescription = in.readString(); - mServiceCapabilities = in.readParcelable(ServiceCapabilities.class.getClassLoader(), android.telephony.ims.RcsContactPresenceTuple.ServiceCapabilities.class); + mServiceCapabilities = in.readParcelable(ServiceCapabilities.class.getClassLoader()); } @Override diff --git a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java index ea022de3bc01a..ee02564267c03 100644 --- a/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java +++ b/telephony/java/android/telephony/ims/RcsContactTerminatedReason.java @@ -37,7 +37,7 @@ public final class RcsContactTerminatedReason implements Parcelable { } private RcsContactTerminatedReason(Parcel in) { - mContactUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mContactUri = in.readParcelable(Uri.class.getClassLoader()); mReason = in.readString(); } diff --git a/telephony/java/android/telephony/ims/RcsContactUceCapability.java b/telephony/java/android/telephony/ims/RcsContactUceCapability.java index 0f1b3695270be..91121187a19a2 100644 --- a/telephony/java/android/telephony/ims/RcsContactUceCapability.java +++ b/telephony/java/android/telephony/ims/RcsContactUceCapability.java @@ -244,14 +244,14 @@ public final class RcsContactUceCapability implements Parcelable { } private RcsContactUceCapability(Parcel in) { - mContactUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mContactUri = in.readParcelable(Uri.class.getClassLoader()); mCapabilityMechanism = in.readInt(); mSourceType = in.readInt(); mRequestResult = in.readInt(); List featureTagList = new ArrayList<>(); in.readStringList(featureTagList); mFeatureTags.addAll(featureTagList); - in.readParcelableList(mPresenceTuples, RcsContactPresenceTuple.class.getClassLoader(), android.telephony.ims.RcsContactPresenceTuple.class); + in.readParcelableList(mPresenceTuples, RcsContactPresenceTuple.class.getClassLoader()); } @Override diff --git a/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java index b9ffd247f658c..af4e23476331e 100644 --- a/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java +++ b/telephony/java/android/telephony/ims/RtpHeaderExtensionType.java @@ -63,7 +63,7 @@ public final class RtpHeaderExtensionType implements Parcelable { private RtpHeaderExtensionType(Parcel in) { mLocalIdentifier = in.readInt(); - mUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mUri = in.readParcelable(Uri.class.getClassLoader()); } public static final @NonNull Creator CREATOR = diff --git a/telephony/java/android/telephony/ims/SipDelegateConfiguration.java b/telephony/java/android/telephony/ims/SipDelegateConfiguration.java index db0ae033713e3..1bf5cad49c537 100644 --- a/telephony/java/android/telephony/ims/SipDelegateConfiguration.java +++ b/telephony/java/android/telephony/ims/SipDelegateConfiguration.java @@ -573,7 +573,7 @@ public final class SipDelegateConfiguration implements Parcelable { mPrivateUserIdentifier = source.readString(); mHomeDomain = source.readString(); mImei = source.readString(); - mGruu = source.readParcelable(null, android.net.Uri.class); + mGruu = source.readParcelable(null); mSipAuthHeader = source.readString(); mSipAuthNonce = source.readString(); mServiceRouteHeader = source.readString(); diff --git a/telephony/java/android/telephony/mbms/DownloadRequest.java b/telephony/java/android/telephony/mbms/DownloadRequest.java index 81d5be8562b69..eb59f87a6c029 100644 --- a/telephony/java/android/telephony/mbms/DownloadRequest.java +++ b/telephony/java/android/telephony/mbms/DownloadRequest.java @@ -242,8 +242,8 @@ public final class DownloadRequest implements Parcelable { private DownloadRequest(Parcel in) { fileServiceId = in.readString(); - sourceUri = in.readParcelable(getClass().getClassLoader(), android.net.Uri.class); - destinationUri = in.readParcelable(getClass().getClassLoader(), android.net.Uri.class); + sourceUri = in.readParcelable(getClass().getClassLoader()); + destinationUri = in.readParcelable(getClass().getClassLoader()); subscriptionId = in.readInt(); serializedResultIntentForApp = in.readString(); version = in.readInt(); diff --git a/telephony/java/android/telephony/mbms/FileInfo.java b/telephony/java/android/telephony/mbms/FileInfo.java index ffd864ebda939..e52b2ce0c5054 100644 --- a/telephony/java/android/telephony/mbms/FileInfo.java +++ b/telephony/java/android/telephony/mbms/FileInfo.java @@ -55,7 +55,7 @@ public final class FileInfo implements Parcelable { } private FileInfo(Parcel in) { - uri = in.readParcelable(null, android.net.Uri.class); + uri = in.readParcelable(null); mimeType = in.readString(); } diff --git a/telephony/java/android/telephony/mbms/FileServiceInfo.java b/telephony/java/android/telephony/mbms/FileServiceInfo.java index 0fc3be6de9299..8777e7f59e3f0 100644 --- a/telephony/java/android/telephony/mbms/FileServiceInfo.java +++ b/telephony/java/android/telephony/mbms/FileServiceInfo.java @@ -58,7 +58,7 @@ public final class FileServiceInfo extends ServiceInfo implements Parcelable { FileServiceInfo(Parcel in) { super(in); files = new ArrayList(); - in.readList(files, FileInfo.class.getClassLoader(), android.telephony.mbms.FileInfo.class); + in.readList(files, FileInfo.class.getClassLoader()); } @Override diff --git a/telephony/java/android/telephony/mbms/ServiceInfo.java b/telephony/java/android/telephony/mbms/ServiceInfo.java index 02424ff75c822..f78e7a6e54c46 100644 --- a/telephony/java/android/telephony/mbms/ServiceInfo.java +++ b/telephony/java/android/telephony/mbms/ServiceInfo.java @@ -80,7 +80,7 @@ public class ServiceInfo { } names = new HashMap(mapCount); while (mapCount-- > 0) { - Locale locale = (java.util.Locale) in.readSerializable(java.util.Locale.class.getClassLoader(), java.util.Locale.class); + Locale locale = (java.util.Locale) in.readSerializable(); String name = in.readString(); names.put(locale, name); } @@ -91,12 +91,12 @@ public class ServiceInfo { } locales = new ArrayList(localesCount); while (localesCount-- > 0) { - Locale l = (java.util.Locale) in.readSerializable(java.util.Locale.class.getClassLoader(), java.util.Locale.class); + Locale l = (java.util.Locale) in.readSerializable(); locales.add(l); } serviceId = in.readString(); - sessionStartTime = (java.util.Date) in.readSerializable(java.util.Date.class.getClassLoader(), java.util.Date.class); - sessionEndTime = (java.util.Date) in.readSerializable(java.util.Date.class.getClassLoader(), java.util.Date.class); + sessionStartTime = (java.util.Date) in.readSerializable(); + sessionEndTime = (java.util.Date) in.readSerializable(); } /** @hide */ diff --git a/telephony/java/android/telephony/mbms/UriPathPair.java b/telephony/java/android/telephony/mbms/UriPathPair.java index 54d9d9e5284e8..9258919919b7c 100644 --- a/telephony/java/android/telephony/mbms/UriPathPair.java +++ b/telephony/java/android/telephony/mbms/UriPathPair.java @@ -48,8 +48,8 @@ public final class UriPathPair implements Parcelable { /** @hide */ private UriPathPair(Parcel in) { - mFilePathUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); - mContentUri = in.readParcelable(Uri.class.getClassLoader(), android.net.Uri.class); + mFilePathUri = in.readParcelable(Uri.class.getClassLoader()); + mContentUri = in.readParcelable(Uri.class.getClassLoader()); } public static final @android.annotation.NonNull Creator CREATOR = new Creator() { diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java index 8b49f4b4593ca..d07d77ca742ad 100644 --- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java +++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java @@ -83,7 +83,7 @@ public final class NetworkScanResult implements Parcelable { scanStatus = in.readInt(); scanError = in.readInt(); List ni = new ArrayList<>(); - in.readParcelableList(ni, Object.class.getClassLoader(), android.telephony.CellInfo.class); + in.readParcelableList(ni, Object.class.getClassLoader()); networkInfos = ni; } diff --git a/telephony/java/com/android/internal/telephony/OperatorInfo.java b/telephony/java/com/android/internal/telephony/OperatorInfo.java index 1820a1dc4d6ce..a6f0f667d0cda 100644 --- a/telephony/java/com/android/internal/telephony/OperatorInfo.java +++ b/telephony/java/com/android/internal/telephony/OperatorInfo.java @@ -189,7 +189,7 @@ public class OperatorInfo implements Parcelable { in.readString(), /*operatorAlphaLong*/ in.readString(), /*operatorAlphaShort*/ in.readString(), /*operatorNumeric*/ - (State) in.readSerializable(com.android.internal.telephony.OperatorInfo.State.class.getClassLoader(), com.android.internal.telephony.OperatorInfo.State.class), /*state*/ + (State) in.readSerializable(), /*state*/ in.readInt()); /*ran*/ return opInfo; } From b78314482d3172f5c7829e9565051c2f76cd80e6 Mon Sep 17 00:00:00 2001 From: Makoto Onuki Date: Wed, 12 Jan 2022 11:46:17 -0800 Subject: [PATCH 093/176] Add checks to detect wrong conditions when creating Applications Bug: 185177290 Test: Boot + monitor logcat Change-Id: Icd9f5e891c7b7fe32ee4144d95dd26139b87d9cf (cherry picked from commit 9b9ee9dc4b8465b351e58f6804f52379e26cb737) Merged-In:Icd9f5e891c7b7fe32ee4144d95dd26139b87d9cf --- core/java/android/app/ActivityThread.java | 6 +++++ core/java/android/app/LoadedApk.java | 33 ++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index d90010e0f7db9..7ac4bddbed579 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -4535,6 +4535,12 @@ public final class ActivityThread extends ClientTransactionHandler // we are back active so skip it. unscheduleGcIdler(); + // To investigate "duplciate Application objects" bug (b/185177290) + if (UserHandle.myUserId() != UserHandle.getUserId(data.info.applicationInfo.uid)) { + Slog.wtf(TAG, "handleCreateService called with wrong appinfo UID: myUserId=" + + UserHandle.myUserId() + " appinfo.uid=" + data.info.applicationInfo.uid); + } + LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index 77af474a04ac4..4e32e9a41869b 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -1341,15 +1341,43 @@ public final class LoadedApk { return mResources; } + /** + * Used to investigate "duplicate app objects" bug (b/185177290). + * makeApplication() should only be called on the main thread, so no synchronization should + * be needed, but syncing anyway just in case. + */ + @GuardedBy("sApplicationCache") + private static final ArrayMap sApplicationCache = new ArrayMap<>(4); + @UnsupportedAppUsage public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } - Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); + // For b/185177290. + final boolean wrongUser = + UserHandle.myUserId() != UserHandle.getUserId(mApplicationInfo.uid); + if (wrongUser) { + Slog.wtf(TAG, "makeApplication called with wrong appinfo UID: myUserId=" + + UserHandle.myUserId() + " appinfo.uid=" + mApplicationInfo.uid); + } + synchronized (sApplicationCache) { + final Application cached = sApplicationCache.get(mPackageName); + if (cached != null) { + // Looks like this is always happening for the system server, because + // the LoadedApk created in systemMain() -> attach() isn't cached properly? + if (!"android".equals(mPackageName)) { + Slog.wtf(TAG, "App instance already created for package=" + mPackageName + + " instance=" + cached); + } + // TODO Return the cached one, unles it's for the wrong user? + // For now, we just add WTF checks. + } + } + Application app = null; final String myProcessName = Process.myProcessName(); @@ -1397,6 +1425,9 @@ public final class LoadedApk { } mActivityThread.mAllApplications.add(app); mApplication = app; + synchronized (sApplicationCache) { + sApplicationCache.put(mPackageName, app); + } if (instrumentation != null) { try { From 3a56afcb749080c7a5540a6c4f96682913a72273 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Thu, 13 Jan 2022 02:43:44 +0000 Subject: [PATCH 094/176] Revert "Fix enrollment cancelation race conditions." This reverts commit c7a7ee892a9dbba3569ea39d2212fd8c100dc2af. Reason for revert: Droidfood blocking bug: 213962104 Change-Id: I370cafcac7e70febbb77a05647a3fd5d0a158abd (cherry picked from commit f4dc031e6c25e01de5efad59e6baf482abc9dd91) Merged-In:I370cafcac7e70febbb77a05647a3fd5d0a158abd --- .../android/hardware/face/FaceManager.java | 49 +- .../android/hardware/face/IFaceService.aidl | 9 +- .../fingerprint/FingerprintManager.java | 30 +- .../fingerprint/IFingerprintService.aidl | 4 +- .../biometrics/sensors/BaseClientMonitor.java | 6 +- .../sensors/BiometricScheduler.java | 423 ++++++++++++++---- .../sensors/BiometricSchedulerOperation.java | 419 ----------------- .../biometrics/sensors/Interruptable.java | 5 - .../sensors/UserAwareBiometricScheduler.java | 35 +- .../biometrics/sensors/face/FaceService.java | 15 +- .../sensors/face/ServiceProvider.java | 4 +- .../sensors/face/aidl/FaceEnrollClient.java | 3 +- .../sensors/face/aidl/FaceProvider.java | 11 +- .../biometrics/sensors/face/aidl/Sensor.java | 2 +- .../biometrics/sensors/face/hidl/Face10.java | 23 +- .../sensors/face/hidl/FaceEnrollClient.java | 3 +- .../fingerprint/FingerprintService.java | 12 +- .../sensors/fingerprint/ServiceProvider.java | 4 +- .../aidl/FingerprintEnrollClient.java | 3 +- .../fingerprint/aidl/FingerprintProvider.java | 11 +- .../sensors/fingerprint/aidl/Sensor.java | 2 +- .../fingerprint/hidl/Fingerprint21.java | 30 +- .../hidl/Fingerprint21UdfpsMock.java | 33 +- .../hidl/FingerprintEnrollClient.java | 3 +- .../BiometricSchedulerOperationTest.java | 326 -------------- .../sensors/BiometricSchedulerTest.java | 268 +++++------ .../UserAwareBiometricSchedulerTest.java | 41 +- .../sensors/face/aidl/SensorTest.java | 1 - .../sensors/face/hidl/Face10Test.java | 5 +- .../sensors/fingerprint/aidl/SensorTest.java | 1 - 30 files changed, 604 insertions(+), 1177 deletions(-) delete mode 100644 services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java delete mode 100644 services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index b97055976e3ec..56f81423db4ee 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -306,21 +306,22 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan throw new IllegalArgumentException("Must supply an enrollment callback"); } - if (cancel != null && cancel.isCanceled()) { - Slog.w(TAG, "enrollment already canceled"); - return; + if (cancel != null) { + if (cancel.isCanceled()) { + Slog.w(TAG, "enrollment already canceled"); + return; + } else { + cancel.setOnCancelListener(new OnEnrollCancelListener()); + } } if (mService != null) { try { mEnrollmentCallback = callback; Trace.beginSection("FaceManager#enroll"); - final long enrollId = mService.enroll(userId, mToken, hardwareAuthToken, - mServiceReceiver, mContext.getOpPackageName(), disabledFeatures, - previewSurface, debugConsent); - if (cancel != null) { - cancel.setOnCancelListener(new OnEnrollCancelListener(enrollId)); - } + mService.enroll(userId, mToken, hardwareAuthToken, mServiceReceiver, + mContext.getOpPackageName(), disabledFeatures, previewSurface, + debugConsent); } catch (RemoteException e) { Slog.w(TAG, "Remote exception in enroll: ", e); // Though this may not be a hardware issue, it will cause apps to give up or @@ -358,20 +359,21 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan throw new IllegalArgumentException("Must supply an enrollment callback"); } - if (cancel != null && cancel.isCanceled()) { - Slog.w(TAG, "enrollRemotely is already canceled."); - return; + if (cancel != null) { + if (cancel.isCanceled()) { + Slog.w(TAG, "enrollRemotely is already canceled."); + return; + } else { + cancel.setOnCancelListener(new OnEnrollCancelListener()); + } } if (mService != null) { try { mEnrollmentCallback = callback; Trace.beginSection("FaceManager#enrollRemotely"); - final long enrolId = mService.enrollRemotely(userId, mToken, hardwareAuthToken, - mServiceReceiver, mContext.getOpPackageName(), disabledFeatures); - if (cancel != null) { - cancel.setOnCancelListener(new OnEnrollCancelListener(enrolId)); - } + mService.enrollRemotely(userId, mToken, hardwareAuthToken, mServiceReceiver, + mContext.getOpPackageName(), disabledFeatures); } catch (RemoteException e) { Slog.w(TAG, "Remote exception in enrollRemotely: ", e); // Though this may not be a hardware issue, it will cause apps to give up or @@ -711,10 +713,10 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } } - private void cancelEnrollment(long requestId) { + private void cancelEnrollment() { if (mService != null) { try { - mService.cancelEnrollment(mToken, requestId); + mService.cancelEnrollment(mToken); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -1098,16 +1100,9 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan } private class OnEnrollCancelListener implements OnCancelListener { - private final long mAuthRequestId; - - private OnEnrollCancelListener(long id) { - mAuthRequestId = id; - } - @Override public void onCancel() { - Slog.d(TAG, "Cancel face enrollment requested for: " + mAuthRequestId); - cancelEnrollment(mAuthRequestId); + cancelEnrollment(); } } diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index 989b001ca8bf0..e9198246dee3f 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -76,16 +76,15 @@ interface IFaceService { void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId); // Start face enrollment - long enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, - String opPackageName, in int [] disabledFeatures, - in Surface previewSurface, boolean debugConsent); + void enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, + String opPackageName, in int [] disabledFeatures, in Surface previewSurface, boolean debugConsent); // Start remote face enrollment - long enrollRemotely(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, + void enrollRemotely(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, String opPackageName, in int [] disabledFeatures); // Cancel enrollment in progress - void cancelEnrollment(IBinder token, long requestId); + void cancelEnrollment(IBinder token); // Removes the specified face enrollment for the specified userId. void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver, diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index acf9427b12416..fe04e5d35784f 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -183,16 +183,9 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing } private class OnEnrollCancelListener implements OnCancelListener { - private final long mAuthRequestId; - - private OnEnrollCancelListener(long id) { - mAuthRequestId = id; - } - @Override public void onCancel() { - Slog.d(TAG, "Cancel fingerprint enrollment requested for: " + mAuthRequestId); - cancelEnrollment(mAuthRequestId); + cancelEnrollment(); } } @@ -653,19 +646,20 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing throw new IllegalArgumentException("Must supply an enrollment callback"); } - if (cancel != null && cancel.isCanceled()) { - Slog.w(TAG, "enrollment already canceled"); - return; + if (cancel != null) { + if (cancel.isCanceled()) { + Slog.w(TAG, "enrollment already canceled"); + return; + } else { + cancel.setOnCancelListener(new OnEnrollCancelListener()); + } } if (mService != null) { try { mEnrollmentCallback = callback; - final long enrollId = mService.enroll(mToken, hardwareAuthToken, userId, - mServiceReceiver, mContext.getOpPackageName(), enrollReason); - if (cancel != null) { - cancel.setOnCancelListener(new OnEnrollCancelListener(enrollId)); - } + mService.enroll(mToken, hardwareAuthToken, userId, mServiceReceiver, + mContext.getOpPackageName(), enrollReason); } catch (RemoteException e) { Slog.w(TAG, "Remote exception in enroll: ", e); // Though this may not be a hardware issue, it will cause apps to give up or try @@ -1308,9 +1302,9 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing return allSensors.isEmpty() ? null : allSensors.get(0); } - private void cancelEnrollment(long requestId) { + private void cancelEnrollment() { if (mService != null) try { - mService.cancelEnrollment(mToken, requestId); + mService.cancelEnrollment(mToken); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl index cbff8b11a72a6..ba1dc6da62a64 100644 --- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl +++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl @@ -84,11 +84,11 @@ interface IFingerprintService { void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId); // Start fingerprint enrollment - long enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver, + void enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver, String opPackageName, int enrollReason); // Cancel enrollment in progress - void cancelEnrollment(IBinder token, long requestId); + void cancelEnrollment(IBinder token); // Any errors resulting from this call will be returned to the listener void remove(IBinder token, int fingerId, int userId, IFingerprintServiceReceiver receiver, diff --git a/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java index 26bbb403f39f0..b73e91173a432 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java @@ -16,8 +16,6 @@ package com.android.server.biometrics.sensors; -import static com.android.internal.annotations.VisibleForTesting.Visibility; - import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; @@ -50,6 +48,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor * Interface that ClientMonitor holders should use to receive callbacks. */ public interface Callback { + /** * Invoked when the ClientMonitor operation has been started (e.g. reached the head of * the queue and becomes the current operation). @@ -204,8 +203,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor } /** Signals this operation has completed its lifecycle and should no longer be used. */ - @VisibleForTesting(visibility = Visibility.PACKAGE) - public void destroy() { + void destroy() { mAlreadyDone = true; if (mToken != null) { try { diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java index 1f91c4d6803e8..a358bc2bad55e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java @@ -17,14 +17,15 @@ package com.android.server.biometrics.sensors; import android.annotation.IntDef; -import android.annotation.MainThread; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; +import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.IBiometricService; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Handler; import android.os.IBinder; +import android.os.Looper; import android.os.RemoteException; import android.os.ServiceManager; import android.util.Slog; @@ -54,7 +55,6 @@ import java.util.Locale; * We currently assume (and require) that each biometric sensor have its own instance of a * {@link BiometricScheduler}. See {@link CoexCoordinator}. */ -@MainThread public class BiometricScheduler { private static final String BASE_TAG = "BiometricScheduler"; @@ -110,6 +110,123 @@ public class BiometricScheduler { } } + /** + * Contains all the necessary information for a HAL operation. + */ + @VisibleForTesting + static final class Operation { + + /** + * The operation is added to the list of pending operations and waiting for its turn. + */ + static final int STATE_WAITING_IN_QUEUE = 0; + + /** + * The operation is added to the list of pending operations, but a subsequent operation + * has been added. This state only applies to {@link Interruptable} operations. When this + * operation reaches the head of the queue, it will send ERROR_CANCELED and finish. + */ + static final int STATE_WAITING_IN_QUEUE_CANCELING = 1; + + /** + * The operation has reached the front of the queue and has started. + */ + static final int STATE_STARTED = 2; + + /** + * The operation was started, but is now canceling. Operations should wait for the HAL to + * acknowledge that the operation was canceled, at which point it finishes. + */ + static final int STATE_STARTED_CANCELING = 3; + + /** + * The operation has reached the head of the queue but is waiting for BiometricService + * to acknowledge and start the operation. + */ + static final int STATE_WAITING_FOR_COOKIE = 4; + + /** + * The {@link BaseClientMonitor.Callback} has been invoked and the client is finished. + */ + static final int STATE_FINISHED = 5; + + @IntDef({STATE_WAITING_IN_QUEUE, + STATE_WAITING_IN_QUEUE_CANCELING, + STATE_STARTED, + STATE_STARTED_CANCELING, + STATE_WAITING_FOR_COOKIE, + STATE_FINISHED}) + @Retention(RetentionPolicy.SOURCE) + @interface OperationState {} + + @NonNull final BaseClientMonitor mClientMonitor; + @Nullable final BaseClientMonitor.Callback mClientCallback; + @OperationState int mState; + + Operation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable BaseClientMonitor.Callback callback + ) { + this(clientMonitor, callback, STATE_WAITING_IN_QUEUE); + } + + protected Operation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable BaseClientMonitor.Callback callback, + @OperationState int state + ) { + mClientMonitor = clientMonitor; + mClientCallback = callback; + mState = state; + } + + public boolean isHalOperation() { + return mClientMonitor instanceof HalClientMonitor; + } + + /** + * @return true if the operation requires the HAL, and the HAL is null. + */ + public boolean isUnstartableHalOperation() { + if (isHalOperation()) { + final HalClientMonitor client = (HalClientMonitor) mClientMonitor; + if (client.getFreshDaemon() == null) { + return true; + } + } + return false; + } + + @Override + public String toString() { + return mClientMonitor + ", State: " + mState; + } + } + + /** + * Monitors an operation's cancellation. If cancellation takes too long, the watchdog will + * kill the current operation and forcibly start the next. + */ + private static final class CancellationWatchdog implements Runnable { + static final int DELAY_MS = 3000; + + final String tag; + final Operation operation; + CancellationWatchdog(String tag, Operation operation) { + this.tag = tag; + this.operation = operation; + } + + @Override + public void run() { + if (operation.mState != Operation.STATE_FINISHED) { + Slog.e(tag, "[Watchdog Triggered]: " + operation); + operation.mClientMonitor.mCallback + .onClientFinished(operation.mClientMonitor, false /* success */); + } + } + } + private static final class CrashState { static final int NUM_ENTRIES = 10; final String timestamp; @@ -146,9 +263,10 @@ public class BiometricScheduler { private final @SensorType int mSensorType; @Nullable private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher; @NonNull private final IBiometricService mBiometricService; - @NonNull protected final Handler mHandler; - @VisibleForTesting @NonNull final Deque mPendingOperations; - @VisibleForTesting @Nullable BiometricSchedulerOperation mCurrentOperation; + @NonNull protected final Handler mHandler = new Handler(Looper.getMainLooper()); + @NonNull private final InternalCallback mInternalCallback; + @VisibleForTesting @NonNull final Deque mPendingOperations; + @VisibleForTesting @Nullable Operation mCurrentOperation; @NonNull private final ArrayDeque mCrashStates; private int mTotalOperationsHandled; @@ -159,7 +277,7 @@ public class BiometricScheduler { // Internal callback, notified when an operation is complete. Notifies the requester // that the operation is complete, before performing internal scheduler work (such as // starting the next client). - private final BaseClientMonitor.Callback mInternalCallback = new BaseClientMonitor.Callback() { + public class InternalCallback implements BaseClientMonitor.Callback { @Override public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { Slog.d(getTag(), "[Started] " + clientMonitor); @@ -168,11 +286,16 @@ public class BiometricScheduler { mCoexCoordinator.addAuthenticationClient(mSensorType, (AuthenticationClient) clientMonitor); } + + if (mCurrentOperation.mClientCallback != null) { + mCurrentOperation.mClientCallback.onClientStarted(clientMonitor); + } } @Override public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) { mHandler.post(() -> { + clientMonitor.destroy(); if (mCurrentOperation == null) { Slog.e(getTag(), "[Finishing] " + clientMonitor + " but current operation is null, success: " + success @@ -180,9 +303,9 @@ public class BiometricScheduler { return; } - if (!mCurrentOperation.isFor(clientMonitor)) { + if (clientMonitor != mCurrentOperation.mClientMonitor) { Slog.e(getTag(), "[Ignoring Finish] " + clientMonitor + " does not match" - + " current: " + mCurrentOperation); + + " current: " + mCurrentOperation.mClientMonitor); return; } @@ -192,33 +315,36 @@ public class BiometricScheduler { (AuthenticationClient) clientMonitor); } + mCurrentOperation.mState = Operation.STATE_FINISHED; + + if (mCurrentOperation.mClientCallback != null) { + mCurrentOperation.mClientCallback.onClientFinished(clientMonitor, success); + } + if (mGestureAvailabilityDispatcher != null) { mGestureAvailabilityDispatcher.markSensorActive( - mCurrentOperation.getSensorId(), false /* active */); + mCurrentOperation.mClientMonitor.getSensorId(), false /* active */); } if (mRecentOperations.size() >= mRecentOperationsLimit) { mRecentOperations.remove(0); } - mRecentOperations.add(mCurrentOperation.getProtoEnum()); + mRecentOperations.add(mCurrentOperation.mClientMonitor.getProtoEnum()); mCurrentOperation = null; mTotalOperationsHandled++; startNextOperationIfIdle(); }); } - }; + } @VisibleForTesting - BiometricScheduler(@NonNull String tag, - @NonNull Handler handler, - @SensorType int sensorType, + BiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, - @NonNull IBiometricService biometricService, - int recentOperationsLimit, + @NonNull IBiometricService biometricService, int recentOperationsLimit, @NonNull CoexCoordinator coexCoordinator) { mBiometricTag = tag; - mHandler = handler; mSensorType = sensorType; + mInternalCallback = new InternalCallback(); mGestureAvailabilityDispatcher = gestureAvailabilityDispatcher; mPendingOperations = new ArrayDeque<>(); mBiometricService = biometricService; @@ -230,26 +356,24 @@ public class BiometricScheduler { /** * Creates a new scheduler. - * * @param tag for the specific instance of the scheduler. Should be unique. - * @param handler handler for callbacks (all methods of this class must be called on the - * thread associated with this handler) * @param sensorType the sensorType that this scheduler is handling. * @param gestureAvailabilityDispatcher may be null if the sensor does not support gestures * (such as fingerprint swipe). */ public BiometricScheduler(@NonNull String tag, - @NonNull Handler handler, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { - this(tag, handler, sensorType, gestureAvailabilityDispatcher, - IBiometricService.Stub.asInterface( - ServiceManager.getService(Context.BIOMETRIC_SERVICE)), - LOG_NUM_RECENT_OPERATIONS, CoexCoordinator.getInstance()); + this(tag, sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( + ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS, + CoexCoordinator.getInstance()); } - @VisibleForTesting - public BaseClientMonitor.Callback getInternalCallback() { + /** + * @return A reference to the internal callback that should be invoked whenever the scheduler + * needs to (e.g. client started, client finished). + */ + @NonNull protected InternalCallback getInternalCallback() { return mInternalCallback; } @@ -268,46 +392,72 @@ public class BiometricScheduler { } mCurrentOperation = mPendingOperations.poll(); + final BaseClientMonitor currentClient = mCurrentOperation.mClientMonitor; Slog.d(getTag(), "[Polled] " + mCurrentOperation); // If the operation at the front of the queue has been marked for cancellation, send // ERROR_CANCELED. No need to start this client. - if (mCurrentOperation.isMarkedCanceling()) { + if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "[Now Cancelling] " + mCurrentOperation); - mCurrentOperation.cancel(mHandler, mInternalCallback); + if (!(currentClient instanceof Interruptable)) { + throw new IllegalStateException("Mis-implemented client or scheduler, " + + "trying to cancel non-interruptable operation: " + mCurrentOperation); + } + + final Interruptable interruptable = (Interruptable) currentClient; + interruptable.cancelWithoutStarting(getInternalCallback()); // Now we wait for the client to send its FinishCallback, which kicks off the next // operation. return; } - if (mGestureAvailabilityDispatcher != null && mCurrentOperation.isAcquisitionOperation()) { + if (mGestureAvailabilityDispatcher != null + && mCurrentOperation.mClientMonitor instanceof AcquisitionClient) { mGestureAvailabilityDispatcher.markSensorActive( - mCurrentOperation.getSensorId(), true /* active */); + mCurrentOperation.mClientMonitor.getSensorId(), + true /* active */); } // Not all operations start immediately. BiometricPrompt waits for its operation // to arrive at the head of the queue, before pinging it to start. - final int cookie = mCurrentOperation.isReadyToStart(); - if (cookie == 0) { - if (!mCurrentOperation.start(mInternalCallback)) { + final boolean shouldStartNow = currentClient.getCookie() == 0; + if (shouldStartNow) { + if (mCurrentOperation.isUnstartableHalOperation()) { + final HalClientMonitor halClientMonitor = + (HalClientMonitor) mCurrentOperation.mClientMonitor; // Note down current length of queue final int pendingOperationsLength = mPendingOperations.size(); - final BiometricSchedulerOperation lastOperation = mPendingOperations.peekLast(); + final Operation lastOperation = mPendingOperations.peekLast(); Slog.e(getTag(), "[Unable To Start] " + mCurrentOperation + ". Last pending operation: " + lastOperation); + // For current operations, 1) unableToStart, which notifies the caller-side, then + // 2) notify operation's callback, to notify applicable system service that the + // operation failed. + halClientMonitor.unableToStart(); + if (mCurrentOperation.mClientCallback != null) { + mCurrentOperation.mClientCallback.onClientFinished( + mCurrentOperation.mClientMonitor, false /* success */); + } + // Then for each operation currently in the pending queue at the time of this // failure, do the same as above. Otherwise, it's possible that something like // setActiveUser fails, but then authenticate (for the wrong user) is invoked. for (int i = 0; i < pendingOperationsLength; i++) { - final BiometricSchedulerOperation operation = mPendingOperations.pollFirst(); - if (operation != null) { - Slog.w(getTag(), "[Aborting Operation] " + operation); - operation.abort(); - } else { + final Operation operation = mPendingOperations.pollFirst(); + if (operation == null) { Slog.e(getTag(), "Null operation, index: " + i + ", expected length: " + pendingOperationsLength); + break; } + if (operation.isHalOperation()) { + ((HalClientMonitor) operation.mClientMonitor).unableToStart(); + } + if (operation.mClientCallback != null) { + operation.mClientCallback.onClientFinished(operation.mClientMonitor, + false /* success */); + } + Slog.w(getTag(), "[Aborted Operation] " + operation); } // It's possible that during cleanup a new set of operations came in. We can try to @@ -315,20 +465,25 @@ public class BiometricScheduler { // actually be multiple operations (i.e. updateActiveUser + authenticate). mCurrentOperation = null; startNextOperationIfIdle(); + } else { + Slog.d(getTag(), "[Starting] " + mCurrentOperation); + currentClient.start(getInternalCallback()); + mCurrentOperation.mState = Operation.STATE_STARTED; } } else { try { - mBiometricService.onReadyForAuthentication(cookie); + mBiometricService.onReadyForAuthentication(currentClient.getCookie()); } catch (RemoteException e) { Slog.e(getTag(), "Remote exception when contacting BiometricService", e); } Slog.d(getTag(), "Waiting for cookie before starting: " + mCurrentOperation); + mCurrentOperation.mState = Operation.STATE_WAITING_FOR_COOKIE; } } /** * Starts the {@link #mCurrentOperation} if - * 1) its state is {@link BiometricSchedulerOperation#STATE_WAITING_FOR_COOKIE} and + * 1) its state is {@link Operation#STATE_WAITING_FOR_COOKIE} and * 2) its cookie matches this cookie * * This is currently only used by {@link com.android.server.biometrics.BiometricService}, which @@ -344,13 +499,45 @@ public class BiometricScheduler { Slog.e(getTag(), "Current operation is null"); return; } + if (mCurrentOperation.mState != Operation.STATE_WAITING_FOR_COOKIE) { + if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { + Slog.d(getTag(), "Operation was marked for cancellation, cancelling now: " + + mCurrentOperation); + // This should trigger the internal onClientFinished callback, which clears the + // operation and starts the next one. + final ErrorConsumer errorConsumer = + (ErrorConsumer) mCurrentOperation.mClientMonitor; + errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED, + 0 /* vendorCode */); + return; + } else { + Slog.e(getTag(), "Operation is in the wrong state: " + mCurrentOperation + + ", expected STATE_WAITING_FOR_COOKIE"); + return; + } + } + if (mCurrentOperation.mClientMonitor.getCookie() != cookie) { + Slog.e(getTag(), "Mismatched cookie for operation: " + mCurrentOperation + + ", received: " + cookie); + return; + } - if (mCurrentOperation.startWithCookie(mInternalCallback, cookie)) { - Slog.d(getTag(), "[Started] Prepared client: " + mCurrentOperation); - } else { + if (mCurrentOperation.isUnstartableHalOperation()) { Slog.e(getTag(), "[Unable To Start] Prepared client: " + mCurrentOperation); + // This is BiometricPrompt trying to auth but something's wrong with the HAL. + final HalClientMonitor halClientMonitor = + (HalClientMonitor) mCurrentOperation.mClientMonitor; + halClientMonitor.unableToStart(); + if (mCurrentOperation.mClientCallback != null) { + mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.mClientMonitor, + false /* success */); + } mCurrentOperation = null; startNextOperationIfIdle(); + } else { + Slog.d(getTag(), "[Starting] Prepared client: " + mCurrentOperation); + mCurrentOperation.mState = Operation.STATE_STARTED; + mCurrentOperation.mClientMonitor.start(getInternalCallback()); } } @@ -375,13 +562,17 @@ public class BiometricScheduler { // pending clients as canceling. Once they reach the head of the queue, the scheduler will // send ERROR_CANCELED and skip the operation. if (clientMonitor.interruptsPrecedingClients()) { - for (BiometricSchedulerOperation operation : mPendingOperations) { - Slog.d(getTag(), "New client, marking pending op as canceling: " + operation); - operation.markCanceling(); + for (Operation operation : mPendingOperations) { + if (operation.mClientMonitor instanceof Interruptable + && operation.mState != Operation.STATE_WAITING_IN_QUEUE_CANCELING) { + Slog.d(getTag(), "New client incoming, marking pending client as canceling: " + + operation.mClientMonitor); + operation.mState = Operation.STATE_WAITING_IN_QUEUE_CANCELING; + } } } - mPendingOperations.add(new BiometricSchedulerOperation(clientMonitor, clientCallback)); + mPendingOperations.add(new Operation(clientMonitor, clientCallback)); Slog.d(getTag(), "[Added] " + clientMonitor + ", new queue size: " + mPendingOperations.size()); @@ -389,34 +580,67 @@ public class BiometricScheduler { // cancellable, start the cancellation process. if (clientMonitor.interruptsPrecedingClients() && mCurrentOperation != null - && mCurrentOperation.isInterruptable() - && mCurrentOperation.isStarted()) { + && mCurrentOperation.mClientMonitor instanceof Interruptable + && mCurrentOperation.mState == Operation.STATE_STARTED) { Slog.d(getTag(), "[Cancelling Interruptable]: " + mCurrentOperation); - mCurrentOperation.cancel(mHandler, mInternalCallback); - } else { - startNextOperationIfIdle(); + cancelInternal(mCurrentOperation); } + + startNextOperationIfIdle(); + } + + private void cancelInternal(Operation operation) { + if (operation != mCurrentOperation) { + Slog.e(getTag(), "cancelInternal invoked on non-current operation: " + operation); + return; + } + if (!(operation.mClientMonitor instanceof Interruptable)) { + Slog.w(getTag(), "Operation not interruptable: " + operation); + return; + } + if (operation.mState == Operation.STATE_STARTED_CANCELING) { + Slog.w(getTag(), "Cancel already invoked for operation: " + operation); + return; + } + if (operation.mState == Operation.STATE_WAITING_FOR_COOKIE) { + Slog.w(getTag(), "Skipping cancellation for non-started operation: " + operation); + // We can set it to null immediately, since the HAL was never notified to start. + if (mCurrentOperation != null) { + mCurrentOperation.mClientMonitor.destroy(); + } + mCurrentOperation = null; + startNextOperationIfIdle(); + return; + } + Slog.d(getTag(), "[Cancelling] Current client: " + operation.mClientMonitor); + final Interruptable interruptable = (Interruptable) operation.mClientMonitor; + interruptable.cancel(); + operation.mState = Operation.STATE_STARTED_CANCELING; + + // Add a watchdog. If the HAL does not acknowledge within the timeout, we will + // forcibly finish this client. + mHandler.postDelayed(new CancellationWatchdog(getTag(), operation), + CancellationWatchdog.DELAY_MS); } /** * Requests to cancel enrollment. * @param token from the caller, should match the token passed in when requesting enrollment */ - public void cancelEnrollment(IBinder token, long requestId) { - Slog.d(getTag(), "cancelEnrollment, requestId: " + requestId); - - if (mCurrentOperation != null - && canCancelEnrollOperation(mCurrentOperation, token, requestId)) { - Slog.d(getTag(), "Cancelling enrollment op: " + mCurrentOperation); - mCurrentOperation.cancel(mHandler, mInternalCallback); - } else { - for (BiometricSchedulerOperation operation : mPendingOperations) { - if (canCancelEnrollOperation(operation, token, requestId)) { - Slog.d(getTag(), "Cancelling pending enrollment op: " + operation); - operation.markCanceling(); - } - } + public void cancelEnrollment(IBinder token) { + if (mCurrentOperation == null) { + Slog.e(getTag(), "Unable to cancel enrollment, null operation"); + return; } + final boolean isEnrolling = mCurrentOperation.mClientMonitor instanceof EnrollClient; + final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token; + if (!isEnrolling || !tokenMatches) { + Slog.w(getTag(), "Not cancelling enrollment, isEnrolling: " + isEnrolling + + " tokenMatches: " + tokenMatches); + return; + } + + cancelInternal(mCurrentOperation); } /** @@ -425,42 +649,62 @@ public class BiometricScheduler { * @param requestId the id returned when requesting authentication */ public void cancelAuthenticationOrDetection(IBinder token, long requestId) { - Slog.d(getTag(), "cancelAuthenticationOrDetection, requestId: " + requestId); + Slog.d(getTag(), "cancelAuthenticationOrDetection, requestId: " + requestId + + " current: " + mCurrentOperation + + " stack size: " + mPendingOperations.size()); if (mCurrentOperation != null && canCancelAuthOperation(mCurrentOperation, token, requestId)) { - Slog.d(getTag(), "Cancelling auth/detect op: " + mCurrentOperation); - mCurrentOperation.cancel(mHandler, mInternalCallback); + Slog.d(getTag(), "Cancelling: " + mCurrentOperation); + cancelInternal(mCurrentOperation); } else { - for (BiometricSchedulerOperation operation : mPendingOperations) { + // Look through the current queue for all authentication clients for the specified + // token, and mark them as STATE_WAITING_IN_QUEUE_CANCELING. Note that we're marking + // all of them, instead of just the first one, since the API surface currently doesn't + // allow us to distinguish between multiple authentication requests from the same + // process. However, this generally does not happen anyway, and would be a class of + // bugs on its own. + for (Operation operation : mPendingOperations) { if (canCancelAuthOperation(operation, token, requestId)) { - Slog.d(getTag(), "Cancelling pending auth/detect op: " + operation); - operation.markCanceling(); + Slog.d(getTag(), "Marking " + operation + + " as STATE_WAITING_IN_QUEUE_CANCELING"); + operation.mState = Operation.STATE_WAITING_IN_QUEUE_CANCELING; } } } } - private static boolean canCancelEnrollOperation(BiometricSchedulerOperation operation, - IBinder token, long requestId) { - return operation.isEnrollOperation() - && operation.isMatchingToken(token) - && operation.isMatchingRequestId(requestId); + private static boolean canCancelAuthOperation(Operation operation, IBinder token, + long requestId) { + // TODO: restrict callers that can cancel without requestId (negative value)? + return isAuthenticationOrDetectionOperation(operation) + && operation.mClientMonitor.getToken() == token + && isMatchingRequestId(operation, requestId); } - private static boolean canCancelAuthOperation(BiometricSchedulerOperation operation, - IBinder token, long requestId) { - // TODO: restrict callers that can cancel without requestId (negative value)? - return operation.isAuthenticationOrDetectionOperation() - && operation.isMatchingToken(token) - && operation.isMatchingRequestId(requestId); + // By default, monitors are not associated with a request id to retain the original + // behavior (i.e. if no requestId is explicitly set then assume it matches) + private static boolean isMatchingRequestId(Operation operation, long requestId) { + return !operation.mClientMonitor.hasRequestId() + || operation.mClientMonitor.getRequestId() == requestId; + } + + private static boolean isAuthenticationOrDetectionOperation(@NonNull Operation operation) { + final boolean isAuthentication = + operation.mClientMonitor instanceof AuthenticationConsumer; + final boolean isDetection = + operation.mClientMonitor instanceof DetectionConsumer; + return isAuthentication || isDetection; } /** * @return the current operation */ public BaseClientMonitor getCurrentClient() { - return mCurrentOperation != null ? mCurrentOperation.getClientMonitor() : null; + if (mCurrentOperation == null) { + return null; + } + return mCurrentOperation.mClientMonitor; } public int getCurrentPendingCount() { @@ -475,7 +719,7 @@ public class BiometricScheduler { new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.US); final String timestamp = dateFormat.format(new Date(System.currentTimeMillis())); final List pendingOperations = new ArrayList<>(); - for (BiometricSchedulerOperation operation : mPendingOperations) { + for (Operation operation : mPendingOperations) { pendingOperations.add(operation.toString()); } @@ -491,7 +735,7 @@ public class BiometricScheduler { pw.println("Type: " + mSensorType); pw.println("Current operation: " + mCurrentOperation); pw.println("Pending operations: " + mPendingOperations.size()); - for (BiometricSchedulerOperation operation : mPendingOperations) { + for (Operation operation : mPendingOperations) { pw.println("Pending operation: " + operation); } for (CrashState crashState : mCrashStates) { @@ -502,7 +746,7 @@ public class BiometricScheduler { public byte[] dumpProtoState(boolean clearSchedulerBuffer) { final ProtoOutputStream proto = new ProtoOutputStream(); proto.write(BiometricSchedulerProto.CURRENT_OPERATION, mCurrentOperation != null - ? mCurrentOperation.getProtoEnum() : BiometricsProto.CM_NONE); + ? mCurrentOperation.mClientMonitor.getProtoEnum() : BiometricsProto.CM_NONE); proto.write(BiometricSchedulerProto.TOTAL_OPERATIONS, mTotalOperationsHandled); if (!mRecentOperations.isEmpty()) { @@ -527,7 +771,6 @@ public class BiometricScheduler { * HAL dies. */ public void reset() { - Slog.d(getTag(), "Resetting scheduler"); mPendingOperations.clear(); mCurrentOperation = null; } diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java deleted file mode 100644 index a8cce153dc706..0000000000000 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.biometrics.sensors; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.hardware.biometrics.BiometricConstants; -import android.os.Handler; -import android.os.IBinder; -import android.util.Slog; - -import com.android.internal.annotations.VisibleForTesting; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Contains all the necessary information for a HAL operation. - */ -public class BiometricSchedulerOperation { - protected static final String TAG = "BiometricSchedulerOperation"; - - /** - * The operation is added to the list of pending operations and waiting for its turn. - */ - protected static final int STATE_WAITING_IN_QUEUE = 0; - - /** - * The operation is added to the list of pending operations, but a subsequent operation - * has been added. This state only applies to {@link Interruptable} operations. When this - * operation reaches the head of the queue, it will send ERROR_CANCELED and finish. - */ - protected static final int STATE_WAITING_IN_QUEUE_CANCELING = 1; - - /** - * The operation has reached the front of the queue and has started. - */ - protected static final int STATE_STARTED = 2; - - /** - * The operation was started, but is now canceling. Operations should wait for the HAL to - * acknowledge that the operation was canceled, at which point it finishes. - */ - protected static final int STATE_STARTED_CANCELING = 3; - - /** - * The operation has reached the head of the queue but is waiting for BiometricService - * to acknowledge and start the operation. - */ - protected static final int STATE_WAITING_FOR_COOKIE = 4; - - /** - * The {@link BaseClientMonitor.Callback} has been invoked and the client is finished. - */ - protected static final int STATE_FINISHED = 5; - - @IntDef({STATE_WAITING_IN_QUEUE, - STATE_WAITING_IN_QUEUE_CANCELING, - STATE_STARTED, - STATE_STARTED_CANCELING, - STATE_WAITING_FOR_COOKIE, - STATE_FINISHED}) - @Retention(RetentionPolicy.SOURCE) - protected @interface OperationState {} - - private static final int CANCEL_WATCHDOG_DELAY_MS = 3000; - - @NonNull - private final BaseClientMonitor mClientMonitor; - @Nullable - private final BaseClientMonitor.Callback mClientCallback; - @OperationState - private int mState; - @VisibleForTesting - @NonNull - final Runnable mCancelWatchdog; - - BiometricSchedulerOperation( - @NonNull BaseClientMonitor clientMonitor, - @Nullable BaseClientMonitor.Callback callback - ) { - this(clientMonitor, callback, STATE_WAITING_IN_QUEUE); - } - - protected BiometricSchedulerOperation( - @NonNull BaseClientMonitor clientMonitor, - @Nullable BaseClientMonitor.Callback callback, - @OperationState int state - ) { - mClientMonitor = clientMonitor; - mClientCallback = callback; - mState = state; - mCancelWatchdog = () -> { - if (!isFinished()) { - Slog.e(TAG, "[Watchdog Triggered]: " + this); - getWrappedCallback().onClientFinished(mClientMonitor, false /* success */); - } - }; - } - - /** - * Zero if this operation is ready to start or has already started. A non-zero cookie - * is returned if the operation has not started and is waiting on - * {@link android.hardware.biometrics.IBiometricService#onReadyForAuthentication(int)}. - * - * @return cookie or 0 if ready/started - */ - public int isReadyToStart() { - if (mState == STATE_WAITING_FOR_COOKIE || mState == STATE_WAITING_IN_QUEUE) { - final int cookie = mClientMonitor.getCookie(); - if (cookie != 0) { - mState = STATE_WAITING_FOR_COOKIE; - } - return cookie; - } - - return 0; - } - - /** - * Start this operation without waiting for a cookie - * (i.e. {@link #isReadyToStart() returns zero} - * - * @param callback lifecycle callback - * @return if this operation started - */ - public boolean start(@NonNull BaseClientMonitor.Callback callback) { - checkInState("start", - STATE_WAITING_IN_QUEUE, - STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); - - if (mClientMonitor.getCookie() != 0) { - throw new IllegalStateException("operation requires cookie"); - } - - return doStart(callback); - } - - /** - * Start this operation after receiving the given cookie. - * - * @param callback lifecycle callback - * @param cookie cookie indicting the operation should begin - * @return if this operation started - */ - public boolean startWithCookie(@NonNull BaseClientMonitor.Callback callback, int cookie) { - checkInState("start", - STATE_WAITING_IN_QUEUE, - STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); - - if (mClientMonitor.getCookie() != cookie) { - Slog.e(TAG, "Mismatched cookie for operation: " + this + ", received: " + cookie); - return false; - } - - return doStart(callback); - } - - private boolean doStart(@NonNull BaseClientMonitor.Callback callback) { - final BaseClientMonitor.Callback cb = getWrappedCallback(callback); - - if (mState == STATE_WAITING_IN_QUEUE_CANCELING) { - Slog.d(TAG, "Operation marked for cancellation, cancelling now: " + this); - - cb.onClientFinished(mClientMonitor, true /* success */); - if (mClientMonitor instanceof ErrorConsumer) { - final ErrorConsumer errorConsumer = (ErrorConsumer) mClientMonitor; - errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED, - 0 /* vendorCode */); - } else { - Slog.w(TAG, "monitor cancelled but does not implement ErrorConsumer"); - } - - return false; - } - - if (isUnstartableHalOperation()) { - Slog.v(TAG, "unable to start: " + this); - ((HalClientMonitor) mClientMonitor).unableToStart(); - cb.onClientFinished(mClientMonitor, false /* success */); - return false; - } - - mState = STATE_STARTED; - mClientMonitor.start(cb); - - Slog.v(TAG, "started: " + this); - return true; - } - - /** - * Abort a pending operation. - * - * This is similar to cancel but the operation must not have been started. It will - * immediately abort the operation and notify the client that it has finished unsuccessfully. - */ - public void abort() { - checkInState("cannot abort a non-pending operation", - STATE_WAITING_IN_QUEUE, - STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); - - if (isHalOperation()) { - ((HalClientMonitor) mClientMonitor).unableToStart(); - } - getWrappedCallback().onClientFinished(mClientMonitor, false /* success */); - - Slog.v(TAG, "Aborted: " + this); - } - - /** Flags this operation as canceled, but does not cancel it until started. */ - public void markCanceling() { - if (mState == STATE_WAITING_IN_QUEUE && isInterruptable()) { - mState = STATE_WAITING_IN_QUEUE_CANCELING; - Slog.v(TAG, "Marked cancelling: " + this); - } - } - - /** - * Cancel the operation now. - * - * @param handler handler to use for the cancellation watchdog - * @param callback lifecycle callback (only used if this operation hasn't started, otherwise - * the callback used from {@link #start(BaseClientMonitor.Callback)} is used) - */ - public void cancel(@NonNull Handler handler, @NonNull BaseClientMonitor.Callback callback) { - checkNotInState("cancel", STATE_FINISHED); - - final int currentState = mState; - if (!isInterruptable()) { - Slog.w(TAG, "Cannot cancel - operation not interruptable: " + this); - return; - } - if (currentState == STATE_STARTED_CANCELING) { - Slog.w(TAG, "Cannot cancel - already invoked for operation: " + this); - return; - } - - mState = STATE_STARTED_CANCELING; - if (currentState == STATE_WAITING_IN_QUEUE - || currentState == STATE_WAITING_IN_QUEUE_CANCELING - || currentState == STATE_WAITING_FOR_COOKIE) { - Slog.d(TAG, "[Cancelling] Current client (without start): " + mClientMonitor); - ((Interruptable) mClientMonitor).cancelWithoutStarting(getWrappedCallback(callback)); - } else { - Slog.d(TAG, "[Cancelling] Current client: " + mClientMonitor); - ((Interruptable) mClientMonitor).cancel(); - } - - // forcibly finish this client if the HAL does not acknowledge within the timeout - handler.postDelayed(mCancelWatchdog, CANCEL_WATCHDOG_DELAY_MS); - } - - @NonNull - private BaseClientMonitor.Callback getWrappedCallback() { - return getWrappedCallback(null); - } - - @NonNull - private BaseClientMonitor.Callback getWrappedCallback( - @Nullable BaseClientMonitor.Callback callback) { - final BaseClientMonitor.Callback destroyCallback = new BaseClientMonitor.Callback() { - @Override - public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, - boolean success) { - mClientMonitor.destroy(); - mState = STATE_FINISHED; - } - }; - return new BaseClientMonitor.CompositeCallback(destroyCallback, callback, mClientCallback); - } - - /** {@link BaseClientMonitor#getSensorId()}. */ - public int getSensorId() { - return mClientMonitor.getSensorId(); - } - - /** {@link BaseClientMonitor#getProtoEnum()}. */ - public int getProtoEnum() { - return mClientMonitor.getProtoEnum(); - } - - /** {@link BaseClientMonitor#getTargetUserId()}. */ - public int getTargetUserId() { - return mClientMonitor.getTargetUserId(); - } - - /** If the given clientMonitor is the same as the one in the constructor. */ - public boolean isFor(@NonNull BaseClientMonitor clientMonitor) { - return mClientMonitor == clientMonitor; - } - - /** If this operation is {@link Interruptable}. */ - public boolean isInterruptable() { - return mClientMonitor instanceof Interruptable; - } - - private boolean isHalOperation() { - return mClientMonitor instanceof HalClientMonitor; - } - - private boolean isUnstartableHalOperation() { - if (isHalOperation()) { - final HalClientMonitor client = (HalClientMonitor) mClientMonitor; - if (client.getFreshDaemon() == null) { - return true; - } - } - return false; - } - - /** If this operation is an enrollment. */ - public boolean isEnrollOperation() { - return mClientMonitor instanceof EnrollClient; - } - - /** If this operation is authentication. */ - public boolean isAuthenticateOperation() { - return mClientMonitor instanceof AuthenticationClient; - } - - /** If this operation is authentication or detection. */ - public boolean isAuthenticationOrDetectionOperation() { - final boolean isAuthentication = mClientMonitor instanceof AuthenticationConsumer; - final boolean isDetection = mClientMonitor instanceof DetectionConsumer; - return isAuthentication || isDetection; - } - - /** If this operation performs acquisition {@link AcquisitionClient}. */ - public boolean isAcquisitionOperation() { - return mClientMonitor instanceof AcquisitionClient; - } - - /** - * If this operation matches the original requestId. - * - * By default, monitors are not associated with a request id to retain the original - * behavior (i.e. if no requestId is explicitly set then assume it matches) - * - * @param requestId a unique id {@link BaseClientMonitor#setRequestId(long)}. - */ - public boolean isMatchingRequestId(long requestId) { - return !mClientMonitor.hasRequestId() - || mClientMonitor.getRequestId() == requestId; - } - - /** If the token matches */ - public boolean isMatchingToken(@Nullable IBinder token) { - return mClientMonitor.getToken() == token; - } - - /** If this operation has started. */ - public boolean isStarted() { - return mState == STATE_STARTED; - } - - /** If this operation is cancelling but has not yet completed. */ - public boolean isCanceling() { - return mState == STATE_STARTED_CANCELING; - } - - /** If this operation has finished and completed its lifecycle. */ - public boolean isFinished() { - return mState == STATE_FINISHED; - } - - /** If {@link #markCanceling()} was called but the operation hasn't been canceled. */ - public boolean isMarkedCanceling() { - return mState == STATE_WAITING_IN_QUEUE_CANCELING; - } - - /** - * The monitor passed to the constructor. - * @deprecated avoid using and move to encapsulate within the operation - */ - @Deprecated - public BaseClientMonitor getClientMonitor() { - return mClientMonitor; - } - - private void checkNotInState(String message, @OperationState int... states) { - for (int state : states) { - if (mState == state) { - throw new IllegalStateException(message + ": illegal state= " + state); - } - } - } - - private void checkInState(String message, @OperationState int... states) { - for (int state : states) { - if (mState == state) { - return; - } - } - throw new IllegalStateException(message + ": illegal state= " + mState); - } - - @Override - public String toString() { - return mClientMonitor + ", State: " + mState; - } -} diff --git a/services/core/java/com/android/server/biometrics/sensors/Interruptable.java b/services/core/java/com/android/server/biometrics/sensors/Interruptable.java index d5093c7564154..fab98b6581a3e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/Interruptable.java +++ b/services/core/java/com/android/server/biometrics/sensors/Interruptable.java @@ -32,11 +32,6 @@ public interface Interruptable { * {@link BaseClientMonitor#start(BaseClientMonitor.Callback)} was invoked. This usually happens * if the client is still waiting in the pending queue and got notified that a subsequent * operation is preempting it. - * - * This method must invoke - * {@link BaseClientMonitor.Callback#onClientFinished(BaseClientMonitor, boolean)} on the - * given callback (with success). - * * @param callback invoked when the operation is completed. */ void cancelWithoutStarting(@NonNull BaseClientMonitor.Callback callback); diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java index 19eaa178c7c9f..b056bf897b5c5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java @@ -16,13 +16,10 @@ package com.android.server.biometrics.sensors; -import static com.android.server.biometrics.sensors.BiometricSchedulerOperation.STATE_STARTED; - import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.IBiometricService; -import android.os.Handler; import android.os.ServiceManager; import android.os.UserHandle; import android.util.Slog; @@ -71,8 +68,9 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { return; } - Slog.d(getTag(), "[Client finished] " + clientMonitor + ", success: " + success); - if (mCurrentOperation != null && mCurrentOperation.isFor(mOwner)) { + Slog.d(getTag(), "[Client finished] " + + clientMonitor + ", success: " + success); + if (mCurrentOperation != null && mCurrentOperation.mClientMonitor == mOwner) { mCurrentOperation = null; startNextOperationIfIdle(); } else { @@ -85,31 +83,26 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { } @VisibleForTesting - UserAwareBiometricScheduler(@NonNull String tag, - @NonNull Handler handler, - @SensorType int sensorType, + UserAwareBiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull IBiometricService biometricService, @NonNull CurrentUserRetriever currentUserRetriever, @NonNull UserSwitchCallback userSwitchCallback, @NonNull CoexCoordinator coexCoordinator) { - super(tag, handler, sensorType, gestureAvailabilityDispatcher, biometricService, + super(tag, sensorType, gestureAvailabilityDispatcher, biometricService, LOG_NUM_RECENT_OPERATIONS, coexCoordinator); mCurrentUserRetriever = currentUserRetriever; mUserSwitchCallback = userSwitchCallback; } - public UserAwareBiometricScheduler(@NonNull String tag, - @NonNull Handler handler, - @SensorType int sensorType, + public UserAwareBiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull CurrentUserRetriever currentUserRetriever, @NonNull UserSwitchCallback userSwitchCallback) { - this(tag, handler, sensorType, gestureAvailabilityDispatcher, - IBiometricService.Stub.asInterface( - ServiceManager.getService(Context.BIOMETRIC_SERVICE)), - currentUserRetriever, userSwitchCallback, CoexCoordinator.getInstance()); + this(tag, sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( + ServiceManager.getService(Context.BIOMETRIC_SERVICE)), currentUserRetriever, + userSwitchCallback, CoexCoordinator.getInstance()); } @Override @@ -129,7 +122,7 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { } final int currentUserId = mCurrentUserRetriever.getCurrentUserId(); - final int nextUserId = mPendingOperations.getFirst().getTargetUserId(); + final int nextUserId = mPendingOperations.getFirst().mClientMonitor.getTargetUserId(); if (nextUserId == currentUserId) { super.startNextOperationIfIdle(); @@ -140,8 +133,8 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { new ClientFinishedCallback(startClient); Slog.d(getTag(), "[Starting User] " + startClient); - mCurrentOperation = new BiometricSchedulerOperation( - startClient, finishedCallback, STATE_STARTED); + mCurrentOperation = new Operation( + startClient, finishedCallback, Operation.STATE_STARTED); startClient.start(finishedCallback); } else { if (mStopUserClient != null) { @@ -154,8 +147,8 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { Slog.d(getTag(), "[Stopping User] current: " + currentUserId + ", next: " + nextUserId + ". " + mStopUserClient); - mCurrentOperation = new BiometricSchedulerOperation( - mStopUserClient, finishedCallback, STATE_STARTED); + mCurrentOperation = new Operation( + mStopUserClient, finishedCallback, Operation.STATE_STARTED); mStopUserClient.start(finishedCallback); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java index 039b08e805c16..675ee545a14f5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java @@ -213,7 +213,7 @@ public class FaceService extends SystemService { } @Override // Binder call - public long enroll(int userId, final IBinder token, final byte[] hardwareAuthToken, + public void enroll(int userId, final IBinder token, final byte[] hardwareAuthToken, final IFaceServiceReceiver receiver, final String opPackageName, final int[] disabledFeatures, Surface previewSurface, boolean debugConsent) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); @@ -221,24 +221,23 @@ public class FaceService extends SystemService { final Pair provider = getSingleProvider(); if (provider == null) { Slog.w(TAG, "Null provider for enroll"); - return -1; + return; } - return provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId, + provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId, receiver, opPackageName, disabledFeatures, previewSurface, debugConsent); } @Override // Binder call - public long enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken, + public void enrollRemotely(int userId, final IBinder token, final byte[] hardwareAuthToken, final IFaceServiceReceiver receiver, final String opPackageName, final int[] disabledFeatures) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); // TODO(b/145027036): Implement this. - return -1; } @Override // Binder call - public void cancelEnrollment(final IBinder token, long requestId) { + public void cancelEnrollment(final IBinder token) { Utils.checkPermission(getContext(), MANAGE_BIOMETRIC); final Pair provider = getSingleProvider(); @@ -247,7 +246,7 @@ public class FaceService extends SystemService { return; } - provider.second.cancelEnrollment(provider.first, token, requestId); + provider.second.cancelEnrollment(provider.first, token); } @Override // Binder call @@ -625,7 +624,7 @@ public class FaceService extends SystemService { private void addHidlProviders(@NonNull List hidlSensors) { for (FaceSensorPropertiesInternal hidlSensor : hidlSensors) { mServiceProviders.add( - Face10.newInstance(getContext(), hidlSensor, mLockoutResetDispatcher)); + new Face10(getContext(), hidlSensor, mLockoutResetDispatcher)); } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java index 77e431c811923..e099ba372b058 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java @@ -94,12 +94,12 @@ public interface ServiceProvider { void scheduleRevokeChallenge(int sensorId, int userId, @NonNull IBinder token, @NonNull String opPackageName, long challenge); - long scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, + void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName, @NonNull int[] disabledFeatures, @Nullable Surface previewSurface, boolean debugConsent); - void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId); + void cancelEnrollment(int sensorId, @NonNull IBinder token); long scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId, @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java index aae4fbe9b0d73..a806277ed45e2 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java @@ -82,14 +82,13 @@ public class FaceEnrollClient extends EnrollClient { FaceEnrollClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, - @NonNull byte[] hardwareAuthToken, @NonNull String opPackageName, long requestId, + @NonNull byte[] hardwareAuthToken, @NonNull String opPackageName, @NonNull BiometricUtils utils, @NonNull int[] disabledFeatures, int timeoutSec, @Nullable Surface previewSurface, int sensorId, int maxTemplatesPerUser, boolean debugConsent) { super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, opPackageName, utils, timeoutSec, BiometricsProtoEnums.MODALITY_FACE, sensorId, false /* shouldVibrate */); - setRequestId(requestId); mEnrollIgnoreList = getContext().getResources() .getIntArray(R.array.config_face_acquire_enroll_ignorelist); mEnrollIgnoreListVendor = getContext().getResources() diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java index ae507abea537d..4bae7756abe00 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java @@ -327,18 +327,17 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { } @Override - public long scheduleEnroll(int sensorId, @NonNull IBinder token, + public void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName, @NonNull int[] disabledFeatures, @Nullable Surface previewSurface, boolean debugConsent) { - final long id = mRequestCounter.incrementAndGet(); mHandler.post(() -> { final int maxTemplatesPerUser = mSensors.get( sensorId).getSensorProperties().maxEnrollmentsPerUser; final FaceEnrollClient client = new FaceEnrollClient(mContext, mSensors.get(sensorId).getLazySession(), token, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, - opPackageName, id, FaceUtils.getInstance(sensorId), disabledFeatures, + opPackageName, FaceUtils.getInstance(sensorId), disabledFeatures, ENROLL_TIMEOUT_SEC, previewSurface, sensorId, maxTemplatesPerUser, debugConsent); scheduleForSensor(sensorId, client, new BaseClientMonitor.Callback() { @@ -352,13 +351,11 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider { } }); }); - return id; } @Override - public void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId) { - mHandler.post(() -> - mSensors.get(sensorId).getScheduler().cancelEnrollment(token, requestId)); + public void cancelEnrollment(int sensorId, @NonNull IBinder token) { + mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelEnrollment(token)); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java index 39270430c21d4..206b8f0779e8e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java @@ -494,7 +494,7 @@ public class Sensor { mToken = new Binder(); mHandler = handler; mSensorProperties = sensorProperties; - mScheduler = new UserAwareBiometricScheduler(tag, mHandler, + mScheduler = new UserAwareBiometricScheduler(tag, BiometricScheduler.SENSOR_TYPE_FACE, null /* gestureAvailabilityDispatcher */, () -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL, new UserAwareBiometricScheduler.UserSwitchCallback() { diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index 493c0a05e3795..f4dcbbba21d73 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -333,13 +333,12 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { Face10(@NonNull Context context, @NonNull FaceSensorPropertiesInternal sensorProps, @NonNull LockoutResetDispatcher lockoutResetDispatcher, - @NonNull Handler handler, @NonNull BiometricScheduler scheduler) { mSensorProperties = sensorProps; mContext = context; mSensorId = sensorProps.sensorId; mScheduler = scheduler; - mHandler = handler; + mHandler = new Handler(Looper.getMainLooper()); mUsageStats = new UsageStats(context); mAuthenticatorIds = new HashMap<>(); mLazyDaemon = Face10.this::getDaemon; @@ -358,12 +357,10 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { } } - public static Face10 newInstance(@NonNull Context context, - @NonNull FaceSensorPropertiesInternal sensorProps, + public Face10(@NonNull Context context, @NonNull FaceSensorPropertiesInternal sensorProps, @NonNull LockoutResetDispatcher lockoutResetDispatcher) { - final Handler handler = new Handler(Looper.getMainLooper()); - return new Face10(context, sensorProps, lockoutResetDispatcher, handler, - new BiometricScheduler(TAG, handler, BiometricScheduler.SENSOR_TYPE_FACE, + this(context, sensorProps, lockoutResetDispatcher, + new BiometricScheduler(TAG, BiometricScheduler.SENSOR_TYPE_FACE, null /* gestureAvailabilityTracker */)); } @@ -576,11 +573,10 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { } @Override - public long scheduleEnroll(int sensorId, @NonNull IBinder token, + public void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName, @NonNull int[] disabledFeatures, @Nullable Surface previewSurface, boolean debugConsent) { - final long id = mRequestCounter.incrementAndGet(); mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); @@ -588,7 +584,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { final FaceEnrollClient client = new FaceEnrollClient(mContext, mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, - opPackageName, id, FaceUtils.getLegacyInstance(mSensorId), disabledFeatures, + opPackageName, FaceUtils.getLegacyInstance(mSensorId), disabledFeatures, ENROLL_TIMEOUT_SEC, previewSurface, mSensorId); mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() { @@ -602,12 +598,13 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { } }); }); - return id; } @Override - public void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId) { - mHandler.post(() -> mScheduler.cancelEnrollment(token, requestId)); + public void cancelEnrollment(int sensorId, @NonNull IBinder token) { + mHandler.post(() -> { + mScheduler.cancelEnrollment(token); + }); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java index 31e5c86103fbe..80828cced4e89 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceEnrollClient.java @@ -53,13 +53,12 @@ public class FaceEnrollClient extends EnrollClient { FaceEnrollClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, - @NonNull byte[] hardwareAuthToken, @NonNull String owner, long requestId, + @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils, @NonNull int[] disabledFeatures, int timeoutSec, @Nullable Surface previewSurface, int sensorId) { super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, timeoutSec, BiometricsProtoEnums.MODALITY_FACE, sensorId, false /* shouldVibrate */); - setRequestId(requestId); mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length); mEnrollIgnoreList = getContext().getResources() .getIntArray(R.array.config_face_acquire_enroll_ignorelist); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java index 6366e19ef1917..3e70ee52ff1b5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java @@ -249,7 +249,7 @@ public class FingerprintService extends SystemService { } @Override // Binder call - public long enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken, + public void enroll(final IBinder token, @NonNull final byte[] hardwareAuthToken, final int userId, final IFingerprintServiceReceiver receiver, final String opPackageName, @FingerprintManager.EnrollReason int enrollReason) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); @@ -257,15 +257,15 @@ public class FingerprintService extends SystemService { final Pair provider = getSingleProvider(); if (provider == null) { Slog.w(TAG, "Null provider for enroll"); - return -1; + return; } - return provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId, + provider.second.scheduleEnroll(provider.first, token, hardwareAuthToken, userId, receiver, opPackageName, enrollReason); } @Override // Binder call - public void cancelEnrollment(final IBinder token, long requestId) { + public void cancelEnrollment(final IBinder token) { Utils.checkPermission(getContext(), MANAGE_FINGERPRINT); final Pair provider = getSingleProvider(); @@ -274,7 +274,7 @@ public class FingerprintService extends SystemService { return; } - provider.second.cancelEnrollment(provider.first, token, requestId); + provider.second.cancelEnrollment(provider.first, token); } @SuppressWarnings("deprecation") @@ -818,7 +818,7 @@ public class FingerprintService extends SystemService { mLockoutResetDispatcher, mGestureAvailabilityDispatcher); } else { fingerprint21 = Fingerprint21.newInstance(getContext(), - mFingerprintStateCallback, hidlSensor, mHandler, + mFingerprintStateCallback, hidlSensor, mLockoutResetDispatcher, mGestureAvailabilityDispatcher); } mServiceProviders.add(fingerprint21); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java index 535705c63cab0..1772f814dd102 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java @@ -88,11 +88,11 @@ public interface ServiceProvider { /** * Schedules fingerprint enrollment. */ - long scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, + void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName, @FingerprintManager.EnrollReason int enrollReason); - void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId); + void cancelEnrollment(int sensorId, @NonNull IBinder token); long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId, @NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index 67507ccbbbfef..ccb34aad3198d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -57,7 +57,7 @@ class FingerprintEnrollClient extends EnrollClient implements Udfps { private boolean mIsPointerDown; FingerprintEnrollClient(@NonNull Context context, - @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, long requestId, + @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils, int sensorId, @@ -69,7 +69,6 @@ class FingerprintEnrollClient extends EnrollClient implements Udfps { super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, 0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, !sensorProps.isAnyUdfpsType() /* shouldVibrate */); - setRequestId(requestId); mSensorProps = sensorProps; mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController); mMaxTemplatesPerUser = maxTemplatesPerUser; diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index eb16c763dea6d..734b1737dfbcb 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -347,16 +347,15 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } @Override - public long scheduleEnroll(int sensorId, @NonNull IBinder token, + public void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName, @FingerprintManager.EnrollReason int enrollReason) { - final long id = mRequestCounter.incrementAndGet(); mHandler.post(() -> { final int maxTemplatesPerUser = mSensors.get(sensorId).getSensorProperties() .maxEnrollmentsPerUser; final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext, - mSensors.get(sensorId).getLazySession(), token, id, + mSensors.get(sensorId).getLazySession(), token, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, opPackageName, FingerprintUtils.getInstance(sensorId), sensorId, mSensors.get(sensorId).getSensorProperties(), @@ -379,13 +378,11 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi } }); }); - return id; } @Override - public void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId) { - mHandler.post(() -> - mSensors.get(sensorId).getScheduler().cancelEnrollment(token, requestId)); + public void cancelEnrollment(int sensorId, @NonNull IBinder token) { + mHandler.post(() -> mSensors.get(sensorId).getScheduler().cancelEnrollment(token)); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index 256761a61a72a..59e4b582ca84e 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java @@ -449,7 +449,7 @@ class Sensor { mHandler = handler; mSensorProperties = sensorProperties; mLockoutCache = new LockoutCache(); - mScheduler = new UserAwareBiometricScheduler(tag, handler, + mScheduler = new UserAwareBiometricScheduler(tag, BiometricScheduler.sensorTypeFromFingerprintProperties(mSensorProperties), gestureAvailabilityDispatcher, () -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL, diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index d352cda609e3d..5f2f4cf6ef3c0 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -42,6 +42,7 @@ import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.Handler; import android.os.IBinder; import android.os.IHwBinder; +import android.os.Looper; import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; @@ -319,8 +320,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider Fingerprint21(@NonNull Context context, @NonNull FingerprintStateCallback fingerprintStateCallback, @NonNull FingerprintSensorPropertiesInternal sensorProps, - @NonNull BiometricScheduler scheduler, - @NonNull Handler handler, + @NonNull BiometricScheduler scheduler, @NonNull Handler handler, @NonNull LockoutResetDispatcher lockoutResetDispatcher, @NonNull HalResultController controller) { mContext = context; @@ -356,15 +356,16 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider public static Fingerprint21 newInstance(@NonNull Context context, @NonNull FingerprintStateCallback fingerprintStateCallback, @NonNull FingerprintSensorPropertiesInternal sensorProps, - @NonNull Handler handler, @NonNull LockoutResetDispatcher lockoutResetDispatcher, @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { + final Handler handler = new Handler(Looper.getMainLooper()); final BiometricScheduler scheduler = - new BiometricScheduler(TAG, handler, + new BiometricScheduler(TAG, BiometricScheduler.sensorTypeFromFingerprintProperties(sensorProps), gestureAvailabilityDispatcher); final HalResultController controller = new HalResultController(sensorProps.sensorId, - context, handler, scheduler); + context, handler, + scheduler); return new Fingerprint21(context, fingerprintStateCallback, sensorProps, scheduler, handler, lockoutResetDispatcher, controller); } @@ -557,20 +558,18 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider } @Override - public long scheduleEnroll(int sensorId, @NonNull IBinder token, + public void scheduleEnroll(int sensorId, @NonNull IBinder token, @NonNull byte[] hardwareAuthToken, int userId, @NonNull IFingerprintServiceReceiver receiver, @NonNull String opPackageName, @FingerprintManager.EnrollReason int enrollReason) { - final long id = mRequestCounter.incrementAndGet(); mHandler.post(() -> { scheduleUpdateActiveUserWithoutHandler(userId); final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext, - mLazyDaemon, token, id, new ClientMonitorCallbackConverter(receiver), - userId, hardwareAuthToken, opPackageName, - FingerprintUtils.getLegacyInstance(mSensorId), ENROLL_TIMEOUT_SEC, - mSensorProperties.sensorId, mUdfpsOverlayController, mSidefpsController, - enrollReason); + mLazyDaemon, token, new ClientMonitorCallbackConverter(receiver), userId, + hardwareAuthToken, opPackageName, FingerprintUtils.getLegacyInstance(mSensorId), + ENROLL_TIMEOUT_SEC, mSensorProperties.sensorId, mUdfpsOverlayController, + mSidefpsController, enrollReason); mScheduler.scheduleClientMonitor(client, new BaseClientMonitor.Callback() { @Override public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { @@ -589,12 +588,13 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider } }); }); - return id; } @Override - public void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId) { - mHandler.post(() -> mScheduler.cancelEnrollment(token, requestId)); + public void cancelEnrollment(int sensorId, @NonNull IBinder token) { + mHandler.post(() -> { + mScheduler.cancelEnrollment(token); + }); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java index 20dab5552df98..dd68b4d37e2a4 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java @@ -26,6 +26,7 @@ import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback; import android.hardware.fingerprint.FingerprintManager.AuthenticationResult; import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; +import android.hardware.fingerprint.FingerprintStateListener; import android.hardware.fingerprint.IUdfpsOverlayController; import android.os.Handler; import android.os.IBinder; @@ -134,17 +135,43 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage @NonNull private final RestartAuthRunnable mRestartAuthRunnable; private static class TestableBiometricScheduler extends BiometricScheduler { + @NonNull private final TestableInternalCallback mInternalCallback; @NonNull private Fingerprint21UdfpsMock mFingerprint21; - TestableBiometricScheduler(@NonNull String tag, @NonNull Handler handler, + TestableBiometricScheduler(@NonNull String tag, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { - super(tag, handler, BiometricScheduler.SENSOR_TYPE_FP_OTHER, + super(tag, BiometricScheduler.SENSOR_TYPE_FP_OTHER, gestureAvailabilityDispatcher); + mInternalCallback = new TestableInternalCallback(); + } + + class TestableInternalCallback extends InternalCallback { + @Override + public void onClientStarted(BaseClientMonitor clientMonitor) { + super.onClientStarted(clientMonitor); + Slog.d(TAG, "Client started: " + clientMonitor); + mFingerprint21.setDebugMessage("Started: " + clientMonitor); + } + + @Override + public void onClientFinished(BaseClientMonitor clientMonitor, boolean success) { + super.onClientFinished(clientMonitor, success); + Slog.d(TAG, "Client finished: " + clientMonitor); + mFingerprint21.setDebugMessage("Finished: " + clientMonitor); + } } void init(@NonNull Fingerprint21UdfpsMock fingerprint21) { mFingerprint21 = fingerprint21; } + + /** + * Expose the internal finish callback so it can be used for testing + */ + @Override + @NonNull protected InternalCallback getInternalCallback() { + return mInternalCallback; + } } /** @@ -253,7 +280,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage final Handler handler = new Handler(Looper.getMainLooper()); final TestableBiometricScheduler scheduler = - new TestableBiometricScheduler(TAG, handler, gestureAvailabilityDispatcher); + new TestableBiometricScheduler(TAG, gestureAvailabilityDispatcher); final MockHalResultController controller = new MockHalResultController(sensorProps.sensorId, context, handler, scheduler); return new Fingerprint21UdfpsMock(context, fingerprintStateCallback, sensorProps, scheduler, diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java index cc50bdfb59aec..1ebf44ca707f9 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintEnrollClient.java @@ -55,7 +55,7 @@ public class FingerprintEnrollClient extends EnrollClient lazyDaemon, @NonNull IBinder token, - long requestId, @NonNull ClientMonitorCallbackConverter listener, int userId, + @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils, int timeoutSec, int sensorId, @Nullable IUdfpsOverlayController udfpsOverlayController, @@ -64,7 +64,6 @@ public class FingerprintEnrollClient extends EnrollClient - extends HalClientMonitor implements Interruptable { - public InterruptableMonitor() { - super(null, null, null, null, 0, null, 0, 0, 0, 0, 0); - } - } - - @Mock - private InterruptableMonitor mClientMonitor; - @Mock - private BaseClientMonitor.Callback mClientCallback; - @Mock - private FakeHal mHal; - @Captor - ArgumentCaptor mStartCallback; - - private Handler mHandler; - private BiometricSchedulerOperation mOperation; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mHandler = new Handler(TestableLooper.get(this).getLooper()); - mOperation = new BiometricSchedulerOperation(mClientMonitor, mClientCallback); - } - - @Test - public void testStartWithCookie() { - final int cookie = 200; - when(mClientMonitor.getCookie()).thenReturn(cookie); - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - assertThat(mOperation.isReadyToStart()).isEqualTo(cookie); - assertThat(mOperation.isStarted()).isFalse(); - assertThat(mOperation.isCanceling()).isFalse(); - assertThat(mOperation.isFinished()).isFalse(); - - final boolean started = mOperation.startWithCookie( - mock(BaseClientMonitor.Callback.class), cookie); - - assertThat(started).isTrue(); - verify(mClientMonitor).start(mStartCallback.capture()); - mStartCallback.getValue().onClientStarted(mClientMonitor); - assertThat(mOperation.isStarted()).isTrue(); - } - - @Test - public void testNoStartWithoutCookie() { - final int goodCookie = 20; - final int badCookie = 22; - when(mClientMonitor.getCookie()).thenReturn(goodCookie); - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - assertThat(mOperation.isReadyToStart()).isEqualTo(goodCookie); - final boolean started = mOperation.startWithCookie( - mock(BaseClientMonitor.Callback.class), badCookie); - - assertThat(started).isFalse(); - assertThat(mOperation.isStarted()).isFalse(); - assertThat(mOperation.isCanceling()).isFalse(); - assertThat(mOperation.isFinished()).isFalse(); - } - - @Test - public void startsWhenReadyAndHalAvailable() { - when(mClientMonitor.getCookie()).thenReturn(0); - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - final BaseClientMonitor.Callback cb = mock(BaseClientMonitor.Callback.class); - mOperation.start(cb); - verify(mClientMonitor).start(mStartCallback.capture()); - mStartCallback.getValue().onClientStarted(mClientMonitor); - - assertThat(mOperation.isStarted()).isTrue(); - assertThat(mOperation.isCanceling()).isFalse(); - assertThat(mOperation.isFinished()).isFalse(); - - verify(mClientCallback).onClientStarted(eq(mClientMonitor)); - verify(cb).onClientStarted(eq(mClientMonitor)); - verify(mClientCallback, never()).onClientFinished(any(), anyBoolean()); - verify(cb, never()).onClientFinished(any(), anyBoolean()); - - mStartCallback.getValue().onClientFinished(mClientMonitor, true); - - assertThat(mOperation.isFinished()).isTrue(); - assertThat(mOperation.isCanceling()).isFalse(); - verify(mClientMonitor).destroy(); - verify(cb).onClientFinished(eq(mClientMonitor), eq(true)); - } - - @Test - public void startFailsWhenReadyButHalNotAvailable() { - when(mClientMonitor.getCookie()).thenReturn(0); - when(mClientMonitor.getFreshDaemon()).thenReturn(null); - - final BaseClientMonitor.Callback cb = mock(BaseClientMonitor.Callback.class); - mOperation.start(cb); - verify(mClientMonitor, never()).start(any()); - - assertThat(mOperation.isStarted()).isFalse(); - assertThat(mOperation.isCanceling()).isFalse(); - assertThat(mOperation.isFinished()).isTrue(); - - verify(mClientCallback, never()).onClientStarted(eq(mClientMonitor)); - verify(cb, never()).onClientStarted(eq(mClientMonitor)); - verify(mClientCallback).onClientFinished(eq(mClientMonitor), eq(false)); - verify(cb).onClientFinished(eq(mClientMonitor), eq(false)); - } - - @Test - public void doesNotStartWithCookie() { - when(mClientMonitor.getCookie()).thenReturn(9); - assertThrows(IllegalStateException.class, - () -> mOperation.start(mock(BaseClientMonitor.Callback.class))); - } - - @Test - public void cannotRestart() { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - mOperation.start(mock(BaseClientMonitor.Callback.class)); - - assertThrows(IllegalStateException.class, - () -> mOperation.start(mock(BaseClientMonitor.Callback.class))); - } - - @Test - public void abortsNotRunning() { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - mOperation.abort(); - - assertThat(mOperation.isFinished()).isTrue(); - verify(mClientMonitor).unableToStart(); - verify(mClientMonitor).destroy(); - assertThrows(IllegalStateException.class, - () -> mOperation.start(mock(BaseClientMonitor.Callback.class))); - } - - @Test - public void cannotAbortRunning() { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - mOperation.start(mock(BaseClientMonitor.Callback.class)); - - assertThrows(IllegalStateException.class, () -> mOperation.abort()); - } - - @Test - public void cancel() { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - final BaseClientMonitor.Callback startCb = mock(BaseClientMonitor.Callback.class); - final BaseClientMonitor.Callback cancelCb = mock(BaseClientMonitor.Callback.class); - mOperation.start(startCb); - verify(mClientMonitor).start(mStartCallback.capture()); - mStartCallback.getValue().onClientStarted(mClientMonitor); - mOperation.cancel(mHandler, cancelCb); - - assertThat(mOperation.isCanceling()).isTrue(); - verify(mClientMonitor).cancel(); - verify(mClientMonitor, never()).cancelWithoutStarting(any()); - verify(mClientMonitor, never()).destroy(); - - mStartCallback.getValue().onClientFinished(mClientMonitor, true); - - assertThat(mOperation.isFinished()).isTrue(); - assertThat(mOperation.isCanceling()).isFalse(); - verify(mClientMonitor).destroy(); - - // should be unused since the operation was started - verify(cancelCb, never()).onClientStarted(any()); - verify(cancelCb, never()).onClientFinished(any(), anyBoolean()); - } - - @Test - public void cancelWithoutStarting() { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - final BaseClientMonitor.Callback cancelCb = mock(BaseClientMonitor.Callback.class); - mOperation.cancel(mHandler, cancelCb); - - assertThat(mOperation.isCanceling()).isTrue(); - ArgumentCaptor cbCaptor = - ArgumentCaptor.forClass(BaseClientMonitor.Callback.class); - verify(mClientMonitor).cancelWithoutStarting(cbCaptor.capture()); - - cbCaptor.getValue().onClientFinished(mClientMonitor, true); - verify(cancelCb).onClientFinished(eq(mClientMonitor), eq(true)); - verify(mClientMonitor, never()).start(any()); - verify(mClientMonitor, never()).cancel(); - verify(mClientMonitor).destroy(); - } - - @Test - public void markCanceling() { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - mOperation.markCanceling(); - - assertThat(mOperation.isMarkedCanceling()).isTrue(); - assertThat(mOperation.isCanceling()).isFalse(); - assertThat(mOperation.isFinished()).isFalse(); - verify(mClientMonitor, never()).start(any()); - verify(mClientMonitor, never()).cancel(); - verify(mClientMonitor, never()).cancelWithoutStarting(any()); - verify(mClientMonitor, never()).unableToStart(); - verify(mClientMonitor, never()).destroy(); - } - - @Test - public void cancelPendingWithCookie() { - markCancellingAndStart(2); - } - - @Test - public void cancelPendingWithoutCookie() { - markCancellingAndStart(null); - } - - private void markCancellingAndStart(Integer withCookie) { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - if (withCookie != null) { - when(mClientMonitor.getCookie()).thenReturn(withCookie); - } - - mOperation.markCanceling(); - final BaseClientMonitor.Callback cb = mock(BaseClientMonitor.Callback.class); - if (withCookie != null) { - mOperation.startWithCookie(cb, withCookie); - } else { - mOperation.start(cb); - } - - assertThat(mOperation.isFinished()).isTrue(); - verify(cb).onClientFinished(eq(mClientMonitor), eq(true)); - verify(mClientMonitor, never()).start(any()); - verify(mClientMonitor, never()).cancel(); - verify(mClientMonitor, never()).cancelWithoutStarting(any()); - verify(mClientMonitor, never()).unableToStart(); - verify(mClientMonitor).destroy(); - } - - @Test - public void cancelWatchdogWhenStarted() { - cancelWatchdog(true); - } - - @Test - public void cancelWatchdogWithoutStarting() { - cancelWatchdog(false); - } - - private void cancelWatchdog(boolean start) { - when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); - - mOperation.start(mock(BaseClientMonitor.Callback.class)); - if (start) { - verify(mClientMonitor).start(mStartCallback.capture()); - mStartCallback.getValue().onClientStarted(mClientMonitor); - } - mOperation.cancel(mHandler, mock(BaseClientMonitor.Callback.class)); - - assertThat(mOperation.isCanceling()).isTrue(); - - // omit call to onClientFinished and trigger watchdog - mOperation.mCancelWatchdog.run(); - - assertThat(mOperation.isFinished()).isTrue(); - assertThat(mOperation.isCanceling()).isFalse(); - verify(mClientMonitor).destroy(); - } -} diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java index ac0831983262c..d192697827f6b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java @@ -16,14 +16,10 @@ package com.android.server.biometrics.sensors; -import static android.testing.TestableLooper.RunWithLooper; - import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNull; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; @@ -38,13 +34,10 @@ import android.content.Context; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.IBiometricService; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; -import android.testing.AndroidTestingRunner; import android.testing.TestableContext; -import android.testing.TestableLooper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -53,18 +46,16 @@ import androidx.test.filters.SmallTest; import com.android.server.biometrics.nano.BiometricSchedulerProto; import com.android.server.biometrics.nano.BiometricsProto; +import com.android.server.biometrics.sensors.BiometricScheduler.Operation; import org.junit.Before; import org.junit.Rule; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @Presubmit @SmallTest -@RunWith(AndroidTestingRunner.class) -@RunWithLooper(setAsMainLooper = true) public class BiometricSchedulerTest { private static final String TAG = "BiometricSchedulerTest"; @@ -85,9 +76,8 @@ public class BiometricSchedulerTest { public void setUp() { MockitoAnnotations.initMocks(this); mToken = new Binder(); - mScheduler = new BiometricScheduler(TAG, new Handler(TestableLooper.get(this).getLooper()), - BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityTracker */, - mBiometricService, LOG_NUM_RECENT_OPERATIONS, + mScheduler = new BiometricScheduler(TAG, BiometricScheduler.SENSOR_TYPE_UNKNOWN, + null /* gestureAvailabilityTracker */, mBiometricService, LOG_NUM_RECENT_OPERATIONS, CoexCoordinator.getInstance()); } @@ -96,9 +86,9 @@ public class BiometricSchedulerTest { final HalClientMonitor.LazyDaemon nonNullDaemon = () -> mock(Object.class); final HalClientMonitor client1 = - new TestHalClientMonitor(mContext, mToken, nonNullDaemon); + new TestClientMonitor(mContext, mToken, nonNullDaemon); final HalClientMonitor client2 = - new TestHalClientMonitor(mContext, mToken, nonNullDaemon); + new TestClientMonitor(mContext, mToken, nonNullDaemon); mScheduler.scheduleClientMonitor(client1); mScheduler.scheduleClientMonitor(client2); @@ -109,17 +99,20 @@ public class BiometricSchedulerTest { @Test public void testRemovesPendingOperations_whenNullHal_andNotBiometricPrompt() { // Even if second client has a non-null daemon, it needs to be canceled. - final TestHalClientMonitor client1 = new TestHalClientMonitor( - mContext, mToken, () -> null); - final TestHalClientMonitor client2 = new TestHalClientMonitor( - mContext, mToken, () -> mock(Object.class)); + Object daemon2 = mock(Object.class); + + final HalClientMonitor.LazyDaemon lazyDaemon1 = () -> null; + final HalClientMonitor.LazyDaemon lazyDaemon2 = () -> daemon2; + + final TestClientMonitor client1 = new TestClientMonitor(mContext, mToken, lazyDaemon1); + final TestClientMonitor client2 = new TestClientMonitor(mContext, mToken, lazyDaemon2); final BaseClientMonitor.Callback callback1 = mock(BaseClientMonitor.Callback.class); final BaseClientMonitor.Callback callback2 = mock(BaseClientMonitor.Callback.class); // Pretend the scheduler is busy so the first operation doesn't start right away. We want // to pretend like there are two operations in the queue before kicking things off - mScheduler.mCurrentOperation = new BiometricSchedulerOperation( + mScheduler.mCurrentOperation = new BiometricScheduler.Operation( mock(BaseClientMonitor.class), mock(BaseClientMonitor.Callback.class)); mScheduler.scheduleClientMonitor(client1, callback1); @@ -129,11 +122,11 @@ public class BiometricSchedulerTest { mScheduler.scheduleClientMonitor(client2, callback2); waitForIdle(); - assertTrue(client1.mUnableToStart); + assertTrue(client1.wasUnableToStart()); verify(callback1).onClientFinished(eq(client1), eq(false) /* success */); verify(callback1, never()).onClientStarted(any()); - assertTrue(client2.mUnableToStart); + assertTrue(client2.wasUnableToStart()); verify(callback2).onClientFinished(eq(client2), eq(false) /* success */); verify(callback2, never()).onClientStarted(any()); @@ -145,19 +138,21 @@ public class BiometricSchedulerTest { // Second non-BiometricPrompt client has a valid daemon final Object daemon2 = mock(Object.class); + final HalClientMonitor.LazyDaemon lazyDaemon1 = () -> null; + final HalClientMonitor.LazyDaemon lazyDaemon2 = () -> daemon2; + final ClientMonitorCallbackConverter listener1 = mock(ClientMonitorCallbackConverter.class); final TestAuthenticationClient client1 = - new TestAuthenticationClient(mContext, () -> null, mToken, listener1); - final TestHalClientMonitor client2 = - new TestHalClientMonitor(mContext, mToken, () -> daemon2); + new TestAuthenticationClient(mContext, lazyDaemon1, mToken, listener1); + final TestClientMonitor client2 = new TestClientMonitor(mContext, mToken, lazyDaemon2); final BaseClientMonitor.Callback callback1 = mock(BaseClientMonitor.Callback.class); final BaseClientMonitor.Callback callback2 = mock(BaseClientMonitor.Callback.class); // Pretend the scheduler is busy so the first operation doesn't start right away. We want // to pretend like there are two operations in the queue before kicking things off - mScheduler.mCurrentOperation = new BiometricSchedulerOperation( + mScheduler.mCurrentOperation = new BiometricScheduler.Operation( mock(BaseClientMonitor.class), mock(BaseClientMonitor.Callback.class)); mScheduler.scheduleClientMonitor(client1, callback1); @@ -177,8 +172,8 @@ public class BiometricSchedulerTest { verify(callback1, never()).onClientStarted(any()); // Client 2 was able to start - assertFalse(client2.mUnableToStart); - assertTrue(client2.mStarted); + assertFalse(client2.wasUnableToStart()); + assertTrue(client2.hasStarted()); verify(callback2).onClientStarted(eq(client2)); } @@ -192,18 +187,16 @@ public class BiometricSchedulerTest { // Schedule a BiometricPrompt authentication request mScheduler.scheduleClientMonitor(client1, callback1); - assertNotEquals(0, mScheduler.mCurrentOperation.isReadyToStart()); - assertEquals(client1, mScheduler.mCurrentOperation.getClientMonitor()); + assertEquals(Operation.STATE_WAITING_FOR_COOKIE, mScheduler.mCurrentOperation.mState); + assertEquals(client1, mScheduler.mCurrentOperation.mClientMonitor); assertEquals(0, mScheduler.mPendingOperations.size()); // Request it to be canceled. The operation can be canceled immediately, and the scheduler // should go back to idle, since in this case the framework has not even requested the HAL // to authenticate yet. mScheduler.cancelAuthenticationOrDetection(mToken, 1 /* requestId */); - waitForIdle(); assertTrue(client1.isAlreadyDone()); assertTrue(client1.mDestroyed); - assertFalse(client1.mStartedHal); assertNull(mScheduler.mCurrentOperation); } @@ -217,8 +210,8 @@ public class BiometricSchedulerTest { // assertEquals(0, bsp.recentOperations.length); // Pretend the scheduler is busy enrolling, and check the proto dump again. - final TestHalClientMonitor client = new TestHalClientMonitor(mContext, mToken, - () -> mock(Object.class), 0, BiometricsProto.CM_ENROLL); + final TestClientMonitor2 client = new TestClientMonitor2(mContext, mToken, + () -> mock(Object.class), BiometricsProto.CM_ENROLL); mScheduler.scheduleClientMonitor(client); waitForIdle(); bsp = getDump(true /* clearSchedulerBuffer */); @@ -237,8 +230,8 @@ public class BiometricSchedulerTest { @Test public void testProtoDump_fifo() throws Exception { // Add the first operation - final TestHalClientMonitor client = new TestHalClientMonitor(mContext, mToken, - () -> mock(Object.class), 0, BiometricsProto.CM_ENROLL); + final TestClientMonitor2 client = new TestClientMonitor2(mContext, mToken, + () -> mock(Object.class), BiometricsProto.CM_ENROLL); mScheduler.scheduleClientMonitor(client); waitForIdle(); BiometricSchedulerProto bsp = getDump(false /* clearSchedulerBuffer */); @@ -251,8 +244,8 @@ public class BiometricSchedulerTest { client.getCallback().onClientFinished(client, true); // Add another operation - final TestHalClientMonitor client2 = new TestHalClientMonitor(mContext, mToken, - () -> mock(Object.class), 0, BiometricsProto.CM_REMOVE); + final TestClientMonitor2 client2 = new TestClientMonitor2(mContext, mToken, + () -> mock(Object.class), BiometricsProto.CM_REMOVE); mScheduler.scheduleClientMonitor(client2); waitForIdle(); bsp = getDump(false /* clearSchedulerBuffer */); @@ -263,8 +256,8 @@ public class BiometricSchedulerTest { client2.getCallback().onClientFinished(client2, true); // And another operation - final TestHalClientMonitor client3 = new TestHalClientMonitor(mContext, mToken, - () -> mock(Object.class), 0, BiometricsProto.CM_AUTHENTICATE); + final TestClientMonitor2 client3 = new TestClientMonitor2(mContext, mToken, + () -> mock(Object.class), BiometricsProto.CM_AUTHENTICATE); mScheduler.scheduleClientMonitor(client3); waitForIdle(); bsp = getDump(false /* clearSchedulerBuffer */); @@ -297,7 +290,8 @@ public class BiometricSchedulerTest { @Test public void testCancelPendingAuth() throws RemoteException { final HalClientMonitor.LazyDaemon lazyDaemon = () -> mock(Object.class); - final TestHalClientMonitor client1 = new TestHalClientMonitor(mContext, mToken, lazyDaemon); + + final TestClientMonitor client1 = new TestClientMonitor(mContext, mToken, lazyDaemon); final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class); final TestAuthenticationClient client2 = new TestAuthenticationClient(mContext, lazyDaemon, mToken, callback); @@ -308,12 +302,14 @@ public class BiometricSchedulerTest { waitForIdle(); assertEquals(mScheduler.getCurrentClient(), client1); - assertFalse(mScheduler.mPendingOperations.getFirst().isStarted()); + assertEquals(Operation.STATE_WAITING_IN_QUEUE, + mScheduler.mPendingOperations.getFirst().mState); // Request cancel before the authentication client has started mScheduler.cancelAuthenticationOrDetection(mToken, 1 /* requestId */); waitForIdle(); - assertTrue(mScheduler.mPendingOperations.getFirst().isMarkedCanceling()); + assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING, + mScheduler.mPendingOperations.getFirst().mState); // Finish the blocking client. The authentication client should send ERROR_CANCELED client1.getCallback().onClientFinished(client1, true /* success */); @@ -330,109 +326,67 @@ public class BiometricSchedulerTest { @Test public void testCancels_whenAuthRequestIdNotSet() { - testCancelsAuthDetectWhenRequestId(null /* requestId */, 2, true /* started */); + testCancelsWhenRequestId(null /* requestId */, 2, true /* started */); } @Test public void testCancels_whenAuthRequestIdNotSet_notStarted() { - testCancelsAuthDetectWhenRequestId(null /* requestId */, 2, false /* started */); + testCancelsWhenRequestId(null /* requestId */, 2, false /* started */); } @Test public void testCancels_whenAuthRequestIdMatches() { - testCancelsAuthDetectWhenRequestId(200L, 200, true /* started */); + testCancelsWhenRequestId(200L, 200, true /* started */); } @Test public void testCancels_whenAuthRequestIdMatches_noStarted() { - testCancelsAuthDetectWhenRequestId(200L, 200, false /* started */); + testCancelsWhenRequestId(200L, 200, false /* started */); } @Test public void testDoesNotCancel_whenAuthRequestIdMismatched() { - testCancelsAuthDetectWhenRequestId(10L, 20, true /* started */); + testCancelsWhenRequestId(10L, 20, true /* started */); } @Test public void testDoesNotCancel_whenAuthRequestIdMismatched_notStarted() { - testCancelsAuthDetectWhenRequestId(10L, 20, false /* started */); - } - - private void testCancelsAuthDetectWhenRequestId(@Nullable Long requestId, long cancelRequestId, - boolean started) { - final HalClientMonitor.LazyDaemon lazyDaemon = () -> mock(Object.class); - final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class); - testCancelsWhenRequestId(requestId, cancelRequestId, started, - new TestAuthenticationClient(mContext, lazyDaemon, mToken, callback)); - } - - @Test - public void testCancels_whenEnrollRequestIdNotSet() { - testCancelsEnrollWhenRequestId(null /* requestId */, 2, false /* started */); - } - - @Test - public void testCancels_whenEnrollRequestIdMatches() { - testCancelsEnrollWhenRequestId(200L, 200, false /* started */); - } - - @Test - public void testDoesNotCancel_whenEnrollRequestIdMismatched() { - testCancelsEnrollWhenRequestId(10L, 20, false /* started */); - } - - private void testCancelsEnrollWhenRequestId(@Nullable Long requestId, long cancelRequestId, - boolean started) { - final HalClientMonitor.LazyDaemon lazyDaemon = () -> mock(Object.class); - final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class); - testCancelsWhenRequestId(requestId, cancelRequestId, started, - new TestEnrollClient(mContext, lazyDaemon, mToken, callback)); + testCancelsWhenRequestId(10L, 20, false /* started */); } private void testCancelsWhenRequestId(@Nullable Long requestId, long cancelRequestId, - boolean started, HalClientMonitor client) { + boolean started) { final boolean matches = requestId == null || requestId == cancelRequestId; + final HalClientMonitor.LazyDaemon lazyDaemon = () -> mock(Object.class); + final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class); + final TestAuthenticationClient client = new TestAuthenticationClient( + mContext, lazyDaemon, mToken, callback); if (requestId != null) { client.setRequestId(requestId); } - final boolean isAuth = client instanceof TestAuthenticationClient; - final boolean isEnroll = client instanceof TestEnrollClient; - mScheduler.scheduleClientMonitor(client); if (started) { mScheduler.startPreparedClient(client.getCookie()); } waitForIdle(); - if (isAuth) { - mScheduler.cancelAuthenticationOrDetection(mToken, cancelRequestId); - } else if (isEnroll) { - mScheduler.cancelEnrollment(mToken, cancelRequestId); - } else { - fail("unexpected operation type"); - } + mScheduler.cancelAuthenticationOrDetection(mToken, cancelRequestId); waitForIdle(); - if (isAuth) { - // auth clients that were waiting for cookie when canceled should never invoke the hal - final TestAuthenticationClient authClient = (TestAuthenticationClient) client; - assertEquals(matches && started ? 1 : 0, authClient.mNumCancels); - assertEquals(started, authClient.mStartedHal); - } else if (isEnroll) { - final TestEnrollClient enrollClient = (TestEnrollClient) client; - assertEquals(matches ? 1 : 0, enrollClient.mNumCancels); - assertTrue(enrollClient.mStartedHal); - } + assertEquals(matches && started ? 1 : 0, client.mNumCancels); if (matches) { - if (started || isEnroll) { // prep'd auth clients and enroll clients - assertTrue(mScheduler.mCurrentOperation.isCanceling()); + if (started) { + assertEquals(Operation.STATE_STARTED_CANCELING, + mScheduler.mCurrentOperation.mState); } } else { - if (started || isEnroll) { // prep'd auth clients and enroll clients - assertTrue(mScheduler.mCurrentOperation.isStarted()); + if (started) { + assertEquals(Operation.STATE_STARTED, + mScheduler.mCurrentOperation.mState); } else { - assertNotEquals(0, mScheduler.mCurrentOperation.isReadyToStart()); + assertEquals(Operation.STATE_WAITING_FOR_COOKIE, + mScheduler.mCurrentOperation.mState); } } } @@ -457,14 +411,18 @@ public class BiometricSchedulerTest { mScheduler.cancelAuthenticationOrDetection(mToken, 9999); waitForIdle(); - assertTrue(mScheduler.mCurrentOperation.isStarted()); - assertFalse(mScheduler.mPendingOperations.getFirst().isStarted()); + assertEquals(Operation.STATE_STARTED, + mScheduler.mCurrentOperation.mState); + assertEquals(Operation.STATE_WAITING_IN_QUEUE, + mScheduler.mPendingOperations.getFirst().mState); mScheduler.cancelAuthenticationOrDetection(mToken, requestId2); waitForIdle(); - assertTrue(mScheduler.mCurrentOperation.isStarted()); - assertTrue(mScheduler.mPendingOperations.getFirst().isMarkedCanceling()); + assertEquals(Operation.STATE_STARTED, + mScheduler.mCurrentOperation.mState); + assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING, + mScheduler.mPendingOperations.getFirst().mState); } @Test @@ -501,12 +459,12 @@ public class BiometricSchedulerTest { @Test public void testClientDestroyed_afterFinish() { final HalClientMonitor.LazyDaemon nonNullDaemon = () -> mock(Object.class); - final TestHalClientMonitor client = - new TestHalClientMonitor(mContext, mToken, nonNullDaemon); + final TestClientMonitor client = + new TestClientMonitor(mContext, mToken, nonNullDaemon); mScheduler.scheduleClientMonitor(client); client.mCallback.onClientFinished(client, true /* success */); waitForIdle(); - assertTrue(client.mDestroyed); + assertTrue(client.wasDestroyed()); } private BiometricSchedulerProto getDump(boolean clearSchedulerBuffer) throws Exception { @@ -514,10 +472,8 @@ public class BiometricSchedulerTest { } private static class TestAuthenticationClient extends AuthenticationClient { - boolean mStartedHal = false; - boolean mStoppedHal = false; - boolean mDestroyed = false; int mNumCancels = 0; + boolean mDestroyed = false; public TestAuthenticationClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @@ -532,16 +488,18 @@ public class BiometricSchedulerTest { @Override protected void stopHalOperation() { - mStoppedHal = true; + } @Override protected void startHalOperation() { - mStartedHal = true; + } @Override - protected void handleLifecycleAfterAuth(boolean authenticated) {} + protected void handleLifecycleAfterAuth(boolean authenticated) { + + } @Override public boolean wasUserDetected() { @@ -561,59 +519,36 @@ public class BiometricSchedulerTest { } } - private static class TestEnrollClient extends EnrollClient { - boolean mStartedHal = false; - boolean mStoppedHal = false; - int mNumCancels = 0; + private static class TestClientMonitor2 extends TestClientMonitor { + private final int mProtoEnum; - TestEnrollClient(@NonNull Context context, - @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, - @NonNull ClientMonitorCallbackConverter listener) { - super(context, lazyDaemon, token, listener, 0 /* userId */, new byte[69], - "test" /* owner */, mock(BiometricUtils.class), - 5 /* timeoutSec */, 0 /* statsModality */, TEST_SENSOR_ID, - true /* shouldVibrate */); + public TestClientMonitor2(@NonNull Context context, @NonNull IBinder token, + @NonNull LazyDaemon lazyDaemon, int protoEnum) { + super(context, token, lazyDaemon); + mProtoEnum = protoEnum; } @Override - protected void stopHalOperation() { - mStoppedHal = true; - } - - @Override - protected void startHalOperation() { - mStartedHal = true; - } - - @Override - protected boolean hasReachedEnrollmentLimit() { - return false; - } - - @Override - public void cancel() { - mNumCancels++; - super.cancel(); + public int getProtoEnum() { + return mProtoEnum; } } - private static class TestHalClientMonitor extends HalClientMonitor { - private final int mProtoEnum; + private static class TestClientMonitor extends HalClientMonitor { private boolean mUnableToStart; private boolean mStarted; private boolean mDestroyed; - TestHalClientMonitor(@NonNull Context context, @NonNull IBinder token, + public TestClientMonitor(@NonNull Context context, @NonNull IBinder token, @NonNull LazyDaemon lazyDaemon) { - this(context, token, lazyDaemon, 0 /* cookie */, BiometricsProto.CM_UPDATE_ACTIVE_USER); + this(context, token, lazyDaemon, 0 /* cookie */); } - TestHalClientMonitor(@NonNull Context context, @NonNull IBinder token, - @NonNull LazyDaemon lazyDaemon, int cookie, int protoEnum) { + public TestClientMonitor(@NonNull Context context, @NonNull IBinder token, + @NonNull LazyDaemon lazyDaemon, int cookie) { super(context, lazyDaemon, token /* token */, null /* listener */, 0 /* userId */, TAG, cookie, TEST_SENSOR_ID, 0 /* statsModality */, 0 /* statsAction */, 0 /* statsClient */); - mProtoEnum = protoEnum; } @Override @@ -624,7 +559,9 @@ public class BiometricSchedulerTest { @Override public int getProtoEnum() { - return mProtoEnum; + // Anything other than CM_NONE, which is used to represent "idle". Tests that need + // real proto enums should use TestClientMonitor2 + return BiometricsProto.CM_UPDATE_ACTIVE_USER; } @Override @@ -636,7 +573,7 @@ public class BiometricSchedulerTest { @Override protected void startHalOperation() { - mStarted = true; + } @Override @@ -644,9 +581,22 @@ public class BiometricSchedulerTest { super.destroy(); mDestroyed = true; } + + public boolean wasUnableToStart() { + return mUnableToStart; + } + + public boolean hasStarted() { + return mStarted; + } + + public boolean wasDestroyed() { + return mDestroyed; + } + } - private void waitForIdle() { - TestableLooper.get(this).processAllMessages(); + private static void waitForIdle() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java index 407f5fb04adf7..7fccd49db04b1 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java @@ -16,8 +16,6 @@ package com.android.server.biometrics.sensors; -import static android.testing.TestableLooper.RunWithLooper; - import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; @@ -30,53 +28,52 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.hardware.biometrics.IBiometricService; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; import android.os.UserHandle; import android.platform.test.annotations.Presubmit; -import android.testing.AndroidTestingRunner; -import android.testing.TestableLooper; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @Presubmit -@RunWith(AndroidTestingRunner.class) -@RunWithLooper @SmallTest public class UserAwareBiometricSchedulerTest { - private static final String TAG = "UserAwareBiometricSchedulerTest"; + private static final String TAG = "BiometricSchedulerTest"; private static final int TEST_SENSOR_ID = 0; - private Handler mHandler; private UserAwareBiometricScheduler mScheduler; - private IBinder mToken = new Binder(); + private IBinder mToken; @Mock private Context mContext; @Mock private IBiometricService mBiometricService; - private TestUserStartedCallback mUserStartedCallback = new TestUserStartedCallback(); - private TestUserStoppedCallback mUserStoppedCallback = new TestUserStoppedCallback(); + private TestUserStartedCallback mUserStartedCallback; + private TestUserStoppedCallback mUserStoppedCallback; private int mCurrentUserId = UserHandle.USER_NULL; - private boolean mStartOperationsFinish = true; - private int mStartUserClientCount = 0; + private boolean mStartOperationsFinish; + private int mStartUserClientCount; @Before public void setUp() { MockitoAnnotations.initMocks(this); - mHandler = new Handler(TestableLooper.get(this).getLooper()); + + mToken = new Binder(); + mStartOperationsFinish = true; + mStartUserClientCount = 0; + mUserStartedCallback = new TestUserStartedCallback(); + mUserStoppedCallback = new TestUserStoppedCallback(); + mScheduler = new UserAwareBiometricScheduler(TAG, - mHandler, BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityDispatcher */, mBiometricService, @@ -120,7 +117,7 @@ public class UserAwareBiometricSchedulerTest { mCurrentUserId = UserHandle.USER_NULL; mStartOperationsFinish = false; - final BaseClientMonitor[] nextClients = new BaseClientMonitor[]{ + final BaseClientMonitor[] nextClients = new BaseClientMonitor[] { mock(BaseClientMonitor.class), mock(BaseClientMonitor.class), mock(BaseClientMonitor.class) @@ -150,11 +147,11 @@ public class UserAwareBiometricSchedulerTest { waitForIdle(); final TestStartUserClient startUserClient = - (TestStartUserClient) mScheduler.mCurrentOperation.getClientMonitor(); + (TestStartUserClient) mScheduler.mCurrentOperation.mClientMonitor; mScheduler.reset(); assertNull(mScheduler.mCurrentOperation); - final BiometricSchedulerOperation fakeOperation = new BiometricSchedulerOperation( + final BiometricScheduler.Operation fakeOperation = new BiometricScheduler.Operation( mock(BaseClientMonitor.class), new BaseClientMonitor.Callback() {}); mScheduler.mCurrentOperation = fakeOperation; startUserClient.mCallback.onClientFinished(startUserClient, true); @@ -197,8 +194,8 @@ public class UserAwareBiometricSchedulerTest { verify(nextClient).start(any()); } - private void waitForIdle() { - TestableLooper.get(this).processAllMessages(); + private static void waitForIdle() { + InstrumentationRegistry.getInstrumentation().waitForIdleSync(); } private class TestUserStoppedCallback implements StopUserClient.UserStoppedCallback { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java index 0891eca9f61c0..a13dff21439d6 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java @@ -79,7 +79,6 @@ public class SensorTest { when(mContext.getSystemService(Context.BIOMETRIC_SERVICE)).thenReturn(mBiometricService); mScheduler = new UserAwareBiometricScheduler(TAG, - new Handler(mLooper.getLooper()), BiometricScheduler.SENSOR_TYPE_FACE, null /* gestureAvailabilityDispatcher */, () -> USER_ID, diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java index 21a7a8ae65b97..39c51d5f5e5e1 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/hidl/Face10Test.java @@ -32,9 +32,7 @@ import android.hardware.face.FaceSensorProperties; import android.hardware.face.FaceSensorPropertiesInternal; import android.hardware.face.IFaceServiceReceiver; import android.os.Binder; -import android.os.Handler; import android.os.IBinder; -import android.os.Looper; import android.os.UserManager; import android.platform.test.annotations.Presubmit; @@ -71,7 +69,6 @@ public class Face10Test { @Mock private BiometricScheduler mScheduler; - private final Handler mHandler = new Handler(Looper.getMainLooper()); private LockoutResetDispatcher mLockoutResetDispatcher; private com.android.server.biometrics.sensors.face.hidl.Face10 mFace10; private IBinder mBinder; @@ -100,7 +97,7 @@ public class Face10Test { resetLockoutRequiresChallenge); Face10.sSystemClock = Clock.fixed(Instant.ofEpochMilli(100), ZoneId.of("PST")); - mFace10 = new Face10(mContext, sensorProps, mLockoutResetDispatcher, mHandler, mScheduler); + mFace10 = new Face10(mContext, sensorProps, mLockoutResetDispatcher, mScheduler); mBinder = new Binder(); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java index a012b8b06c7f5..0d520ca9a4e41 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java @@ -79,7 +79,6 @@ public class SensorTest { when(mContext.getSystemService(Context.BIOMETRIC_SERVICE)).thenReturn(mBiometricService); mScheduler = new UserAwareBiometricScheduler(TAG, - new Handler(mLooper.getLooper()), BiometricScheduler.SENSOR_TYPE_FP_OTHER, null /* gestureAvailabilityDispatcher */, () -> USER_ID, From 9fdff9bb07db462d8afb1ac1d6ad26ec3c4755ed Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Wed, 19 Jan 2022 16:00:50 +0000 Subject: [PATCH 095/176] Revert "Implement Java Choreographer multi frame timeline." Revert "Use FrameData for Choreographer upgrade." Revert "CTS for Java Choreographer frame timeline API." Revert submission 16569180-javachoreo Reason for revert: Droidfood blocking bug: 215299245 Reverted Changes: I822782874:Implement Java Choreographer multi frame timeline.... I80eb378e6:Use FrameData for Choreographer upgrade. I561845761:CTS for Java Choreographer frame timeline API. Change-Id: Ic1ae32b46fa072b1f1c577d80258bca91506a704 (cherry picked from commit e7a48fba65d5a0b55971a04d995ec2338f78716f) Merged-In:Ic1ae32b46fa072b1f1c577d80258bca91506a704 --- core/api/current.txt | 18 -- core/java/android/view/Choreographer.java | 212 ++---------------- .../android/view/DisplayEventReceiver.java | 53 ++--- .../jni/android_view_DisplayEventReceiver.cpp | 63 +----- 4 files changed, 32 insertions(+), 314 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 280eb8023766b..ea6ab0ce14a1b 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -48079,33 +48079,15 @@ package android.view { public final class Choreographer { method public static android.view.Choreographer getInstance(); - method public void postExtendedFrameCallback(@NonNull android.view.Choreographer.ExtendedFrameCallback); method public void postFrameCallback(android.view.Choreographer.FrameCallback); method public void postFrameCallbackDelayed(android.view.Choreographer.FrameCallback, long); - method public void removeExtendedFrameCallback(@Nullable android.view.Choreographer.ExtendedFrameCallback); method public void removeFrameCallback(android.view.Choreographer.FrameCallback); } - public static interface Choreographer.ExtendedFrameCallback { - method public void onVsync(@NonNull android.view.Choreographer.FrameData); - } - public static interface Choreographer.FrameCallback { method public void doFrame(long); } - public static class Choreographer.FrameData { - method public long getFrameTimeNanos(); - method @NonNull public android.view.Choreographer.FrameTimeline[] getFrameTimelines(); - method @NonNull public android.view.Choreographer.FrameTimeline getPreferredFrameTimeline(); - } - - public static class Choreographer.FrameTimeline { - method public long getDeadlineNanos(); - method public long getExpectedPresentTimeNanos(); - method public long getVsyncId(); - } - public interface CollapsibleActionView { method public void onActionViewCollapsed(); method public void onActionViewExpanded(); diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 9b8523f9b0061..be172f748b55f 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -19,9 +19,6 @@ package android.view; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.FrameInfo; @@ -154,15 +151,10 @@ public final class Choreographer { private static final int MSG_DO_SCHEDULE_VSYNC = 1; private static final int MSG_DO_SCHEDULE_CALLBACK = 2; - // All frame callbacks posted by applications have this token or EXTENDED_FRAME_CALLBACK_TOKEN. + // All frame callbacks posted by applications have this token. private static final Object FRAME_CALLBACK_TOKEN = new Object() { public String toString() { return "FRAME_CALLBACK_TOKEN"; } }; - private static final Object EXTENDED_FRAME_CALLBACK_TOKEN = new Object() { - public String toString() { - return "EXTENDED_FRAME_CALLBACK_TOKEN"; - } - }; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Object mLock = new Object(); @@ -491,24 +483,6 @@ public final class Choreographer { } } - /** - * Posts an extended frame callback to run on the next frame. - *

    - * The callback runs once then is automatically removed. - *

    - * - * @param callback The extended frame callback to run during the next frame. - * - * @see #removeExtendedFrameCallback - */ - public void postExtendedFrameCallback(@NonNull ExtendedFrameCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - - postCallbackDelayedInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN, 0); - } - /** * Removes callbacks that have the specified action and token. * @@ -598,21 +572,6 @@ public final class Choreographer { removeCallbacksInternal(CALLBACK_ANIMATION, callback, FRAME_CALLBACK_TOKEN); } - /** - * Removes a previously posted extended frame callback. - * - * @param callback The extended frame callback to remove. - * - * @see #postExtendedFrameCallback - */ - public void removeExtendedFrameCallback(@Nullable ExtendedFrameCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - - removeCallbacksInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN); - } - /** * Gets the time when the current frame started. *

    @@ -714,7 +673,7 @@ public final class Choreographer { * @hide */ public long getVsyncId() { - return mLastVsyncEventData.preferredFrameTimeline().vsyncId; + return mLastVsyncEventData.id; } /** @@ -725,7 +684,7 @@ public final class Choreographer { * @hide */ public long getFrameDeadline() { - return mLastVsyncEventData.preferredFrameTimeline().deadline; + return mLastVsyncEventData.frameDeadline; } void setFPSDivisor(int divisor) { @@ -746,9 +705,8 @@ public final class Choreographer { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "Choreographer#doFrame " + vsyncEventData.preferredFrameTimeline().vsyncId); + "Choreographer#doFrame " + vsyncEventData.id); } - FrameData frameData = new FrameData(frameTimeNanos, vsyncEventData); synchronized (mLock) { if (!mFrameScheduled) { traceMessage("Frame not scheduled"); @@ -779,7 +737,6 @@ public final class Choreographer { + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past."); } frameTimeNanos = startNanos - lastFrameOffset; - frameData.setFrameTimeNanos(-lastFrameOffset); } if (frameTimeNanos < mLastFrameTimeNanos) { @@ -801,10 +758,8 @@ public final class Choreographer { } } - mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, - vsyncEventData.preferredFrameTimeline().vsyncId, - vsyncEventData.preferredFrameTimeline().deadline, startNanos, - vsyncEventData.frameInterval); + mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id, + vsyncEventData.frameDeadline, startNanos, vsyncEventData.frameInterval); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastFrameIntervalNanos = frameIntervalNanos; @@ -814,17 +769,17 @@ public final class Choreographer { AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS); mFrameInfo.markInputHandlingStart(); - doCallbacks(Choreographer.CALLBACK_INPUT, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos, frameIntervalNanos); mFrameInfo.markAnimationsStart(); - doCallbacks(Choreographer.CALLBACK_ANIMATION, frameData, frameIntervalNanos); - doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameData, + doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos, frameIntervalNanos); mFrameInfo.markPerformTraversalsStart(); - doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, frameIntervalNanos); - doCallbacks(Choreographer.CALLBACK_COMMIT, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, frameIntervalNanos); } finally { AnimationUtils.unlockAnimationClock(); Trace.traceEnd(Trace.TRACE_TAG_VIEW); @@ -838,9 +793,8 @@ public final class Choreographer { } } - void doCallbacks(int callbackType, FrameData frameData, long frameIntervalNanos) { + void doCallbacks(int callbackType, long frameTimeNanos, long frameIntervalNanos) { CallbackRecord callbacks; - long frameTimeNanos = frameData.mFrameTimeNanos; synchronized (mLock) { // We use "now" to determine when callbacks become due because it's possible // for earlier processing phases in a frame to post callbacks that should run @@ -877,7 +831,6 @@ public final class Choreographer { } frameTimeNanos = now - lastFrameOffset; mLastFrameTimeNanos = frameTimeNanos; - frameData.setFrameTimeNanos(frameTimeNanos); } } } @@ -889,7 +842,7 @@ public final class Choreographer { + ", action=" + c.action + ", token=" + c.token + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime)); } - c.run(frameData); + c.run(frameTimeNanos); } } finally { synchronized (mLock) { @@ -989,130 +942,6 @@ public final class Choreographer { public void doFrame(long frameTimeNanos); } - /** Holds data that describes one possible VSync frame event to render at. */ - public static class FrameTimeline { - static final FrameTimeline INVALID_FRAME_TIMELINE = new FrameTimeline( - FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE); - - FrameTimeline(long vsyncId, long expectedPresentTimeNanos, long deadlineNanos) { - this.mVsyncId = vsyncId; - this.mExpectedPresentTimeNanos = expectedPresentTimeNanos; - this.mDeadlineNanos = deadlineNanos; - } - - private long mVsyncId; - private long mExpectedPresentTimeNanos; - private long mDeadlineNanos; - - /** - * The id that corresponds to this frame timeline, used to correlate a frame - * produced by HWUI with the timeline data stored in Surface Flinger. - */ - public long getVsyncId() { - return mVsyncId; - } - - /** Sets the vsync ID. */ - void resetVsyncId() { - mVsyncId = FrameInfo.INVALID_VSYNC_ID; - } - - /** - * The time in {@link System#nanoTime()} timebase which this frame is expected to be - * presented. - */ - public long getExpectedPresentTimeNanos() { - return mExpectedPresentTimeNanos; - } - - /** - * The time in {@link System#nanoTime()} timebase which this frame needs to be ready by. - */ - public long getDeadlineNanos() { - return mDeadlineNanos; - } - } - - /** - * The payload for {@link ExtendedFrameCallback} which includes frame information such as when - * the frame started being rendered, and multiple possible frame timelines and their - * information including deadline and expected present time. - */ - public static class FrameData { - static final FrameTimeline[] INVALID_FRAME_TIMELINES = new FrameTimeline[0]; - FrameData() { - this.mFrameTimelines = INVALID_FRAME_TIMELINES; - this.mPreferredFrameTimeline = FrameTimeline.INVALID_FRAME_TIMELINE; - } - - FrameData(long frameTimeNanos, DisplayEventReceiver.VsyncEventData vsyncEventData) { - FrameTimeline[] frameTimelines = - new FrameTimeline[vsyncEventData.frameTimelines.length]; - for (int i = 0; i < vsyncEventData.frameTimelines.length; i++) { - DisplayEventReceiver.VsyncEventData.FrameTimeline frameTimeline = - vsyncEventData.frameTimelines[i]; - frameTimelines[i] = new FrameTimeline(frameTimeline.vsyncId, - frameTimeline.expectedPresentTime, frameTimeline.deadline); - } - this.mFrameTimeNanos = frameTimeNanos; - this.mFrameTimelines = frameTimelines; - this.mPreferredFrameTimeline = - frameTimelines[vsyncEventData.preferredFrameTimelineIndex]; - } - - private long mFrameTimeNanos; - private final FrameTimeline[] mFrameTimelines; - private final FrameTimeline mPreferredFrameTimeline; - - void setFrameTimeNanos(long frameTimeNanos) { - mFrameTimeNanos = frameTimeNanos; - for (FrameTimeline ft : mFrameTimelines) { - // The ID is no longer valid because the frame time that was registered with the ID - // no longer matches. - // TODO(b/205721584): Ask SF for valid vsync information. - ft.resetVsyncId(); - } - } - - /** The time in nanoseconds when the frame started being rendered. */ - public long getFrameTimeNanos() { - return mFrameTimeNanos; - } - - /** The possible frame timelines, sorted chronologically. */ - @NonNull - @SuppressLint("ArrayReturn") // For API consistency and speed. - public FrameTimeline[] getFrameTimelines() { - return mFrameTimelines; - } - - /** The platform-preferred frame timeline. */ - @NonNull - public FrameTimeline getPreferredFrameTimeline() { - return mPreferredFrameTimeline; - } - } - - /** - * Implement this interface to receive a callback to start the next frame. The callback is - * invoked on the {@link Looper} thread to which the {@link Choreographer} is attached. The - * callback payload contains information about multiple possible frames, allowing choice of - * the appropriate frame based on latency requirements. - * - * @see FrameCallback - */ - public interface ExtendedFrameCallback { - /** - * Called when a new display frame is being rendered. - * - * @param data The payload which includes frame information. Divide nanosecond values by - * {@code 1000000} to convert it to the {@link SystemClock#uptimeMillis()} - * time base. - * @see FrameCallback#doFrame - **/ - void onVsync(@NonNull FrameData data); - } - private final class FrameHandler extends Handler { public FrameHandler(Looper looper) { super(looper); @@ -1154,8 +983,7 @@ public final class Choreographer { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "Choreographer#onVsync " - + vsyncEventData.preferredFrameTimeline().vsyncId); + "Choreographer#onVsync " + vsyncEventData.id); } // Post the vsync event to the Handler. // The idea is to prevent incoming vsync events from completely starving @@ -1198,9 +1026,7 @@ public final class Choreographer { private static final class CallbackRecord { public CallbackRecord next; public long dueTime; - /** Runnable or FrameCallback or ExtendedFrameCallback object. */ - public Object action; - /** Denotes the action type. */ + public Object action; // Runnable or FrameCallback public Object token; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1211,14 +1037,6 @@ public final class Choreographer { ((Runnable)action).run(); } } - - void run(FrameData frameData) { - if (token == EXTENDED_FRAME_CALLBACK_TOKEN) { - ((ExtendedFrameCallback) action).onVsync(frameData); - } else { - run(frameData.getFrameTimeNanos()); - } - } } private final class CallbackQueue { diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 774bab41fb9a9..5c086328bda73 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -138,28 +138,13 @@ public abstract class DisplayEventReceiver { } static final class VsyncEventData { + // The frame timeline vsync id, used to correlate a frame + // produced by HWUI with the timeline data stored in Surface Flinger. + public final long id; - static final FrameTimeline[] INVALID_FRAME_TIMELINES = - {new FrameTimeline(FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE)}; - - public static class FrameTimeline { - FrameTimeline(long vsyncId, long expectedPresentTime, long deadline) { - this.vsyncId = vsyncId; - this.expectedPresentTime = expectedPresentTime; - this.deadline = deadline; - } - - // The frame timeline vsync id, used to correlate a frame - // produced by HWUI with the timeline data stored in Surface Flinger. - public final long vsyncId; - - // The frame timestamp for when the frame is expected to be presented. - public final long expectedPresentTime; - - // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is - // allotted for the frame to be completed. - public final long deadline; - } + // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is + // allotted for the frame to be completed. + public final long frameDeadline; /** * The current interval between frames in ns. This will be used to align @@ -168,27 +153,16 @@ public abstract class DisplayEventReceiver { */ public final long frameInterval; - public final FrameTimeline[] frameTimelines; - - public final int preferredFrameTimelineIndex; - - // Called from native code. - @SuppressWarnings("unused") - VsyncEventData(FrameTimeline[] frameTimelines, int preferredFrameTimelineIndex, - long frameInterval) { - this.frameTimelines = frameTimelines; - this.preferredFrameTimelineIndex = preferredFrameTimelineIndex; + VsyncEventData(long id, long frameDeadline, long frameInterval) { + this.id = id; + this.frameDeadline = frameDeadline; this.frameInterval = frameInterval; } VsyncEventData() { + this.id = FrameInfo.INVALID_VSYNC_ID; + this.frameDeadline = Long.MAX_VALUE; this.frameInterval = -1; - this.frameTimelines = INVALID_FRAME_TIMELINES; - this.preferredFrameTimelineIndex = 0; - } - - public FrameTimeline preferredFrameTimeline() { - return frameTimelines[preferredFrameTimelineIndex]; } } @@ -282,8 +256,9 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, - VsyncEventData vsyncEventData) { - onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); + long frameTimelineVsyncId, long frameDeadline, long frameInterval) { + onVsync(timestampNanos, physicalDisplayId, frame, + new VsyncEventData(frameTimelineVsyncId, frameDeadline, frameInterval)); } // Called from native code. diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index d91d526e3d4c4..ce772cf9faff0 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -48,16 +48,6 @@ static struct { jmethodID init; } frameRateOverrideClassInfo; - struct { - jclass clazz; - jmethodID init; - } frameTimelineClassInfo; - - struct { - jclass clazz; - jmethodID init; - } vsyncEventDataClassInfo; - } gDisplayEventReceiverClassInfo; @@ -115,38 +105,9 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); - - ScopedLocalRef - frameTimelineObjs(env, - env->NewObjectArray(vsyncEventData.frameTimelines.size(), - gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.clazz, - /*initial element*/ NULL)); - for (int i = 0; i < vsyncEventData.frameTimelines.size(); i++) { - VsyncEventData::FrameTimeline frameTimeline = vsyncEventData.frameTimelines[i]; - ScopedLocalRef - frameTimelineObj(env, - env->NewObject(gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.clazz, - gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.init, - frameTimeline.id, - frameTimeline.expectedPresentTime, - frameTimeline.deadlineTimestamp)); - env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get()); - } - ScopedLocalRef - vsyncEventDataJava(env, - env->NewObject(gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo.clazz, - gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo.init, - frameTimelineObjs.get(), - vsyncEventData.preferredFrameTimelineIndex, - vsyncEventData.frameInterval)); - env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, - timestamp, displayId.value, count, vsyncEventDataJava.get()); + timestamp, displayId.value, count, vsyncEventData.id, + vsyncEventData.deadlineTimestamp, vsyncEventData.frameInterval); ALOGV("receiver %p ~ Returned from vsync handler.", this); } @@ -278,7 +239,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", - "(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V"); + "(JJIJJJ)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchModeChanged = @@ -297,24 +258,6 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.clazz, "", "(IF)V"); - jclass frameTimelineClazz = - FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData$FrameTimeline"); - gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz = - MakeGlobalRefOrDie(env, frameTimelineClazz); - gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, - "", "(JJJ)V"); - - jclass vsyncEventDataClazz = - FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData"); - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz = - MakeGlobalRefOrDie(env, vsyncEventDataClazz); - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.init = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, - "", - "([Landroid/view/" - "DisplayEventReceiver$VsyncEventData$FrameTimeline;IJ)V"); - return res; } From 74b4c1e1e9bdbff648102b35bae58cd4c341a099 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Wed, 19 Jan 2022 16:00:50 +0000 Subject: [PATCH 096/176] Revert "Implement Java Choreographer multi frame timeline." Revert "Use FrameData for Choreographer upgrade." Revert "CTS for Java Choreographer frame timeline API." Revert submission 16569180-javachoreo Reason for revert: Droidfood blocking bug: 215299245 Reverted Changes: I822782874:Implement Java Choreographer multi frame timeline.... I80eb378e6:Use FrameData for Choreographer upgrade. I561845761:CTS for Java Choreographer frame timeline API. Change-Id: Ic1ae32b46fa072b1f1c577d80258bca91506a704 (cherry picked from commit e7a48fba65d5a0b55971a04d995ec2338f78716f) Merged-In:Ic1ae32b46fa072b1f1c577d80258bca91506a704 --- core/api/current.txt | 18 -- core/java/android/view/Choreographer.java | 212 ++---------------- .../android/view/DisplayEventReceiver.java | 53 ++--- .../jni/android_view_DisplayEventReceiver.cpp | 63 +----- 4 files changed, 32 insertions(+), 314 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 06e3bd038e799..7ea8f317866b2 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -48163,33 +48163,15 @@ package android.view { public final class Choreographer { method public static android.view.Choreographer getInstance(); - method public void postExtendedFrameCallback(@NonNull android.view.Choreographer.ExtendedFrameCallback); method public void postFrameCallback(android.view.Choreographer.FrameCallback); method public void postFrameCallbackDelayed(android.view.Choreographer.FrameCallback, long); - method public void removeExtendedFrameCallback(@Nullable android.view.Choreographer.ExtendedFrameCallback); method public void removeFrameCallback(android.view.Choreographer.FrameCallback); } - public static interface Choreographer.ExtendedFrameCallback { - method public void onVsync(@NonNull android.view.Choreographer.FrameData); - } - public static interface Choreographer.FrameCallback { method public void doFrame(long); } - public static class Choreographer.FrameData { - method public long getFrameTimeNanos(); - method @NonNull public android.view.Choreographer.FrameTimeline[] getFrameTimelines(); - method @NonNull public android.view.Choreographer.FrameTimeline getPreferredFrameTimeline(); - } - - public static class Choreographer.FrameTimeline { - method public long getDeadlineNanos(); - method public long getExpectedPresentTimeNanos(); - method public long getVsyncId(); - } - public interface CollapsibleActionView { method public void onActionViewCollapsed(); method public void onActionViewExpanded(); diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 9b8523f9b0061..be172f748b55f 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -19,9 +19,6 @@ package android.view; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.FrameInfo; @@ -154,15 +151,10 @@ public final class Choreographer { private static final int MSG_DO_SCHEDULE_VSYNC = 1; private static final int MSG_DO_SCHEDULE_CALLBACK = 2; - // All frame callbacks posted by applications have this token or EXTENDED_FRAME_CALLBACK_TOKEN. + // All frame callbacks posted by applications have this token. private static final Object FRAME_CALLBACK_TOKEN = new Object() { public String toString() { return "FRAME_CALLBACK_TOKEN"; } }; - private static final Object EXTENDED_FRAME_CALLBACK_TOKEN = new Object() { - public String toString() { - return "EXTENDED_FRAME_CALLBACK_TOKEN"; - } - }; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Object mLock = new Object(); @@ -491,24 +483,6 @@ public final class Choreographer { } } - /** - * Posts an extended frame callback to run on the next frame. - *

    - * The callback runs once then is automatically removed. - *

    - * - * @param callback The extended frame callback to run during the next frame. - * - * @see #removeExtendedFrameCallback - */ - public void postExtendedFrameCallback(@NonNull ExtendedFrameCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - - postCallbackDelayedInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN, 0); - } - /** * Removes callbacks that have the specified action and token. * @@ -598,21 +572,6 @@ public final class Choreographer { removeCallbacksInternal(CALLBACK_ANIMATION, callback, FRAME_CALLBACK_TOKEN); } - /** - * Removes a previously posted extended frame callback. - * - * @param callback The extended frame callback to remove. - * - * @see #postExtendedFrameCallback - */ - public void removeExtendedFrameCallback(@Nullable ExtendedFrameCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - - removeCallbacksInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN); - } - /** * Gets the time when the current frame started. *

    @@ -714,7 +673,7 @@ public final class Choreographer { * @hide */ public long getVsyncId() { - return mLastVsyncEventData.preferredFrameTimeline().vsyncId; + return mLastVsyncEventData.id; } /** @@ -725,7 +684,7 @@ public final class Choreographer { * @hide */ public long getFrameDeadline() { - return mLastVsyncEventData.preferredFrameTimeline().deadline; + return mLastVsyncEventData.frameDeadline; } void setFPSDivisor(int divisor) { @@ -746,9 +705,8 @@ public final class Choreographer { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "Choreographer#doFrame " + vsyncEventData.preferredFrameTimeline().vsyncId); + "Choreographer#doFrame " + vsyncEventData.id); } - FrameData frameData = new FrameData(frameTimeNanos, vsyncEventData); synchronized (mLock) { if (!mFrameScheduled) { traceMessage("Frame not scheduled"); @@ -779,7 +737,6 @@ public final class Choreographer { + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past."); } frameTimeNanos = startNanos - lastFrameOffset; - frameData.setFrameTimeNanos(-lastFrameOffset); } if (frameTimeNanos < mLastFrameTimeNanos) { @@ -801,10 +758,8 @@ public final class Choreographer { } } - mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, - vsyncEventData.preferredFrameTimeline().vsyncId, - vsyncEventData.preferredFrameTimeline().deadline, startNanos, - vsyncEventData.frameInterval); + mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id, + vsyncEventData.frameDeadline, startNanos, vsyncEventData.frameInterval); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastFrameIntervalNanos = frameIntervalNanos; @@ -814,17 +769,17 @@ public final class Choreographer { AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS); mFrameInfo.markInputHandlingStart(); - doCallbacks(Choreographer.CALLBACK_INPUT, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos, frameIntervalNanos); mFrameInfo.markAnimationsStart(); - doCallbacks(Choreographer.CALLBACK_ANIMATION, frameData, frameIntervalNanos); - doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameData, + doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos, frameIntervalNanos); mFrameInfo.markPerformTraversalsStart(); - doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, frameIntervalNanos); - doCallbacks(Choreographer.CALLBACK_COMMIT, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, frameIntervalNanos); } finally { AnimationUtils.unlockAnimationClock(); Trace.traceEnd(Trace.TRACE_TAG_VIEW); @@ -838,9 +793,8 @@ public final class Choreographer { } } - void doCallbacks(int callbackType, FrameData frameData, long frameIntervalNanos) { + void doCallbacks(int callbackType, long frameTimeNanos, long frameIntervalNanos) { CallbackRecord callbacks; - long frameTimeNanos = frameData.mFrameTimeNanos; synchronized (mLock) { // We use "now" to determine when callbacks become due because it's possible // for earlier processing phases in a frame to post callbacks that should run @@ -877,7 +831,6 @@ public final class Choreographer { } frameTimeNanos = now - lastFrameOffset; mLastFrameTimeNanos = frameTimeNanos; - frameData.setFrameTimeNanos(frameTimeNanos); } } } @@ -889,7 +842,7 @@ public final class Choreographer { + ", action=" + c.action + ", token=" + c.token + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime)); } - c.run(frameData); + c.run(frameTimeNanos); } } finally { synchronized (mLock) { @@ -989,130 +942,6 @@ public final class Choreographer { public void doFrame(long frameTimeNanos); } - /** Holds data that describes one possible VSync frame event to render at. */ - public static class FrameTimeline { - static final FrameTimeline INVALID_FRAME_TIMELINE = new FrameTimeline( - FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE); - - FrameTimeline(long vsyncId, long expectedPresentTimeNanos, long deadlineNanos) { - this.mVsyncId = vsyncId; - this.mExpectedPresentTimeNanos = expectedPresentTimeNanos; - this.mDeadlineNanos = deadlineNanos; - } - - private long mVsyncId; - private long mExpectedPresentTimeNanos; - private long mDeadlineNanos; - - /** - * The id that corresponds to this frame timeline, used to correlate a frame - * produced by HWUI with the timeline data stored in Surface Flinger. - */ - public long getVsyncId() { - return mVsyncId; - } - - /** Sets the vsync ID. */ - void resetVsyncId() { - mVsyncId = FrameInfo.INVALID_VSYNC_ID; - } - - /** - * The time in {@link System#nanoTime()} timebase which this frame is expected to be - * presented. - */ - public long getExpectedPresentTimeNanos() { - return mExpectedPresentTimeNanos; - } - - /** - * The time in {@link System#nanoTime()} timebase which this frame needs to be ready by. - */ - public long getDeadlineNanos() { - return mDeadlineNanos; - } - } - - /** - * The payload for {@link ExtendedFrameCallback} which includes frame information such as when - * the frame started being rendered, and multiple possible frame timelines and their - * information including deadline and expected present time. - */ - public static class FrameData { - static final FrameTimeline[] INVALID_FRAME_TIMELINES = new FrameTimeline[0]; - FrameData() { - this.mFrameTimelines = INVALID_FRAME_TIMELINES; - this.mPreferredFrameTimeline = FrameTimeline.INVALID_FRAME_TIMELINE; - } - - FrameData(long frameTimeNanos, DisplayEventReceiver.VsyncEventData vsyncEventData) { - FrameTimeline[] frameTimelines = - new FrameTimeline[vsyncEventData.frameTimelines.length]; - for (int i = 0; i < vsyncEventData.frameTimelines.length; i++) { - DisplayEventReceiver.VsyncEventData.FrameTimeline frameTimeline = - vsyncEventData.frameTimelines[i]; - frameTimelines[i] = new FrameTimeline(frameTimeline.vsyncId, - frameTimeline.expectedPresentTime, frameTimeline.deadline); - } - this.mFrameTimeNanos = frameTimeNanos; - this.mFrameTimelines = frameTimelines; - this.mPreferredFrameTimeline = - frameTimelines[vsyncEventData.preferredFrameTimelineIndex]; - } - - private long mFrameTimeNanos; - private final FrameTimeline[] mFrameTimelines; - private final FrameTimeline mPreferredFrameTimeline; - - void setFrameTimeNanos(long frameTimeNanos) { - mFrameTimeNanos = frameTimeNanos; - for (FrameTimeline ft : mFrameTimelines) { - // The ID is no longer valid because the frame time that was registered with the ID - // no longer matches. - // TODO(b/205721584): Ask SF for valid vsync information. - ft.resetVsyncId(); - } - } - - /** The time in nanoseconds when the frame started being rendered. */ - public long getFrameTimeNanos() { - return mFrameTimeNanos; - } - - /** The possible frame timelines, sorted chronologically. */ - @NonNull - @SuppressLint("ArrayReturn") // For API consistency and speed. - public FrameTimeline[] getFrameTimelines() { - return mFrameTimelines; - } - - /** The platform-preferred frame timeline. */ - @NonNull - public FrameTimeline getPreferredFrameTimeline() { - return mPreferredFrameTimeline; - } - } - - /** - * Implement this interface to receive a callback to start the next frame. The callback is - * invoked on the {@link Looper} thread to which the {@link Choreographer} is attached. The - * callback payload contains information about multiple possible frames, allowing choice of - * the appropriate frame based on latency requirements. - * - * @see FrameCallback - */ - public interface ExtendedFrameCallback { - /** - * Called when a new display frame is being rendered. - * - * @param data The payload which includes frame information. Divide nanosecond values by - * {@code 1000000} to convert it to the {@link SystemClock#uptimeMillis()} - * time base. - * @see FrameCallback#doFrame - **/ - void onVsync(@NonNull FrameData data); - } - private final class FrameHandler extends Handler { public FrameHandler(Looper looper) { super(looper); @@ -1154,8 +983,7 @@ public final class Choreographer { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "Choreographer#onVsync " - + vsyncEventData.preferredFrameTimeline().vsyncId); + "Choreographer#onVsync " + vsyncEventData.id); } // Post the vsync event to the Handler. // The idea is to prevent incoming vsync events from completely starving @@ -1198,9 +1026,7 @@ public final class Choreographer { private static final class CallbackRecord { public CallbackRecord next; public long dueTime; - /** Runnable or FrameCallback or ExtendedFrameCallback object. */ - public Object action; - /** Denotes the action type. */ + public Object action; // Runnable or FrameCallback public Object token; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1211,14 +1037,6 @@ public final class Choreographer { ((Runnable)action).run(); } } - - void run(FrameData frameData) { - if (token == EXTENDED_FRAME_CALLBACK_TOKEN) { - ((ExtendedFrameCallback) action).onVsync(frameData); - } else { - run(frameData.getFrameTimeNanos()); - } - } } private final class CallbackQueue { diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 774bab41fb9a9..5c086328bda73 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -138,28 +138,13 @@ public abstract class DisplayEventReceiver { } static final class VsyncEventData { + // The frame timeline vsync id, used to correlate a frame + // produced by HWUI with the timeline data stored in Surface Flinger. + public final long id; - static final FrameTimeline[] INVALID_FRAME_TIMELINES = - {new FrameTimeline(FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE)}; - - public static class FrameTimeline { - FrameTimeline(long vsyncId, long expectedPresentTime, long deadline) { - this.vsyncId = vsyncId; - this.expectedPresentTime = expectedPresentTime; - this.deadline = deadline; - } - - // The frame timeline vsync id, used to correlate a frame - // produced by HWUI with the timeline data stored in Surface Flinger. - public final long vsyncId; - - // The frame timestamp for when the frame is expected to be presented. - public final long expectedPresentTime; - - // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is - // allotted for the frame to be completed. - public final long deadline; - } + // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is + // allotted for the frame to be completed. + public final long frameDeadline; /** * The current interval between frames in ns. This will be used to align @@ -168,27 +153,16 @@ public abstract class DisplayEventReceiver { */ public final long frameInterval; - public final FrameTimeline[] frameTimelines; - - public final int preferredFrameTimelineIndex; - - // Called from native code. - @SuppressWarnings("unused") - VsyncEventData(FrameTimeline[] frameTimelines, int preferredFrameTimelineIndex, - long frameInterval) { - this.frameTimelines = frameTimelines; - this.preferredFrameTimelineIndex = preferredFrameTimelineIndex; + VsyncEventData(long id, long frameDeadline, long frameInterval) { + this.id = id; + this.frameDeadline = frameDeadline; this.frameInterval = frameInterval; } VsyncEventData() { + this.id = FrameInfo.INVALID_VSYNC_ID; + this.frameDeadline = Long.MAX_VALUE; this.frameInterval = -1; - this.frameTimelines = INVALID_FRAME_TIMELINES; - this.preferredFrameTimelineIndex = 0; - } - - public FrameTimeline preferredFrameTimeline() { - return frameTimelines[preferredFrameTimelineIndex]; } } @@ -282,8 +256,9 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, - VsyncEventData vsyncEventData) { - onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); + long frameTimelineVsyncId, long frameDeadline, long frameInterval) { + onVsync(timestampNanos, physicalDisplayId, frame, + new VsyncEventData(frameTimelineVsyncId, frameDeadline, frameInterval)); } // Called from native code. diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index d91d526e3d4c4..ce772cf9faff0 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -48,16 +48,6 @@ static struct { jmethodID init; } frameRateOverrideClassInfo; - struct { - jclass clazz; - jmethodID init; - } frameTimelineClassInfo; - - struct { - jclass clazz; - jmethodID init; - } vsyncEventDataClassInfo; - } gDisplayEventReceiverClassInfo; @@ -115,38 +105,9 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); - - ScopedLocalRef - frameTimelineObjs(env, - env->NewObjectArray(vsyncEventData.frameTimelines.size(), - gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.clazz, - /*initial element*/ NULL)); - for (int i = 0; i < vsyncEventData.frameTimelines.size(); i++) { - VsyncEventData::FrameTimeline frameTimeline = vsyncEventData.frameTimelines[i]; - ScopedLocalRef - frameTimelineObj(env, - env->NewObject(gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.clazz, - gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.init, - frameTimeline.id, - frameTimeline.expectedPresentTime, - frameTimeline.deadlineTimestamp)); - env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get()); - } - ScopedLocalRef - vsyncEventDataJava(env, - env->NewObject(gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo.clazz, - gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo.init, - frameTimelineObjs.get(), - vsyncEventData.preferredFrameTimelineIndex, - vsyncEventData.frameInterval)); - env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, - timestamp, displayId.value, count, vsyncEventDataJava.get()); + timestamp, displayId.value, count, vsyncEventData.id, + vsyncEventData.deadlineTimestamp, vsyncEventData.frameInterval); ALOGV("receiver %p ~ Returned from vsync handler.", this); } @@ -278,7 +239,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", - "(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V"); + "(JJIJJJ)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchModeChanged = @@ -297,24 +258,6 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.clazz, "", "(IF)V"); - jclass frameTimelineClazz = - FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData$FrameTimeline"); - gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz = - MakeGlobalRefOrDie(env, frameTimelineClazz); - gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, - "", "(JJJ)V"); - - jclass vsyncEventDataClazz = - FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData"); - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz = - MakeGlobalRefOrDie(env, vsyncEventDataClazz); - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.init = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, - "", - "([Landroid/view/" - "DisplayEventReceiver$VsyncEventData$FrameTimeline;IJ)V"); - return res; } From 7a7f20bcf6d511d7477fbf84429e9213a0584ab0 Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Thu, 20 Jan 2022 16:16:54 +0100 Subject: [PATCH 097/176] Remove READ_COMMUNAL_STATE from Shell This seems to have been mistakenly added back in I591b98578dbb94ca8b5be8a553b81d23a143ee16 after being removed in I51ffbfe5ddc89008d660fab7cfd5808cb827d300 Gets Android to boot without crashing the system process Fixes: 215527822 Change-Id: I5bc4920166101042ee36a97fe17a574b88caf29a (cherry picked from commit 4611f177e056a53b8bda68d3375440c516555aad) Merged-In:I5bc4920166101042ee36a97fe17a574b88caf29a --- packages/Shell/AndroidManifest.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index c1a812f5ebb8c..c16cae0412fe6 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -623,10 +623,6 @@ - - - - From cc6a06075722bacee5f5bfb8a38587d6bef209f3 Mon Sep 17 00:00:00 2001 From: Pablo Gamito Date: Thu, 20 Jan 2022 16:16:54 +0100 Subject: [PATCH 098/176] Remove READ_COMMUNAL_STATE from Shell This seems to have been mistakenly added back in I591b98578dbb94ca8b5be8a553b81d23a143ee16 after being removed in I51ffbfe5ddc89008d660fab7cfd5808cb827d300 Gets Android to boot without crashing the system process Fixes: 215527822 Change-Id: I5bc4920166101042ee36a97fe17a574b88caf29a (cherry picked from commit 4611f177e056a53b8bda68d3375440c516555aad) Merged-In:I5bc4920166101042ee36a97fe17a574b88caf29a --- packages/Shell/AndroidManifest.xml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index c1a812f5ebb8c..c16cae0412fe6 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -623,10 +623,6 @@ - - - - From 6f9e242b38583fe94e312f0e515173cb9909b257 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Wed, 19 Jan 2022 16:00:50 +0000 Subject: [PATCH 099/176] Revert "Implement Java Choreographer multi frame timeline." Revert "Use FrameData for Choreographer upgrade." Revert "CTS for Java Choreographer frame timeline API." Revert submission 16569180-javachoreo Reason for revert: Droidfood blocking bug: 215299245 Reverted Changes: I822782874:Implement Java Choreographer multi frame timeline.... I80eb378e6:Use FrameData for Choreographer upgrade. I561845761:CTS for Java Choreographer frame timeline API. Change-Id: Ic1ae32b46fa072b1f1c577d80258bca91506a704 (cherry picked from commit e7a48fba65d5a0b55971a04d995ec2338f78716f) Merged-In:Ic1ae32b46fa072b1f1c577d80258bca91506a704 --- core/api/current.txt | 18 -- core/java/android/view/Choreographer.java | 212 ++---------------- .../android/view/DisplayEventReceiver.java | 53 ++--- .../jni/android_view_DisplayEventReceiver.cpp | 63 +----- 4 files changed, 32 insertions(+), 314 deletions(-) diff --git a/core/api/current.txt b/core/api/current.txt index 69422212fb841..e4f89d03f5f06 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -48167,33 +48167,15 @@ package android.view { public final class Choreographer { method public static android.view.Choreographer getInstance(); - method public void postExtendedFrameCallback(@NonNull android.view.Choreographer.ExtendedFrameCallback); method public void postFrameCallback(android.view.Choreographer.FrameCallback); method public void postFrameCallbackDelayed(android.view.Choreographer.FrameCallback, long); - method public void removeExtendedFrameCallback(@Nullable android.view.Choreographer.ExtendedFrameCallback); method public void removeFrameCallback(android.view.Choreographer.FrameCallback); } - public static interface Choreographer.ExtendedFrameCallback { - method public void onVsync(@NonNull android.view.Choreographer.FrameData); - } - public static interface Choreographer.FrameCallback { method public void doFrame(long); } - public static class Choreographer.FrameData { - method public long getFrameTimeNanos(); - method @NonNull public android.view.Choreographer.FrameTimeline[] getFrameTimelines(); - method @NonNull public android.view.Choreographer.FrameTimeline getPreferredFrameTimeline(); - } - - public static class Choreographer.FrameTimeline { - method public long getDeadlineNanos(); - method public long getExpectedPresentTimeNanos(); - method public long getVsyncId(); - } - public interface CollapsibleActionView { method public void onActionViewCollapsed(); method public void onActionViewExpanded(); diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 9b8523f9b0061..be172f748b55f 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -19,9 +19,6 @@ package android.view; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SuppressLint; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.FrameInfo; @@ -154,15 +151,10 @@ public final class Choreographer { private static final int MSG_DO_SCHEDULE_VSYNC = 1; private static final int MSG_DO_SCHEDULE_CALLBACK = 2; - // All frame callbacks posted by applications have this token or EXTENDED_FRAME_CALLBACK_TOKEN. + // All frame callbacks posted by applications have this token. private static final Object FRAME_CALLBACK_TOKEN = new Object() { public String toString() { return "FRAME_CALLBACK_TOKEN"; } }; - private static final Object EXTENDED_FRAME_CALLBACK_TOKEN = new Object() { - public String toString() { - return "EXTENDED_FRAME_CALLBACK_TOKEN"; - } - }; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private final Object mLock = new Object(); @@ -491,24 +483,6 @@ public final class Choreographer { } } - /** - * Posts an extended frame callback to run on the next frame. - *

    - * The callback runs once then is automatically removed. - *

    - * - * @param callback The extended frame callback to run during the next frame. - * - * @see #removeExtendedFrameCallback - */ - public void postExtendedFrameCallback(@NonNull ExtendedFrameCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - - postCallbackDelayedInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN, 0); - } - /** * Removes callbacks that have the specified action and token. * @@ -598,21 +572,6 @@ public final class Choreographer { removeCallbacksInternal(CALLBACK_ANIMATION, callback, FRAME_CALLBACK_TOKEN); } - /** - * Removes a previously posted extended frame callback. - * - * @param callback The extended frame callback to remove. - * - * @see #postExtendedFrameCallback - */ - public void removeExtendedFrameCallback(@Nullable ExtendedFrameCallback callback) { - if (callback == null) { - throw new IllegalArgumentException("callback must not be null"); - } - - removeCallbacksInternal(CALLBACK_ANIMATION, callback, EXTENDED_FRAME_CALLBACK_TOKEN); - } - /** * Gets the time when the current frame started. *

    @@ -714,7 +673,7 @@ public final class Choreographer { * @hide */ public long getVsyncId() { - return mLastVsyncEventData.preferredFrameTimeline().vsyncId; + return mLastVsyncEventData.id; } /** @@ -725,7 +684,7 @@ public final class Choreographer { * @hide */ public long getFrameDeadline() { - return mLastVsyncEventData.preferredFrameTimeline().deadline; + return mLastVsyncEventData.frameDeadline; } void setFPSDivisor(int divisor) { @@ -746,9 +705,8 @@ public final class Choreographer { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "Choreographer#doFrame " + vsyncEventData.preferredFrameTimeline().vsyncId); + "Choreographer#doFrame " + vsyncEventData.id); } - FrameData frameData = new FrameData(frameTimeNanos, vsyncEventData); synchronized (mLock) { if (!mFrameScheduled) { traceMessage("Frame not scheduled"); @@ -779,7 +737,6 @@ public final class Choreographer { + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past."); } frameTimeNanos = startNanos - lastFrameOffset; - frameData.setFrameTimeNanos(-lastFrameOffset); } if (frameTimeNanos < mLastFrameTimeNanos) { @@ -801,10 +758,8 @@ public final class Choreographer { } } - mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, - vsyncEventData.preferredFrameTimeline().vsyncId, - vsyncEventData.preferredFrameTimeline().deadline, startNanos, - vsyncEventData.frameInterval); + mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id, + vsyncEventData.frameDeadline, startNanos, vsyncEventData.frameInterval); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastFrameIntervalNanos = frameIntervalNanos; @@ -814,17 +769,17 @@ public final class Choreographer { AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS); mFrameInfo.markInputHandlingStart(); - doCallbacks(Choreographer.CALLBACK_INPUT, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_INPUT, frameTimeNanos, frameIntervalNanos); mFrameInfo.markAnimationsStart(); - doCallbacks(Choreographer.CALLBACK_ANIMATION, frameData, frameIntervalNanos); - doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameData, + doCallbacks(Choreographer.CALLBACK_ANIMATION, frameTimeNanos, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_INSETS_ANIMATION, frameTimeNanos, frameIntervalNanos); mFrameInfo.markPerformTraversalsStart(); - doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_TRAVERSAL, frameTimeNanos, frameIntervalNanos); - doCallbacks(Choreographer.CALLBACK_COMMIT, frameData, frameIntervalNanos); + doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos, frameIntervalNanos); } finally { AnimationUtils.unlockAnimationClock(); Trace.traceEnd(Trace.TRACE_TAG_VIEW); @@ -838,9 +793,8 @@ public final class Choreographer { } } - void doCallbacks(int callbackType, FrameData frameData, long frameIntervalNanos) { + void doCallbacks(int callbackType, long frameTimeNanos, long frameIntervalNanos) { CallbackRecord callbacks; - long frameTimeNanos = frameData.mFrameTimeNanos; synchronized (mLock) { // We use "now" to determine when callbacks become due because it's possible // for earlier processing phases in a frame to post callbacks that should run @@ -877,7 +831,6 @@ public final class Choreographer { } frameTimeNanos = now - lastFrameOffset; mLastFrameTimeNanos = frameTimeNanos; - frameData.setFrameTimeNanos(frameTimeNanos); } } } @@ -889,7 +842,7 @@ public final class Choreographer { + ", action=" + c.action + ", token=" + c.token + ", latencyMillis=" + (SystemClock.uptimeMillis() - c.dueTime)); } - c.run(frameData); + c.run(frameTimeNanos); } } finally { synchronized (mLock) { @@ -989,130 +942,6 @@ public final class Choreographer { public void doFrame(long frameTimeNanos); } - /** Holds data that describes one possible VSync frame event to render at. */ - public static class FrameTimeline { - static final FrameTimeline INVALID_FRAME_TIMELINE = new FrameTimeline( - FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE); - - FrameTimeline(long vsyncId, long expectedPresentTimeNanos, long deadlineNanos) { - this.mVsyncId = vsyncId; - this.mExpectedPresentTimeNanos = expectedPresentTimeNanos; - this.mDeadlineNanos = deadlineNanos; - } - - private long mVsyncId; - private long mExpectedPresentTimeNanos; - private long mDeadlineNanos; - - /** - * The id that corresponds to this frame timeline, used to correlate a frame - * produced by HWUI with the timeline data stored in Surface Flinger. - */ - public long getVsyncId() { - return mVsyncId; - } - - /** Sets the vsync ID. */ - void resetVsyncId() { - mVsyncId = FrameInfo.INVALID_VSYNC_ID; - } - - /** - * The time in {@link System#nanoTime()} timebase which this frame is expected to be - * presented. - */ - public long getExpectedPresentTimeNanos() { - return mExpectedPresentTimeNanos; - } - - /** - * The time in {@link System#nanoTime()} timebase which this frame needs to be ready by. - */ - public long getDeadlineNanos() { - return mDeadlineNanos; - } - } - - /** - * The payload for {@link ExtendedFrameCallback} which includes frame information such as when - * the frame started being rendered, and multiple possible frame timelines and their - * information including deadline and expected present time. - */ - public static class FrameData { - static final FrameTimeline[] INVALID_FRAME_TIMELINES = new FrameTimeline[0]; - FrameData() { - this.mFrameTimelines = INVALID_FRAME_TIMELINES; - this.mPreferredFrameTimeline = FrameTimeline.INVALID_FRAME_TIMELINE; - } - - FrameData(long frameTimeNanos, DisplayEventReceiver.VsyncEventData vsyncEventData) { - FrameTimeline[] frameTimelines = - new FrameTimeline[vsyncEventData.frameTimelines.length]; - for (int i = 0; i < vsyncEventData.frameTimelines.length; i++) { - DisplayEventReceiver.VsyncEventData.FrameTimeline frameTimeline = - vsyncEventData.frameTimelines[i]; - frameTimelines[i] = new FrameTimeline(frameTimeline.vsyncId, - frameTimeline.expectedPresentTime, frameTimeline.deadline); - } - this.mFrameTimeNanos = frameTimeNanos; - this.mFrameTimelines = frameTimelines; - this.mPreferredFrameTimeline = - frameTimelines[vsyncEventData.preferredFrameTimelineIndex]; - } - - private long mFrameTimeNanos; - private final FrameTimeline[] mFrameTimelines; - private final FrameTimeline mPreferredFrameTimeline; - - void setFrameTimeNanos(long frameTimeNanos) { - mFrameTimeNanos = frameTimeNanos; - for (FrameTimeline ft : mFrameTimelines) { - // The ID is no longer valid because the frame time that was registered with the ID - // no longer matches. - // TODO(b/205721584): Ask SF for valid vsync information. - ft.resetVsyncId(); - } - } - - /** The time in nanoseconds when the frame started being rendered. */ - public long getFrameTimeNanos() { - return mFrameTimeNanos; - } - - /** The possible frame timelines, sorted chronologically. */ - @NonNull - @SuppressLint("ArrayReturn") // For API consistency and speed. - public FrameTimeline[] getFrameTimelines() { - return mFrameTimelines; - } - - /** The platform-preferred frame timeline. */ - @NonNull - public FrameTimeline getPreferredFrameTimeline() { - return mPreferredFrameTimeline; - } - } - - /** - * Implement this interface to receive a callback to start the next frame. The callback is - * invoked on the {@link Looper} thread to which the {@link Choreographer} is attached. The - * callback payload contains information about multiple possible frames, allowing choice of - * the appropriate frame based on latency requirements. - * - * @see FrameCallback - */ - public interface ExtendedFrameCallback { - /** - * Called when a new display frame is being rendered. - * - * @param data The payload which includes frame information. Divide nanosecond values by - * {@code 1000000} to convert it to the {@link SystemClock#uptimeMillis()} - * time base. - * @see FrameCallback#doFrame - **/ - void onVsync(@NonNull FrameData data); - } - private final class FrameHandler extends Handler { public FrameHandler(Looper looper) { super(looper); @@ -1154,8 +983,7 @@ public final class Choreographer { try { if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, - "Choreographer#onVsync " - + vsyncEventData.preferredFrameTimeline().vsyncId); + "Choreographer#onVsync " + vsyncEventData.id); } // Post the vsync event to the Handler. // The idea is to prevent incoming vsync events from completely starving @@ -1198,9 +1026,7 @@ public final class Choreographer { private static final class CallbackRecord { public CallbackRecord next; public long dueTime; - /** Runnable or FrameCallback or ExtendedFrameCallback object. */ - public Object action; - /** Denotes the action type. */ + public Object action; // Runnable or FrameCallback public Object token; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -1211,14 +1037,6 @@ public final class Choreographer { ((Runnable)action).run(); } } - - void run(FrameData frameData) { - if (token == EXTENDED_FRAME_CALLBACK_TOKEN) { - ((ExtendedFrameCallback) action).onVsync(frameData); - } else { - run(frameData.getFrameTimeNanos()); - } - } } private final class CallbackQueue { diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 774bab41fb9a9..5c086328bda73 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -138,28 +138,13 @@ public abstract class DisplayEventReceiver { } static final class VsyncEventData { + // The frame timeline vsync id, used to correlate a frame + // produced by HWUI with the timeline data stored in Surface Flinger. + public final long id; - static final FrameTimeline[] INVALID_FRAME_TIMELINES = - {new FrameTimeline(FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE)}; - - public static class FrameTimeline { - FrameTimeline(long vsyncId, long expectedPresentTime, long deadline) { - this.vsyncId = vsyncId; - this.expectedPresentTime = expectedPresentTime; - this.deadline = deadline; - } - - // The frame timeline vsync id, used to correlate a frame - // produced by HWUI with the timeline data stored in Surface Flinger. - public final long vsyncId; - - // The frame timestamp for when the frame is expected to be presented. - public final long expectedPresentTime; - - // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is - // allotted for the frame to be completed. - public final long deadline; - } + // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is + // allotted for the frame to be completed. + public final long frameDeadline; /** * The current interval between frames in ns. This will be used to align @@ -168,27 +153,16 @@ public abstract class DisplayEventReceiver { */ public final long frameInterval; - public final FrameTimeline[] frameTimelines; - - public final int preferredFrameTimelineIndex; - - // Called from native code. - @SuppressWarnings("unused") - VsyncEventData(FrameTimeline[] frameTimelines, int preferredFrameTimelineIndex, - long frameInterval) { - this.frameTimelines = frameTimelines; - this.preferredFrameTimelineIndex = preferredFrameTimelineIndex; + VsyncEventData(long id, long frameDeadline, long frameInterval) { + this.id = id; + this.frameDeadline = frameDeadline; this.frameInterval = frameInterval; } VsyncEventData() { + this.id = FrameInfo.INVALID_VSYNC_ID; + this.frameDeadline = Long.MAX_VALUE; this.frameInterval = -1; - this.frameTimelines = INVALID_FRAME_TIMELINES; - this.preferredFrameTimelineIndex = 0; - } - - public FrameTimeline preferredFrameTimeline() { - return frameTimelines[preferredFrameTimelineIndex]; } } @@ -282,8 +256,9 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, - VsyncEventData vsyncEventData) { - onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); + long frameTimelineVsyncId, long frameDeadline, long frameInterval) { + onVsync(timestampNanos, physicalDisplayId, frame, + new VsyncEventData(frameTimelineVsyncId, frameDeadline, frameInterval)); } // Called from native code. diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index d91d526e3d4c4..ce772cf9faff0 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -48,16 +48,6 @@ static struct { jmethodID init; } frameRateOverrideClassInfo; - struct { - jclass clazz; - jmethodID init; - } frameTimelineClassInfo; - - struct { - jclass clazz; - jmethodID init; - } vsyncEventDataClassInfo; - } gDisplayEventReceiverClassInfo; @@ -115,38 +105,9 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla ScopedLocalRef receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); - - ScopedLocalRef - frameTimelineObjs(env, - env->NewObjectArray(vsyncEventData.frameTimelines.size(), - gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.clazz, - /*initial element*/ NULL)); - for (int i = 0; i < vsyncEventData.frameTimelines.size(); i++) { - VsyncEventData::FrameTimeline frameTimeline = vsyncEventData.frameTimelines[i]; - ScopedLocalRef - frameTimelineObj(env, - env->NewObject(gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.clazz, - gDisplayEventReceiverClassInfo - .frameTimelineClassInfo.init, - frameTimeline.id, - frameTimeline.expectedPresentTime, - frameTimeline.deadlineTimestamp)); - env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get()); - } - ScopedLocalRef - vsyncEventDataJava(env, - env->NewObject(gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo.clazz, - gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo.init, - frameTimelineObjs.get(), - vsyncEventData.preferredFrameTimelineIndex, - vsyncEventData.frameInterval)); - env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, - timestamp, displayId.value, count, vsyncEventDataJava.get()); + timestamp, displayId.value, count, vsyncEventData.id, + vsyncEventData.deadlineTimestamp, vsyncEventData.frameInterval); ALOGV("receiver %p ~ Returned from vsync handler.", this); } @@ -278,7 +239,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", - "(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V"); + "(JJIJJJ)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchModeChanged = @@ -297,24 +258,6 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameRateOverrideClassInfo.clazz, "", "(IF)V"); - jclass frameTimelineClazz = - FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData$FrameTimeline"); - gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz = - MakeGlobalRefOrDie(env, frameTimelineClazz); - gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, - "", "(JJJ)V"); - - jclass vsyncEventDataClazz = - FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData"); - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz = - MakeGlobalRefOrDie(env, vsyncEventDataClazz); - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.init = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, - "", - "([Landroid/view/" - "DisplayEventReceiver$VsyncEventData$FrameTimeline;IJ)V"); - return res; } From ccacf9019c8d7afbaad5d4e9562e211362b2b231 Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Tue, 25 Jan 2022 15:28:18 +0000 Subject: [PATCH 100/176] Revert "Add support for USB audio docks." Revert submission 16691170-usb_doc Reason for revert: 216248574 Reverted Changes: I090e86b2e:Add support for USB audio docks. I461661dd4:audio policy: implement routing policy for USB doc... Change-Id: Ie28b74de7b8654cd199c86d06697bb52f0fa8f3d (cherry picked from commit 01f03c3d9f8cf1fa594d62332ead89c088770c5a) Merged-In:Ie28b74de7b8654cd199c86d06697bb52f0fa8f3d --- .../server/audio/AudioDeviceInventory.java | 3 -- .../com/android/server/usb/UsbAlsaDevice.java | 48 +++++++------------ .../android/server/usb/UsbAlsaManager.java | 3 +- .../android/server/usb/UsbHostManager.java | 8 ++-- .../usb/descriptors/UsbDescriptorParser.java | 31 ------------ 5 files changed, 24 insertions(+), 69 deletions(-) diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index 2dd6bf5755794..0961fcb31ace1 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -1360,9 +1360,6 @@ public class AudioDeviceInventory { case AudioSystem.DEVICE_OUT_USB_HEADSET: connType = AudioRoutesInfo.MAIN_USB; break; - case AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET: - connType = AudioRoutesInfo.MAIN_DOCK_SPEAKERS; - break; } synchronized (mCurAudioRoutes) { diff --git a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java index 85b1de5478e17..9d4db003a2978 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaDevice.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaDevice.java @@ -41,7 +41,6 @@ public final class UsbAlsaDevice { private final boolean mIsInputHeadset; private final boolean mIsOutputHeadset; - private final boolean mIsDock; private boolean mSelected = false; private int mOutputState; @@ -54,7 +53,7 @@ public final class UsbAlsaDevice { public UsbAlsaDevice(IAudioService audioService, int card, int device, String deviceAddress, boolean hasOutput, boolean hasInput, - boolean isInputHeadset, boolean isOutputHeadset, boolean isDock) { + boolean isInputHeadset, boolean isOutputHeadset) { mAudioService = audioService; mCardNum = card; mDeviceNum = device; @@ -63,32 +62,31 @@ public final class UsbAlsaDevice { mHasInput = hasInput; mIsInputHeadset = isInputHeadset; mIsOutputHeadset = isOutputHeadset; - mIsDock = isDock; } /** - * @return the ALSA card number associated with this peripheral. + * @returns the ALSA card number associated with this peripheral. */ public int getCardNum() { return mCardNum; } /** - * @return the ALSA device number associated with this peripheral. + * @returns the ALSA device number associated with this peripheral. */ public int getDeviceNum() { return mDeviceNum; } /** - * @return the USB device device address associated with this peripheral. + * @returns the USB device device address associated with this peripheral. */ public String getDeviceAddress() { return mDeviceAddress; } /** - * @return the ALSA card/device address string. + * @returns the ALSA card/device address string. */ public String getAlsaCardDeviceString() { if (mCardNum < 0 || mDeviceNum < 0) { @@ -100,42 +98,35 @@ public final class UsbAlsaDevice { } /** - * @return true if the device supports output. + * @returns true if the device supports output. */ public boolean hasOutput() { return mHasOutput; } /** - * @return true if the device supports input (recording). + * @returns true if the device supports input (recording). */ public boolean hasInput() { return mHasInput; } /** - * @return true if the device is a headset for purposes of input. + * @returns true if the device is a headset for purposes of input. */ public boolean isInputHeadset() { return mIsInputHeadset; } /** - * @return true if the device is a headset for purposes of output. + * @returns true if the device is a headset for purposes of output. */ public boolean isOutputHeadset() { return mIsOutputHeadset; } /** - * @return true if the device is a USB dock. - */ - public boolean isDock() { - return mIsDock; - } - - /** - * @return true if input jack is detected or jack detection is not supported. + * @returns true if input jack is detected or jack detection is not supported. */ private synchronized boolean isInputJackConnected() { if (mJackDetector == null) { @@ -145,7 +136,7 @@ public final class UsbAlsaDevice { } /** - * @return true if input jack is detected or jack detection is not supported. + * @returns true if input jack is detected or jack detection is not supported. */ private synchronized boolean isOutputJackConnected() { if (mJackDetector == null) { @@ -199,10 +190,9 @@ public final class UsbAlsaDevice { try { // Output Device if (mHasOutput) { - int device = mIsDock ? AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET - : (mIsOutputHeadset - ? AudioSystem.DEVICE_OUT_USB_HEADSET - : AudioSystem.DEVICE_OUT_USB_DEVICE); + int device = mIsOutputHeadset + ? AudioSystem.DEVICE_OUT_USB_HEADSET + : AudioSystem.DEVICE_OUT_USB_DEVICE; if (DEBUG) { Slog.d(TAG, "pre-call device:0x" + Integer.toHexString(device) + " addr:" + alsaCardDeviceString @@ -241,7 +231,7 @@ public final class UsbAlsaDevice { /** * @Override - * @return a string representation of the object. + * @returns a string representation of the object. */ public synchronized String toString() { return "UsbAlsaDevice: [card: " + mCardNum @@ -283,7 +273,7 @@ public final class UsbAlsaDevice { /** * @Override - * @return true if the objects are equivalent. + * @returns true if the objects are equivalent. */ public boolean equals(Object obj) { if (!(obj instanceof UsbAlsaDevice)) { @@ -295,13 +285,12 @@ public final class UsbAlsaDevice { && mHasOutput == other.mHasOutput && mHasInput == other.mHasInput && mIsInputHeadset == other.mIsInputHeadset - && mIsOutputHeadset == other.mIsOutputHeadset - && mIsDock == other.mIsDock); + && mIsOutputHeadset == other.mIsOutputHeadset); } /** * @Override - * @return a hash code generated from the object contents. + * @returns a hash code generated from the object contents. */ public int hashCode() { final int prime = 31; @@ -312,7 +301,6 @@ public final class UsbAlsaDevice { result = prime * result + (mHasInput ? 0 : 1); result = prime * result + (mIsInputHeadset ? 0 : 1); result = prime * result + (mIsOutputHeadset ? 0 : 1); - result = prime * result + (mIsDock ? 0 : 1); return result; } diff --git a/services/usb/java/com/android/server/usb/UsbAlsaManager.java b/services/usb/java/com/android/server/usb/UsbAlsaManager.java index fd9b9952331a8..1c72eb8db708b 100644 --- a/services/usb/java/com/android/server/usb/UsbAlsaManager.java +++ b/services/usb/java/com/android/server/usb/UsbAlsaManager.java @@ -237,7 +237,6 @@ public final class UsbAlsaManager { if (hasInput || hasOutput) { boolean isInputHeadset = parser.isInputHeadset(); boolean isOutputHeadset = parser.isOutputHeadset(); - boolean isDock = parser.isDock(); if (mAudioService == null) { Slog.e(TAG, "no AudioService"); @@ -247,7 +246,7 @@ public final class UsbAlsaManager { UsbAlsaDevice alsaDevice = new UsbAlsaDevice(mAudioService, cardRec.getCardNum(), 0 /*device*/, deviceAddress, hasOutput, hasInput, - isInputHeadset, isOutputHeadset, isDock); + isInputHeadset, isOutputHeadset); if (alsaDevice != null) { alsaDevice.setDeviceNameAndDescription( cardRec.getCardName(), cardRec.getCardDescription()); diff --git a/services/usb/java/com/android/server/usb/UsbHostManager.java b/services/usb/java/com/android/server/usb/UsbHostManager.java index 94cc826ffc438..9ac270f17fc49 100644 --- a/services/usb/java/com/android/server/usb/UsbHostManager.java +++ b/services/usb/java/com/android/server/usb/UsbHostManager.java @@ -165,7 +165,7 @@ public class UsbHostManager { pw.println("manfacturer:0x" + Integer.toHexString(deviceDescriptor.getVendorID()) + " product:" + Integer.toHexString(deviceDescriptor.getProductID())); pw.println("isHeadset[in: " + parser.isInputHeadset() - + " , out: " + parser.isOutputHeadset() + "], isDock: " + parser.isDock()); + + " , out: " + parser.isOutputHeadset() + "]"); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); } @@ -179,8 +179,9 @@ public class UsbHostManager { UsbDescriptorsTree descriptorTree = new UsbDescriptorsTree(); descriptorTree.parse(parser); descriptorTree.report(new TextReportCanvas(parser, stringBuilder)); + stringBuilder.append("isHeadset[in: " + parser.isInputHeadset() - + " , out: " + parser.isOutputHeadset() + "], isDock: " + parser.isDock()); + + " , out: " + parser.isOutputHeadset() + "]"); pw.println(stringBuilder.toString()); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); @@ -197,8 +198,9 @@ public class UsbHostManager { descriptor.report(canvas); } pw.println(stringBuilder.toString()); + pw.println("isHeadset[in: " + parser.isInputHeadset() - + " , out: " + parser.isOutputHeadset() + "], isDock: " + parser.isDock()); + + " , out: " + parser.isOutputHeadset() + "]"); } else { pw.println(formatTime() + " Disconnect " + mDeviceAddress); } diff --git a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java index 6e68a9174cb53..3412a6f80cc7c 100644 --- a/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java +++ b/services/usb/java/com/android/server/usb/descriptors/UsbDescriptorParser.java @@ -870,35 +870,4 @@ public final class UsbDescriptorParser { return getOutputHeadsetProbability() >= OUT_HEADSET_TRIGGER; } - /** - * isDock() indicates if the connected USB output peripheral is a docking station with - * audio output. - * A valid audio dock must declare only one audio output control terminal of type - * TERMINAL_EXTERN_DIGITAL. - */ - public boolean isDock() { - if (hasMIDIInterface() || hasHIDInterface()) { - return false; - } - - ArrayList acDescriptors = - getACInterfaceDescriptors(UsbACInterface.ACI_OUTPUT_TERMINAL, - UsbACInterface.AUDIO_AUDIOCONTROL); - - if (acDescriptors.size() != 1) { - return false; - } - - if (acDescriptors.get(0) instanceof UsbACTerminal) { - UsbACTerminal outDescr = (UsbACTerminal) acDescriptors.get(0); - if (outDescr.getTerminalType() == UsbTerminalTypes.TERMINAL_EXTERN_DIGITAL) { - return true; - } - } else { - Log.w(TAG, "Undefined Audio Output terminal l: " + acDescriptors.get(0).getLength() - + " t:0x" + Integer.toHexString(acDescriptors.get(0).getType())); - } - return false; - } - } From caba0ba763a4a2e01e332be2c96fe18532fd68b3 Mon Sep 17 00:00:00 2001 From: Jackal Guo Date: Wed, 26 Jan 2022 12:20:21 +0000 Subject: [PATCH 101/176] Revert "Verify the incoming package first." This reverts commit 8423dd15ff7b12687d6726ce555f7a0717ae7f14. Reason for revert: b/216248574 Change-Id: I3e0c2d4b453d50f773bdf55d26886f2df8accf2a (cherry picked from commit 70737fcd233e9c721509d85adb82fec3a1642a6d) Merged-In:I3e0c2d4b453d50f773bdf55d26886f2df8accf2a --- .../server/am/ActivityManagerService.java | 70 ++++++------------- .../server/vibrator/VibrationSettings.java | 2 +- .../server/am/ActivityManagerServiceTest.java | 15 ++-- 3 files changed, 28 insertions(+), 59 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b1b4c4447ec8c..f67e732b47ddf 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2871,51 +2871,13 @@ public class ActivityManagerService extends IActivityManager.Stub return mode == AppOpsManager.MODE_ALLOWED; } - /** - * Checks whether the calling package is trusted. - * - * The calling package is trusted if it's from system or the supposed package name matches the - * UID making the call. - * - * @throws SecurityException if the package name and UID don't match. - */ - private void verifyCallingPackage(String callingPackage) { - final int callingUid = Binder.getCallingUid(); - // The caller is System or Shell. - if (callingUid == SYSTEM_UID || isCallerShell()) { - return; - } - - // Handle the special UIDs that don't have real package (audioserver, cameraserver, etc). - final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid, - null /* packageName */); - if (resolvedPackage != null && resolvedPackage.equals(callingPackage)) { - return; - } - - final int claimedUid = getPackageManagerInternal().getPackageUid(callingPackage, - 0 /* flags */, UserHandle.getUserId(callingUid)); - if (callingUid == claimedUid) { - return; - } - - throw new SecurityException( - "Claimed calling package " + callingPackage + " does not match the calling UID " - + Binder.getCallingUid()); - } - - private void enforceUsageStatsPermission(String callingPackage, String func) { - verifyCallingPackage(callingPackage); - // Since the protection level of PACKAGE_USAGE_STATS has 'appop', apps may grant this - // permission via that way. We need to check both app-ops and permission. - if (!hasUsageStatsPermission(callingPackage)) { - enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, func); - } - } - @Override public int getPackageProcessState(String packageName, String callingPackage) { - enforceUsageStatsPermission(callingPackage, "getPackageProcessState"); + if (!hasUsageStatsPermission(callingPackage)) { + enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, + "getPackageProcessState"); + } + final int[] procState = {PROCESS_STATE_NONEXISTENT}; synchronized (mProcLock) { mProcessList.forEachLruProcessesLOSP(false, proc -> { @@ -6976,7 +6938,11 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public int getUidProcessState(int uid, String callingPackage) { - enforceUsageStatsPermission(callingPackage, "getUidProcessState"); + if (!hasUsageStatsPermission(callingPackage)) { + enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, + "getUidProcessState"); + } + synchronized (mProcLock) { return mProcessList.getUidProcStateLOSP(uid); } @@ -6984,7 +6950,11 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public @ProcessCapability int getUidProcessCapabilities(int uid, String callingPackage) { - enforceUsageStatsPermission(callingPackage, "getUidProcessCapabilities"); + if (!hasUsageStatsPermission(callingPackage)) { + enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, + "getUidProcessState"); + } + synchronized (mProcLock) { return mProcessList.getUidProcessCapabilityLOSP(uid); } @@ -6993,7 +6963,10 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void registerUidObserver(IUidObserver observer, int which, int cutpoint, String callingPackage) { - enforceUsageStatsPermission(callingPackage, "registerUidObserver"); + if (!hasUsageStatsPermission(callingPackage)) { + enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, + "registerUidObserver"); + } mUidObserverController.register(observer, which, cutpoint, callingPackage, Binder.getCallingUid()); } @@ -7005,7 +6978,10 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public boolean isUidActive(int uid, String callingPackage) { - enforceUsageStatsPermission(callingPackage, "isUidActive"); + if (!hasUsageStatsPermission(callingPackage)) { + enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, + "isUidActive"); + } synchronized (mProcLock) { if (isUidActiveLOSP(uid)) { return true; diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java index eafd9d7f0b6c4..6c5d9520151bf 100644 --- a/services/core/java/com/android/server/vibrator/VibrationSettings.java +++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java @@ -179,7 +179,7 @@ final class VibrationSettings { try { ActivityManager.getService().registerUidObserver(mUidObserver, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE, - ActivityManager.PROCESS_STATE_UNKNOWN, mContext.getOpPackageName()); + ActivityManager.PROCESS_STATE_UNKNOWN, null); } catch (RemoteException e) { // ignored; both services live in system_server } diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java index 677f0f642e6eb..36c37c4dbf2af 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java @@ -541,14 +541,11 @@ public class ActivityManagerServiceTest { | ActivityManager.UID_OBSERVER_CAPABILITY }; final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length]; - doReturn(Process.myUid()).when(sPackageManagerInternal) - .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId()); for (int i = 0; i < observers.length; ++i) { observers[i] = mock(IUidObserver.Stub.class); when(observers[i].asBinder()).thenReturn((IBinder) observers[i]); mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */, - ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, - mContext.getOpPackageName()); + ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */); // When we invoke AMS.registerUidObserver, there are some interactions with observers[i] // mock in RemoteCallbackList class. We don't want to test those interactions and @@ -677,12 +674,10 @@ public class ActivityManagerServiceTest { mockNoteOperation(); final IUidObserver observer = mock(IUidObserver.Stub.class); + when(observer.asBinder()).thenReturn((IBinder) observer); - doReturn(Process.myUid()).when(sPackageManagerInternal) - .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId()); mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */, - ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, - mContext.getOpPackageName()); + ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */); // When we invoke AMS.registerUidObserver, there are some interactions with observer // mock in RemoteCallbackList class. We don't want to test those interactions and // at the same time, we don't want those to interfere with verifyNoMoreInteractions. @@ -776,9 +771,7 @@ public class ActivityManagerServiceTest { final IUidObserver observer = mock(IUidObserver.Stub.class); when(observer.asBinder()).thenReturn((IBinder) observer); - doReturn(Process.myUid()).when(sPackageManagerInternal) - .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId()); - mAms.registerUidObserver(observer, 0, 0, mContext.getOpPackageName()); + mAms.registerUidObserver(observer, 0, 0, null); // Verify that when observers are registered, then validateUids is correctly updated. addPendingUidChanges(pendingItemsForUids); mAms.mUidObserverController.dispatchUidsChanged(); From 2b99c36c360f297c7ba74c3787a7e50c9b08fd3c Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Fri, 28 Jan 2022 02:27:43 +0000 Subject: [PATCH 102/176] Revert "Replace mHandler.sendMessage() with sendToTarget()" This reverts commit 2742a030a673a49ee355d262747a0fe8de591ad3. Reason for revert: Droidfood Blocking Bug: 216588046 Bug: 192412909 Bug: 216588046 Change-Id: I1ad88b3315c35ca4b820a847d346e5a51ed9dac7 (cherry picked from commit 91832babba939ed39a14a81627bc3852539ad1b2) Merged-In:I1ad88b3315c35ca4b820a847d346e5a51ed9dac7 --- .../InputMethodManagerService.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index c6a206bfff52a..85b7a88835f84 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -1524,8 +1524,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Override public void onUserUnlocking(@NonNull TargetUser user) { // Called on ActivityManager thread. - mService.mHandler.obtainMessage(MSG_SYSTEM_UNLOCK_USER, user.getUserIdentifier(), 0) - .sendToTarget(); + mService.mHandler.sendMessage(mService.mHandler.obtainMessage(MSG_SYSTEM_UNLOCK_USER, + /* arg1= */ user.getUserIdentifier(), /* arg2= */ 0)); } } @@ -2234,7 +2234,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // We probably should create a simple wrapper of IInputMethodClient as the first step // to get rid of executeOrSendMessage() then should prohibit system_server to be the // IME client for long term. - msg.sendToTarget(); + mHandler.sendMessage(msg); } else { handleMessage(msg); msg.recycle(); @@ -3674,10 +3674,9 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Always call subtype picker, because subtype picker is a superset of input method // picker. - final int displayId = - (mCurClient != null) ? mCurClient.selfReportedDisplayId : DEFAULT_DISPLAY; - mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId) - .sendToTarget(); + mHandler.sendMessage(mHandler.obtainMessage( + MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, + (mCurClient != null) ? mCurClient.selfReportedDisplayId : DEFAULT_DISPLAY)); } } @@ -3692,8 +3691,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } // Always call subtype picker, because subtype picker is a superset of input method // picker. - mHandler.obtainMessage(MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId) - .sendToTarget(); + mHandler.sendMessage(mHandler.obtainMessage( + MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)); } /** @@ -3950,7 +3949,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Override public void removeImeSurface() { mContext.enforceCallingPermission(Manifest.permission.INTERNAL_SYSTEM_WINDOW, null); - mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE).sendToTarget(); + mHandler.sendMessage(mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); } @Override @@ -5020,13 +5019,14 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @Override public void removeImeSurface() { - mService.mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE).sendToTarget(); + mService.mHandler.sendMessage(mService.mHandler.obtainMessage(MSG_REMOVE_IME_SURFACE)); } @Override public void updateImeWindowStatus(boolean disableImeIcon) { - mService.mHandler.obtainMessage(MSG_UPDATE_IME_WINDOW_STATUS, disableImeIcon ? 1 : 0, 0) - .sendToTarget(); + mService.mHandler.sendMessage( + mService.mHandler.obtainMessage(MSG_UPDATE_IME_WINDOW_STATUS, + disableImeIcon ? 1 : 0, 0)); } } From 059431abba3bd1ef5dd63166b6a2406896d55e63 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Fri, 28 Jan 2022 01:44:19 +0000 Subject: [PATCH 103/176] Revert "Remove InputMethodManagerService#mCaller" This reverts commit 7c46dc83efe879304dde3cadd105d0b96547e73d. Reason for revert: Droidfood blocking bug: 216588046 Bug: 192412909 Bug: 216588046 Change-Id: I12902c08d21d851a13ef7319f87e5dc784182228 (cherry picked from commit cc0498759b0e752d73d0551afa33ed9675d6e445) Merged-In:I12902c08d21d851a13ef7319f87e5dc784182228 --- .../InputMethodManagerService.java | 46 ++++++------------- 1 file changed, 15 insertions(+), 31 deletions(-) diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java index 85b7a88835f84..01fd6639ca5d5 100644 --- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java +++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java @@ -160,6 +160,7 @@ import com.android.internal.inputmethod.StartInputReason; import com.android.internal.inputmethod.UnbindReason; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.notification.SystemNotificationChannels; +import com.android.internal.os.HandlerCaller; import com.android.internal.os.SomeArgs; import com.android.internal.os.TransferPipe; import com.android.internal.util.DumpUtils; @@ -273,6 +274,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub final WindowManagerInternal mWindowManagerInternal; final PackageManagerInternal mPackageManagerInternal; final InputManagerInternal mInputManagerInternal; + private final HandlerCaller mCaller; final boolean mHasFeature; private final ArrayMap> mAdditionalSubtypeMap = new ArrayMap<>(); @@ -1585,6 +1587,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mImeDisplayValidator = mWindowManagerInternal::getDisplayImePolicy; + mCaller = new HandlerCaller(context, thread.getLooper(), this::handleMessage, + true /*asyncHandler*/); mAppOpsManager = mContext.getSystemService(AppOpsManager.class); mUserManager = mContext.getSystemService(UserManager.class); mUserManagerInternal = LocalServices.getService(UserManagerInternal.class); @@ -2208,24 +2212,6 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } } - @NonNull - private Message obtainMessageOO(int what, Object arg1, Object arg2) { - final SomeArgs args = SomeArgs.obtain(); - args.arg1 = arg1; - args.arg2 = arg2; - return mHandler.obtainMessage(what, 0, 0, args); - } - - @NonNull - private Message obtainMessageIIIO(int what, int argi1, int argi2, int argi3, Object arg1) { - final SomeArgs args = SomeArgs.obtain(); - args.arg1 = arg1; - args.argi1 = argi1; - args.argi2 = argi2; - args.argi3 = argi3; - return mHandler.obtainMessage(what, 0, 0, args); - } - private void executeOrSendMessage(IInputMethodClient target, Message msg) { if (target.asBinder() instanceof Binder) { // This is supposed to be emulating the one-way semantics when the IME client is @@ -2234,7 +2220,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // We probably should create a simple wrapper of IInputMethodClient as the first step // to get rid of executeOrSendMessage() then should prohibit system_server to be the // IME client for long term. - mHandler.sendMessage(msg); + mCaller.sendMessage(msg); } else { handleMessage(msg); msg.recycle(); @@ -2256,7 +2242,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub scheduleSetActiveToClient(mCurClient, false /* active */, false /* fullscreen */, false /* reportToImeController */); - executeOrSendMessage(mCurClient.client, mHandler.obtainMessage( + executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIIO( MSG_UNBIND_CLIENT, getSequenceNumberLocked(), unbindClientReason, mCurClient.client)); mCurClient.sessionRequested = false; @@ -2538,9 +2524,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub @AnyThread void scheduleNotifyImeUidToAudioService(int uid) { - mHandler.removeMessages(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE); - mHandler.obtainMessage(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE, uid, 0 /* unused */) - .sendToTarget(); + mCaller.removeMessages(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE); + mCaller.obtainMessageI(MSG_NOTIFY_IME_UID_TO_AUDIO_SERVICE, uid).sendToTarget(); } @BinderThread @@ -2565,7 +2550,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub InputBindResult res = attachNewInputLocked( StartInputReason.SESSION_CREATED_BY_IME, true); if (res.method != null) { - executeOrSendMessage(mCurClient.client, obtainMessageOO( + executeOrSendMessage(mCurClient.client, mCaller.obtainMessageOO( MSG_BIND_CLIENT, mCurClient.client, res)); } return; @@ -3674,7 +3659,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub // Always call subtype picker, because subtype picker is a superset of input method // picker. - mHandler.sendMessage(mHandler.obtainMessage( + mHandler.sendMessage(mCaller.obtainMessageII( MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, (mCurClient != null) ? mCurClient.selfReportedDisplayId : DEFAULT_DISPLAY)); } @@ -3691,7 +3676,7 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } // Always call subtype picker, because subtype picker is a superset of input method // picker. - mHandler.sendMessage(mHandler.obtainMessage( + mHandler.sendMessage(mCaller.obtainMessageII( MSG_SHOW_IM_SUBTYPE_PICKER, auxiliarySubtypeMode, displayId)); } @@ -4455,8 +4440,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub private void scheduleSetActiveToClient(ClientState state, boolean active, boolean fullscreen, boolean reportToImeController) { - executeOrSendMessage(state.client, obtainMessageIIIO(MSG_SET_ACTIVE, - active ? 1 : 0, fullscreen ? 1 : 0, reportToImeController ? 1 : 0, state)); + executeOrSendMessage(state.client, mCaller.obtainMessageIIIIO(MSG_SET_ACTIVE, + active ? 1 : 0, fullscreen ? 1 : 0, reportToImeController ? 1 : 0, 0, state)); } @GuardedBy("ImfLock.class") @@ -5092,9 +5077,8 @@ public final class InputMethodManagerService extends IInputMethodManager.Stub } if (mCurClient != null && mCurClient.client != null) { mInFullscreenMode = fullscreen; - executeOrSendMessage(mCurClient.client, mHandler.obtainMessage( - MSG_REPORT_FULLSCREEN_MODE, fullscreen ? 1 : 0, 0 /* unused */, - mCurClient)); + executeOrSendMessage(mCurClient.client, mCaller.obtainMessageIO( + MSG_REPORT_FULLSCREEN_MODE, fullscreen ? 1 : 0, mCurClient)); } } } From a44e45fca150509ea15ce5313aa0045691901d66 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Sat, 29 Jan 2022 00:40:58 +0000 Subject: [PATCH 104/176] Revert "Define new AUDIO/VIDEO/IMAGE permissions" Revert "Fix PermissionPolicyTest and SplitPermissionsSystemTest" Revert submission 15933906-t-define-media-permissions Reason for revert: Droidfood Blocking Bug: 216588046 Reverted Changes: If3d357bae:Define new AUDIO/VIDEO/IMAGE permissions I79afe120d:Update DefaultPermissionGrantPolicyTest for new pe... I321282b1f:Fix PermissionPolicyTest and SplitPermissionsSyste... Change-Id: I8b425ddacc8a68dc853c3c9cd5bda921f085e2b7 (cherry picked from commit da2c9b15aa5f1f21ae05a57682af17d827ab8499) Merged-In:I8b425ddacc8a68dc853c3c9cd5bda921f085e2b7 --- core/api/current.txt | 5 -- core/java/android/app/AppOpsManager.java | 6 +- core/res/AndroidManifest.xml | 55 ------------------- .../drawable/perm_group_read_media_aural.xml | 26 --------- .../drawable/perm_group_read_media_visual.xml | 26 --------- core/res/res/values/strings.xml | 25 --------- data/etc/platform.xml | 12 ---- 7 files changed, 3 insertions(+), 152 deletions(-) delete mode 100644 core/res/res/drawable/perm_group_read_media_aural.xml delete mode 100644 core/res/res/drawable/perm_group_read_media_visual.xml diff --git a/core/api/current.txt b/core/api/current.txt index 25bf224eab4a1..d73b68ead9f37 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -135,9 +135,6 @@ package android { field public static final String READ_HOME_APP_SEARCH_DATA = "android.permission.READ_HOME_APP_SEARCH_DATA"; field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE"; field public static final String READ_LOGS = "android.permission.READ_LOGS"; - field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO"; - field public static final String READ_MEDIA_IMAGE = "android.permission.READ_MEDIA_IMAGE"; - field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO"; field public static final String READ_NEARBY_STREAMING_POLICY = "android.permission.READ_NEARBY_STREAMING_POLICY"; field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS"; field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; @@ -223,8 +220,6 @@ package android { field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES"; field public static final String NOTIFICATIONS = "android.permission-group.NOTIFICATIONS"; field public static final String PHONE = "android.permission-group.PHONE"; - field public static final String READ_MEDIA_AURAL = "android.permission-group.READ_MEDIA_AURAL"; - field public static final String READ_MEDIA_VISUAL = "android.permission-group.READ_MEDIA_VISUAL"; field public static final String SENSORS = "android.permission-group.SENSORS"; field public static final String SMS = "android.permission-group.SMS"; field public static final String STORAGE = "android.permission-group.STORAGE"; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 008123407cffd..68c69e555bda9 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -2344,11 +2344,11 @@ public class AppOpsManager { Manifest.permission.USE_BIOMETRIC, Manifest.permission.ACTIVITY_RECOGNITION, Manifest.permission.SMS_FINANCIAL_TRANSACTIONS, - Manifest.permission.READ_MEDIA_AUDIO, + null, null, // no permission for OP_WRITE_MEDIA_AUDIO - Manifest.permission.READ_MEDIA_VIDEO, + null, null, // no permission for OP_WRITE_MEDIA_VIDEO - Manifest.permission.READ_MEDIA_IMAGE, + null, null, // no permission for OP_WRITE_MEDIA_IMAGES null, // no permission for OP_LEGACY_STORAGE null, // no permission for OP_ACCESS_ACCESSIBILITY diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index bc6ac01ccfb74..bb4e9d39ba4bc 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -975,61 +975,6 @@ android:permissionFlags="softRestricted|immutablyRestricted" android:protectionLevel="dangerous" /> - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/res/res/drawable/perm_group_read_media_visual.xml b/core/res/res/drawable/perm_group_read_media_visual.xml deleted file mode 100644 index a5db2718c9834..0000000000000 --- a/core/res/res/drawable/perm_group_read_media_visual.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - \ No newline at end of file diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 44ede49af15b9..76b6a7407b9a9 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -880,16 +880,6 @@ access photos, media, and files on your device - - Music & other audio - - access audio files on your device - - - Photos & videos - - access images and video files on your device - Microphone @@ -1903,21 +1893,6 @@ Allows the app to read the contents of your shared storage. - - read audio files from shared storage - - Allows the app to read audio files from your shared storage. - - - read video files from shared storage - - Allows the app to read video files from your shared storage. - - - read image files from shared storage - - Allows the app to read image files from your shared storage. - modify or delete the contents of your shared storage diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 88920c865511b..92fca3661fbc1 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -231,18 +231,6 @@ targetSdk="29"> - - - - - - - - - From ebf305bda0ec4f8754ad7a9d6679f699392bd5db Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Sat, 29 Jan 2022 00:40:58 +0000 Subject: [PATCH 105/176] Revert "Define new AUDIO/VIDEO/IMAGE permissions" Revert "Fix PermissionPolicyTest and SplitPermissionsSystemTest" Revert submission 15933906-t-define-media-permissions Reason for revert: Droidfood Blocking Bug: 216588046 Reverted Changes: If3d357bae:Define new AUDIO/VIDEO/IMAGE permissions I79afe120d:Update DefaultPermissionGrantPolicyTest for new pe... I321282b1f:Fix PermissionPolicyTest and SplitPermissionsSyste... Change-Id: I8b425ddacc8a68dc853c3c9cd5bda921f085e2b7 (cherry picked from commit da2c9b15aa5f1f21ae05a57682af17d827ab8499) Merged-In:I8b425ddacc8a68dc853c3c9cd5bda921f085e2b7 --- core/api/current.txt | 5 -- core/java/android/app/AppOpsManager.java | 6 +- core/res/AndroidManifest.xml | 55 ------------------- .../drawable/perm_group_read_media_aural.xml | 26 --------- .../drawable/perm_group_read_media_visual.xml | 26 --------- core/res/res/values/strings.xml | 25 --------- data/etc/platform.xml | 12 ---- 7 files changed, 3 insertions(+), 152 deletions(-) delete mode 100644 core/res/res/drawable/perm_group_read_media_aural.xml delete mode 100644 core/res/res/drawable/perm_group_read_media_visual.xml diff --git a/core/api/current.txt b/core/api/current.txt index 11e0a6bfb151c..460c8291f365b 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -135,9 +135,6 @@ package android { field public static final String READ_HOME_APP_SEARCH_DATA = "android.permission.READ_HOME_APP_SEARCH_DATA"; field @Deprecated public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE"; field public static final String READ_LOGS = "android.permission.READ_LOGS"; - field public static final String READ_MEDIA_AUDIO = "android.permission.READ_MEDIA_AUDIO"; - field public static final String READ_MEDIA_IMAGE = "android.permission.READ_MEDIA_IMAGE"; - field public static final String READ_MEDIA_VIDEO = "android.permission.READ_MEDIA_VIDEO"; field public static final String READ_NEARBY_STREAMING_POLICY = "android.permission.READ_NEARBY_STREAMING_POLICY"; field public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS"; field public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"; @@ -223,8 +220,6 @@ package android { field public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES"; field public static final String NOTIFICATIONS = "android.permission-group.NOTIFICATIONS"; field public static final String PHONE = "android.permission-group.PHONE"; - field public static final String READ_MEDIA_AURAL = "android.permission-group.READ_MEDIA_AURAL"; - field public static final String READ_MEDIA_VISUAL = "android.permission-group.READ_MEDIA_VISUAL"; field public static final String SENSORS = "android.permission-group.SENSORS"; field public static final String SMS = "android.permission-group.SMS"; field public static final String STORAGE = "android.permission-group.STORAGE"; diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 0d1bc05df67b4..fdf37f6633eef 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -2363,11 +2363,11 @@ public class AppOpsManager { Manifest.permission.USE_BIOMETRIC, Manifest.permission.ACTIVITY_RECOGNITION, Manifest.permission.SMS_FINANCIAL_TRANSACTIONS, - Manifest.permission.READ_MEDIA_AUDIO, + null, null, // no permission for OP_WRITE_MEDIA_AUDIO - Manifest.permission.READ_MEDIA_VIDEO, + null, null, // no permission for OP_WRITE_MEDIA_VIDEO - Manifest.permission.READ_MEDIA_IMAGE, + null, null, // no permission for OP_WRITE_MEDIA_IMAGES null, // no permission for OP_LEGACY_STORAGE null, // no permission for OP_ACCESS_ACCESSIBILITY diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 6e54197463ebd..5e5eb066c26ec 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -977,61 +977,6 @@ android:permissionFlags="softRestricted|immutablyRestricted" android:protectionLevel="dangerous" /> - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/core/res/res/drawable/perm_group_read_media_visual.xml b/core/res/res/drawable/perm_group_read_media_visual.xml deleted file mode 100644 index a5db2718c9834..0000000000000 --- a/core/res/res/drawable/perm_group_read_media_visual.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - \ No newline at end of file diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 49a12d12ed212..610c6a69822cb 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -880,16 +880,6 @@ access photos, media, and files on your device - - Music & other audio - - access audio files on your device - - - Photos & videos - - access images and video files on your device - Microphone @@ -1903,21 +1893,6 @@ Allows the app to read the contents of your shared storage. - - read audio files from shared storage - - Allows the app to read audio files from your shared storage. - - - read video files from shared storage - - Allows the app to read video files from your shared storage. - - - read image files from shared storage - - Allows the app to read image files from your shared storage. - modify or delete the contents of your shared storage diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 88920c865511b..92fca3661fbc1 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -231,18 +231,6 @@ targetSdk="29"> - - - - - - - - - From 00ce71390387ade0982dc21cdfc197689e4ef887 Mon Sep 17 00:00:00 2001 From: Winson Date: Tue, 1 Feb 2022 19:21:17 -0800 Subject: [PATCH 106/176] Null check package for DexOptHelper A package can be null if the APK storage has been ejected or the package install was orphaned via bad parse. This might've been broken in the refactor when this was moved to PackageState. Bug: 217395249 Change-Id: I6353f1832abe502a448991cdb399f7d15c8e9d1f (cherry picked from commit 3f520b19e17086e44310554c933d83bc9929662d) Merged-In:I6353f1832abe502a448991cdb399f7d15c8e9d1f --- services/core/java/com/android/server/pm/DexOptHelper.java | 3 ++- .../core/java/com/android/server/pm/PackageDexOptimizer.java | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java index ba89916e6dfa7..53eb9cf7d9fe5 100644 --- a/services/core/java/com/android/server/pm/DexOptHelper.java +++ b/services/core/java/com/android/server/pm/DexOptHelper.java @@ -293,7 +293,8 @@ final class DexOptHelper { public ArraySet getOptimizablePackages() { ArraySet pkgs = new ArraySet<>(); mPm.forEachPackageState(packageState -> { - if (mPm.mPackageDexOptimizer.canOptimizePackage(packageState.getPkg())) { + final AndroidPackage pkg = packageState.getPkg(); + if (pkg != null && mPm.mPackageDexOptimizer.canOptimizePackage(pkg)) { pkgs.add(packageState.getPackageName()); } }); diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index a5b42f03b6dfa..69d498794e64a 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -182,7 +182,7 @@ public class PackageDexOptimizer { mInjector = injector; } - boolean canOptimizePackage(AndroidPackage pkg) { + boolean canOptimizePackage(@NonNull AndroidPackage pkg) { // We do not dexopt a package with no code. // Note that the system package is marked as having no code, however we can // still optimize it via dexoptSystemServerPath. From e981a22d41649cbdbcc9255e113be1bb573ac2e3 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 3 Feb 2022 16:01:29 +0000 Subject: [PATCH 107/176] Revert "Enable IMS#canImeRenderGesturalNavButtons() by default" This reverts commit 793e15271306d84451733363818e83e661112d44 [1]. Reason for revert: No back button on the setup wizard. [1]: I45e511f5cfec93cdd002d23c091b4fe735b28227 Bug: 215545985 Fix: 217668258 Change-Id: Iac77c5bfafc5d208a1d3f3b56f0f7ee81d51031b (cherry picked from commit c35df2f1ec687dc30562aef3be55d4a30969f46b) Merged-In:Iac77c5bfafc5d208a1d3f3b56f0f7ee81d51031b --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index fc2fbc39dbebc..223b8ccf44c84 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -346,7 +346,7 @@ public class InputMethodService extends AbstractInputMethodService { */ @AnyThread public static boolean canImeRenderGesturalNavButtons() { - return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true); + return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, false); } /** From 22f9b487bb49a58df84b885e5d9876a8a4c8f629 Mon Sep 17 00:00:00 2001 From: Yohei Yukawa Date: Thu, 3 Feb 2022 16:01:29 +0000 Subject: [PATCH 108/176] Revert "Enable IMS#canImeRenderGesturalNavButtons() by default" This reverts commit 793e15271306d84451733363818e83e661112d44 [1]. Reason for revert: No back button on the setup wizard. [1]: I45e511f5cfec93cdd002d23c091b4fe735b28227 Bug: 215545985 Fix: 217668258 Change-Id: Iac77c5bfafc5d208a1d3f3b56f0f7ee81d51031b (cherry picked from commit c35df2f1ec687dc30562aef3be55d4a30969f46b) Merged-In:Iac77c5bfafc5d208a1d3f3b56f0f7ee81d51031b --- core/java/android/inputmethodservice/InputMethodService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index fc2fbc39dbebc..223b8ccf44c84 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -346,7 +346,7 @@ public class InputMethodService extends AbstractInputMethodService { */ @AnyThread public static boolean canImeRenderGesturalNavButtons() { - return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true); + return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, false); } /** From 6ce44c47fe812d7d8384a97d0dac7623eff1f742 Mon Sep 17 00:00:00 2001 From: Avichal Rakesh Date: Fri, 4 Feb 2022 21:36:53 +0000 Subject: [PATCH 109/176] Revert "Prevent onImageAvailable from being called on stale listeners" This reverts commit 666ad3a9ac1492744256e86ada9617a897c0b799. Reason for revert: This CL breaks Google Translate Bug: 217847856 Change-Id: I5510ece72c2bc65d838d176f88a0ceaadb8faadb (cherry picked from commit ea4dbac40a5e7491007170190e5f062f17900a4e) Merged-In:I5510ece72c2bc65d838d176f88a0ceaadb8faadb --- media/java/android/media/ImageReader.java | 62 ++++++++--------------- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/media/java/android/media/ImageReader.java b/media/java/android/media/ImageReader.java index 5f02a430f3841..e2e48d35a6725 100644 --- a/media/java/android/media/ImageReader.java +++ b/media/java/android/media/ImageReader.java @@ -43,7 +43,6 @@ import java.util.Objects; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.locks.StampedLock; /** *

    The ImageReader class allows direct application access to image data @@ -676,8 +675,7 @@ public class ImageReader implements AutoCloseable { * If no handler specified and the calling thread has no looper. */ public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) { - long writeStamp = mListenerLock.writeLock(); - try { + synchronized (mListenerLock) { if (listener != null) { Looper looper = handler != null ? handler.getLooper() : Looper.myLooper(); if (looper == null) { @@ -693,8 +691,6 @@ public class ImageReader implements AutoCloseable { mListenerExecutor = null; } mListener = listener; - } finally { - mListenerLock.unlockWrite(writeStamp); } } @@ -717,12 +713,9 @@ public class ImageReader implements AutoCloseable { throw new IllegalArgumentException("executor must not be null"); } - long writeStamp = mListenerLock.writeLock(); - try { + synchronized (mListenerLock) { mListenerExecutor = executor; mListener = listener; - } finally { - mListenerLock.unlockWrite(writeStamp); } } @@ -738,8 +731,6 @@ public class ImageReader implements AutoCloseable { /** * Callback that is called when a new image is available from ImageReader. * - * This callback must not modify or close the passed {@code reader}. - * * @param reader the ImageReader the callback is associated with. * @see ImageReader * @see Image @@ -898,41 +889,28 @@ public class ImageReader implements AutoCloseable { return; } - synchronized (ir.mCloseLock) { - if (!ir.mIsReaderValid) { - // It's dangerous to fire onImageAvailable() callback when the ImageReader - // is being closed, as application could acquire next image in the - // onImageAvailable() callback. - return; - } - } - final Executor executor; - final long readStamp = ir.mListenerLock.readLock(); - try { + final OnImageAvailableListener listener; + synchronized (ir.mListenerLock) { executor = ir.mListenerExecutor; - if (executor == null) { - return; - } - } finally { - ir.mListenerLock.unlockRead(readStamp); + listener = ir.mListener; + } + final boolean isReaderValid; + synchronized (ir.mCloseLock) { + isReaderValid = ir.mIsReaderValid; } - executor.execute(() -> { - // Acquire readlock to ensure that the ImageReader does not change its - // state while a listener is actively processing. - final long rStamp = ir.mListenerLock.readLock(); - try { - // Fire onImageAvailable of the latest non-null listener - // This ensures that if the listener changes while messages are in queue, the - // in-flight messages will call onImageAvailable of the new listener instead - if (ir.mListener != null) { - ir.mListener.onImageAvailable(ir); + // It's dangerous to fire onImageAvailable() callback when the ImageReader + // is being closed, as application could acquire next image in the + // onImageAvailable() callback. + if (executor != null && listener != null && isReaderValid) { + executor.execute(new Runnable() { + @Override + public void run() { + listener.onImageAvailable(ir); } - } finally { - ir.mListenerLock.unlockRead(rStamp); - } - }); + }); + } } /** @@ -1092,7 +1070,7 @@ public class ImageReader implements AutoCloseable { private Surface mSurface; private int mEstimatedNativeAllocBytes; - private final StampedLock mListenerLock = new StampedLock(); + private final Object mListenerLock = new Object(); private final Object mCloseLock = new Object(); private boolean mIsReaderValid = false; private OnImageAvailableListener mListener; From 8b077f0866ec126c7c41b586bfdb390c721814a7 Mon Sep 17 00:00:00 2001 From: Shubham Dubey Date: Sun, 6 Feb 2022 04:15:32 +0000 Subject: [PATCH 110/176] Revert "Enable notification permission feature" Revert "Ask for notification permission" Revert submission 16789354-jr-enable-perm-feature Reason for revert: Breaking Camera and Notification tests BUG:218116478 BUG:218116141 BUG:218220073 BUG:218219131 Reverted Changes: Ife73f3d46:Ask for notification permission I718cc8cb1:Enable notification permission feature Change-Id: I9cb652b91861d0e68d8b0f783c0499f97bd6c291 (cherry picked from commit 7940ad02a778c3e681195c6d79dc9c271ae25048) Merged-In:I9cb652b91861d0e68d8b0f783c0499f97bd6c291 --- .../android/providers/settings/SettingsProvider.java | 12 ++++-------- .../notification/NotificationManagerServiceTest.java | 3 --- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 077337cdc8c3e..51870e2e958ed 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -3624,7 +3624,7 @@ public class SettingsProvider extends ContentProvider { } private final class UpgradeController { - private static final int SETTINGS_VERSION = 210; + private static final int SETTINGS_VERSION = 209; private final int mUserId; @@ -5498,21 +5498,17 @@ public class SettingsProvider extends ContentProvider { } if (currentVersion == 208) { - // Unused - currentVersion = 209; - } - if (currentVersion == 209) { - // Version 209: Enable enforcement of + // Version 208: Enable enforcement of // android.Manifest.permission#POST_NOTIFICATIONS in order for applications // to post notifications. final SettingsState secureSettings = getSecureSettingsLocked(userId); secureSettings.insertSettingLocked( Secure.NOTIFICATION_PERMISSION_ENABLED, - /* enabled= */ "1", + /* enabled= */" 1", /* tag= */ null, /* makeDefault= */ false, SettingsState.SYSTEM_PACKAGE_NAME); - currentVersion = 210; + currentVersion = 209; } // vXXX: Add new settings above this point. diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index d4d076566fb36..9f92294135c0b 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -372,9 +372,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { "android.permission.WRITE_DEVICE_CONFIG", "android.permission.READ_DEVICE_CONFIG", "android.permission.READ_CONTACTS"); - Settings.Secure.putIntForUser( - getContext().getContentResolver(), - Settings.Secure.NOTIFICATION_PERMISSION_ENABLED, 0, USER_SYSTEM); MockitoAnnotations.initMocks(this); From 37cffa5cc72ea53b00b32d6f27cb5b6f457c9694 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 8 Feb 2022 00:57:38 +0000 Subject: [PATCH 111/176] Revert "Revert "Revert "User consent for Logcat data access""" This reverts commit ec8c5511afb4a1f6e1f1b300ef7ac5263a990cc1. Reason for revert: Droidfood Blocking Bug: 218267535 Change-Id: I313f3fb7fdfbefb1c62b474b09f5b14e6ca0afd5 (cherry picked from commit 761d4a0ccf9528df41c8b7854b454d43cd740676) Merged-In:I313f3fb7fdfbefb1c62b474b09f5b14e6ca0afd5 --- .../android/app/ActivityManagerInternal.java | 8 - .../os/logcat/ILogcatManagerService.aidl | 2 - core/res/AndroidManifest.xml | 8 - core/res/res/values/strings.xml | 14 - core/res/res/values/symbols.xml | 5 - .../server/am/ActivityManagerService.java | 17 - .../logcat/LogAccessConfirmationActivity.java | 130 -------- .../server/logcat/LogcatManagerService.java | 312 +----------------- 8 files changed, 9 insertions(+), 487 deletions(-) delete mode 100644 services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index a58ceaa990226..cce7dd338b3dc 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -214,14 +214,6 @@ public abstract class ActivityManagerInternal { */ public abstract boolean isSystemReady(); - /** - * Returns package name given pid. - * - * @param pid The pid we are searching package name for. - */ - @Nullable - public abstract String getPackageNameByPid(int pid); - /** * Sets if the given pid has an overlay UI or not. * diff --git a/core/java/android/os/logcat/ILogcatManagerService.aidl b/core/java/android/os/logcat/ILogcatManagerService.aidl index 02db2749bbe8a..68b5679919d69 100644 --- a/core/java/android/os/logcat/ILogcatManagerService.aidl +++ b/core/java/android/os/logcat/ILogcatManagerService.aidl @@ -22,7 +22,5 @@ package android.os.logcat; interface ILogcatManagerService { void startThread(in int uid, in int gid, in int pid, in int fd); void finishThread(in int uid, in int gid, in int pid, in int fd); - void approve(in int uid, in int gid, in int pid, in int fd); - void decline(in int uid, in int gid, in int pid, in int fd); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 74bf152344c3b..bc3771917bd25 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6601,14 +6601,6 @@ android:exported="false"> - - - Harmful app detected - - System log access request - - Only this time - - Don\u2019t allow - - - %s requests system logs for functional debugging. - These logs might contain information that apps and services on your device have written. - - - Don\u2019t show again - %1$s wants to show %2$s slices diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 2b25c3eb099b1..f582b78fe7cd6 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3862,11 +3862,6 @@ - - - - - diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0310b0fc44695..bc5047c4c8992 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16089,23 +16089,6 @@ public class ActivityManagerService extends IActivityManager.Stub return mSystemReady; } - /** - * Returns package name by pid. - */ - @Override - @Nullable - public String getPackageNameByPid(int pid) { - synchronized (mPidsSelfLocked) { - final ProcessRecord app = mPidsSelfLocked.get(pid); - - if (app != null && app.info != null) { - return app.info.packageName; - } - - return null; - } - } - /** * Sets if the given pid has an overlay UI or not. * diff --git a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java b/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java deleted file mode 100644 index 6b442a6a395e9..0000000000000 --- a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.logcat; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentSender; -import android.os.Bundle; -import android.os.ServiceManager; -import android.os.logcat.ILogcatManagerService; -import android.util.Slog; -import android.view.View; -import android.widget.TextView; - -import com.android.internal.R; -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; - - -/** - * This dialog is shown to the user before an activity in a harmful app is launched. - * - * See {@code PackageManager.setLogcatAppInfo} for more info. - */ -public class LogAccessConfirmationActivity extends AlertActivity implements - DialogInterface.OnClickListener { - private static final String TAG = LogAccessConfirmationActivity.class.getSimpleName(); - - private String mPackageName; - private IntentSender mTarget; - private final ILogcatManagerService mLogcatManagerService = - ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat")); - - private int mUid; - private int mGid; - private int mPid; - private int mFd; - - private static final String EXTRA_UID = "uid"; - private static final String EXTRA_GID = "gid"; - private static final String EXTRA_PID = "pid"; - private static final String EXTRA_FD = "fd"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Intent intent = getIntent(); - mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); - mUid = intent.getIntExtra("uid", 0); - mGid = intent.getIntExtra("gid", 0); - mPid = intent.getIntExtra("pid", 0); - mFd = intent.getIntExtra("fd", 0); - - final AlertController.AlertParams p = mAlertParams; - p.mTitle = getString(R.string.log_access_confirmation_title); - p.mView = createView(); - - p.mPositiveButtonText = getString(R.string.log_access_confirmation_allow); - p.mPositiveButtonListener = this; - p.mNegativeButtonText = getString(R.string.log_access_confirmation_deny); - p.mNegativeButtonListener = this; - - mAlert.installContent(mAlertParams); - } - - private View createView() { - final View view = getLayoutInflater().inflate(R.layout.harmful_app_warning_dialog, - null /*root*/); - ((TextView) view.findViewById(R.id.app_name_text)) - .setText(mPackageName); - ((TextView) view.findViewById(R.id.message)) - .setText(getIntent().getExtras().getString("body")); - return view; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - try { - mLogcatManagerService.approve(mUid, mGid, mPid, mFd); - } catch (Throwable t) { - Slog.e(TAG, "Could not start the LogcatManagerService.", t); - } - finish(); - break; - case DialogInterface.BUTTON_NEGATIVE: - try { - mLogcatManagerService.decline(mUid, mGid, mPid, mFd); - } catch (Throwable t) { - Slog.e(TAG, "Could not start the LogcatManagerService.", t); - } - finish(); - break; - } - } - - /** - * Create the Intent for a LogAccessConfirmationActivity. - */ - public static Intent createIntent(Context context, String targetPackageName, - IntentSender target, int uid, int gid, int pid, int fd) { - final Intent intent = new Intent(); - intent.setClass(context, LogAccessConfirmationActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName); - intent.putExtra(EXTRA_UID, uid); - intent.putExtra(EXTRA_GID, gid); - intent.putExtra(EXTRA_PID, pid); - intent.putExtra(EXTRA_FD, fd); - - return intent; - } - -} diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java index 140c6d48b57b7..ff6372aec3bd9 100644 --- a/services/core/java/com/android/server/logcat/LogcatManagerService.java +++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java @@ -16,36 +16,20 @@ package com.android.server.logcat; -import android.annotation.NonNull; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.app.ActivityManagerInternal; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.os.ILogd; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import android.os.logcat.ILogcatManagerService; import android.util.Slog; -import com.android.internal.R; -import com.android.internal.notification.SystemNotificationChannels; -import com.android.internal.util.ArrayUtils; -import com.android.server.LocalServices; import com.android.server.SystemService; -import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** - * Service responsible for managing the access to Logcat. + * Service responsible for manage the access to Logcat. */ public final class LogcatManagerService extends SystemService { @@ -54,43 +38,6 @@ public final class LogcatManagerService extends SystemService { private final BinderService mBinderService; private final ExecutorService mThreadExecutor; private ILogd mLogdService; - private NotificationManager mNotificationManager; - private @NonNull ActivityManager mActivityManager; - private ActivityManagerInternal mActivityManagerInternal; - private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2; - private static int sUidImportanceListenerCount = 0; - private static final int AID_SHELL_UID = 2000; - - // TODO This allowlist is just a temporary workaround for the tests: - // FrameworksServicesTests - // PlatformRuleTests - // After adapting the test suites, the allowlist will be removed in - // the upcoming bug fix patches. - private static final String[] ALLOWABLE_TESTING_PACKAGES = { - "android.platform.test.rule.tests", - "com.android.frameworks.servicestests" - }; - - // TODO Same as the above ALLOWABLE_TESTING_PACKAGES. - private boolean isAllowableTestingPackage(int uid) { - PackageManager pm = mContext.getPackageManager(); - - String[] packageNames = pm.getPackagesForUid(uid); - - if (ArrayUtils.isEmpty(packageNames)) { - return false; - } - - for (String name : packageNames) { - Slog.e(TAG, "isAllowableTestingPackage: " + name); - - if (Arrays.asList(ALLOWABLE_TESTING_PACKAGES).contains(name)) { - return true; - } - } - - return false; - }; private final class BinderService extends ILogcatManagerService.Stub { @Override @@ -104,197 +51,6 @@ public final class LogcatManagerService extends SystemService { // the logd data access is finished. mThreadExecutor.execute(new LogdMonitor(uid, gid, pid, fd, false)); } - - @Override - public void approve(int uid, int gid, int pid, int fd) { - try { - getLogdService().approve(uid, gid, pid, fd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - @Override - public void decline(int uid, int gid, int pid, int fd) { - try { - getLogdService().decline(uid, gid, pid, fd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } - - private ILogd getLogdService() { - synchronized (LogcatManagerService.this) { - if (mLogdService == null) { - LogcatManagerService.this.addLogdService(); - } - return mLogdService; - } - } - - private String getBodyString(Context context, String callingPackage, int uid) { - PackageManager pm = context.getPackageManager(); - try { - return context.getString( - com.android.internal.R.string.log_access_confirmation_body, - pm.getApplicationInfoAsUser(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AUTO, - UserHandle.getUserId(uid)).loadLabel(pm)); - } catch (NameNotFoundException e) { - // App name is unknown. - return null; - } - } - - private void sendNotification(int notificationId, String clientInfo, int uid, int gid, int pid, - int fd) { - - final ActivityManagerInternal activityManagerInternal = - LocalServices.getService(ActivityManagerInternal.class); - - PackageManager pm = mContext.getPackageManager(); - String packageName = activityManagerInternal.getPackageNameByPid(pid); - if (packageName != null) { - String notificationBody = getBodyString(mContext, packageName, uid); - - final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext, - packageName, null, uid, gid, pid, fd); - - if (notificationBody == null) { - // Decline the logd access if the nofitication body is unknown - Slog.e(TAG, "Unknown notification body, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - // TODO Next version will replace notification with dialogue - // per UX guidance. - generateNotificationWithBodyContent(notificationId, clientInfo, notificationBody, - mIntent); - return; - - } - - String[] packageNames = pm.getPackagesForUid(uid); - - if (ArrayUtils.isEmpty(packageNames)) { - // Decline the logd access if the app name is unknown - Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - String firstPackageName = packageNames[0]; - - if (firstPackageName == null || firstPackageName.length() == 0) { - // Decline the logd access if the package name from uid is unknown - Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - String notificationBody = getBodyString(mContext, firstPackageName, uid); - - final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext, - firstPackageName, null, uid, gid, pid, fd); - - if (notificationBody == null) { - Slog.e(TAG, "Unknown notification body, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - // TODO Next version will replace notification with dialogue - // per UX guidance. - generateNotificationWithBodyContent(notificationId, clientInfo, - notificationBody, mIntent); - } - - private void declineLogdAccess(int uid, int gid, int pid, int fd) { - try { - getLogdService().decline(uid, gid, pid, fd); - } catch (RemoteException ex) { - Slog.e(TAG, "Fails to call remote functions ", ex); - } - } - - private void generateNotificationWithBodyContent(int notificationId, String clientInfo, - String notificationBody, Intent intent) { - final Notification.Builder notificationBuilder = new Notification.Builder( - mContext, - SystemNotificationChannels.ACCESSIBILITY_SECURITY_POLICY); - intent.setFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.setIdentifier(String.valueOf(notificationId) + clientInfo); - intent.putExtra("body", notificationBody); - - notificationBuilder - .setSmallIcon(R.drawable.ic_info) - .setContentTitle( - mContext.getString(R.string.log_access_confirmation_title)) - .setContentText(notificationBody) - .setContentIntent( - PendingIntent.getActivity(mContext, 0, intent, - PendingIntent.FLAG_IMMUTABLE)) - .setTicker(mContext.getString(R.string.log_access_confirmation_title)) - .setOnlyAlertOnce(true) - .setAutoCancel(true); - mNotificationManager.notify(notificationId, notificationBuilder.build()); - } - - /** - * A class which watches an uid for background access and notifies the logdMonitor when - * the package status becomes foreground (importance change) - */ - private class UidImportanceListener implements ActivityManager.OnUidImportanceListener { - private final int mExpectedUid; - private final int mExpectedGid; - private final int mExpectedPid; - private final int mExpectedFd; - private int mExpectedImportance; - private int mCurrentImportance = RunningAppProcessInfo.IMPORTANCE_GONE; - - UidImportanceListener(int uid, int gid, int pid, int fd, int importance) { - mExpectedUid = uid; - mExpectedGid = gid; - mExpectedPid = pid; - mExpectedFd = fd; - mExpectedImportance = importance; - } - - @Override - public void onUidImportance(int uid, int importance) { - if (uid == mExpectedUid) { - mCurrentImportance = importance; - - /** - * 1) If the process status changes to foreground, send a notification - * for user consent. - * 2) If the process status remains background, we decline logd access request. - **/ - if (importance <= RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE) { - String clientInfo = getClientInfo(uid, mExpectedGid, mExpectedPid, mExpectedFd); - sendNotification(0, clientInfo, uid, mExpectedGid, mExpectedPid, - mExpectedFd); - mActivityManager.removeOnUidImportanceListener(this); - - synchronized (LogcatManagerService.this) { - sUidImportanceListenerCount--; - } - } else { - try { - getLogdService().decline(uid, mExpectedGid, mExpectedPid, mExpectedFd); - } catch (RemoteException ex) { - Slog.e(TAG, "Fails to call remote functions ", ex); - } - } - } - } - } - - private static String getClientInfo(int uid, int gid, int pid, int fd) { - return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID=" - + Integer.toString(pid) + " FD=" + Integer.toString(fd); } private class LogdMonitor implements Runnable { @@ -318,7 +74,9 @@ public final class LogcatManagerService extends SystemService { } /** - * LogdMonitor generates a prompt for users. + * The current version grant the permission by default. + * And track the logd access. + * The next version will generate a prompt for users. * The users decide whether the logd access is allowed. */ @Override @@ -328,61 +86,10 @@ public final class LogcatManagerService extends SystemService { } if (mStart) { - - // TODO See the comments of ALLOWABLE_TESTING_PACKAGES. - if (isAllowableTestingPackage(mUid)) { - try { - getLogdService().approve(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - return; - } - - // If the access request is coming from adb shell, approve the logd access - if (mUid == AID_SHELL_UID) { - try { - getLogdService().approve(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - return; - } - - final int procState = LocalServices.getService(ActivityManagerInternal.class) - .getUidProcessState(mUid); - // If the process is foreground, send a notification for user consent - if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - String clientInfo = getClientInfo(mUid, mGid, mPid, mFd); - sendNotification(0, clientInfo, mUid, mGid, mPid, mFd); - } else { - /** - * If the process is background, add a background process change listener and - * monitor if the process status changes. - * To avoid clients registering multiple listeners, we limit the number of - * maximum listeners to MAX_UID_IMPORTANCE_COUNT_LISTENER. - **/ - if (mActivityManager == null) { - return; - } - - synchronized (LogcatManagerService.this) { - if (sUidImportanceListenerCount < MAX_UID_IMPORTANCE_COUNT_LISTENER) { - // Trigger addOnUidImportanceListener when there is an update from - // the importance of the process - mActivityManager.addOnUidImportanceListener(new UidImportanceListener( - mUid, mGid, mPid, mFd, - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE), - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); - sUidImportanceListenerCount++; - } else { - try { - getLogdService().decline(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } + try { + mLogdService.approve(mUid, mGid, mPid, mFd); + } catch (RemoteException ex) { + Slog.e(TAG, "Fails to call remote functions ", ex); } } } @@ -393,8 +100,6 @@ public final class LogcatManagerService extends SystemService { mContext = context; mBinderService = new BinderService(); mThreadExecutor = Executors.newCachedThreadPool(); - mActivityManager = context.getSystemService(ActivityManager.class); - mNotificationManager = mContext.getSystemService(NotificationManager.class); } @Override @@ -409,4 +114,5 @@ public final class LogcatManagerService extends SystemService { private void addLogdService() { mLogdService = ILogd.Stub.asInterface(ServiceManager.getService("logd")); } + } From 40c505226f51604ac6ecfac3a534bd8644e04fcb Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 8 Feb 2022 00:57:38 +0000 Subject: [PATCH 112/176] Revert "Revert "Revert "User consent for Logcat data access""" This reverts commit ec8c5511afb4a1f6e1f1b300ef7ac5263a990cc1. Reason for revert: Droidfood Blocking Bug: 218267535 Change-Id: I313f3fb7fdfbefb1c62b474b09f5b14e6ca0afd5 (cherry picked from commit 761d4a0ccf9528df41c8b7854b454d43cd740676) Merged-In:I313f3fb7fdfbefb1c62b474b09f5b14e6ca0afd5 --- .../android/app/ActivityManagerInternal.java | 8 - .../os/logcat/ILogcatManagerService.aidl | 2 - core/res/AndroidManifest.xml | 8 - core/res/res/values/strings.xml | 14 - core/res/res/values/symbols.xml | 5 - .../server/am/ActivityManagerService.java | 17 - .../logcat/LogAccessConfirmationActivity.java | 130 -------- .../server/logcat/LogcatManagerService.java | 312 +----------------- 8 files changed, 9 insertions(+), 487 deletions(-) delete mode 100644 services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index a58ceaa990226..cce7dd338b3dc 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -214,14 +214,6 @@ public abstract class ActivityManagerInternal { */ public abstract boolean isSystemReady(); - /** - * Returns package name given pid. - * - * @param pid The pid we are searching package name for. - */ - @Nullable - public abstract String getPackageNameByPid(int pid); - /** * Sets if the given pid has an overlay UI or not. * diff --git a/core/java/android/os/logcat/ILogcatManagerService.aidl b/core/java/android/os/logcat/ILogcatManagerService.aidl index 02db2749bbe8a..68b5679919d69 100644 --- a/core/java/android/os/logcat/ILogcatManagerService.aidl +++ b/core/java/android/os/logcat/ILogcatManagerService.aidl @@ -22,7 +22,5 @@ package android.os.logcat; interface ILogcatManagerService { void startThread(in int uid, in int gid, in int pid, in int fd); void finishThread(in int uid, in int gid, in int pid, in int fd); - void approve(in int uid, in int gid, in int pid, in int fd); - void decline(in int uid, in int gid, in int pid, in int fd); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 74bf152344c3b..bc3771917bd25 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6601,14 +6601,6 @@ android:exported="false"> - - - Harmful app detected - - System log access request - - Only this time - - Don\u2019t allow - - - %s requests system logs for functional debugging. - These logs might contain information that apps and services on your device have written. - - - Don\u2019t show again - %1$s wants to show %2$s slices diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 2b25c3eb099b1..f582b78fe7cd6 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3862,11 +3862,6 @@ - - - - - diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 0310b0fc44695..bc5047c4c8992 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16089,23 +16089,6 @@ public class ActivityManagerService extends IActivityManager.Stub return mSystemReady; } - /** - * Returns package name by pid. - */ - @Override - @Nullable - public String getPackageNameByPid(int pid) { - synchronized (mPidsSelfLocked) { - final ProcessRecord app = mPidsSelfLocked.get(pid); - - if (app != null && app.info != null) { - return app.info.packageName; - } - - return null; - } - } - /** * Sets if the given pid has an overlay UI or not. * diff --git a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java b/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java deleted file mode 100644 index 6b442a6a395e9..0000000000000 --- a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.logcat; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentSender; -import android.os.Bundle; -import android.os.ServiceManager; -import android.os.logcat.ILogcatManagerService; -import android.util.Slog; -import android.view.View; -import android.widget.TextView; - -import com.android.internal.R; -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; - - -/** - * This dialog is shown to the user before an activity in a harmful app is launched. - * - * See {@code PackageManager.setLogcatAppInfo} for more info. - */ -public class LogAccessConfirmationActivity extends AlertActivity implements - DialogInterface.OnClickListener { - private static final String TAG = LogAccessConfirmationActivity.class.getSimpleName(); - - private String mPackageName; - private IntentSender mTarget; - private final ILogcatManagerService mLogcatManagerService = - ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat")); - - private int mUid; - private int mGid; - private int mPid; - private int mFd; - - private static final String EXTRA_UID = "uid"; - private static final String EXTRA_GID = "gid"; - private static final String EXTRA_PID = "pid"; - private static final String EXTRA_FD = "fd"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Intent intent = getIntent(); - mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); - mUid = intent.getIntExtra("uid", 0); - mGid = intent.getIntExtra("gid", 0); - mPid = intent.getIntExtra("pid", 0); - mFd = intent.getIntExtra("fd", 0); - - final AlertController.AlertParams p = mAlertParams; - p.mTitle = getString(R.string.log_access_confirmation_title); - p.mView = createView(); - - p.mPositiveButtonText = getString(R.string.log_access_confirmation_allow); - p.mPositiveButtonListener = this; - p.mNegativeButtonText = getString(R.string.log_access_confirmation_deny); - p.mNegativeButtonListener = this; - - mAlert.installContent(mAlertParams); - } - - private View createView() { - final View view = getLayoutInflater().inflate(R.layout.harmful_app_warning_dialog, - null /*root*/); - ((TextView) view.findViewById(R.id.app_name_text)) - .setText(mPackageName); - ((TextView) view.findViewById(R.id.message)) - .setText(getIntent().getExtras().getString("body")); - return view; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - try { - mLogcatManagerService.approve(mUid, mGid, mPid, mFd); - } catch (Throwable t) { - Slog.e(TAG, "Could not start the LogcatManagerService.", t); - } - finish(); - break; - case DialogInterface.BUTTON_NEGATIVE: - try { - mLogcatManagerService.decline(mUid, mGid, mPid, mFd); - } catch (Throwable t) { - Slog.e(TAG, "Could not start the LogcatManagerService.", t); - } - finish(); - break; - } - } - - /** - * Create the Intent for a LogAccessConfirmationActivity. - */ - public static Intent createIntent(Context context, String targetPackageName, - IntentSender target, int uid, int gid, int pid, int fd) { - final Intent intent = new Intent(); - intent.setClass(context, LogAccessConfirmationActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName); - intent.putExtra(EXTRA_UID, uid); - intent.putExtra(EXTRA_GID, gid); - intent.putExtra(EXTRA_PID, pid); - intent.putExtra(EXTRA_FD, fd); - - return intent; - } - -} diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java index 140c6d48b57b7..ff6372aec3bd9 100644 --- a/services/core/java/com/android/server/logcat/LogcatManagerService.java +++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java @@ -16,36 +16,20 @@ package com.android.server.logcat; -import android.annotation.NonNull; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.app.ActivityManagerInternal; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.os.ILogd; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import android.os.logcat.ILogcatManagerService; import android.util.Slog; -import com.android.internal.R; -import com.android.internal.notification.SystemNotificationChannels; -import com.android.internal.util.ArrayUtils; -import com.android.server.LocalServices; import com.android.server.SystemService; -import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** - * Service responsible for managing the access to Logcat. + * Service responsible for manage the access to Logcat. */ public final class LogcatManagerService extends SystemService { @@ -54,43 +38,6 @@ public final class LogcatManagerService extends SystemService { private final BinderService mBinderService; private final ExecutorService mThreadExecutor; private ILogd mLogdService; - private NotificationManager mNotificationManager; - private @NonNull ActivityManager mActivityManager; - private ActivityManagerInternal mActivityManagerInternal; - private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2; - private static int sUidImportanceListenerCount = 0; - private static final int AID_SHELL_UID = 2000; - - // TODO This allowlist is just a temporary workaround for the tests: - // FrameworksServicesTests - // PlatformRuleTests - // After adapting the test suites, the allowlist will be removed in - // the upcoming bug fix patches. - private static final String[] ALLOWABLE_TESTING_PACKAGES = { - "android.platform.test.rule.tests", - "com.android.frameworks.servicestests" - }; - - // TODO Same as the above ALLOWABLE_TESTING_PACKAGES. - private boolean isAllowableTestingPackage(int uid) { - PackageManager pm = mContext.getPackageManager(); - - String[] packageNames = pm.getPackagesForUid(uid); - - if (ArrayUtils.isEmpty(packageNames)) { - return false; - } - - for (String name : packageNames) { - Slog.e(TAG, "isAllowableTestingPackage: " + name); - - if (Arrays.asList(ALLOWABLE_TESTING_PACKAGES).contains(name)) { - return true; - } - } - - return false; - }; private final class BinderService extends ILogcatManagerService.Stub { @Override @@ -104,197 +51,6 @@ public final class LogcatManagerService extends SystemService { // the logd data access is finished. mThreadExecutor.execute(new LogdMonitor(uid, gid, pid, fd, false)); } - - @Override - public void approve(int uid, int gid, int pid, int fd) { - try { - getLogdService().approve(uid, gid, pid, fd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - @Override - public void decline(int uid, int gid, int pid, int fd) { - try { - getLogdService().decline(uid, gid, pid, fd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } - - private ILogd getLogdService() { - synchronized (LogcatManagerService.this) { - if (mLogdService == null) { - LogcatManagerService.this.addLogdService(); - } - return mLogdService; - } - } - - private String getBodyString(Context context, String callingPackage, int uid) { - PackageManager pm = context.getPackageManager(); - try { - return context.getString( - com.android.internal.R.string.log_access_confirmation_body, - pm.getApplicationInfoAsUser(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AUTO, - UserHandle.getUserId(uid)).loadLabel(pm)); - } catch (NameNotFoundException e) { - // App name is unknown. - return null; - } - } - - private void sendNotification(int notificationId, String clientInfo, int uid, int gid, int pid, - int fd) { - - final ActivityManagerInternal activityManagerInternal = - LocalServices.getService(ActivityManagerInternal.class); - - PackageManager pm = mContext.getPackageManager(); - String packageName = activityManagerInternal.getPackageNameByPid(pid); - if (packageName != null) { - String notificationBody = getBodyString(mContext, packageName, uid); - - final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext, - packageName, null, uid, gid, pid, fd); - - if (notificationBody == null) { - // Decline the logd access if the nofitication body is unknown - Slog.e(TAG, "Unknown notification body, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - // TODO Next version will replace notification with dialogue - // per UX guidance. - generateNotificationWithBodyContent(notificationId, clientInfo, notificationBody, - mIntent); - return; - - } - - String[] packageNames = pm.getPackagesForUid(uid); - - if (ArrayUtils.isEmpty(packageNames)) { - // Decline the logd access if the app name is unknown - Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - String firstPackageName = packageNames[0]; - - if (firstPackageName == null || firstPackageName.length() == 0) { - // Decline the logd access if the package name from uid is unknown - Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - String notificationBody = getBodyString(mContext, firstPackageName, uid); - - final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext, - firstPackageName, null, uid, gid, pid, fd); - - if (notificationBody == null) { - Slog.e(TAG, "Unknown notification body, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - // TODO Next version will replace notification with dialogue - // per UX guidance. - generateNotificationWithBodyContent(notificationId, clientInfo, - notificationBody, mIntent); - } - - private void declineLogdAccess(int uid, int gid, int pid, int fd) { - try { - getLogdService().decline(uid, gid, pid, fd); - } catch (RemoteException ex) { - Slog.e(TAG, "Fails to call remote functions ", ex); - } - } - - private void generateNotificationWithBodyContent(int notificationId, String clientInfo, - String notificationBody, Intent intent) { - final Notification.Builder notificationBuilder = new Notification.Builder( - mContext, - SystemNotificationChannels.ACCESSIBILITY_SECURITY_POLICY); - intent.setFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.setIdentifier(String.valueOf(notificationId) + clientInfo); - intent.putExtra("body", notificationBody); - - notificationBuilder - .setSmallIcon(R.drawable.ic_info) - .setContentTitle( - mContext.getString(R.string.log_access_confirmation_title)) - .setContentText(notificationBody) - .setContentIntent( - PendingIntent.getActivity(mContext, 0, intent, - PendingIntent.FLAG_IMMUTABLE)) - .setTicker(mContext.getString(R.string.log_access_confirmation_title)) - .setOnlyAlertOnce(true) - .setAutoCancel(true); - mNotificationManager.notify(notificationId, notificationBuilder.build()); - } - - /** - * A class which watches an uid for background access and notifies the logdMonitor when - * the package status becomes foreground (importance change) - */ - private class UidImportanceListener implements ActivityManager.OnUidImportanceListener { - private final int mExpectedUid; - private final int mExpectedGid; - private final int mExpectedPid; - private final int mExpectedFd; - private int mExpectedImportance; - private int mCurrentImportance = RunningAppProcessInfo.IMPORTANCE_GONE; - - UidImportanceListener(int uid, int gid, int pid, int fd, int importance) { - mExpectedUid = uid; - mExpectedGid = gid; - mExpectedPid = pid; - mExpectedFd = fd; - mExpectedImportance = importance; - } - - @Override - public void onUidImportance(int uid, int importance) { - if (uid == mExpectedUid) { - mCurrentImportance = importance; - - /** - * 1) If the process status changes to foreground, send a notification - * for user consent. - * 2) If the process status remains background, we decline logd access request. - **/ - if (importance <= RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE) { - String clientInfo = getClientInfo(uid, mExpectedGid, mExpectedPid, mExpectedFd); - sendNotification(0, clientInfo, uid, mExpectedGid, mExpectedPid, - mExpectedFd); - mActivityManager.removeOnUidImportanceListener(this); - - synchronized (LogcatManagerService.this) { - sUidImportanceListenerCount--; - } - } else { - try { - getLogdService().decline(uid, mExpectedGid, mExpectedPid, mExpectedFd); - } catch (RemoteException ex) { - Slog.e(TAG, "Fails to call remote functions ", ex); - } - } - } - } - } - - private static String getClientInfo(int uid, int gid, int pid, int fd) { - return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID=" - + Integer.toString(pid) + " FD=" + Integer.toString(fd); } private class LogdMonitor implements Runnable { @@ -318,7 +74,9 @@ public final class LogcatManagerService extends SystemService { } /** - * LogdMonitor generates a prompt for users. + * The current version grant the permission by default. + * And track the logd access. + * The next version will generate a prompt for users. * The users decide whether the logd access is allowed. */ @Override @@ -328,61 +86,10 @@ public final class LogcatManagerService extends SystemService { } if (mStart) { - - // TODO See the comments of ALLOWABLE_TESTING_PACKAGES. - if (isAllowableTestingPackage(mUid)) { - try { - getLogdService().approve(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - return; - } - - // If the access request is coming from adb shell, approve the logd access - if (mUid == AID_SHELL_UID) { - try { - getLogdService().approve(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - return; - } - - final int procState = LocalServices.getService(ActivityManagerInternal.class) - .getUidProcessState(mUid); - // If the process is foreground, send a notification for user consent - if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - String clientInfo = getClientInfo(mUid, mGid, mPid, mFd); - sendNotification(0, clientInfo, mUid, mGid, mPid, mFd); - } else { - /** - * If the process is background, add a background process change listener and - * monitor if the process status changes. - * To avoid clients registering multiple listeners, we limit the number of - * maximum listeners to MAX_UID_IMPORTANCE_COUNT_LISTENER. - **/ - if (mActivityManager == null) { - return; - } - - synchronized (LogcatManagerService.this) { - if (sUidImportanceListenerCount < MAX_UID_IMPORTANCE_COUNT_LISTENER) { - // Trigger addOnUidImportanceListener when there is an update from - // the importance of the process - mActivityManager.addOnUidImportanceListener(new UidImportanceListener( - mUid, mGid, mPid, mFd, - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE), - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); - sUidImportanceListenerCount++; - } else { - try { - getLogdService().decline(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } + try { + mLogdService.approve(mUid, mGid, mPid, mFd); + } catch (RemoteException ex) { + Slog.e(TAG, "Fails to call remote functions ", ex); } } } @@ -393,8 +100,6 @@ public final class LogcatManagerService extends SystemService { mContext = context; mBinderService = new BinderService(); mThreadExecutor = Executors.newCachedThreadPool(); - mActivityManager = context.getSystemService(ActivityManager.class); - mNotificationManager = mContext.getSystemService(NotificationManager.class); } @Override @@ -409,4 +114,5 @@ public final class LogcatManagerService extends SystemService { private void addLogdService() { mLogdService = ILogd.Stub.asInterface(ServiceManager.getService("logd")); } + } From a286e2fa7fc690a4547ca13896490ce77faeac1f Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 8 Feb 2022 23:23:44 +0000 Subject: [PATCH 113/176] Revert "Flip flag for clipboard UI" This reverts commit 8f948ea5d4016c5fda7529b4e77c22ea5205097a. Reason for revert: Droidfood Blocking Bug: 218458652 Change-Id: Idff38f6c989b9700ab985a2036cd3746f1908f9a (cherry picked from commit 97c392aa7b983be46315f802785cd603fa27ba6a) Merged-In:Idff38f6c989b9700ab985a2036cd3746f1908f9a --- .../android/systemui/clipboardoverlay/ClipboardListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index 54664f2fdd935..72b40d42b7b8a 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -48,7 +48,7 @@ public class ClipboardListener extends CoreStartable @Override public void start() { if (DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, true)) { + DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, false)) { mClipboardManager = requireNonNull(mContext.getSystemService(ClipboardManager.class)); mClipboardManager.addPrimaryClipChangedListener(this); } From 011e4f8f887f5caf8518d5fe63f0477ca19152b4 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 8 Feb 2022 23:23:44 +0000 Subject: [PATCH 114/176] Revert "Flip flag for clipboard UI" This reverts commit 8f948ea5d4016c5fda7529b4e77c22ea5205097a. Reason for revert: Droidfood Blocking Bug: 218458652 Change-Id: Idff38f6c989b9700ab985a2036cd3746f1908f9a (cherry picked from commit 97c392aa7b983be46315f802785cd603fa27ba6a) Merged-In:Idff38f6c989b9700ab985a2036cd3746f1908f9a --- .../android/systemui/clipboardoverlay/ClipboardListener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java index 54664f2fdd935..72b40d42b7b8a 100644 --- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java +++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardListener.java @@ -48,7 +48,7 @@ public class ClipboardListener extends CoreStartable @Override public void start() { if (DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, true)) { + DeviceConfig.NAMESPACE_SYSTEMUI, CLIPBOARD_OVERLAY_ENABLED, false)) { mClipboardManager = requireNonNull(mContext.getSystemService(ClipboardManager.class)); mClipboardManager.addPrimaryClipChangedListener(this); } From be76cce84832bb19195756af318b3620afafa90b Mon Sep 17 00:00:00 2001 From: Wenhao Wang Date: Tue, 8 Feb 2022 16:28:08 +0000 Subject: [PATCH 115/176] Revert "Short term fix: Allow native processes for Logcat data access" This reverts commit b19cc07516a9f136e990019093b43d7fc9d2bdf1. Reason for revert: Move fix to logd side Change-Id: I4e98bded353be9142b302b075dd472dce4b4f9c7 (cherry picked from commit aa2a4852e4b248de0863e738cbeb639f2963ebcc) Merged-In:I4e98bded353be9142b302b075dd472dce4b4f9c7 --- .../com/android/server/logcat/LogcatManagerService.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java index 78322967ec15d..140c6d48b57b7 100644 --- a/services/core/java/com/android/server/logcat/LogcatManagerService.java +++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java @@ -59,7 +59,7 @@ public final class LogcatManagerService extends SystemService { private ActivityManagerInternal mActivityManagerInternal; private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2; private static int sUidImportanceListenerCount = 0; - private static final int AID_APP_UID = 10000; + private static final int AID_SHELL_UID = 2000; // TODO This allowlist is just a temporary workaround for the tests: // FrameworksServicesTests @@ -339,10 +339,8 @@ public final class LogcatManagerService extends SystemService { return; } - // If the access request is coming from native apps, approve the logd access - // TODO: This is needed to make tooling to work. However, - // we intend to be stricter with respect to native processes in a follow-up CL - if (mUid < AID_APP_UID) { + // If the access request is coming from adb shell, approve the logd access + if (mUid == AID_SHELL_UID) { try { getLogdService().approve(mUid, mGid, mPid, mFd); } catch (RemoteException e) { From 31165b1aeafd73c1739db9748ccd937a34501900 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Tue, 8 Feb 2022 00:57:38 +0000 Subject: [PATCH 116/176] Revert "Revert "Revert "User consent for Logcat data access""" This reverts commit ec8c5511afb4a1f6e1f1b300ef7ac5263a990cc1. Reason for revert: Droidfood Blocking Bug: 218267535 Change-Id: I313f3fb7fdfbefb1c62b474b09f5b14e6ca0afd5 (cherry picked from commit 761d4a0ccf9528df41c8b7854b454d43cd740676) Merged-In:I313f3fb7fdfbefb1c62b474b09f5b14e6ca0afd5 --- .../android/app/ActivityManagerInternal.java | 8 - .../os/logcat/ILogcatManagerService.aidl | 2 - core/res/AndroidManifest.xml | 8 - core/res/res/values/strings.xml | 14 - core/res/res/values/symbols.xml | 5 - .../server/am/ActivityManagerService.java | 17 - .../logcat/LogAccessConfirmationActivity.java | 130 -------- .../server/logcat/LogcatManagerService.java | 312 +----------------- 8 files changed, 9 insertions(+), 487 deletions(-) delete mode 100644 services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index a58ceaa990226..cce7dd338b3dc 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -214,14 +214,6 @@ public abstract class ActivityManagerInternal { */ public abstract boolean isSystemReady(); - /** - * Returns package name given pid. - * - * @param pid The pid we are searching package name for. - */ - @Nullable - public abstract String getPackageNameByPid(int pid); - /** * Sets if the given pid has an overlay UI or not. * diff --git a/core/java/android/os/logcat/ILogcatManagerService.aidl b/core/java/android/os/logcat/ILogcatManagerService.aidl index 02db2749bbe8a..68b5679919d69 100644 --- a/core/java/android/os/logcat/ILogcatManagerService.aidl +++ b/core/java/android/os/logcat/ILogcatManagerService.aidl @@ -22,7 +22,5 @@ package android.os.logcat; interface ILogcatManagerService { void startThread(in int uid, in int gid, in int pid, in int fd); void finishThread(in int uid, in int gid, in int pid, in int fd); - void approve(in int uid, in int gid, in int pid, in int fd); - void decline(in int uid, in int gid, in int pid, in int fd); } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 74bf152344c3b..bc3771917bd25 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -6601,14 +6601,6 @@ android:exported="false"> - - - Harmful app detected - - System log access request - - Only this time - - Don\u2019t allow - - - %s requests system logs for functional debugging. - These logs might contain information that apps and services on your device have written. - - - Don\u2019t show again - %1$s wants to show %2$s slices diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index ea648dd104827..69af74efb061d 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3865,11 +3865,6 @@ - - - - - diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 4977278979d3e..0ef2d8bc1e9ee 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -16106,23 +16106,6 @@ public class ActivityManagerService extends IActivityManager.Stub return mSystemReady; } - /** - * Returns package name by pid. - */ - @Override - @Nullable - public String getPackageNameByPid(int pid) { - synchronized (mPidsSelfLocked) { - final ProcessRecord app = mPidsSelfLocked.get(pid); - - if (app != null && app.info != null) { - return app.info.packageName; - } - - return null; - } - } - /** * Sets if the given pid has an overlay UI or not. * diff --git a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java b/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java deleted file mode 100644 index 6b442a6a395e9..0000000000000 --- a/services/core/java/com/android/server/logcat/LogAccessConfirmationActivity.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2022 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.logcat; - -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.IntentSender; -import android.os.Bundle; -import android.os.ServiceManager; -import android.os.logcat.ILogcatManagerService; -import android.util.Slog; -import android.view.View; -import android.widget.TextView; - -import com.android.internal.R; -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; - - -/** - * This dialog is shown to the user before an activity in a harmful app is launched. - * - * See {@code PackageManager.setLogcatAppInfo} for more info. - */ -public class LogAccessConfirmationActivity extends AlertActivity implements - DialogInterface.OnClickListener { - private static final String TAG = LogAccessConfirmationActivity.class.getSimpleName(); - - private String mPackageName; - private IntentSender mTarget; - private final ILogcatManagerService mLogcatManagerService = - ILogcatManagerService.Stub.asInterface(ServiceManager.getService("logcat")); - - private int mUid; - private int mGid; - private int mPid; - private int mFd; - - private static final String EXTRA_UID = "uid"; - private static final String EXTRA_GID = "gid"; - private static final String EXTRA_PID = "pid"; - private static final String EXTRA_FD = "fd"; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - final Intent intent = getIntent(); - mPackageName = intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME); - mUid = intent.getIntExtra("uid", 0); - mGid = intent.getIntExtra("gid", 0); - mPid = intent.getIntExtra("pid", 0); - mFd = intent.getIntExtra("fd", 0); - - final AlertController.AlertParams p = mAlertParams; - p.mTitle = getString(R.string.log_access_confirmation_title); - p.mView = createView(); - - p.mPositiveButtonText = getString(R.string.log_access_confirmation_allow); - p.mPositiveButtonListener = this; - p.mNegativeButtonText = getString(R.string.log_access_confirmation_deny); - p.mNegativeButtonListener = this; - - mAlert.installContent(mAlertParams); - } - - private View createView() { - final View view = getLayoutInflater().inflate(R.layout.harmful_app_warning_dialog, - null /*root*/); - ((TextView) view.findViewById(R.id.app_name_text)) - .setText(mPackageName); - ((TextView) view.findViewById(R.id.message)) - .setText(getIntent().getExtras().getString("body")); - return view; - } - - @Override - public void onClick(DialogInterface dialog, int which) { - switch (which) { - case DialogInterface.BUTTON_POSITIVE: - try { - mLogcatManagerService.approve(mUid, mGid, mPid, mFd); - } catch (Throwable t) { - Slog.e(TAG, "Could not start the LogcatManagerService.", t); - } - finish(); - break; - case DialogInterface.BUTTON_NEGATIVE: - try { - mLogcatManagerService.decline(mUid, mGid, mPid, mFd); - } catch (Throwable t) { - Slog.e(TAG, "Could not start the LogcatManagerService.", t); - } - finish(); - break; - } - } - - /** - * Create the Intent for a LogAccessConfirmationActivity. - */ - public static Intent createIntent(Context context, String targetPackageName, - IntentSender target, int uid, int gid, int pid, int fd) { - final Intent intent = new Intent(); - intent.setClass(context, LogAccessConfirmationActivity.class); - intent.putExtra(Intent.EXTRA_PACKAGE_NAME, targetPackageName); - intent.putExtra(EXTRA_UID, uid); - intent.putExtra(EXTRA_GID, gid); - intent.putExtra(EXTRA_PID, pid); - intent.putExtra(EXTRA_FD, fd); - - return intent; - } - -} diff --git a/services/core/java/com/android/server/logcat/LogcatManagerService.java b/services/core/java/com/android/server/logcat/LogcatManagerService.java index 140c6d48b57b7..ff6372aec3bd9 100644 --- a/services/core/java/com/android/server/logcat/LogcatManagerService.java +++ b/services/core/java/com/android/server/logcat/LogcatManagerService.java @@ -16,36 +16,20 @@ package com.android.server.logcat; -import android.annotation.NonNull; -import android.app.ActivityManager; -import android.app.ActivityManager.RunningAppProcessInfo; -import android.app.ActivityManagerInternal; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.os.ILogd; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import android.os.logcat.ILogcatManagerService; import android.util.Slog; -import com.android.internal.R; -import com.android.internal.notification.SystemNotificationChannels; -import com.android.internal.util.ArrayUtils; -import com.android.server.LocalServices; import com.android.server.SystemService; -import java.util.Arrays; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** - * Service responsible for managing the access to Logcat. + * Service responsible for manage the access to Logcat. */ public final class LogcatManagerService extends SystemService { @@ -54,43 +38,6 @@ public final class LogcatManagerService extends SystemService { private final BinderService mBinderService; private final ExecutorService mThreadExecutor; private ILogd mLogdService; - private NotificationManager mNotificationManager; - private @NonNull ActivityManager mActivityManager; - private ActivityManagerInternal mActivityManagerInternal; - private static final int MAX_UID_IMPORTANCE_COUNT_LISTENER = 2; - private static int sUidImportanceListenerCount = 0; - private static final int AID_SHELL_UID = 2000; - - // TODO This allowlist is just a temporary workaround for the tests: - // FrameworksServicesTests - // PlatformRuleTests - // After adapting the test suites, the allowlist will be removed in - // the upcoming bug fix patches. - private static final String[] ALLOWABLE_TESTING_PACKAGES = { - "android.platform.test.rule.tests", - "com.android.frameworks.servicestests" - }; - - // TODO Same as the above ALLOWABLE_TESTING_PACKAGES. - private boolean isAllowableTestingPackage(int uid) { - PackageManager pm = mContext.getPackageManager(); - - String[] packageNames = pm.getPackagesForUid(uid); - - if (ArrayUtils.isEmpty(packageNames)) { - return false; - } - - for (String name : packageNames) { - Slog.e(TAG, "isAllowableTestingPackage: " + name); - - if (Arrays.asList(ALLOWABLE_TESTING_PACKAGES).contains(name)) { - return true; - } - } - - return false; - }; private final class BinderService extends ILogcatManagerService.Stub { @Override @@ -104,197 +51,6 @@ public final class LogcatManagerService extends SystemService { // the logd data access is finished. mThreadExecutor.execute(new LogdMonitor(uid, gid, pid, fd, false)); } - - @Override - public void approve(int uid, int gid, int pid, int fd) { - try { - getLogdService().approve(uid, gid, pid, fd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - - @Override - public void decline(int uid, int gid, int pid, int fd) { - try { - getLogdService().decline(uid, gid, pid, fd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } - - private ILogd getLogdService() { - synchronized (LogcatManagerService.this) { - if (mLogdService == null) { - LogcatManagerService.this.addLogdService(); - } - return mLogdService; - } - } - - private String getBodyString(Context context, String callingPackage, int uid) { - PackageManager pm = context.getPackageManager(); - try { - return context.getString( - com.android.internal.R.string.log_access_confirmation_body, - pm.getApplicationInfoAsUser(callingPackage, PackageManager.MATCH_DIRECT_BOOT_AUTO, - UserHandle.getUserId(uid)).loadLabel(pm)); - } catch (NameNotFoundException e) { - // App name is unknown. - return null; - } - } - - private void sendNotification(int notificationId, String clientInfo, int uid, int gid, int pid, - int fd) { - - final ActivityManagerInternal activityManagerInternal = - LocalServices.getService(ActivityManagerInternal.class); - - PackageManager pm = mContext.getPackageManager(); - String packageName = activityManagerInternal.getPackageNameByPid(pid); - if (packageName != null) { - String notificationBody = getBodyString(mContext, packageName, uid); - - final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext, - packageName, null, uid, gid, pid, fd); - - if (notificationBody == null) { - // Decline the logd access if the nofitication body is unknown - Slog.e(TAG, "Unknown notification body, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - // TODO Next version will replace notification with dialogue - // per UX guidance. - generateNotificationWithBodyContent(notificationId, clientInfo, notificationBody, - mIntent); - return; - - } - - String[] packageNames = pm.getPackagesForUid(uid); - - if (ArrayUtils.isEmpty(packageNames)) { - // Decline the logd access if the app name is unknown - Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - String firstPackageName = packageNames[0]; - - if (firstPackageName == null || firstPackageName.length() == 0) { - // Decline the logd access if the package name from uid is unknown - Slog.e(TAG, "Unknown calling package name, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - String notificationBody = getBodyString(mContext, firstPackageName, uid); - - final Intent mIntent = LogAccessConfirmationActivity.createIntent(mContext, - firstPackageName, null, uid, gid, pid, fd); - - if (notificationBody == null) { - Slog.e(TAG, "Unknown notification body, declining the logd access"); - declineLogdAccess(uid, gid, pid, fd); - return; - } - - // TODO Next version will replace notification with dialogue - // per UX guidance. - generateNotificationWithBodyContent(notificationId, clientInfo, - notificationBody, mIntent); - } - - private void declineLogdAccess(int uid, int gid, int pid, int fd) { - try { - getLogdService().decline(uid, gid, pid, fd); - } catch (RemoteException ex) { - Slog.e(TAG, "Fails to call remote functions ", ex); - } - } - - private void generateNotificationWithBodyContent(int notificationId, String clientInfo, - String notificationBody, Intent intent) { - final Notification.Builder notificationBuilder = new Notification.Builder( - mContext, - SystemNotificationChannels.ACCESSIBILITY_SECURITY_POLICY); - intent.setFlags( - Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - intent.setIdentifier(String.valueOf(notificationId) + clientInfo); - intent.putExtra("body", notificationBody); - - notificationBuilder - .setSmallIcon(R.drawable.ic_info) - .setContentTitle( - mContext.getString(R.string.log_access_confirmation_title)) - .setContentText(notificationBody) - .setContentIntent( - PendingIntent.getActivity(mContext, 0, intent, - PendingIntent.FLAG_IMMUTABLE)) - .setTicker(mContext.getString(R.string.log_access_confirmation_title)) - .setOnlyAlertOnce(true) - .setAutoCancel(true); - mNotificationManager.notify(notificationId, notificationBuilder.build()); - } - - /** - * A class which watches an uid for background access and notifies the logdMonitor when - * the package status becomes foreground (importance change) - */ - private class UidImportanceListener implements ActivityManager.OnUidImportanceListener { - private final int mExpectedUid; - private final int mExpectedGid; - private final int mExpectedPid; - private final int mExpectedFd; - private int mExpectedImportance; - private int mCurrentImportance = RunningAppProcessInfo.IMPORTANCE_GONE; - - UidImportanceListener(int uid, int gid, int pid, int fd, int importance) { - mExpectedUid = uid; - mExpectedGid = gid; - mExpectedPid = pid; - mExpectedFd = fd; - mExpectedImportance = importance; - } - - @Override - public void onUidImportance(int uid, int importance) { - if (uid == mExpectedUid) { - mCurrentImportance = importance; - - /** - * 1) If the process status changes to foreground, send a notification - * for user consent. - * 2) If the process status remains background, we decline logd access request. - **/ - if (importance <= RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE) { - String clientInfo = getClientInfo(uid, mExpectedGid, mExpectedPid, mExpectedFd); - sendNotification(0, clientInfo, uid, mExpectedGid, mExpectedPid, - mExpectedFd); - mActivityManager.removeOnUidImportanceListener(this); - - synchronized (LogcatManagerService.this) { - sUidImportanceListenerCount--; - } - } else { - try { - getLogdService().decline(uid, mExpectedGid, mExpectedPid, mExpectedFd); - } catch (RemoteException ex) { - Slog.e(TAG, "Fails to call remote functions ", ex); - } - } - } - } - } - - private static String getClientInfo(int uid, int gid, int pid, int fd) { - return "UID=" + Integer.toString(uid) + " GID=" + Integer.toString(gid) + " PID=" - + Integer.toString(pid) + " FD=" + Integer.toString(fd); } private class LogdMonitor implements Runnable { @@ -318,7 +74,9 @@ public final class LogcatManagerService extends SystemService { } /** - * LogdMonitor generates a prompt for users. + * The current version grant the permission by default. + * And track the logd access. + * The next version will generate a prompt for users. * The users decide whether the logd access is allowed. */ @Override @@ -328,61 +86,10 @@ public final class LogcatManagerService extends SystemService { } if (mStart) { - - // TODO See the comments of ALLOWABLE_TESTING_PACKAGES. - if (isAllowableTestingPackage(mUid)) { - try { - getLogdService().approve(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - return; - } - - // If the access request is coming from adb shell, approve the logd access - if (mUid == AID_SHELL_UID) { - try { - getLogdService().approve(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - return; - } - - final int procState = LocalServices.getService(ActivityManagerInternal.class) - .getUidProcessState(mUid); - // If the process is foreground, send a notification for user consent - if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) { - String clientInfo = getClientInfo(mUid, mGid, mPid, mFd); - sendNotification(0, clientInfo, mUid, mGid, mPid, mFd); - } else { - /** - * If the process is background, add a background process change listener and - * monitor if the process status changes. - * To avoid clients registering multiple listeners, we limit the number of - * maximum listeners to MAX_UID_IMPORTANCE_COUNT_LISTENER. - **/ - if (mActivityManager == null) { - return; - } - - synchronized (LogcatManagerService.this) { - if (sUidImportanceListenerCount < MAX_UID_IMPORTANCE_COUNT_LISTENER) { - // Trigger addOnUidImportanceListener when there is an update from - // the importance of the process - mActivityManager.addOnUidImportanceListener(new UidImportanceListener( - mUid, mGid, mPid, mFd, - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE), - RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE); - sUidImportanceListenerCount++; - } else { - try { - getLogdService().decline(mUid, mGid, mPid, mFd); - } catch (RemoteException e) { - e.printStackTrace(); - } - } - } + try { + mLogdService.approve(mUid, mGid, mPid, mFd); + } catch (RemoteException ex) { + Slog.e(TAG, "Fails to call remote functions ", ex); } } } @@ -393,8 +100,6 @@ public final class LogcatManagerService extends SystemService { mContext = context; mBinderService = new BinderService(); mThreadExecutor = Executors.newCachedThreadPool(); - mActivityManager = context.getSystemService(ActivityManager.class); - mNotificationManager = mContext.getSystemService(NotificationManager.class); } @Override @@ -409,4 +114,5 @@ public final class LogcatManagerService extends SystemService { private void addLogdService() { mLogdService = ILogd.Stub.asInterface(ServiceManager.getService("logd")); } + } From c7be2a51bb5b506a4ffd166018fb8a4ecf85d7da Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 10 Feb 2022 17:27:03 -0500 Subject: [PATCH 117/176] Use a real pkg name and uid Rather than trying to reconstruct it, as some apps use | in their tag. Test: atest NotificationManagerServiceTest Test: atest NotificationPermissionMigrationTest Test: make sure an app that uses | in its tag can post notifs Fixes: 218812985 Change-Id: Ic6332bdb827a3b603efe5b79d242bfe0bb61917d (cherry picked from commit 5bc56484a352c4edb303514cd74af931c50d60ff) Merged-In:Ic6332bdb827a3b603efe5b79d242bfe0bb61917d --- .../NotificationManagerService.java | 19 ++++++++----- .../NotificationManagerServiceTest.java | 28 +++++++++++++------ .../NotificationPermissionMigrationTest.java | 12 +++++--- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2717f0c4c8a47..037935d3630ea 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -5805,6 +5805,7 @@ public class NotificationManagerService extends SystemService { || channel.isImportanceLockedByCriticalDeviceFunction()); final StatusBarNotification adjustedSbn = notificationRecord.getSbn(); userId = adjustedSbn.getUser().getIdentifier(); + int uid = adjustedSbn.getUid(); ArrayMap summaries = mAutobundledSummaries.get(userId); if (summaries == null) { summaries = new ArrayMap<>(); @@ -5851,7 +5852,7 @@ public class NotificationManagerService extends SystemService { notificationRecord.getIsAppImportanceLocked()); summaries.put(pkg, summarySbn.getKey()); } - if (summaryRecord != null && checkDisqualifyingFeatures(userId, MY_UID, + if (summaryRecord != null && checkDisqualifyingFeatures(userId, uid, summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord, true)) { return summaryRecord; @@ -6822,7 +6823,6 @@ public class NotificationManagerService extends SystemService { return false; } - // blocked apps boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid); synchronized (mNotificationLock) { @@ -7215,10 +7215,12 @@ public class NotificationManagerService extends SystemService { if (mAssistants.isEnabled()) { mAssistants.onNotificationEnqueuedLocked(r); mHandler.postDelayed( - new PostNotificationRunnable(r.getKey(), enqueueElapsedTimeMs), + new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), enqueueElapsedTimeMs), DELAY_FOR_ASSISTANT_TIME); } else { - mHandler.post(new PostNotificationRunnable(r.getKey(), enqueueElapsedTimeMs)); + mHandler.post(new PostNotificationRunnable(r.getKey(), + r.getSbn().getPackageName(), r.getUid(), enqueueElapsedTimeMs)); } } } @@ -7242,16 +7244,19 @@ public class NotificationManagerService extends SystemService { protected class PostNotificationRunnable implements Runnable { private final String key; private final long postElapsedTimeMs; + private final String pkg; + private final int uid; - PostNotificationRunnable(String key, @ElapsedRealtimeLong long postElapsedTimeMs) { + PostNotificationRunnable(String key, String pkg, int uid, + @ElapsedRealtimeLong long postElapsedTimeMs) { this.key = key; + this.pkg = pkg; + this.uid = uid; this.postElapsedTimeMs = postElapsedTimeMs; } @Override public void run() { - String pkg = StatusBarNotification.getPkgFromKey(key); - int uid = StatusBarNotification.getUidFromKey(key); boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid); synchronized (mNotificationLock) { try { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index ef9494aca4a5d..62614ca9c44c8 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1338,7 +1338,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -1359,7 +1360,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3921,7 +3923,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3938,7 +3941,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3954,7 +3958,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3967,12 +3972,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); r = generateNotificationRecord(mTestNotificationChannel, 1, null, false); r.setCriticality(CriticalNotificationExtractor.CRITICAL); - runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); mService.addEnqueuedNotification(r); runnable.run(); @@ -4416,6 +4423,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(original.getKey(), + original.getSbn().getPackageName(), + original.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -4438,6 +4447,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(update.getKey(), + update.getSbn().getPackageName(), + update.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -6533,7 +6544,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNull(update.getSbn().getNotification().getSmallIcon()); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(update.getKey(), + mService.new PostNotificationRunnable(update.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java index fec5405c3390d..d922f403c3c73 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java @@ -657,7 +657,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -790,7 +791,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -806,7 +808,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -822,7 +825,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); From 7deb60b3f3931c39345c0e761be88bca41703ec8 Mon Sep 17 00:00:00 2001 From: Julia Reynolds Date: Thu, 10 Feb 2022 17:27:03 -0500 Subject: [PATCH 118/176] Use a real pkg name and uid Rather than trying to reconstruct it, as some apps use | in their tag. Test: atest NotificationManagerServiceTest Test: atest NotificationPermissionMigrationTest Test: make sure an app that uses | in its tag can post notifs Fixes: 218812985 Change-Id: Ic6332bdb827a3b603efe5b79d242bfe0bb61917d (cherry picked from commit 5bc56484a352c4edb303514cd74af931c50d60ff) Merged-In:Ic6332bdb827a3b603efe5b79d242bfe0bb61917d --- .../NotificationManagerService.java | 19 ++++++++----- .../NotificationManagerServiceTest.java | 28 +++++++++++++------ .../NotificationPermissionMigrationTest.java | 12 +++++--- 3 files changed, 40 insertions(+), 19 deletions(-) diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 2717f0c4c8a47..037935d3630ea 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -5805,6 +5805,7 @@ public class NotificationManagerService extends SystemService { || channel.isImportanceLockedByCriticalDeviceFunction()); final StatusBarNotification adjustedSbn = notificationRecord.getSbn(); userId = adjustedSbn.getUser().getIdentifier(); + int uid = adjustedSbn.getUid(); ArrayMap summaries = mAutobundledSummaries.get(userId); if (summaries == null) { summaries = new ArrayMap<>(); @@ -5851,7 +5852,7 @@ public class NotificationManagerService extends SystemService { notificationRecord.getIsAppImportanceLocked()); summaries.put(pkg, summarySbn.getKey()); } - if (summaryRecord != null && checkDisqualifyingFeatures(userId, MY_UID, + if (summaryRecord != null && checkDisqualifyingFeatures(userId, uid, summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord, true)) { return summaryRecord; @@ -6822,7 +6823,6 @@ public class NotificationManagerService extends SystemService { return false; } - // blocked apps boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid); synchronized (mNotificationLock) { @@ -7215,10 +7215,12 @@ public class NotificationManagerService extends SystemService { if (mAssistants.isEnabled()) { mAssistants.onNotificationEnqueuedLocked(r); mHandler.postDelayed( - new PostNotificationRunnable(r.getKey(), enqueueElapsedTimeMs), + new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), enqueueElapsedTimeMs), DELAY_FOR_ASSISTANT_TIME); } else { - mHandler.post(new PostNotificationRunnable(r.getKey(), enqueueElapsedTimeMs)); + mHandler.post(new PostNotificationRunnable(r.getKey(), + r.getSbn().getPackageName(), r.getUid(), enqueueElapsedTimeMs)); } } } @@ -7242,16 +7244,19 @@ public class NotificationManagerService extends SystemService { protected class PostNotificationRunnable implements Runnable { private final String key; private final long postElapsedTimeMs; + private final String pkg; + private final int uid; - PostNotificationRunnable(String key, @ElapsedRealtimeLong long postElapsedTimeMs) { + PostNotificationRunnable(String key, String pkg, int uid, + @ElapsedRealtimeLong long postElapsedTimeMs) { this.key = key; + this.pkg = pkg; + this.uid = uid; this.postElapsedTimeMs = postElapsedTimeMs; } @Override public void run() { - String pkg = StatusBarNotification.getPkgFromKey(key); - int uid = StatusBarNotification.getUidFromKey(key); boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid); synchronized (mNotificationLock) { try { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java index ef9494aca4a5d..62614ca9c44c8 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -1338,7 +1338,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -1359,7 +1360,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3921,7 +3923,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationRecord r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3938,7 +3941,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r = generateNotificationRecord(mTestNotificationChannel, 0, null, false); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3954,7 +3958,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -3967,12 +3972,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { r.setCriticality(CriticalNotificationExtractor.CRITICAL_LOW); mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); r = generateNotificationRecord(mTestNotificationChannel, 1, null, false); r.setCriticality(CriticalNotificationExtractor.CRITICAL); - runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); mService.addEnqueuedNotification(r); runnable.run(); @@ -4416,6 +4423,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(original.getKey(), + original.getSbn().getPackageName(), + original.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -4438,6 +4447,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { NotificationManagerService.PostNotificationRunnable runnable = mService.new PostNotificationRunnable(update.getKey(), + update.getSbn().getPackageName(), + update.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -6533,7 +6544,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertNull(update.getSbn().getNotification().getSmallIcon()); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(update.getKey(), + mService.new PostNotificationRunnable(update.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java index fec5405c3390d..d922f403c3c73 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java @@ -657,7 +657,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -790,7 +791,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { mService.addEnqueuedNotification(r); NotificationManagerService.PostNotificationRunnable runnable = - mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -806,7 +808,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); @@ -822,7 +825,8 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { r = new NotificationRecord(mContext, sbn, mTestNotificationChannel); mService.addEnqueuedNotification(r); - runnable = mService.new PostNotificationRunnable(r.getKey(), SystemClock.elapsedRealtime()); + runnable = mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(), + r.getUid(), SystemClock.elapsedRealtime()); runnable.run(); waitForIdle(); From 7342a2c688f7c1df0c19f22ec00f25ec646fb592 Mon Sep 17 00:00:00 2001 From: Hai Zhang Date: Fri, 11 Feb 2022 18:07:02 +0000 Subject: [PATCH 119/176] Revert "Query only necessary columns in ChooserActivity.extractF..." Revert submission 16791148-chooseractivity-queryresolver Reason for revert: b/218994001 Reverted Changes: I91bbd3971:Query only necessary columns in ChooserActivity.ex... I2ab9c6f03:Query only necessary columns in ChooserActivity.ex... Fixes: 16850551 Change-Id: Idbc6270bb0dc1f2402c44d111bdcebe8a25f28c2 (cherry picked from commit 454c526e5e30c47998bbec29548f01ed948faad2) Merged-In:Idbc6270bb0dc1f2402c44d111bdcebe8a25f28c2 --- .../com/android/internal/app/ChooserActivity.java | 12 +++--------- .../android/internal/app/ChooserWrapperActivity.java | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 150eb65269086..4ae6bf7e8379d 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -217,12 +217,6 @@ public class ChooserActivity extends ResolverActivity implements private static final int APP_PREDICTION_SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20; public static final String APP_PREDICTION_INTENT_FILTER_KEY = "intent_filter"; - private static final String[] QUERY_FILE_INFO_PROJECTION = { - OpenableColumns.DISPLAY_NAME, - Downloads.Impl.COLUMN_TITLE, - DocumentsContract.Document.COLUMN_FLAGS - }; - private static final String PLURALS_COUNT = "count"; private static final String PLURALS_FILE_NAME = "file_name"; @@ -1480,15 +1474,15 @@ public class ChooserActivity extends ResolverActivity implements * and to avoid mocking Android core classes. */ @VisibleForTesting - public Cursor queryResolver(ContentResolver resolver, String[] projection, Uri uri) { - return resolver.query(uri, projection, null, null, null); + public Cursor queryResolver(ContentResolver resolver, Uri uri) { + return resolver.query(uri, null, null, null, null); } private FileInfo extractFileInfo(Uri uri, ContentResolver resolver) { String fileName = null; boolean hasThumbnail = false; - try (Cursor cursor = queryResolver(resolver, QUERY_FILE_INFO_PROJECTION, uri)) { + try (Cursor cursor = queryResolver(resolver, uri)) { if (cursor != null && cursor.getCount() > 0) { int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); int titleIndex = cursor.getColumnIndex(Downloads.Impl.COLUMN_TITLE); diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java index 139bc36156ad5..7f8598217ec69 100644 --- a/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java +++ b/core/tests/coretests/src/com/android/internal/app/ChooserWrapperActivity.java @@ -192,7 +192,7 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW } @Override - public Cursor queryResolver(ContentResolver resolver, String[] projection, Uri uri) { + public Cursor queryResolver(ContentResolver resolver, Uri uri) { if (sOverrides.resolverCursor != null) { return sOverrides.resolverCursor; } @@ -201,7 +201,7 @@ public class ChooserWrapperActivity extends ChooserActivity implements IChooserW throw new SecurityException("Test exception handling"); } - return super.queryResolver(resolver, projection, uri); + return super.queryResolver(resolver, uri); } @Override From 9dea78e2190bf68de7e301d4a273170a2340561c Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 14 Feb 2022 17:54:33 +0000 Subject: [PATCH 120/176] Revert "Support multiple dark tint areas in status bar" Revert "Update car to reflect changes to support multiple dark t..." Revert submission 16776797-multiple_dark_tint_areas Reason for revert: b/219387839 Reverted Changes: I9d78676e8:Update oslo to reflect changes to support multiple... Ie171e70b3:Update car to reflect changes to support multiple ... I0d8696f6b:Support multiple dark tint areas in status bar Change-Id: I3c4c0497d5850d1a702489dff35a7cc38b82c083 (cherry picked from commit 66a5c34eb82ede1192d71ba556cbfd121c27d2f3) Merged-In:I3c4c0497d5850d1a702489dff35a7cc38b82c083 --- .../systemui/plugins/DarkIconDispatcher.java | 31 ++++++++--------- .../com/android/systemui/DarkReceiverImpl.kt | 6 ++-- .../systemui/battery/BatteryMeterView.java | 7 ++-- .../statusbar/HeadsUpStatusBarView.java | 6 ++-- .../systemui/statusbar/StatusBarIconView.java | 5 ++- .../statusbar/StatusBarMobileView.java | 10 +++--- .../systemui/statusbar/StatusBarWifiView.java | 7 ++-- .../phone/DarkIconDispatcherImpl.java | 31 +++++++++-------- .../statusbar/phone/DemoStatusIcons.java | 8 ++--- .../phone/HeadsUpAppearanceController.java | 5 ++- .../phone/KeyguardStatusBarView.java | 11 +++---- .../statusbar/phone/LightBarController.java | 21 +++++++----- .../phone/NotificationIconAreaController.java | 17 ++++++---- .../systemui/statusbar/policy/Clock.java | 5 ++- .../phone/LightBarControllerTest.java | 33 ++----------------- 15 files changed, 83 insertions(+), 120 deletions(-) diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java index 757ed76eff369..c7bc858c82661 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java @@ -25,8 +25,6 @@ import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.plugins.annotations.DependsOn; import com.android.systemui.plugins.annotations.ProvidesInterface; -import java.util.ArrayList; - /** * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark * intensity. Accessible through {@link PluginDependency} @@ -34,15 +32,15 @@ import java.util.ArrayList; @ProvidesInterface(version = DarkIconDispatcher.VERSION) @DependsOn(target = DarkReceiver.class) public interface DarkIconDispatcher { - int VERSION = 2; + int VERSION = 1; /** * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. * - * @param r the areas in which icons should change its tint, in logical screen + * @param r the area in which icons should change its tint, in logical screen * coordinates */ - void setIconsDarkArea(ArrayList r); + void setIconsDarkArea(Rect r); /** * Adds a receiver to receive callbacks onDarkChanged @@ -78,8 +76,8 @@ public interface DarkIconDispatcher { * @return the tint to apply to view depending on the desired tint color and * the screen tintArea in which to apply that tint */ - static int getTint(ArrayList tintAreas, View view, int color) { - if (isInAreas(tintAreas, view)) { + static int getTint(Rect tintArea, View view, int color) { + if (isInArea(tintArea, view)) { return color; } else { return DEFAULT_ICON_TINT; @@ -87,16 +85,15 @@ public interface DarkIconDispatcher { } /** - * @return true if more than half of the view area are in any of the given - * areas, false otherwise + * @return the dark intensity to apply to view depending on the desired dark + * intensity and the screen tintArea in which to apply that intensity */ - static boolean isInAreas(ArrayList areas, View view) { - for (Rect area : areas) { - if (isInArea(area, view)) { - return true; - } + static float getDarkIntensity(Rect tintArea, View view, float intensity) { + if (isInArea(tintArea, view)) { + return intensity; + } else { + return 0f; } - return false; } /** @@ -125,7 +122,7 @@ public interface DarkIconDispatcher { */ @ProvidesInterface(version = DarkReceiver.VERSION) interface DarkReceiver { - int VERSION = 2; - void onDarkChanged(ArrayList areas, float darkIntensity, int tint); + int VERSION = 1; + void onDarkChanged(Rect area, float darkIntensity, int tint); } } diff --git a/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt b/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt index 13d96e44be9e6..42d38cb3463c5 100644 --- a/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt @@ -32,11 +32,11 @@ class DarkReceiverImpl @JvmOverloads constructor( private val dualToneHandler = DualToneHandler(context) init { - onDarkChanged(ArrayList(), 1f, DarkIconDispatcher.DEFAULT_ICON_TINT) + onDarkChanged(Rect(), 1f, DarkIconDispatcher.DEFAULT_ICON_TINT) } - override fun onDarkChanged(areas: ArrayList?, darkIntensity: Float, tint: Int) { - val intensity = if (DarkIconDispatcher.isInAreas(areas, this)) darkIntensity else 0f + override fun onDarkChanged(area: Rect?, darkIntensity: Float, tint: Int) { + val intensity = if (DarkIconDispatcher.isInArea(area, this)) darkIntensity else 0f setBackgroundColor(dualToneHandler.getSingleColor(intensity)) } } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java index 2b0c083e2f31b..f8e7697f58313 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java @@ -56,7 +56,6 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.text.NumberFormat; -import java.util.ArrayList; public class BatteryMeterView extends LinearLayout implements DarkReceiver { @@ -126,7 +125,7 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver { updateShowPercent(); mDualToneHandler = new DualToneHandler(context); // Init to not dark at all. - onDarkChanged(new ArrayList(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT); + onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT); setClipChildren(false); setClipToPadding(false); @@ -354,8 +353,8 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver { } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - float intensity = DarkIconDispatcher.isInAreas(areas, this) ? darkIntensity : 0; + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0; mNonAdaptedSingleToneColor = mDualToneHandler.getSingleColor(intensity); mNonAdaptedForegroundColor = mDualToneHandler.getFillColor(intensity); mNonAdaptedBackgroundColor = mDualToneHandler.getBackgroundColor(intensity); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java index 4d933d9ad21ee..8e6cf36f8e74a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java @@ -31,8 +31,6 @@ import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener; -import java.util.ArrayList; - /** * The view in the statusBar that contains part of the heads-up information @@ -163,8 +161,8 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout { return mIconDrawingRect; } - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - mTextView.setTextColor(DarkIconDispatcher.getTint(areas, this, tint)); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + mTextView.setTextColor(DarkIconDispatcher.getTint(area, this, tint)); } public void setOnDrawingRectChangedListener(Runnable onDrawingRectChangedListener) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 72c4ce8afe9b5..e9387499cf4a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -61,7 +61,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.util.drawable.DrawableSize; import java.text.NumberFormat; -import java.util.ArrayList; import java.util.Arrays; public class StatusBarIconView extends AnimatedImageView implements StatusIconDisplayable { @@ -966,8 +965,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - int areaTint = getTint(areas, this, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + int areaTint = getTint(area, this, tint); ColorStateList color = ColorStateList.valueOf(areaTint); setImageTintList(color); setDecorColor(areaTint); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index 465ab93132f94..68dcdd9ff49fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -17,7 +17,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.plugins.DarkIconDispatcher.getTint; -import static com.android.systemui.plugins.DarkIconDispatcher.isInAreas; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; @@ -40,8 +40,6 @@ import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; -import java.util.ArrayList; - public class StatusBarMobileView extends FrameLayout implements DarkReceiver, StatusIconDisplayable { private static final String TAG = "StatusBarMobileView"; @@ -224,11 +222,11 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - float intensity = isInAreas(areas, this) ? darkIntensity : 0; + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + float intensity = isInArea(area, this) ? darkIntensity : 0; mMobileDrawable.setTintList( ColorStateList.valueOf(mDualToneHandler.getSingleColor(intensity))); - ColorStateList color = ColorStateList.valueOf(getTint(areas, this, tint)); + ColorStateList color = ColorStateList.valueOf(getTint(area, this, tint)); mIn.setImageTintList(color); mOut.setImageTintList(color); mMobileType.setImageTintList(color); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java index a6986d7978336..6dbcc44e385b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.plugins.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; @@ -36,8 +37,6 @@ import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import java.util.ArrayList; - /** * Start small: StatusBarWifiView will be able to layout from a WifiIconState */ @@ -236,8 +235,8 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - int areaTint = getTint(areas, this, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + int areaTint = getTint(area, this, tint); ColorStateList color = ColorStateList.valueOf(areaTint); mWifiIcon.setImageTintList(color); mIn.setImageTintList(color); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java index 150da1687b393..d06de75056d2a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java @@ -30,7 +30,6 @@ import com.android.systemui.statusbar.CommandQueue; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import javax.inject.Inject; @@ -41,7 +40,7 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, LightBarTransitionsController.DarkIntensityApplier { private final LightBarTransitionsController mTransitionsController; - private final ArrayList mTintAreas = new ArrayList<>(); + private final Rect mTintArea = new Rect(); private final ArrayMap mReceivers = new ArrayMap<>(); private int mIconTint = DEFAULT_ICON_TINT; @@ -70,14 +69,14 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, public void addDarkReceiver(DarkReceiver receiver) { mReceivers.put(receiver, receiver); - receiver.onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } public void addDarkReceiver(ImageView imageView) { DarkReceiver receiver = (area, darkIntensity, tint) -> imageView.setImageTintList( - ColorStateList.valueOf(getTint(mTintAreas, imageView, mIconTint))); + ColorStateList.valueOf(getTint(mTintArea, imageView, mIconTint))); mReceivers.put(imageView, receiver); - receiver.onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } public void removeDarkReceiver(DarkReceiver object) { @@ -89,23 +88,23 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, } public void applyDark(DarkReceiver object) { - mReceivers.get(object).onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + mReceivers.get(object).onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } /** * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. * - * @param darkAreas the areas in which icons should change it's tint, in logical screen - * coordinates + * @param darkArea the area in which icons should change it's tint, in logical screen + * coordinates */ - public void setIconsDarkArea(ArrayList darkAreas) { - if (darkAreas == null && mTintAreas.isEmpty()) { + public void setIconsDarkArea(Rect darkArea) { + if (darkArea == null && mTintArea.isEmpty()) { return; } - - mTintAreas.clear(); - if (darkAreas != null) { - mTintAreas.addAll(darkAreas); + if (darkArea == null) { + mTintArea.setEmpty(); + } else { + mTintArea.set(darkArea); } applyIconTint(); } @@ -125,7 +124,7 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, private void applyIconTint() { for (int i = 0; i < mReceivers.size(); i++) { - mReceivers.valueAt(i).onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + mReceivers.valueAt(i).onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } } @@ -134,6 +133,6 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, pw.println("DarkIconDispatcher: "); pw.println(" mIconTint: 0x" + Integer.toHexString(mIconTint)); pw.println(" mDarkIntensity: " + mDarkIntensity + "f"); - pw.println(" mTintAreas: " + mTintAreas); + pw.println(" mTintArea: " + mTintArea); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 6dbbf0d532465..ee51efb090ddc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -315,14 +315,14 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - setColor(DarkIconDispatcher.getTint(areas, mStatusIcons, tint)); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + setColor(DarkIconDispatcher.getTint(area, mStatusIcons, tint)); if (mWifiView != null) { - mWifiView.onDarkChanged(areas, darkIntensity, tint); + mWifiView.onDarkChanged(area, darkIntensity, tint); } for (StatusBarMobileView view : mMobileViews) { - view.onDarkChanged(areas, darkIntensity, tint); + view.onDarkChanged(area, darkIntensity, tint); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 9863a0ed1ce0c..866f0d3243911 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -41,7 +41,6 @@ import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.ViewController; import java.util.Optional; -import java.util.ArrayList; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -370,8 +369,8 @@ public class HeadsUpAppearanceController extends ViewController areas, float darkIntensity, int tint) { - mView.onDarkChanged(areas, darkIntensity, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + mView.onDarkChanged(area, darkIntensity, tint); } public void onStateChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index 65173a230871b..b8e9875be7e22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -50,7 +50,6 @@ import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; /** * The header group on Keyguard. @@ -61,7 +60,7 @@ public class KeyguardStatusBarView extends RelativeLayout { private static final int LAYOUT_CUTOUT = 1; private static final int LAYOUT_NO_CUTOUT = 2; - private final ArrayList mEmptyTintRect = new ArrayList<>(); + private final Rect mEmptyRect = new Rect(0, 0, 0, 0); private boolean mShowPercentAvailable; private boolean mBatteryCharging; @@ -477,14 +476,14 @@ public class KeyguardStatusBarView extends RelativeLayout { iconManager.setTint(iconColor); } - applyDarkness(R.id.battery, mEmptyTintRect, intensity, iconColor); - applyDarkness(R.id.clock, mEmptyTintRect, intensity, iconColor); + applyDarkness(R.id.battery, mEmptyRect, intensity, iconColor); + applyDarkness(R.id.clock, mEmptyRect, intensity, iconColor); } - private void applyDarkness(int id, ArrayList tintAreas, float intensity, int color) { + private void applyDarkness(int id, Rect tintArea, float intensity, int color) { View v = findViewById(id); if (v instanceof DarkReceiver) { - ((DarkReceiver) v).onDarkChanged(tintAreas, intensity, color); + ((DarkReceiver) v).onDarkChanged(tintArea, intensity, color); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java index 4082db7b6bef3..88ae0db5bad0d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java @@ -25,7 +25,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE import android.content.Context; import android.graphics.Color; -import android.graphics.Rect; import android.view.InsetsFlags; import android.view.ViewDebug; import android.view.WindowInsetsController.Appearance; @@ -42,7 +41,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import javax.inject.Inject; @@ -216,23 +214,27 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private void updateStatus() { final int numStacks = mAppearanceRegions.length; - final ArrayList lightBarBounds = new ArrayList<>(); + int numLightStacks = 0; + + // We can only have maximum one light stack. + int indexLightStack = -1; for (int i = 0; i < numStacks; i++) { - final AppearanceRegion ar = mAppearanceRegions[i]; - if (isLight(ar.getAppearance(), mStatusBarMode, APPEARANCE_LIGHT_STATUS_BARS)) { - lightBarBounds.add(ar.getBounds()); + if (isLight(mAppearanceRegions[i].getAppearance(), mStatusBarMode, + APPEARANCE_LIGHT_STATUS_BARS)) { + numLightStacks++; + indexLightStack = i; } } // If no one is light, all icons become white. - if (lightBarBounds.isEmpty()) { + if (numLightStacks == 0) { mStatusBarIconController.getTransitionsController().setIconsDark( false, animateChange()); } // If all stacks are light, all icons get dark. - else if (lightBarBounds.size() == numStacks) { + else if (numLightStacks == numStacks) { mStatusBarIconController.setIconsDarkArea(null); mStatusBarIconController.getTransitionsController().setIconsDark(true, animateChange()); @@ -240,7 +242,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC // Not the same for every stack, magic! else { - mStatusBarIconController.setIconsDarkArea(lightBarBounds); + mStatusBarIconController.setIconsDarkArea( + mAppearanceRegions[indexLightStack].getBounds()); mStatusBarIconController.getTransitionsController().setIconsDark(true, animateChange()); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index e70c81de81afb..c36130073765f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -83,7 +83,7 @@ public class NotificationIconAreaController implements private NotificationIconContainer mNotificationIcons; private NotificationIconContainer mShelfIcons; private NotificationIconContainer mAodIcons; - private final ArrayList mTintAreas = new ArrayList<>(); + private final Rect mTintArea = new Rect(); private Context mContext; private final DemoModeController mDemoModeController; @@ -240,14 +240,17 @@ public class NotificationIconAreaController implements * See {@link com.android.systemui.statusbar.policy.DarkIconDispatcher#setIconsDarkArea}. * Sets the color that should be used to tint any icons in the notification area. * - * @param tintAreas the areas in which to tint the icons, specified in screen coordinates + * @param tintArea the area in which to tint the icons, specified in screen coordinates * @param darkIntensity */ - public void onDarkChanged(ArrayList tintAreas, float darkIntensity, int iconTint) { - mTintAreas.clear(); - mTintAreas.addAll(tintAreas); + public void onDarkChanged(Rect tintArea, float darkIntensity, int iconTint) { + if (tintArea == null) { + mTintArea.setEmpty(); + } else { + mTintArea.set(tintArea); + } - if (DarkIconDispatcher.isInAreas(tintAreas, mNotificationIconArea)) { + if (DarkIconDispatcher.isInArea(tintArea, mNotificationIconArea)) { mIconTint = iconTint; } @@ -486,7 +489,7 @@ public class NotificationIconAreaController implements int color = StatusBarIconView.NO_COLOR; boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mContrastColorUtil); if (colorize) { - color = DarkIconDispatcher.getTint(mTintAreas, v, tint); + color = DarkIconDispatcher.getTint(mTintArea, v, tint); } v.setStaticDrawableColor(color); v.setDecorColor(tint); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 562816fbe21fc..97d344ad6b63e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -56,7 +56,6 @@ import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; @@ -315,8 +314,8 @@ public class Clock extends TextView implements } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - mNonAdaptedColor = DarkIconDispatcher.getTint(areas, this, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + mNonAdaptedColor = DarkIconDispatcher.getTint(area, this, tint); setTextColor(mNonAdaptedColor); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java index cc4abfcaa42f5..7e33c01572e1a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java @@ -20,8 +20,6 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; -import static junit.framework.Assert.assertTrue; - import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -43,9 +41,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; - -import java.util.ArrayList; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -96,9 +91,7 @@ public class LightBarControllerTest extends SysuiTestCase { mLightBarController.onStatusBarAppearanceChanged( appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT, false /* navbarColorManagedByIme */); - ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - verify(mStatusBarIconController).setIconsDarkArea(captor.capture()); - assertTrue(captor.getValue().contains(firstBounds)); + verify(mStatusBarIconController).setIconsDarkArea(eq(firstBounds)); verify(mLightBarTransitionsController).setIconsDark(eq(true), anyBoolean()); } @@ -113,29 +106,7 @@ public class LightBarControllerTest extends SysuiTestCase { mLightBarController.onStatusBarAppearanceChanged( appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT, false /* navbarColorManagedByIme */); - ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - verify(mStatusBarIconController).setIconsDarkArea(captor.capture()); - assertTrue(captor.getValue().contains(secondBounds)); - verify(mLightBarTransitionsController).setIconsDark(eq(true), anyBoolean()); - } - - @Test - public void testOnStatusBarAppearanceChanged_multipleStacks_oneStackLightMultipleStackDark() { - final Rect firstBounds = new Rect(0, 0, 1, 1); - final Rect secondBounds = new Rect(1, 0, 2, 1); - final Rect thirdBounds = new Rect(2, 0, 3, 1); - final AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{ - new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, firstBounds), - new AppearanceRegion(0 /* appearance */, secondBounds), - new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, thirdBounds) - }; - mLightBarController.onStatusBarAppearanceChanged( - appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT, - false /* navbarColorManagedByIme */); - ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - verify(mStatusBarIconController).setIconsDarkArea(captor.capture()); - assertTrue(captor.getValue().contains(firstBounds)); - assertTrue(captor.getValue().contains(thirdBounds)); + verify(mStatusBarIconController).setIconsDarkArea(eq(secondBounds)); verify(mLightBarTransitionsController).setIconsDark(eq(true), anyBoolean()); } From 51f8b20afef45d2c43cc6a25abab181aa32549f0 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 14 Feb 2022 17:54:33 +0000 Subject: [PATCH 121/176] Revert "Support multiple dark tint areas in status bar" Revert "Update car to reflect changes to support multiple dark t..." Revert submission 16776797-multiple_dark_tint_areas Reason for revert: b/219387839 Reverted Changes: I9d78676e8:Update oslo to reflect changes to support multiple... Ie171e70b3:Update car to reflect changes to support multiple ... I0d8696f6b:Support multiple dark tint areas in status bar Change-Id: I3c4c0497d5850d1a702489dff35a7cc38b82c083 (cherry picked from commit 66a5c34eb82ede1192d71ba556cbfd121c27d2f3) Merged-In:I3c4c0497d5850d1a702489dff35a7cc38b82c083 --- .../systemui/plugins/DarkIconDispatcher.java | 31 ++++++++--------- .../com/android/systemui/DarkReceiverImpl.kt | 6 ++-- .../systemui/battery/BatteryMeterView.java | 7 ++-- .../statusbar/HeadsUpStatusBarView.java | 6 ++-- .../systemui/statusbar/StatusBarIconView.java | 5 ++- .../statusbar/StatusBarMobileView.java | 10 +++--- .../systemui/statusbar/StatusBarWifiView.java | 7 ++-- .../phone/DarkIconDispatcherImpl.java | 31 +++++++++-------- .../statusbar/phone/DemoStatusIcons.java | 8 ++--- .../phone/HeadsUpAppearanceController.java | 5 ++- .../phone/KeyguardStatusBarView.java | 11 +++---- .../statusbar/phone/LightBarController.java | 21 +++++++----- .../phone/NotificationIconAreaController.java | 17 ++++++---- .../systemui/statusbar/policy/Clock.java | 5 ++- .../phone/LightBarControllerTest.java | 33 ++----------------- 15 files changed, 83 insertions(+), 120 deletions(-) diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java index 757ed76eff369..c7bc858c82661 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/DarkIconDispatcher.java @@ -25,8 +25,6 @@ import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.plugins.annotations.DependsOn; import com.android.systemui.plugins.annotations.ProvidesInterface; -import java.util.ArrayList; - /** * Dispatches events to {@link DarkReceiver}s about changes in darkness, tint area and dark * intensity. Accessible through {@link PluginDependency} @@ -34,15 +32,15 @@ import java.util.ArrayList; @ProvidesInterface(version = DarkIconDispatcher.VERSION) @DependsOn(target = DarkReceiver.class) public interface DarkIconDispatcher { - int VERSION = 2; + int VERSION = 1; /** * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. * - * @param r the areas in which icons should change its tint, in logical screen + * @param r the area in which icons should change its tint, in logical screen * coordinates */ - void setIconsDarkArea(ArrayList r); + void setIconsDarkArea(Rect r); /** * Adds a receiver to receive callbacks onDarkChanged @@ -78,8 +76,8 @@ public interface DarkIconDispatcher { * @return the tint to apply to view depending on the desired tint color and * the screen tintArea in which to apply that tint */ - static int getTint(ArrayList tintAreas, View view, int color) { - if (isInAreas(tintAreas, view)) { + static int getTint(Rect tintArea, View view, int color) { + if (isInArea(tintArea, view)) { return color; } else { return DEFAULT_ICON_TINT; @@ -87,16 +85,15 @@ public interface DarkIconDispatcher { } /** - * @return true if more than half of the view area are in any of the given - * areas, false otherwise + * @return the dark intensity to apply to view depending on the desired dark + * intensity and the screen tintArea in which to apply that intensity */ - static boolean isInAreas(ArrayList areas, View view) { - for (Rect area : areas) { - if (isInArea(area, view)) { - return true; - } + static float getDarkIntensity(Rect tintArea, View view, float intensity) { + if (isInArea(tintArea, view)) { + return intensity; + } else { + return 0f; } - return false; } /** @@ -125,7 +122,7 @@ public interface DarkIconDispatcher { */ @ProvidesInterface(version = DarkReceiver.VERSION) interface DarkReceiver { - int VERSION = 2; - void onDarkChanged(ArrayList areas, float darkIntensity, int tint); + int VERSION = 1; + void onDarkChanged(Rect area, float darkIntensity, int tint); } } diff --git a/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt b/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt index 13d96e44be9e6..42d38cb3463c5 100644 --- a/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt +++ b/packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt @@ -32,11 +32,11 @@ class DarkReceiverImpl @JvmOverloads constructor( private val dualToneHandler = DualToneHandler(context) init { - onDarkChanged(ArrayList(), 1f, DarkIconDispatcher.DEFAULT_ICON_TINT) + onDarkChanged(Rect(), 1f, DarkIconDispatcher.DEFAULT_ICON_TINT) } - override fun onDarkChanged(areas: ArrayList?, darkIntensity: Float, tint: Int) { - val intensity = if (DarkIconDispatcher.isInAreas(areas, this)) darkIntensity else 0f + override fun onDarkChanged(area: Rect?, darkIntensity: Float, tint: Int) { + val intensity = if (DarkIconDispatcher.isInArea(area, this)) darkIntensity else 0f setBackgroundColor(dualToneHandler.getSingleColor(intensity)) } } \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java index 2b0c083e2f31b..f8e7697f58313 100644 --- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java +++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java @@ -56,7 +56,6 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.text.NumberFormat; -import java.util.ArrayList; public class BatteryMeterView extends LinearLayout implements DarkReceiver { @@ -126,7 +125,7 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver { updateShowPercent(); mDualToneHandler = new DualToneHandler(context); // Init to not dark at all. - onDarkChanged(new ArrayList(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT); + onDarkChanged(new Rect(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT); setClipChildren(false); setClipToPadding(false); @@ -354,8 +353,8 @@ public class BatteryMeterView extends LinearLayout implements DarkReceiver { } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - float intensity = DarkIconDispatcher.isInAreas(areas, this) ? darkIntensity : 0; + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + float intensity = DarkIconDispatcher.isInArea(area, this) ? darkIntensity : 0; mNonAdaptedSingleToneColor = mDualToneHandler.getSingleColor(intensity); mNonAdaptedForegroundColor = mDualToneHandler.getFillColor(intensity); mNonAdaptedBackgroundColor = mDualToneHandler.getBackgroundColor(intensity); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java index 4d933d9ad21ee..8e6cf36f8e74a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java @@ -31,8 +31,6 @@ import com.android.systemui.plugins.DarkIconDispatcher; import com.android.systemui.statusbar.notification.collection.NotificationEntry; import com.android.systemui.statusbar.notification.collection.NotificationEntry.OnSensitivityChangedListener; -import java.util.ArrayList; - /** * The view in the statusBar that contains part of the heads-up information @@ -163,8 +161,8 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout { return mIconDrawingRect; } - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - mTextView.setTextColor(DarkIconDispatcher.getTint(areas, this, tint)); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + mTextView.setTextColor(DarkIconDispatcher.getTint(area, this, tint)); } public void setOnDrawingRectChangedListener(Runnable onDrawingRectChangedListener) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java index 72c4ce8afe9b5..e9387499cf4a0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java @@ -61,7 +61,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils; import com.android.systemui.util.drawable.DrawableSize; import java.text.NumberFormat; -import java.util.ArrayList; import java.util.Arrays; public class StatusBarIconView extends AnimatedImageView implements StatusIconDisplayable { @@ -966,8 +965,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - int areaTint = getTint(areas, this, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + int areaTint = getTint(area, this, tint); ColorStateList color = ColorStateList.valueOf(areaTint); setImageTintList(color); setDecorColor(areaTint); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java index 465ab93132f94..68dcdd9ff49fa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarMobileView.java @@ -17,7 +17,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.plugins.DarkIconDispatcher.getTint; -import static com.android.systemui.plugins.DarkIconDispatcher.isInAreas; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; @@ -40,8 +40,6 @@ import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.MobileIconState; -import java.util.ArrayList; - public class StatusBarMobileView extends FrameLayout implements DarkReceiver, StatusIconDisplayable { private static final String TAG = "StatusBarMobileView"; @@ -224,11 +222,11 @@ public class StatusBarMobileView extends FrameLayout implements DarkReceiver, } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - float intensity = isInAreas(areas, this) ? darkIntensity : 0; + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + float intensity = isInArea(area, this) ? darkIntensity : 0; mMobileDrawable.setTintList( ColorStateList.valueOf(mDualToneHandler.getSingleColor(intensity))); - ColorStateList color = ColorStateList.valueOf(getTint(areas, this, tint)); + ColorStateList color = ColorStateList.valueOf(getTint(area, this, tint)); mIn.setImageTintList(color); mOut.setImageTintList(color); mMobileType.setImageTintList(color); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java index a6986d7978336..6dbcc44e385b7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarWifiView.java @@ -17,6 +17,7 @@ package com.android.systemui.statusbar; import static com.android.systemui.plugins.DarkIconDispatcher.getTint; +import static com.android.systemui.plugins.DarkIconDispatcher.isInArea; import static com.android.systemui.statusbar.StatusBarIconView.STATE_DOT; import static com.android.systemui.statusbar.StatusBarIconView.STATE_HIDDEN; import static com.android.systemui.statusbar.StatusBarIconView.STATE_ICON; @@ -36,8 +37,6 @@ import com.android.systemui.R; import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.WifiIconState; -import java.util.ArrayList; - /** * Start small: StatusBarWifiView will be able to layout from a WifiIconState */ @@ -236,8 +235,8 @@ public class StatusBarWifiView extends FrameLayout implements DarkReceiver, } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - int areaTint = getTint(areas, this, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + int areaTint = getTint(area, this, tint); ColorStateList color = ColorStateList.valueOf(areaTint); mWifiIcon.setImageTintList(color); mIn.setImageTintList(color); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java index 150da1687b393..d06de75056d2a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DarkIconDispatcherImpl.java @@ -30,7 +30,6 @@ import com.android.systemui.statusbar.CommandQueue; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import javax.inject.Inject; @@ -41,7 +40,7 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, LightBarTransitionsController.DarkIntensityApplier { private final LightBarTransitionsController mTransitionsController; - private final ArrayList mTintAreas = new ArrayList<>(); + private final Rect mTintArea = new Rect(); private final ArrayMap mReceivers = new ArrayMap<>(); private int mIconTint = DEFAULT_ICON_TINT; @@ -70,14 +69,14 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, public void addDarkReceiver(DarkReceiver receiver) { mReceivers.put(receiver, receiver); - receiver.onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } public void addDarkReceiver(ImageView imageView) { DarkReceiver receiver = (area, darkIntensity, tint) -> imageView.setImageTintList( - ColorStateList.valueOf(getTint(mTintAreas, imageView, mIconTint))); + ColorStateList.valueOf(getTint(mTintArea, imageView, mIconTint))); mReceivers.put(imageView, receiver); - receiver.onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + receiver.onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } public void removeDarkReceiver(DarkReceiver object) { @@ -89,23 +88,23 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, } public void applyDark(DarkReceiver object) { - mReceivers.get(object).onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + mReceivers.get(object).onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } /** * Sets the dark area so {@link #applyDark} only affects the icons in the specified area. * - * @param darkAreas the areas in which icons should change it's tint, in logical screen - * coordinates + * @param darkArea the area in which icons should change it's tint, in logical screen + * coordinates */ - public void setIconsDarkArea(ArrayList darkAreas) { - if (darkAreas == null && mTintAreas.isEmpty()) { + public void setIconsDarkArea(Rect darkArea) { + if (darkArea == null && mTintArea.isEmpty()) { return; } - - mTintAreas.clear(); - if (darkAreas != null) { - mTintAreas.addAll(darkAreas); + if (darkArea == null) { + mTintArea.setEmpty(); + } else { + mTintArea.set(darkArea); } applyIconTint(); } @@ -125,7 +124,7 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, private void applyIconTint() { for (int i = 0; i < mReceivers.size(); i++) { - mReceivers.valueAt(i).onDarkChanged(mTintAreas, mDarkIntensity, mIconTint); + mReceivers.valueAt(i).onDarkChanged(mTintArea, mDarkIntensity, mIconTint); } } @@ -134,6 +133,6 @@ public class DarkIconDispatcherImpl implements SysuiDarkIconDispatcher, pw.println("DarkIconDispatcher: "); pw.println(" mIconTint: 0x" + Integer.toHexString(mIconTint)); pw.println(" mDarkIntensity: " + mDarkIntensity + "f"); - pw.println(" mTintAreas: " + mTintAreas); + pw.println(" mTintArea: " + mTintArea); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java index 6dbbf0d532465..ee51efb090ddc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java @@ -315,14 +315,14 @@ public class DemoStatusIcons extends StatusIconContainer implements DemoMode, Da } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - setColor(DarkIconDispatcher.getTint(areas, mStatusIcons, tint)); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + setColor(DarkIconDispatcher.getTint(area, mStatusIcons, tint)); if (mWifiView != null) { - mWifiView.onDarkChanged(areas, darkIntensity, tint); + mWifiView.onDarkChanged(area, darkIntensity, tint); } for (StatusBarMobileView view : mMobileViews) { - view.onDarkChanged(areas, darkIntensity, tint); + view.onDarkChanged(area, darkIntensity, tint); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java index 9863a0ed1ce0c..866f0d3243911 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java @@ -41,7 +41,6 @@ import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener; import com.android.systemui.util.ViewController; import java.util.Optional; -import java.util.ArrayList; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -370,8 +369,8 @@ public class HeadsUpAppearanceController extends ViewController areas, float darkIntensity, int tint) { - mView.onDarkChanged(areas, darkIntensity, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + mView.onDarkChanged(area, darkIntensity, tint); } public void onStateChanged() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java index 65173a230871b..b8e9875be7e22 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java @@ -50,7 +50,6 @@ import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; /** * The header group on Keyguard. @@ -61,7 +60,7 @@ public class KeyguardStatusBarView extends RelativeLayout { private static final int LAYOUT_CUTOUT = 1; private static final int LAYOUT_NO_CUTOUT = 2; - private final ArrayList mEmptyTintRect = new ArrayList<>(); + private final Rect mEmptyRect = new Rect(0, 0, 0, 0); private boolean mShowPercentAvailable; private boolean mBatteryCharging; @@ -477,14 +476,14 @@ public class KeyguardStatusBarView extends RelativeLayout { iconManager.setTint(iconColor); } - applyDarkness(R.id.battery, mEmptyTintRect, intensity, iconColor); - applyDarkness(R.id.clock, mEmptyTintRect, intensity, iconColor); + applyDarkness(R.id.battery, mEmptyRect, intensity, iconColor); + applyDarkness(R.id.clock, mEmptyRect, intensity, iconColor); } - private void applyDarkness(int id, ArrayList tintAreas, float intensity, int color) { + private void applyDarkness(int id, Rect tintArea, float intensity, int color) { View v = findViewById(id); if (v instanceof DarkReceiver) { - ((DarkReceiver) v).onDarkChanged(tintAreas, intensity, color); + ((DarkReceiver) v).onDarkChanged(tintArea, intensity, color); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java index 4082db7b6bef3..88ae0db5bad0d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarController.java @@ -25,7 +25,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE import android.content.Context; import android.graphics.Color; -import android.graphics.Rect; import android.view.InsetsFlags; import android.view.ViewDebug; import android.view.WindowInsetsController.Appearance; @@ -42,7 +41,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import javax.inject.Inject; @@ -216,23 +214,27 @@ public class LightBarController implements BatteryController.BatteryStateChangeC private void updateStatus() { final int numStacks = mAppearanceRegions.length; - final ArrayList lightBarBounds = new ArrayList<>(); + int numLightStacks = 0; + + // We can only have maximum one light stack. + int indexLightStack = -1; for (int i = 0; i < numStacks; i++) { - final AppearanceRegion ar = mAppearanceRegions[i]; - if (isLight(ar.getAppearance(), mStatusBarMode, APPEARANCE_LIGHT_STATUS_BARS)) { - lightBarBounds.add(ar.getBounds()); + if (isLight(mAppearanceRegions[i].getAppearance(), mStatusBarMode, + APPEARANCE_LIGHT_STATUS_BARS)) { + numLightStacks++; + indexLightStack = i; } } // If no one is light, all icons become white. - if (lightBarBounds.isEmpty()) { + if (numLightStacks == 0) { mStatusBarIconController.getTransitionsController().setIconsDark( false, animateChange()); } // If all stacks are light, all icons get dark. - else if (lightBarBounds.size() == numStacks) { + else if (numLightStacks == numStacks) { mStatusBarIconController.setIconsDarkArea(null); mStatusBarIconController.getTransitionsController().setIconsDark(true, animateChange()); @@ -240,7 +242,8 @@ public class LightBarController implements BatteryController.BatteryStateChangeC // Not the same for every stack, magic! else { - mStatusBarIconController.setIconsDarkArea(lightBarBounds); + mStatusBarIconController.setIconsDarkArea( + mAppearanceRegions[indexLightStack].getBounds()); mStatusBarIconController.getTransitionsController().setIconsDark(true, animateChange()); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java index e70c81de81afb..c36130073765f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java @@ -83,7 +83,7 @@ public class NotificationIconAreaController implements private NotificationIconContainer mNotificationIcons; private NotificationIconContainer mShelfIcons; private NotificationIconContainer mAodIcons; - private final ArrayList mTintAreas = new ArrayList<>(); + private final Rect mTintArea = new Rect(); private Context mContext; private final DemoModeController mDemoModeController; @@ -240,14 +240,17 @@ public class NotificationIconAreaController implements * See {@link com.android.systemui.statusbar.policy.DarkIconDispatcher#setIconsDarkArea}. * Sets the color that should be used to tint any icons in the notification area. * - * @param tintAreas the areas in which to tint the icons, specified in screen coordinates + * @param tintArea the area in which to tint the icons, specified in screen coordinates * @param darkIntensity */ - public void onDarkChanged(ArrayList tintAreas, float darkIntensity, int iconTint) { - mTintAreas.clear(); - mTintAreas.addAll(tintAreas); + public void onDarkChanged(Rect tintArea, float darkIntensity, int iconTint) { + if (tintArea == null) { + mTintArea.setEmpty(); + } else { + mTintArea.set(tintArea); + } - if (DarkIconDispatcher.isInAreas(tintAreas, mNotificationIconArea)) { + if (DarkIconDispatcher.isInArea(tintArea, mNotificationIconArea)) { mIconTint = iconTint; } @@ -486,7 +489,7 @@ public class NotificationIconAreaController implements int color = StatusBarIconView.NO_COLOR; boolean colorize = !isPreL || NotificationUtils.isGrayscale(v, mContrastColorUtil); if (colorize) { - color = DarkIconDispatcher.getTint(mTintAreas, v, tint); + color = DarkIconDispatcher.getTint(mTintArea, v, tint); } v.setStaticDrawableColor(color); v.setDecorColor(tint); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java index 562816fbe21fc..97d344ad6b63e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java @@ -56,7 +56,6 @@ import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import java.text.SimpleDateFormat; -import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; import java.util.TimeZone; @@ -315,8 +314,8 @@ public class Clock extends TextView implements } @Override - public void onDarkChanged(ArrayList areas, float darkIntensity, int tint) { - mNonAdaptedColor = DarkIconDispatcher.getTint(areas, this, tint); + public void onDarkChanged(Rect area, float darkIntensity, int tint) { + mNonAdaptedColor = DarkIconDispatcher.getTint(area, this, tint); setTextColor(mNonAdaptedColor); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java index cc4abfcaa42f5..7e33c01572e1a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LightBarControllerTest.java @@ -20,8 +20,6 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT; -import static junit.framework.Assert.assertTrue; - import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; @@ -43,9 +41,6 @@ import com.android.systemui.statusbar.policy.BatteryController; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; - -import java.util.ArrayList; @SmallTest @RunWith(AndroidTestingRunner.class) @@ -96,9 +91,7 @@ public class LightBarControllerTest extends SysuiTestCase { mLightBarController.onStatusBarAppearanceChanged( appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT, false /* navbarColorManagedByIme */); - ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - verify(mStatusBarIconController).setIconsDarkArea(captor.capture()); - assertTrue(captor.getValue().contains(firstBounds)); + verify(mStatusBarIconController).setIconsDarkArea(eq(firstBounds)); verify(mLightBarTransitionsController).setIconsDark(eq(true), anyBoolean()); } @@ -113,29 +106,7 @@ public class LightBarControllerTest extends SysuiTestCase { mLightBarController.onStatusBarAppearanceChanged( appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT, false /* navbarColorManagedByIme */); - ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - verify(mStatusBarIconController).setIconsDarkArea(captor.capture()); - assertTrue(captor.getValue().contains(secondBounds)); - verify(mLightBarTransitionsController).setIconsDark(eq(true), anyBoolean()); - } - - @Test - public void testOnStatusBarAppearanceChanged_multipleStacks_oneStackLightMultipleStackDark() { - final Rect firstBounds = new Rect(0, 0, 1, 1); - final Rect secondBounds = new Rect(1, 0, 2, 1); - final Rect thirdBounds = new Rect(2, 0, 3, 1); - final AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{ - new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, firstBounds), - new AppearanceRegion(0 /* appearance */, secondBounds), - new AppearanceRegion(APPEARANCE_LIGHT_STATUS_BARS, thirdBounds) - }; - mLightBarController.onStatusBarAppearanceChanged( - appearanceRegions, true /* sbModeChanged */, MODE_TRANSPARENT, - false /* navbarColorManagedByIme */); - ArgumentCaptor> captor = ArgumentCaptor.forClass(ArrayList.class); - verify(mStatusBarIconController).setIconsDarkArea(captor.capture()); - assertTrue(captor.getValue().contains(firstBounds)); - assertTrue(captor.getValue().contains(thirdBounds)); + verify(mStatusBarIconController).setIconsDarkArea(eq(secondBounds)); verify(mLightBarTransitionsController).setIconsDark(eq(true), anyBoolean()); } From 47e64970dae682ca922c5aedcaf0f1c031c8f5ac Mon Sep 17 00:00:00 2001 From: Evan Chen Date: Tue, 15 Feb 2022 23:38:39 +0000 Subject: [PATCH 122/176] Fix ble stop scan crash when BT is not turned on Need to check if BT is one before stop ble scan Test: atest CtsCompanionDeviceManagerCoreTestCases atest CtsCompanionDeviceManagerUiAutomationTestCases atest CtsOsTestCases:CompanionDeviceManagerTest Bug: 219684162 Change-Id: Ib257923e7c63e2fcd76ef9791adc77d70fee5de9 (cherry picked from commit 465f4c8b4bb4c554eb1fb5304966216ec123eafb) Merged-In:Ib257923e7c63e2fcd76ef9791adc77d70fee5de9 --- .../companion/presence/BleCompanionDeviceScanner.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java index a771e7b1aa4a9..b026990280a73 100644 --- a/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java +++ b/services/companion/java/com/android/server/companion/presence/BleCompanionDeviceScanner.java @@ -21,6 +21,8 @@ import static android.bluetooth.BluetoothAdapter.ACTION_BLE_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.ACTION_STATE_CHANGED; import static android.bluetooth.BluetoothAdapter.EXTRA_PREVIOUS_STATE; import static android.bluetooth.BluetoothAdapter.EXTRA_STATE; +import static android.bluetooth.BluetoothAdapter.STATE_BLE_ON; +import static android.bluetooth.BluetoothAdapter.STATE_ON; import static android.bluetooth.BluetoothAdapter.nameForState; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_ALREADY_STARTED; import static android.bluetooth.le.ScanCallback.SCAN_FAILED_APPLICATION_REGISTRATION_FAILED; @@ -232,8 +234,14 @@ class BleCompanionDeviceScanner implements AssociationStore.OnChangeListener { return; } - mBleScanner.stopScan(mScanCallback); mScanning = false; + + if (mBtAdapter.getState() != STATE_ON && mBtAdapter.getState() != STATE_BLE_ON) { + Log.d(TAG, "BT Adapter is not turned ON"); + return; + } + + mBleScanner.stopScan(mScanCallback); } @MainThread From a7c0b4b95638780a68fb58ee1047842dad07d3e5 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Wed, 26 Jan 2022 19:01:08 +0000 Subject: [PATCH 123/176] [Ongoing Call] Catch a security exception instead of crashing SysUI. This will mean that the ongoing call chip will stay visible even when the user is in the calling process. However, this is much better than crashing SysUI. Fixes: 216693695 Bug: 216489355 Bug: 216248574 Test: verified starting a call won't crash SysUI even with ag/16659008 in the build. Test: new unit test Change-Id: I1108fc6fe01f284364331dd9de57ebe9390d4d78 Merged-In: I1108fc6fe01f284364331dd9de57ebe9390d4d78 (cherry picked from commit 706633bcf8b4ff03b6ff58066bbbe9e2ff7b9820) Merged-In:I1108fc6fe01f284364331dd9de57ebe9390d4d78 --- .../ongoingcall/OngoingCallController.kt | 19 +++++++++++++---- .../ongoingcall/OngoingCallControllerTest.kt | 21 +++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt index c7f7258513d02..6e7231ef5ca38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt @@ -242,8 +242,14 @@ class OngoingCallController @Inject constructor( * Sets up an [IUidObserver] to monitor the status of the application managing the ongoing call. */ private fun setUpUidObserver(currentCallNotificationInfo: CallNotificationInfo) { - isCallAppVisible = isProcessVisibleToUser( - iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null)) + try { + isCallAppVisible = isProcessVisibleToUser( + iActivityManager.getUidProcessState(currentCallNotificationInfo.uid, null) + ) + } catch (se: SecurityException) { + Log.e(TAG, "Security exception when trying to get process state: $se") + return + } if (uidObserver != null) { iActivityManager.unregisterUidObserver(uidObserver) @@ -275,12 +281,17 @@ class OngoingCallController @Inject constructor( override fun onUidCachedChanged(uid: Int, cached: Boolean) {} } - iActivityManager.registerUidObserver( + try { + iActivityManager.registerUidObserver( uidObserver, ActivityManager.UID_OBSERVER_PROCSTATE, ActivityManager.PROCESS_STATE_UNKNOWN, null - ) + ) + } catch (se: SecurityException) { + Log.e(TAG, "Security exception when trying to register uid observer: $se") + return + } } /** Returns true if the given [procState] represents a process that's visible to the user. */ diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt index 0920cac9c0944..807664d093dab 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt @@ -217,6 +217,27 @@ class OngoingCallControllerTest : SysuiTestCase() { verify(mockIActivityManager, times(numCalls - 1)).unregisterUidObserver(any()) } + /** Regression test for b/216248574. */ + @Test + fun entryUpdated_getUidProcessStateThrowsException_noCrash() { + `when`(mockIActivityManager.getUidProcessState(eq(CALL_UID), nullable(String::class.java))) + .thenThrow(SecurityException()) + + // No assert required, just check no crash + notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + } + + /** Regression test for b/216248574. */ + @Test + fun entryUpdated_registerUidObserverThrowsException_noCrash() { + `when`(mockIActivityManager.registerUidObserver( + any(), any(), any(), nullable(String::class.java) + )).thenThrow(SecurityException()) + + // No assert required, just check no crash + notifCollectionListener.onEntryUpdated(createOngoingCallNotifEntry()) + } + /** * If a call notification is never added before #onEntryRemoved is called, then the listener * should never be notified. From 02254cca9c69d774dad44b74952cb641a6331b91 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Thu, 24 Feb 2022 20:13:04 +0000 Subject: [PATCH 124/176] Revert "Always parse sharedUserId and sharedUserLabel" Revert "Update all manifest to use sharedUserMaxSdkVersion" Revert submission 16942428-cherrypick-always_parse_shared_uid-s48c52h8kp Reason for revert: Bug: 221088088 Reverted Changes: Ia355f3343:Always parse sharedUserId and sharedUserLabel I19727d1cc:Update all manifest to use sharedUserMaxSdkVersion... Change-Id: Ia4c26e1d0b43d5c7c08b9ababc8eb95639f0ce04 (cherry picked from commit 65082c53c628cb671fc15d9983d5d7447ed6466f) Merged-In:Ia4c26e1d0b43d5c7c08b9ababc8eb95639f0ce04 --- .../server/pm/InstallPackageHelper.java | 29 ++++++++++--------- .../server/pm/pkg/parsing/ParsingPackage.java | 3 -- .../pm/pkg/parsing/ParsingPackageImpl.java | 11 ------- .../pm/pkg/parsing/ParsingPackageRead.java | 7 ----- .../pm/pkg/parsing/ParsingPackageUtils.java | 9 +++--- .../parsing/parcelling/AndroidPackageTest.kt | 1 - 6 files changed, 20 insertions(+), 40 deletions(-) diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index db0b0c58b046a..365cecc8fd243 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -36,6 +36,7 @@ import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE; import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; +import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD; import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4; import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile; import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED; @@ -183,6 +184,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -1595,16 +1597,18 @@ final class InstallPackageHelper { parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash()); } - // APK should not change its sharedUserId declarations - final var oldSharedUid = oldPackage.getSharedUserId() != null - ? oldPackage.getSharedUserId() : ""; - final var newSharedUid = parsedPackage.getSharedUserId() != null - ? parsedPackage.getSharedUserId() : ""; - if (!oldSharedUid.equals(newSharedUid)) { + // Check for shared user id changes + if (!Objects.equals(oldPackage.getSharedUserId(), + parsedPackage.getSharedUserId()) + // Don't mark as invalid if the app is trying to + // leave a sharedUserId + && parsedPackage.getSharedUserId() != null) { throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, "Package " + parsedPackage.getPackageName() + " shared user changed from " - + oldSharedUid + " to " + newSharedUid); + + (oldPackage.getSharedUserId() != null + ? oldPackage.getSharedUserId() : "") + + " to " + parsedPackage.getSharedUserId()); } // In case of rollback, remember per-user/profile install state @@ -3693,13 +3697,10 @@ final class InstallPackageHelper { } disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr( parsedPackage.getPackageName()); - if (parsedPackage.getSharedUserId() != null && !parsedPackage.isLeavingSharedUid()) { - sharedUserSetting = mPm.mSettings.getSharedUserLPw( - parsedPackage.getSharedUserId(), - 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); - } else { - sharedUserSetting = null; - } + sharedUserSetting = (parsedPackage.getSharedUserId() != null) + ? mPm.mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(), + 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true) + : null; if (DEBUG_PACKAGE_SCANNING && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 && sharedUserSetting != null) { diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java index f6f9faf98c40a..cdc2b1245b1ee 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java @@ -290,9 +290,6 @@ public interface ParsingPackage extends ParsingPackageRead { /** @see R#styleable.AndroidManifest_inheritKeyStoreKeys */ ParsingPackage setInheritKeyStoreKeys(boolean inheritKeyStoreKeys); - /** @see R#styleable.AndroidManifest_sharedUserMaxSdkVersion */ - ParsingPackage setLeavingSharedUid(boolean leavingSharedUid); - ParsingPackage setLabelRes(int labelRes); ParsingPackage setLargestWidthLimitDp(int largestWidthLimitDp); diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java index 67670272ef8b0..177eaca8e06f5 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java @@ -549,7 +549,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private static final long SDK_LIBRARY = 1L << 49; private static final long INHERIT_KEYSTORE_KEYS = 1L << 50; private static final long ENABLE_ON_BACK_INVOKED_CALLBACK = 1L << 51; - private static final long LEAVING_SHARED_UID = 1L << 52; } private ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) { @@ -2403,11 +2402,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return getBoolean(Booleans.ENABLE_ON_BACK_INVOKED_CALLBACK); } - @Override - public boolean isLeavingSharedUid() { - return getBoolean(Booleans.LEAVING_SHARED_UID); - } - @Override public ParsingPackageImpl setBaseRevisionCode(int value) { baseRevisionCode = value; @@ -2556,11 +2550,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return setBoolean(Booleans.INHERIT_KEYSTORE_KEYS, value); } - @Override - public ParsingPackageImpl setLeavingSharedUid(boolean value) { - return setBoolean(Booleans.LEAVING_SHARED_UID, value); - } - @Override public ParsingPackageImpl setLabelRes(int value) { labelRes = value; diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java index 50033f652bfd1..428374fa21a89 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java @@ -360,11 +360,4 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt * @see R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback */ boolean isOnBackInvokedCallbackEnabled(); - - /** - * Returns true if R.styleable#AndroidManifest_sharedUserMaxSdkVersion is set to a value - * smaller than the current SDK version. - * @see R.styleable#AndroidManifest_sharedUserMaxSdkVersion - */ - boolean isLeavingSharedUid(); } diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index ed1ab01e1d122..f30daa930e6c5 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -1032,6 +1032,11 @@ public class ParsingPackageUtils { private static ParseResult parseSharedUser(ParseInput input, ParsingPackage pkg, TypedArray sa) { + int maxSdkVersion = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa); + if ((maxSdkVersion != 0) && maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT) { + return input.success(pkg); + } + String str = nonConfigString(0, R.styleable.AndroidManifest_sharedUserId, sa); if (TextUtils.isEmpty(str)) { return input.success(pkg); @@ -1047,11 +1052,7 @@ public class ParsingPackageUtils { } } - int maxSdkVersion = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa); - boolean leaving = (maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT); - return input.success(pkg - .setLeavingSharedUid(leaving) .setSharedUserId(str.intern()) .setSharedUserLabel(resId(R.styleable.AndroidManifest_sharedUserLabel, sa))); } diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt index 83ccabf039359..cd2d0fce66917 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt @@ -238,7 +238,6 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::isVendor, AndroidPackage::isVisibleToInstantApps, AndroidPackage::isVmSafeMode, - AndroidPackage::isLeavingSharedUid, AndroidPackage::isResetEnabledSettingsOnAppDataCleared, AndroidPackage::getMaxAspectRatio, AndroidPackage::getMinAspectRatio, From 6ffab5c9d47a63a54142fadf9afe3e6c3b468a07 Mon Sep 17 00:00:00 2001 From: Daniel Chapin Date: Thu, 24 Feb 2022 20:13:04 +0000 Subject: [PATCH 125/176] Revert "Always parse sharedUserId and sharedUserLabel" Revert "Update all manifest to use sharedUserMaxSdkVersion" Revert submission 16942428-cherrypick-always_parse_shared_uid-s48c52h8kp Reason for revert: Bug: 221088088 Reverted Changes: Ia355f3343:Always parse sharedUserId and sharedUserLabel I19727d1cc:Update all manifest to use sharedUserMaxSdkVersion... Change-Id: Ia4c26e1d0b43d5c7c08b9ababc8eb95639f0ce04 (cherry picked from commit 65082c53c628cb671fc15d9983d5d7447ed6466f) Merged-In:Ia4c26e1d0b43d5c7c08b9ababc8eb95639f0ce04 --- .../server/pm/InstallPackageHelper.java | 29 ++++++++++--------- .../server/pm/pkg/parsing/ParsingPackage.java | 3 -- .../pm/pkg/parsing/ParsingPackageImpl.java | 11 ------- .../pm/pkg/parsing/ParsingPackageRead.java | 7 ----- .../pm/pkg/parsing/ParsingPackageUtils.java | 9 +++--- .../parsing/parcelling/AndroidPackageTest.kt | 1 - 6 files changed, 20 insertions(+), 40 deletions(-) diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java index db0b0c58b046a..365cecc8fd243 100644 --- a/services/core/java/com/android/server/pm/InstallPackageHelper.java +++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java @@ -36,6 +36,7 @@ import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE; import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP; import static android.content.pm.PackageManager.INSTALL_SUCCEEDED; import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN; +import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD; import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4; import static android.content.pm.parsing.ApkLiteParseUtils.isApkFile; import static android.os.PowerExemptionManager.REASON_PACKAGE_REPLACED; @@ -183,6 +184,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -1595,16 +1597,18 @@ final class InstallPackageHelper { parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash()); } - // APK should not change its sharedUserId declarations - final var oldSharedUid = oldPackage.getSharedUserId() != null - ? oldPackage.getSharedUserId() : ""; - final var newSharedUid = parsedPackage.getSharedUserId() != null - ? parsedPackage.getSharedUserId() : ""; - if (!oldSharedUid.equals(newSharedUid)) { + // Check for shared user id changes + if (!Objects.equals(oldPackage.getSharedUserId(), + parsedPackage.getSharedUserId()) + // Don't mark as invalid if the app is trying to + // leave a sharedUserId + && parsedPackage.getSharedUserId() != null) { throw new PrepareFailure(INSTALL_FAILED_UID_CHANGED, "Package " + parsedPackage.getPackageName() + " shared user changed from " - + oldSharedUid + " to " + newSharedUid); + + (oldPackage.getSharedUserId() != null + ? oldPackage.getSharedUserId() : "") + + " to " + parsedPackage.getSharedUserId()); } // In case of rollback, remember per-user/profile install state @@ -3693,13 +3697,10 @@ final class InstallPackageHelper { } disabledPkgSetting = mPm.mSettings.getDisabledSystemPkgLPr( parsedPackage.getPackageName()); - if (parsedPackage.getSharedUserId() != null && !parsedPackage.isLeavingSharedUid()) { - sharedUserSetting = mPm.mSettings.getSharedUserLPw( - parsedPackage.getSharedUserId(), - 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/); - } else { - sharedUserSetting = null; - } + sharedUserSetting = (parsedPackage.getSharedUserId() != null) + ? mPm.mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(), + 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true) + : null; if (DEBUG_PACKAGE_SCANNING && (parseFlags & ParsingPackageUtils.PARSE_CHATTY) != 0 && sharedUserSetting != null) { diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java index f6f9faf98c40a..cdc2b1245b1ee 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackage.java @@ -290,9 +290,6 @@ public interface ParsingPackage extends ParsingPackageRead { /** @see R#styleable.AndroidManifest_inheritKeyStoreKeys */ ParsingPackage setInheritKeyStoreKeys(boolean inheritKeyStoreKeys); - /** @see R#styleable.AndroidManifest_sharedUserMaxSdkVersion */ - ParsingPackage setLeavingSharedUid(boolean leavingSharedUid); - ParsingPackage setLabelRes(int labelRes); ParsingPackage setLargestWidthLimitDp(int largestWidthLimitDp); diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java index 67670272ef8b0..177eaca8e06f5 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageImpl.java @@ -549,7 +549,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, private static final long SDK_LIBRARY = 1L << 49; private static final long INHERIT_KEYSTORE_KEYS = 1L << 50; private static final long ENABLE_ON_BACK_INVOKED_CALLBACK = 1L << 51; - private static final long LEAVING_SHARED_UID = 1L << 52; } private ParsingPackageImpl setBoolean(@Booleans.Values long flag, boolean value) { @@ -2403,11 +2402,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return getBoolean(Booleans.ENABLE_ON_BACK_INVOKED_CALLBACK); } - @Override - public boolean isLeavingSharedUid() { - return getBoolean(Booleans.LEAVING_SHARED_UID); - } - @Override public ParsingPackageImpl setBaseRevisionCode(int value) { baseRevisionCode = value; @@ -2556,11 +2550,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return setBoolean(Booleans.INHERIT_KEYSTORE_KEYS, value); } - @Override - public ParsingPackageImpl setLeavingSharedUid(boolean value) { - return setBoolean(Booleans.LEAVING_SHARED_UID, value); - } - @Override public ParsingPackageImpl setLabelRes(int value) { labelRes = value; diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java index 50033f652bfd1..428374fa21a89 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageRead.java @@ -360,11 +360,4 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt * @see R.styleable.AndroidManifestApplication_enableOnBackInvokedCallback */ boolean isOnBackInvokedCallbackEnabled(); - - /** - * Returns true if R.styleable#AndroidManifest_sharedUserMaxSdkVersion is set to a value - * smaller than the current SDK version. - * @see R.styleable#AndroidManifest_sharedUserMaxSdkVersion - */ - boolean isLeavingSharedUid(); } diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index ed1ab01e1d122..f30daa930e6c5 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -1032,6 +1032,11 @@ public class ParsingPackageUtils { private static ParseResult parseSharedUser(ParseInput input, ParsingPackage pkg, TypedArray sa) { + int maxSdkVersion = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa); + if ((maxSdkVersion != 0) && maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT) { + return input.success(pkg); + } + String str = nonConfigString(0, R.styleable.AndroidManifest_sharedUserId, sa); if (TextUtils.isEmpty(str)) { return input.success(pkg); @@ -1047,11 +1052,7 @@ public class ParsingPackageUtils { } } - int maxSdkVersion = anInteger(0, R.styleable.AndroidManifest_sharedUserMaxSdkVersion, sa); - boolean leaving = (maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT); - return input.success(pkg - .setLeavingSharedUid(leaving) .setSharedUserId(str.intern()) .setSharedUserLabel(resId(R.styleable.AndroidManifest_sharedUserLabel, sa))); } diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt index 83ccabf039359..cd2d0fce66917 100644 --- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt +++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt @@ -238,7 +238,6 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag AndroidPackage::isVendor, AndroidPackage::isVisibleToInstantApps, AndroidPackage::isVmSafeMode, - AndroidPackage::isLeavingSharedUid, AndroidPackage::isResetEnabledSettingsOnAppDataCleared, AndroidPackage::getMaxAspectRatio, AndroidPackage::getMinAspectRatio, From 710ad12e8143cde2a27add221f43860248eb68f7 Mon Sep 17 00:00:00 2001 From: Shashwat Razdan Date: Thu, 3 Mar 2022 00:34:33 +0000 Subject: [PATCH 126/176] Revert "Adding multiple provider support in AbstractMasterSystem..." Revert "Adding tests for multiple provider support in AbstractMa..." Revert submission 17008428-cherrypick-multi-provider-cloudsearch-2yrjp5zxz1 Reason for revert: Broke TextToSpeech service Reverted Changes: If1d0ac733:Adding tests for multiple provider support in Abst... I1da7f54bc:Adding multiple provider support in AbstractMaster... Change-Id: Ic57ef1339b4b06b4b22981090a651eb4c570ca69 Bug: 222221754 (cherry picked from commit 05a066042b383894ca3ce37af52b2ee9a794038b) Merged-In: Ic57ef1339b4b06b4b22981090a651eb4c570ca69 --- core/res/res/values/config.xml | 4 +- core/res/res/values/symbols.xml | 2 +- .../CloudSearchManagerService.java | 57 +--- ...CloudSearchManagerServiceShellCommand.java | 7 +- .../CloudSearchPerUserService.java | 24 +- .../infra/AbstractMasterSystemService.java | 306 ++++-------------- .../infra/AbstractPerUserSystemService.java | 122 ++----- ...FrameworkResourcesServiceNameResolver.java | 139 +++----- .../server/infra/ServiceNameResolver.java | 71 +--- 9 files changed, 164 insertions(+), 568 deletions(-) diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 4648f8a546861..c2cb57d84b34d 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -4130,9 +4130,9 @@ This service must be trusted, as it can be activated without explicit consent of the user. If no service with the specified name exists on the device, cloudsearch will be disabled. Example: "com.android.intelligence/.CloudSearchService" - config_defaultCloudSearchServices is for the multiple provider case. + config_defaultCloudSearchService is for the single provider case. --> - + - + - + - - 26dp - 200dp From 8c64340c063e8b677ff051ccbd72f909e1958983 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Fri, 24 Jun 2022 02:12:53 +0100 Subject: [PATCH 161/176] Release outstanding suspend blockers when shutting down DPC Right now DPC removes all messages but doesn't actually clean up all of the outstanding state that's in flight. In general, this isn't that harmful for most things as the display is going away at this point, but if any suspend blockers are being held pending this work then we end up in a state where the device can never suspend. This causes severe battery drain that can only be fixed by a reboot. Test: manual Fixes: 213407479 Change-Id: I5b61f5bd498f09026d5b398bb3a8ccdaa91601fe (cherry picked from commit 5747d1a5511b76a91ea98947c356d15c09cc30ba) Merged-In: I5b61f5bd498f09026d5b398bb3a8ccdaa91601fe --- .../display/DisplayPowerController.java | 41 ++++++++++++++++++- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index d05a902c65932..6a57e4070f657 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -461,6 +461,18 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private boolean mIsRbcActive; + // Whether there's a callback to tell listeners the display has changed scheduled to run. When + // true it implies a wakelock is being held to guarantee the update happens before we collapse + // into suspend and so needs to be cleaned up if the thread is exiting. + // Should only be accessed on the Handler thread. + private boolean mOnStateChangedPending; + + // Count of proximity messages currently on this DPC's Handler. Used to keep track of how many + // suspend blocker acquisitions are pending when shutting down this DPC. + // Should only be accessed on the Handler thread. + private int mOnProximityPositiveMessages; + private int mOnProximityNegativeMessages; + // Animators. private ObjectAnimator mColorFadeOnAnimator; private ObjectAnimator mColorFadeOffAnimator; @@ -1091,10 +1103,24 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mHbmController.stop(); mBrightnessThrottler.stop(); mHandler.removeCallbacksAndMessages(null); + + // Release any outstanding wakelocks we're still holding because of pending messages. if (mUnfinishedBusiness) { mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdUnfinishedBusiness); mUnfinishedBusiness = false; } + if (mOnStateChangedPending) { + mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged); + mOnStateChangedPending = false; + } + for (int i = 0; i < mOnProximityPositiveMessages; i++) { + mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive); + } + mOnProximityPositiveMessages = 0; + for (int i = 0; i < mOnProximityNegativeMessages; i++) { + mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative); + } + mOnProximityNegativeMessages = 0; final float brightness = mPowerState != null ? mPowerState.getScreenBrightness() @@ -2248,8 +2274,11 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call } private void sendOnStateChangedWithWakelock() { - mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdOnStateChanged); - mHandler.post(mOnStateChangedRunnable); + if (!mOnStateChangedPending) { + mOnStateChangedPending = true; + mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdOnStateChanged); + mHandler.post(mOnStateChangedRunnable); + } } private void logDisplayPolicyChanged(int newPolicy) { @@ -2408,6 +2437,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private final Runnable mOnStateChangedRunnable = new Runnable() { @Override public void run() { + mOnStateChangedPending = false; mCallbacks.onStateChanged(); mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdOnStateChanged); } @@ -2416,17 +2446,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private void sendOnProximityPositiveWithWakelock() { mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxPositive); mHandler.post(mOnProximityPositiveRunnable); + mOnProximityPositiveMessages++; } private final Runnable mOnProximityPositiveRunnable = new Runnable() { @Override public void run() { + mOnProximityPositiveMessages--; mCallbacks.onProximityPositive(); mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxPositive); } }; private void sendOnProximityNegativeWithWakelock() { + mOnProximityNegativeMessages++; mCallbacks.acquireSuspendBlocker(mSuspendBlockerIdProxNegative); mHandler.post(mOnProximityNegativeRunnable); } @@ -2434,6 +2467,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call private final Runnable mOnProximityNegativeRunnable = new Runnable() { @Override public void run() { + mOnProximityNegativeMessages--; mCallbacks.onProximityNegative(); mCallbacks.releaseSuspendBlocker(mSuspendBlockerIdProxNegative); } @@ -2533,6 +2567,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call pw.println(" mReportedToPolicy=" + reportedToPolicyToString(mReportedScreenStateToPolicy)); pw.println(" mIsRbcActive=" + mIsRbcActive); + pw.println(" mOnStateChangePending=" + mOnStateChangedPending); + pw.println(" mOnProximityPositiveMessages=" + mOnProximityPositiveMessages); + pw.println(" mOnProximityNegativeMessages=" + mOnProximityNegativeMessages); if (mScreenBrightnessRampAnimator != null) { pw.println(" mScreenBrightnessRampAnimator.isAnimating()=" From ee84425d7d58099d4022b52726c74deff9719031 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Thu, 23 Jun 2022 11:22:54 -0400 Subject: [PATCH 162/176] Move bottom padding from ScrollView to child That way, the content will scroll up when obscured by the footer, as it contains extra blank space for this. Fixes: 232032549 Test: manual in multiple configurations and devices Test: atest SystemUITests Change-Id: I69433e8d84f5a63266e99b0ae0b387355c55e592 (cherry picked from commit b7ac6e7f5e22bac543e8c4dcde64544bc84def5a) Merged-In: I69433e8d84f5a63266e99b0ae0b387355c55e592 --- .../src/com/android/systemui/qs/QSContainerImpl.java | 3 +-- .../SystemUI/src/com/android/systemui/qs/QSPanel.java | 4 ++-- .../src/com/android/systemui/qs/QSContainerImplTest.kt | 3 ++- .../tests/src/com/android/systemui/qs/QSPanelTest.kt | 8 ++++++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java index 5d2060d8043e0..7b1ddd62ec6e9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java @@ -139,12 +139,11 @@ public class QSContainerImpl extends FrameLayout implements Dumpable { void updateResources(QSPanelController qsPanelController, QuickStatusBarHeaderController quickStatusBarHeaderController) { - int bottomPadding = getResources().getDimensionPixelSize(R.dimen.qs_panel_padding_bottom); mQSPanelContainer.setPaddingRelative( mQSPanelContainer.getPaddingStart(), QSUtils.getQsHeaderSystemIconsAreaHeight(mContext), mQSPanelContainer.getPaddingEnd(), - bottomPadding); + mQSPanelContainer.getPaddingBottom()); int horizontalMargins = getResources().getDimensionPixelSize(R.dimen.qs_horizontal_margin); int horizontalPadding = getResources().getDimensionPixelSize( diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 41724ef62683c..324c019590844 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -362,11 +362,11 @@ public class QSPanel extends LinearLayout implements Tunable { protected void updatePadding() { final Resources res = mContext.getResources(); int paddingTop = res.getDimensionPixelSize(R.dimen.qs_panel_padding_top); - // Bottom padding only when there's a new footer with its height. + int paddingBottom = res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom); setPaddingRelative(getPaddingStart(), paddingTop, getPaddingEnd(), - getPaddingBottom()); + paddingBottom); } void addOnConfigurationChangedListener(OnConfigurationChangedListener listener) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt index 489c8c86028e4..bf237abba8fae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt @@ -57,6 +57,7 @@ class QSContainerImplTest : SysuiTestCase() { @Test fun testContainerBottomPadding() { + val originalPadding = qsPanelContainer.paddingBottom qsContainer.updateResources( qsPanelController, quickStatusBarHeaderController @@ -66,7 +67,7 @@ class QSContainerImplTest : SysuiTestCase() { anyInt(), anyInt(), anyInt(), - eq(mContext.resources.getDimensionPixelSize(R.dimen.footer_actions_height)) + eq(originalPadding) ) } } \ No newline at end of file diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt index 60cfd7249919e..b98be75a51c79 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt @@ -150,6 +150,14 @@ class QSPanelTest : SysuiTestCase() { assertThat(footer.isVisibleToUser).isTrue() } + @Test + fun testBottomPadding() { + val padding = 10 + context.orCreateTestableResources.addOverride(R.dimen.qs_panel_padding_bottom, padding) + qsPanel.updatePadding() + assertThat(qsPanel.paddingBottom).isEqualTo(padding) + } + private infix fun View.isLeftOf(other: View): Boolean { val rect = Rect() getBoundsOnScreen(rect) From c113a129072f3c73c8b56fcd35ee117ede11abe9 Mon Sep 17 00:00:00 2001 From: William Hester Date: Wed, 15 Jun 2022 17:24:50 -0700 Subject: [PATCH 163/176] Fix ADB key file reading The "adb_temp_keys.xml" file is used to keep track of each ADB key and when it was previously connected. It also keeps track of authorized WiFi networks. It is written correctly, however, the parser currently is unable to read the file that it wrote, meaning that: 1. ADB keys never properly expire 2. WiFi APs are never properly restored Furthermore, because of complex interactions with restoring the adb_keys file in Test Harness Mode, duplicate keys get appended repteatedly to the adb_keys file if they're not in the key map. This cleans up the file, making it more testable, adds tests for the previously broken functionality, and just performs some simple restructuring of bits of the code that were error-prone. Now, the adb_keys file is nothing but a view of the temp keys file. When keys are added to the temp keys file, we completely rewrite the adb_keys file with the set of keys present in the temp keys file, meaning that duplicates cannot be added. This also introduces a method for other system services (primarily for TestHarnessModeService) to notify the AdbDebuggingManager that the key files were modified, and it should reload the state. Bug: 236299256 Test: atest AdbDebuggingManagerTest Change-Id: Iae955aca17e873288d58b16f184bd4d325d50d86 (cherry picked from commit efb8194ec4f4c60817999aa190c931a41f2196c7) Merged-In: Iae955aca17e873288d58b16f184bd4d325d50d86 --- .../android/debug/AdbManagerInternal.java | 6 + .../server/adb/AdbDebuggingManager.java | 543 ++++++++---------- .../com/android/server/adb/AdbService.java | 8 + .../testharness/TestHarnessModeService.java | 1 + .../server/adb/AdbDebuggingManagerTest.java | 205 +++++-- 5 files changed, 405 insertions(+), 358 deletions(-) diff --git a/core/java/android/debug/AdbManagerInternal.java b/core/java/android/debug/AdbManagerInternal.java index d730129507d7f..e448706fabfea 100644 --- a/core/java/android/debug/AdbManagerInternal.java +++ b/core/java/android/debug/AdbManagerInternal.java @@ -54,6 +54,12 @@ public abstract class AdbManagerInternal { */ public abstract File getAdbTempKeysFile(); + /** + * Notify the AdbManager that the key files have changed and any in-memory state should be + * reloaded. + */ + public abstract void notifyKeyFilesUpdated(); + /** * Starts adbd for a transport. */ diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 297d28dadde3c..56990eda3e780 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -19,7 +19,7 @@ package com.android.server.adb; import static com.android.internal.util.dump.DumpUtils.writeStringIfNotNull; import android.annotation.NonNull; -import android.annotation.TestApi; +import android.annotation.Nullable; import android.app.ActivityManager; import android.app.Notification; import android.app.NotificationChannel; @@ -102,11 +102,26 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; /** - * Provides communication to the Android Debug Bridge daemon to allow, deny, or clear public keysi + * Provides communication to the Android Debug Bridge daemon to allow, deny, or clear public keys * that are authorized to connect to the ADB service itself. + * + *

    The AdbDebuggingManager controls two files: + *

      + *
    1. adb_keys + *
    2. adb_temp_keys.xml + *
    + * + *

    The ADB Daemon (adbd) reads only the adb_keys file for authorization. Public keys + * from registered hosts are stored in adb_keys, one entry per line. + * + *

    AdbDebuggingManager also keeps adb_temp_keys.xml, which is used for two things + *

      + *
    1. Removing unused keys from the adb_keys file + *
    2. Managing authorized WiFi access points for ADB over WiFi + *
    */ public class AdbDebuggingManager { - private static final String TAG = "AdbDebuggingManager"; + private static final String TAG = AdbDebuggingManager.class.getSimpleName(); private static final boolean DEBUG = false; private static final boolean MDNS_DEBUG = false; @@ -118,18 +133,20 @@ public class AdbDebuggingManager { // as a subsequent connection occurs within the allowed duration. private static final String ADB_TEMP_KEYS_FILE = "adb_temp_keys.xml"; private static final int BUFFER_SIZE = 65536; + private static final Ticker SYSTEM_TICKER = () -> System.currentTimeMillis(); private final Context mContext; private final ContentResolver mContentResolver; - private final Handler mHandler; - private AdbDebuggingThread mThread; + @VisibleForTesting final AdbDebuggingHandler mHandler; + @Nullable private AdbDebuggingThread mThread; private boolean mAdbUsbEnabled = false; private boolean mAdbWifiEnabled = false; private String mFingerprints; // A key can be used more than once (e.g. USB, wifi), so need to keep a refcount - private final Map mConnectedKeys; - private String mConfirmComponent; - private final File mTestUserKeyFile; + private final Map mConnectedKeys = new HashMap<>(); + private final String mConfirmComponent; + @Nullable private final File mUserKeyFile; + @Nullable private final File mTempKeysFile; private static final String WIFI_PERSISTENT_CONFIG_PROPERTY = "persist.adb.tls_server.enable"; @@ -138,37 +155,44 @@ public class AdbDebuggingManager { private static final int PAIRING_CODE_LENGTH = 6; private PairingThread mPairingThread = null; // A list of keys connected via wifi - private final Set mWifiConnectedKeys; + private final Set mWifiConnectedKeys = new HashSet<>(); // The current info of the adbwifi connection. - private AdbConnectionInfo mAdbConnectionInfo; + private AdbConnectionInfo mAdbConnectionInfo = new AdbConnectionInfo(); // Polls for a tls port property when adb wifi is enabled private AdbConnectionPortPoller mConnectionPortPoller; private final PortListenerImpl mPortListener = new PortListenerImpl(); + private final Ticker mTicker; public AdbDebuggingManager(Context context) { - mHandler = new AdbDebuggingHandler(FgThread.get().getLooper()); - mContext = context; - mContentResolver = mContext.getContentResolver(); - mTestUserKeyFile = null; - mConnectedKeys = new HashMap(); - mWifiConnectedKeys = new HashSet(); - mAdbConnectionInfo = new AdbConnectionInfo(); + this( + context, + /* confirmComponent= */ null, + getAdbFile(ADB_KEYS_FILE), + getAdbFile(ADB_TEMP_KEYS_FILE), + /* adbDebuggingThread= */ null, + SYSTEM_TICKER); } /** * Constructor that accepts the component to be invoked to confirm if the user wants to allow * an adb connection from the key. */ - @TestApi - protected AdbDebuggingManager(Context context, String confirmComponent, File testUserKeyFile) { - mHandler = new AdbDebuggingHandler(FgThread.get().getLooper()); + @VisibleForTesting + AdbDebuggingManager( + Context context, + String confirmComponent, + File testUserKeyFile, + File tempKeysFile, + AdbDebuggingThread adbDebuggingThread, + Ticker ticker) { mContext = context; mContentResolver = mContext.getContentResolver(); mConfirmComponent = confirmComponent; - mTestUserKeyFile = testUserKeyFile; - mConnectedKeys = new HashMap(); - mWifiConnectedKeys = new HashSet(); - mAdbConnectionInfo = new AdbConnectionInfo(); + mUserKeyFile = testUserKeyFile; + mTempKeysFile = tempKeysFile; + mThread = adbDebuggingThread; + mTicker = ticker; + mHandler = new AdbDebuggingHandler(FgThread.get().getLooper(), mThread); } static void sendBroadcastWithDebugPermission(@NonNull Context context, @NonNull Intent intent, @@ -189,8 +213,7 @@ public class AdbDebuggingManager { // consisting of only letters, digits, and hyphens, must begin and end // with a letter or digit, must not contain consecutive hyphens, and // must contain at least one letter. - @VisibleForTesting - static final String SERVICE_PROTOCOL = "adb-tls-pairing"; + @VisibleForTesting static final String SERVICE_PROTOCOL = "adb-tls-pairing"; private final String mServiceType = String.format("_%s._tcp.", SERVICE_PROTOCOL); private int mPort; @@ -352,16 +375,24 @@ public class AdbDebuggingManager { } } - class AdbDebuggingThread extends Thread { + @VisibleForTesting + static class AdbDebuggingThread extends Thread { private boolean mStopped; private LocalSocket mSocket; private OutputStream mOutputStream; private InputStream mInputStream; + private Handler mHandler; + @VisibleForTesting AdbDebuggingThread() { super(TAG); } + @VisibleForTesting + void setHandler(Handler handler) { + mHandler = handler; + } + @Override public void run() { if (DEBUG) Slog.d(TAG, "Entering thread"); @@ -536,7 +567,7 @@ public class AdbDebuggingManager { } } - class AdbConnectionInfo { + private static class AdbConnectionInfo { private String mBssid; private String mSsid; private int mPort; @@ -743,11 +774,14 @@ public class AdbDebuggingManager { // Notification when adbd socket is disconnected. static final int MSG_ADBD_SOCKET_DISCONNECTED = 27; + // === Messages from other parts of the system + private static final int MESSAGE_KEY_FILES_UPDATED = 28; + // === Messages we can send to adbd =========== static final String MSG_DISCONNECT_DEVICE = "DD"; static final String MSG_DISABLE_ADBDWIFI = "DA"; - private AdbKeyStore mAdbKeyStore; + @Nullable @VisibleForTesting AdbKeyStore mAdbKeyStore; // Usb, Wi-Fi transports can be enabled together or separately, so don't break the framework // connection unless all transport types are disconnected. @@ -762,19 +796,19 @@ public class AdbDebuggingManager { } }; - AdbDebuggingHandler(Looper looper) { - super(looper); - } - - /** - * Constructor that accepts the AdbDebuggingThread to which responses should be sent - * and the AdbKeyStore to be used to store the temporary grants. - */ - @TestApi - AdbDebuggingHandler(Looper looper, AdbDebuggingThread thread, AdbKeyStore adbKeyStore) { + /** Constructor that accepts the AdbDebuggingThread to which responses should be sent. */ + @VisibleForTesting + AdbDebuggingHandler(Looper looper, AdbDebuggingThread thread) { super(looper); mThread = thread; - mAdbKeyStore = adbKeyStore; + } + + /** Initialize the AdbKeyStore so tests can grab mAdbKeyStore immediately. */ + @VisibleForTesting + void initKeyStore() { + if (mAdbKeyStore == null) { + mAdbKeyStore = new AdbKeyStore(); + } } // Show when at least one device is connected. @@ -805,6 +839,7 @@ public class AdbDebuggingManager { registerForAuthTimeChanges(); mThread = new AdbDebuggingThread(); + mThread.setHandler(mHandler); mThread.start(); mAdbKeyStore.updateKeyStore(); @@ -825,8 +860,7 @@ public class AdbDebuggingManager { if (!mConnectedKeys.isEmpty()) { for (Map.Entry entry : mConnectedKeys.entrySet()) { - mAdbKeyStore.setLastConnectionTime(entry.getKey(), - System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(entry.getKey(), mTicker.currentTimeMillis()); } sendPersistKeyStoreMessage(); mConnectedKeys.clear(); @@ -836,9 +870,7 @@ public class AdbDebuggingManager { } public void handleMessage(Message msg) { - if (mAdbKeyStore == null) { - mAdbKeyStore = new AdbKeyStore(); - } + initKeyStore(); switch (msg.what) { case MESSAGE_ADB_ENABLED: @@ -873,7 +905,7 @@ public class AdbDebuggingManager { if (!mConnectedKeys.containsKey(key)) { mConnectedKeys.put(key, 1); } - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(key, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); } @@ -920,9 +952,7 @@ public class AdbDebuggingManager { mConnectedKeys.clear(); // If the key store has not yet been instantiated then do so now; this avoids // the unnecessary creation of the key store when adb is not enabled. - if (mAdbKeyStore == null) { - mAdbKeyStore = new AdbKeyStore(); - } + initKeyStore(); mWifiConnectedKeys.clear(); mAdbKeyStore.deleteKeyStore(); cancelJobToUpdateAdbKeyStore(); @@ -937,7 +967,8 @@ public class AdbDebuggingManager { alwaysAllow = true; int refcount = mConnectedKeys.get(key) - 1; if (refcount == 0) { - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime( + key, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); mConnectedKeys.remove(key); @@ -963,7 +994,7 @@ public class AdbDebuggingManager { if (!mConnectedKeys.isEmpty()) { for (Map.Entry entry : mConnectedKeys.entrySet()) { mAdbKeyStore.setLastConnectionTime(entry.getKey(), - System.currentTimeMillis()); + mTicker.currentTimeMillis()); } sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); @@ -984,7 +1015,7 @@ public class AdbDebuggingManager { } else { mConnectedKeys.put(key, mConnectedKeys.get(key) + 1); } - mAdbKeyStore.setLastConnectionTime(key, System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(key, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); logAdbConnectionChanged(key, AdbProtoEnums.AUTOMATICALLY_ALLOWED, true); @@ -1206,6 +1237,10 @@ public class AdbDebuggingManager { } break; } + case MESSAGE_KEY_FILES_UPDATED: { + mAdbKeyStore.reloadKeyMap(); + break; + } } } @@ -1377,8 +1412,7 @@ public class AdbDebuggingManager { AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL); // Add the key into the keystore - mAdbKeyStore.setLastConnectionTime(publicKey, - System.currentTimeMillis()); + mAdbKeyStore.setLastConnectionTime(publicKey, mTicker.currentTimeMillis()); sendPersistKeyStoreMessage(); scheduleJobToUpdateAdbKeyStore(); } @@ -1449,19 +1483,13 @@ public class AdbDebuggingManager { extras.add(new AbstractMap.SimpleEntry("ssid", ssid)); extras.add(new AbstractMap.SimpleEntry("bssid", bssid)); int currentUserId = ActivityManager.getCurrentUser(); - UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); - String componentString; - if (userInfo.isAdmin()) { - componentString = Resources.getSystem().getString( - com.android.internal.R.string.config_customAdbWifiNetworkConfirmationComponent); - } else { - componentString = Resources.getSystem().getString( - com.android.internal.R.string.config_customAdbWifiNetworkConfirmationComponent); - } + String componentString = + Resources.getSystem().getString( + R.string.config_customAdbWifiNetworkConfirmationComponent); ComponentName componentName = ComponentName.unflattenFromString(componentString); + UserInfo userInfo = UserManager.get(mContext).getUserInfo(currentUserId); if (startConfirmationActivity(componentName, userInfo.getUserHandle(), extras) - || startConfirmationService(componentName, userInfo.getUserHandle(), - extras)) { + || startConfirmationService(componentName, userInfo.getUserHandle(), extras)) { return; } Slog.e(TAG, "Unable to start customAdbWifiNetworkConfirmation[SecondaryUser]Component " @@ -1543,7 +1571,7 @@ public class AdbDebuggingManager { /** * Returns a new File with the specified name in the adb directory. */ - private File getAdbFile(String fileName) { + private static File getAdbFile(String fileName) { File dataDir = Environment.getDataDirectory(); File adbDir = new File(dataDir, ADB_DIRECTORY); @@ -1556,66 +1584,38 @@ public class AdbDebuggingManager { } File getAdbTempKeysFile() { - return getAdbFile(ADB_TEMP_KEYS_FILE); + return mTempKeysFile; } File getUserKeyFile() { - return mTestUserKeyFile == null ? getAdbFile(ADB_KEYS_FILE) : mTestUserKeyFile; - } - - private void writeKey(String key) { - try { - File keyFile = getUserKeyFile(); - - if (keyFile == null) { - return; - } - - FileOutputStream fo = new FileOutputStream(keyFile, true); - fo.write(key.getBytes()); - fo.write('\n'); - fo.close(); - - FileUtils.setPermissions(keyFile.toString(), - FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1); - } catch (IOException ex) { - Slog.e(TAG, "Error writing key:" + ex); - } + return mUserKeyFile; } private void writeKeys(Iterable keys) { - AtomicFile atomicKeyFile = null; + if (mUserKeyFile == null) { + return; + } + + AtomicFile atomicKeyFile = new AtomicFile(mUserKeyFile); + // Note: Do not use a try-with-resources with the FileOutputStream, because AtomicFile + // requires that it's cleaned up with AtomicFile.failWrite(); FileOutputStream fo = null; try { - File keyFile = getUserKeyFile(); - - if (keyFile == null) { - return; - } - - atomicKeyFile = new AtomicFile(keyFile); fo = atomicKeyFile.startWrite(); for (String key : keys) { fo.write(key.getBytes()); fo.write('\n'); } atomicKeyFile.finishWrite(fo); - - FileUtils.setPermissions(keyFile.toString(), - FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1); } catch (IOException ex) { Slog.e(TAG, "Error writing keys: " + ex); - if (atomicKeyFile != null) { - atomicKeyFile.failWrite(fo); - } + atomicKeyFile.failWrite(fo); + return; } - } - private void deleteKeyFile() { - File keyFile = getUserKeyFile(); - if (keyFile != null) { - keyFile.delete(); - } + FileUtils.setPermissions( + mUserKeyFile.toString(), + FileUtils.S_IRUSR | FileUtils.S_IWUSR | FileUtils.S_IRGRP, -1, -1); } /** @@ -1744,6 +1744,13 @@ public class AdbDebuggingManager { return mAdbWifiEnabled; } + /** + * Notify that they key files were updated so the AdbKeyManager reloads the keys. + */ + public void notifyKeyFilesUpdated() { + mHandler.sendEmptyMessage(AdbDebuggingHandler.MESSAGE_KEY_FILES_UPDATED); + } + /** * Sends a message to the handler to persist the keystore. */ @@ -1778,7 +1785,7 @@ public class AdbDebuggingManager { try { dump.write("keystore", AdbDebuggingManagerProto.KEYSTORE, - FileUtils.readTextFile(getAdbTempKeysFile(), 0, null)); + FileUtils.readTextFile(mTempKeysFile, 0, null)); } catch (IOException e) { Slog.i(TAG, "Cannot read keystore: ", e); } @@ -1792,12 +1799,12 @@ public class AdbDebuggingManager { * ADB_ALLOWED_CONNECTION_TIME setting. */ class AdbKeyStore { - private Map mKeyMap; - private Set mSystemKeys; - private File mKeyFile; private AtomicFile mAtomicKeyFile; - private List mTrustedNetworks; + private final Set mSystemKeys; + private final Map mKeyMap = new HashMap<>(); + private final List mTrustedNetworks = new ArrayList<>(); + private static final int KEYSTORE_VERSION = 1; private static final int MAX_SUPPORTED_KEYSTORE_VERSION = 1; private static final String XML_KEYSTORE_START_TAG = "keyStore"; @@ -1819,26 +1826,22 @@ public class AdbDebuggingManager { public static final long NO_PREVIOUS_CONNECTION = 0; /** - * Constructor that uses the default location for the persistent adb keystore. + * Create an AdbKeyStore instance. + * + *

    Upon creation, we parse {@link #mTempKeysFile} to determine authorized WiFi APs and + * retrieve the map of stored ADB keys and their last connected times. After that, we read + * the {@link #mUserKeyFile}, and any keys that exist in that file that do not exist in the + * map are added to the map (for backwards compatibility). */ AdbKeyStore() { - init(); - } - - /** - * Constructor that uses the specified file as the location for the persistent adb keystore. - */ - AdbKeyStore(File keyFile) { - mKeyFile = keyFile; - init(); - } - - private void init() { initKeyFile(); - mKeyMap = getKeyMap(); - mTrustedNetworks = getTrustedNetworks(); + readTempKeysFile(); mSystemKeys = getSystemKeysFromFile(SYSTEM_KEY_FILE); - addUserKeysToKeyStore(); + addExistingUserKeysToKeyStore(); + } + + public void reloadKeyMap() { + readTempKeysFile(); } public void addTrustedNetwork(String bssid) { @@ -1877,7 +1880,6 @@ public class AdbDebuggingManager { public void removeKey(String key) { if (mKeyMap.containsKey(key)) { mKeyMap.remove(key); - writeKeys(mKeyMap.keySet()); sendPersistKeyStoreMessage(); } } @@ -1886,12 +1888,9 @@ public class AdbDebuggingManager { * Initializes the key file that will be used to persist the adb grants. */ private void initKeyFile() { - if (mKeyFile == null) { - mKeyFile = getAdbTempKeysFile(); - } - // getAdbTempKeysFile can return null if the adb file cannot be obtained - if (mKeyFile != null) { - mAtomicKeyFile = new AtomicFile(mKeyFile); + // mTempKeysFile can be null if the adb file cannot be obtained + if (mTempKeysFile != null) { + mAtomicKeyFile = new AtomicFile(mTempKeysFile); } } @@ -1932,201 +1931,108 @@ public class AdbDebuggingManager { } /** - * Returns the key map with the keys and last connection times from the key file. + * Update the key map and the trusted networks list with values parsed from the temp keys + * file. */ - private Map getKeyMap() { - Map keyMap = new HashMap(); - // if the AtomicFile could not be instantiated before attempt again; if it still fails - // return an empty key map. + private void readTempKeysFile() { + mKeyMap.clear(); + mTrustedNetworks.clear(); if (mAtomicKeyFile == null) { initKeyFile(); if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); - return keyMap; + Slog.e( + TAG, + "Unable to obtain the key file, " + mTempKeysFile + ", for reading"); + return; } } if (!mAtomicKeyFile.exists()) { - return keyMap; + return; } try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { - TypedXmlPullParser parser = Xml.resolvePullParser(keyStream); - // Check for supported keystore version. - XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); - if (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null || !XML_KEYSTORE_START_TAG.equals(tagName)) { - Slog.e(TAG, "Expected " + XML_KEYSTORE_START_TAG + ", but got tag=" - + tagName); - return keyMap; - } + TypedXmlPullParser parser; + try { + parser = Xml.resolvePullParser(keyStream); + XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); + int keystoreVersion = parser.getAttributeInt(null, XML_ATTRIBUTE_VERSION); if (keystoreVersion > MAX_SUPPORTED_KEYSTORE_VERSION) { Slog.e(TAG, "Keystore version=" + keystoreVersion + " not supported (max_supported=" + MAX_SUPPORTED_KEYSTORE_VERSION + ")"); - return keyMap; + return; } + } catch (XmlPullParserException e) { + // This could be because the XML document doesn't start with + // XML_KEYSTORE_START_TAG. Try again, instead just starting the document with + // the adbKey tag (the old format). + parser = Xml.resolvePullParser(keyStream); } - while (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null) { - break; - } else if (!tagName.equals(XML_TAG_ADB_KEY)) { - XmlUtils.skipCurrentTag(parser); - continue; - } - String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); - long connectionTime; - try { - connectionTime = parser.getAttributeLong(null, - XML_ATTRIBUTE_LAST_CONNECTION); - } catch (XmlPullParserException e) { - Slog.e(TAG, - "Caught a NumberFormatException parsing the last connection time: " - + e); - XmlUtils.skipCurrentTag(parser); - continue; - } - keyMap.put(key, connectionTime); - } + readKeyStoreContents(parser); } catch (IOException e) { Slog.e(TAG, "Caught an IOException parsing the XML key file: ", e); } catch (XmlPullParserException e) { - Slog.w(TAG, "Caught XmlPullParserException parsing the XML key file: ", e); - // The file could be written in a format prior to introducing keystore tag. - return getKeyMapBeforeKeystoreVersion(); + Slog.e(TAG, "Caught XmlPullParserException parsing the XML key file: ", e); } - return keyMap; } - - /** - * Returns the key map with the keys and last connection times from the key file. - * This implementation was prior to adding the XML_KEYSTORE_START_TAG. - */ - private Map getKeyMapBeforeKeystoreVersion() { - Map keyMap = new HashMap(); - // if the AtomicFile could not be instantiated before attempt again; if it still fails - // return an empty key map. - if (mAtomicKeyFile == null) { - initKeyFile(); - if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); - return keyMap; + private void readKeyStoreContents(TypedXmlPullParser parser) + throws XmlPullParserException, IOException { + // This parser is very forgiving. For backwards-compatibility, we simply iterate through + // all the tags in the file, skipping over anything that's not an tag or a + // tag. Invalid tags (such as ones that don't have a valid "lastConnection" + // attribute) are simply ignored. + while ((parser.next()) != XmlPullParser.END_DOCUMENT) { + String tagName = parser.getName(); + if (XML_TAG_ADB_KEY.equals(tagName)) { + addAdbKeyToKeyMap(parser); + } else if (XML_TAG_WIFI_ACCESS_POINT.equals(tagName)) { + addTrustedNetworkToTrustedNetworks(parser); + } else { + Slog.w(TAG, "Ignoring tag '" + tagName + "'. Not recognized."); } + XmlUtils.skipCurrentTag(parser); } - if (!mAtomicKeyFile.exists()) { - return keyMap; - } - try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { - TypedXmlPullParser parser = Xml.resolvePullParser(keyStream); - XmlUtils.beginDocument(parser, XML_TAG_ADB_KEY); - while (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null) { - break; - } else if (!tagName.equals(XML_TAG_ADB_KEY)) { - XmlUtils.skipCurrentTag(parser); - continue; - } - String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); - long connectionTime; - try { - connectionTime = parser.getAttributeLong(null, - XML_ATTRIBUTE_LAST_CONNECTION); - } catch (XmlPullParserException e) { - Slog.e(TAG, - "Caught a NumberFormatException parsing the last connection time: " - + e); - XmlUtils.skipCurrentTag(parser); - continue; - } - keyMap.put(key, connectionTime); - } - } catch (IOException | XmlPullParserException e) { - Slog.e(TAG, "Caught an exception parsing the XML key file: ", e); - } - return keyMap; } - /** - * Returns the map of trusted networks from the keystore file. - * - * This was implemented in keystore version 1. - */ - private List getTrustedNetworks() { - List trustedNetworks = new ArrayList(); - // if the AtomicFile could not be instantiated before attempt again; if it still fails - // return an empty key map. - if (mAtomicKeyFile == null) { - initKeyFile(); - if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for reading"); - return trustedNetworks; - } + private void addAdbKeyToKeyMap(TypedXmlPullParser parser) { + String key = parser.getAttributeValue(null, XML_ATTRIBUTE_KEY); + try { + long connectionTime = + parser.getAttributeLong(null, XML_ATTRIBUTE_LAST_CONNECTION); + mKeyMap.put(key, connectionTime); + } catch (XmlPullParserException e) { + Slog.e(TAG, "Error reading adbKey attributes", e); } - if (!mAtomicKeyFile.exists()) { - return trustedNetworks; - } - try (FileInputStream keyStream = mAtomicKeyFile.openRead()) { - TypedXmlPullParser parser = Xml.resolvePullParser(keyStream); - // Check for supported keystore version. - XmlUtils.beginDocument(parser, XML_KEYSTORE_START_TAG); - if (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null || !XML_KEYSTORE_START_TAG.equals(tagName)) { - Slog.e(TAG, "Expected " + XML_KEYSTORE_START_TAG + ", but got tag=" - + tagName); - return trustedNetworks; - } - int keystoreVersion = parser.getAttributeInt(null, XML_ATTRIBUTE_VERSION); - if (keystoreVersion > MAX_SUPPORTED_KEYSTORE_VERSION) { - Slog.e(TAG, "Keystore version=" + keystoreVersion - + " not supported (max_supported=" - + MAX_SUPPORTED_KEYSTORE_VERSION); - return trustedNetworks; - } - } - while (parser.next() != XmlPullParser.END_DOCUMENT) { - String tagName = parser.getName(); - if (tagName == null) { - break; - } else if (!tagName.equals(XML_TAG_WIFI_ACCESS_POINT)) { - XmlUtils.skipCurrentTag(parser); - continue; - } - String bssid = parser.getAttributeValue(null, XML_ATTRIBUTE_WIFI_BSSID); - trustedNetworks.add(bssid); - } - } catch (IOException | XmlPullParserException | NumberFormatException e) { - Slog.e(TAG, "Caught an exception parsing the XML key file: ", e); - } - return trustedNetworks; + } + + private void addTrustedNetworkToTrustedNetworks(TypedXmlPullParser parser) { + String bssid = parser.getAttributeValue(null, XML_ATTRIBUTE_WIFI_BSSID); + mTrustedNetworks.add(bssid); } /** * Updates the keystore with keys that were previously set to be always allowed before the * connection time of keys was tracked. */ - private void addUserKeysToKeyStore() { - File userKeyFile = getUserKeyFile(); + private void addExistingUserKeysToKeyStore() { + if (mUserKeyFile == null || !mUserKeyFile.exists()) { + return; + } boolean mapUpdated = false; - if (userKeyFile != null && userKeyFile.exists()) { - try (BufferedReader in = new BufferedReader(new FileReader(userKeyFile))) { - long time = System.currentTimeMillis(); - String key; - while ((key = in.readLine()) != null) { - // if the keystore does not contain the key from the user key file then add - // it to the Map with the current system time to prevent it from expiring - // immediately if the user is actively using this key. - if (!mKeyMap.containsKey(key)) { - mKeyMap.put(key, time); - mapUpdated = true; - } + try (BufferedReader in = new BufferedReader(new FileReader(mUserKeyFile))) { + String key; + while ((key = in.readLine()) != null) { + // if the keystore does not contain the key from the user key file then add + // it to the Map with the current system time to prevent it from expiring + // immediately if the user is actively using this key. + if (!mKeyMap.containsKey(key)) { + mKeyMap.put(key, mTicker.currentTimeMillis()); + mapUpdated = true; } - } catch (IOException e) { - Slog.e(TAG, "Caught an exception reading " + userKeyFile + ": " + e); } + } catch (IOException e) { + Slog.e(TAG, "Caught an exception reading " + mUserKeyFile + ": " + e); } if (mapUpdated) { sendPersistKeyStoreMessage(); @@ -2147,7 +2053,9 @@ public class AdbDebuggingManager { if (mAtomicKeyFile == null) { initKeyFile(); if (mAtomicKeyFile == null) { - Slog.e(TAG, "Unable to obtain the key file, " + mKeyFile + ", for writing"); + Slog.e( + TAG, + "Unable to obtain the key file, " + mTempKeysFile + ", for writing"); return; } } @@ -2178,17 +2086,21 @@ public class AdbDebuggingManager { Slog.e(TAG, "Caught an exception writing the key map: ", e); mAtomicKeyFile.failWrite(keyStream); } + writeKeys(mKeyMap.keySet()); } private boolean filterOutOldKeys() { - boolean keysDeleted = false; long allowedTime = getAllowedConnectionTime(); - long systemTime = System.currentTimeMillis(); + if (allowedTime == 0) { + return false; + } + boolean keysDeleted = false; + long systemTime = mTicker.currentTimeMillis(); Iterator> keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry keyEntry = keyMapIterator.next(); long connectionTime = keyEntry.getValue(); - if (allowedTime != 0 && systemTime > (connectionTime + allowedTime)) { + if (systemTime > (connectionTime + allowedTime)) { keyMapIterator.remove(); keysDeleted = true; } @@ -2212,7 +2124,7 @@ public class AdbDebuggingManager { if (allowedTime == 0) { return minExpiration; } - long systemTime = System.currentTimeMillis(); + long systemTime = mTicker.currentTimeMillis(); Iterator> keyMapIterator = mKeyMap.entrySet().iterator(); while (keyMapIterator.hasNext()) { Map.Entry keyEntry = keyMapIterator.next(); @@ -2233,7 +2145,9 @@ public class AdbDebuggingManager { public void deleteKeyStore() { mKeyMap.clear(); mTrustedNetworks.clear(); - deleteKeyFile(); + if (mUserKeyFile != null) { + mUserKeyFile.delete(); + } if (mAtomicKeyFile == null) { return; } @@ -2260,7 +2174,8 @@ public class AdbDebuggingManager { * is set to true the time will be set even if it is older than the previously written * connection time. */ - public void setLastConnectionTime(String key, long connectionTime, boolean force) { + @VisibleForTesting + void setLastConnectionTime(String key, long connectionTime, boolean force) { // Do not set the connection time to a value that is earlier than what was previously // stored as the last connection time unless force is set. if (mKeyMap.containsKey(key) && mKeyMap.get(key) >= connectionTime && !force) { @@ -2271,11 +2186,6 @@ public class AdbDebuggingManager { if (mSystemKeys.contains(key)) { return; } - // if this is the first time the key is being added then write it to the key file as - // well. - if (!mKeyMap.containsKey(key)) { - writeKey(key); - } mKeyMap.put(key, connectionTime); } @@ -2307,12 +2217,8 @@ public class AdbDebuggingManager { long allowedConnectionTime = getAllowedConnectionTime(); // if the allowed connection time is 0 then revert to the previous behavior of always // allowing previously granted adb grants. - if (allowedConnectionTime == 0 || (System.currentTimeMillis() < (lastConnectionTime - + allowedConnectionTime))) { - return true; - } else { - return false; - } + return allowedConnectionTime == 0 + || (mTicker.currentTimeMillis() < (lastConnectionTime + allowedConnectionTime)); } /** @@ -2324,4 +2230,15 @@ public class AdbDebuggingManager { return mTrustedNetworks.contains(bssid); } } + + /** + * A Guava-like interface for getting the current system time. + * + * This allows us to swap a fake ticker in for testing to reduce "Thread.sleep()" calls and test + * for exact expected times instead of random ones. + */ + @VisibleForTesting + interface Ticker { + long currentTimeMillis(); + } } diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java index 5d0c732d5f48f..55d8dba69626b 100644 --- a/services/core/java/com/android/server/adb/AdbService.java +++ b/services/core/java/com/android/server/adb/AdbService.java @@ -151,6 +151,14 @@ public class AdbService extends IAdbManager.Stub { return mDebuggingManager == null ? null : mDebuggingManager.getAdbTempKeysFile(); } + @Override + public void notifyKeyFilesUpdated() { + if (mDebuggingManager == null) { + return; + } + mDebuggingManager.notifyKeyFilesUpdated(); + } + @Override public void startAdbdForTransport(byte transportType) { FgThread.getHandler().sendMessage(obtainMessage( diff --git a/services/core/java/com/android/server/testharness/TestHarnessModeService.java b/services/core/java/com/android/server/testharness/TestHarnessModeService.java index b6a413524c5c5..452bdf4098287 100644 --- a/services/core/java/com/android/server/testharness/TestHarnessModeService.java +++ b/services/core/java/com/android/server/testharness/TestHarnessModeService.java @@ -189,6 +189,7 @@ public class TestHarnessModeService extends SystemService { if (adbManager.getAdbTempKeysFile() != null) { writeBytesToFile(persistentData.mAdbTempKeys, adbManager.getAdbTempKeysFile().toPath()); } + adbManager.notifyKeyFilesUpdated(); } private void configureUser() { diff --git a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java index b36aa0617be56..e87dd4b423b26 100644 --- a/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/adb/AdbDebuggingManagerTest.java @@ -36,8 +36,6 @@ import android.util.Log; import androidx.test.InstrumentationRegistry; -import com.android.server.FgThread; - import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -48,6 +46,11 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.FileReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; @@ -88,6 +91,7 @@ public final class AdbDebuggingManagerTest { private long mOriginalAllowedConnectionTime; private File mAdbKeyXmlFile; private File mAdbKeyFile; + private FakeTicker mFakeTicker; @Before public void setUp() throws Exception { @@ -96,14 +100,25 @@ public final class AdbDebuggingManagerTest { if (mAdbKeyFile.exists()) { mAdbKeyFile.delete(); } - mManager = new AdbDebuggingManager(mContext, ADB_CONFIRM_COMPONENT, mAdbKeyFile); mAdbKeyXmlFile = new File(mContext.getFilesDir(), "test_adb_keys.xml"); if (mAdbKeyXmlFile.exists()) { mAdbKeyXmlFile.delete(); } + + mFakeTicker = new FakeTicker(); + // Set the ticker time to October 22, 2008 (the day the T-Mobile G1 was released) + mFakeTicker.advance(1224658800L); + mThread = new AdbDebuggingThreadTest(); - mKeyStore = mManager.new AdbKeyStore(mAdbKeyXmlFile); - mHandler = mManager.new AdbDebuggingHandler(FgThread.get().getLooper(), mThread, mKeyStore); + mManager = new AdbDebuggingManager( + mContext, ADB_CONFIRM_COMPONENT, mAdbKeyFile, mAdbKeyXmlFile, mThread, mFakeTicker); + + mHandler = mManager.mHandler; + mThread.setHandler(mHandler); + + mHandler.initKeyStore(); + mKeyStore = mHandler.mAdbKeyStore; + mOriginalAllowedConnectionTime = mKeyStore.getAllowedConnectionTime(); mBlockingQueue = new ArrayBlockingQueue<>(1); } @@ -122,7 +137,7 @@ public final class AdbDebuggingManagerTest { private void setAllowedConnectionTime(long connectionTime) { Settings.Global.putLong(mContext.getContentResolver(), Settings.Global.ADB_ALLOWED_CONNECTION_TIME, connectionTime); - }; + } @Test public void testAllowNewKeyOnce() throws Exception { @@ -158,20 +173,15 @@ public final class AdbDebuggingManagerTest { // Allow a connection from a new key with the 'Always allow' option selected. runAdbTest(TEST_KEY_1, true, true, false); - // Get the last connection time for the currently connected key to verify that it is updated - // after the disconnect. - long lastConnectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - - // Sleep for a small amount of time to ensure a difference can be observed in the last - // connection time after a disconnect. - Thread.sleep(10); + // Advance the clock by 10ms to ensure there's a difference + mFakeTicker.advance(10 * 1_000_000); // Send the disconnect message for the currently connected key to trigger an update of the // last connection time. disconnectKey(TEST_KEY_1); - assertNotEquals( + assertEquals( "The last connection time was not updated after the disconnect", - lastConnectionTime, + mFakeTicker.currentTimeMillis(), mKeyStore.getLastConnectionTime(TEST_KEY_1)); } @@ -244,8 +254,8 @@ public final class AdbDebuggingManagerTest { // Get the current last connection time for comparison after the scheduled job is run long lastConnectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - // Sleep a small amount of time to ensure that the updated connection time changes - Thread.sleep(10); + // Advance a small amount of time to ensure that the updated connection time changes + mFakeTicker.advance(10); // Send a message to the handler to update the last connection time for the active key updateKeyStore(); @@ -269,13 +279,13 @@ public final class AdbDebuggingManagerTest { persistKeyStore(); assertTrue( "The key with the 'Always allow' option selected was not persisted in the keystore", - mManager.new AdbKeyStore(mAdbKeyXmlFile).isKeyAuthorized(TEST_KEY_1)); + mManager.new AdbKeyStore().isKeyAuthorized(TEST_KEY_1)); // Get the current last connection time to ensure it is updated in the persisted keystore. long lastConnectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - // Sleep a small amount of time to ensure the last connection time is updated. - Thread.sleep(10); + // Advance a small amount of time to ensure the last connection time is updated. + mFakeTicker.advance(10); // Send a message to the handler to update the last connection time for the active key. updateKeyStore(); @@ -286,7 +296,7 @@ public final class AdbDebuggingManagerTest { assertNotEquals( "The last connection time in the key file was not updated after the update " + "connection time message", lastConnectionTime, - mManager.new AdbKeyStore(mAdbKeyXmlFile).getLastConnectionTime(TEST_KEY_1)); + mManager.new AdbKeyStore().getLastConnectionTime(TEST_KEY_1)); // Verify that the key is in the adb_keys file assertTrue("The key was not in the adb_keys file after persisting the keystore", isKeyInFile(TEST_KEY_1, mAdbKeyFile)); @@ -327,8 +337,8 @@ public final class AdbDebuggingManagerTest { // Set the allowed window to a small value to ensure the time is beyond the allowed window. setAllowedConnectionTime(1); - // Sleep for a small amount of time to exceed the allowed window. - Thread.sleep(10); + // Advance a small amount of time to exceed the allowed window. + mFakeTicker.advance(10); // The AdbKeyStore has a method to get the time of the next key expiration to ensure the // scheduled job runs at the time of the next expiration or after 24 hours, whichever occurs @@ -478,9 +488,12 @@ public final class AdbDebuggingManagerTest { // Set the current expiration time to a minute from expiration and verify this new value is // returned. final long newExpirationTime = 60000; - mKeyStore.setLastConnectionTime(TEST_KEY_1, - System.currentTimeMillis() - Settings.Global.DEFAULT_ADB_ALLOWED_CONNECTION_TIME - + newExpirationTime, true); + mKeyStore.setLastConnectionTime( + TEST_KEY_1, + mFakeTicker.currentTimeMillis() + - Settings.Global.DEFAULT_ADB_ALLOWED_CONNECTION_TIME + + newExpirationTime, + true); expirationTime = mKeyStore.getNextExpirationTime(); if (Math.abs(expirationTime - newExpirationTime) > epsilon) { fail("The expiration time for a key about to expire, " + expirationTime @@ -525,7 +538,7 @@ public final class AdbDebuggingManagerTest { // Get the last connection time for the key to verify that it is updated when the connected // key message is sent. long connectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - Thread.sleep(10); + mFakeTicker.advance(10); mHandler.obtainMessage(AdbDebuggingManager.AdbDebuggingHandler.MESSAGE_ADB_CONNECTED_KEY, TEST_KEY_1).sendToTarget(); flushHandlerQueue(); @@ -536,7 +549,7 @@ public final class AdbDebuggingManagerTest { // Verify that the scheduled job updates the connection time of the key. connectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - Thread.sleep(10); + mFakeTicker.advance(10); updateKeyStore(); assertNotEquals( "The connection time for the key must be updated when the update keystore message" @@ -545,7 +558,7 @@ public final class AdbDebuggingManagerTest { // Verify that the connection time is updated when the key is disconnected. connectionTime = mKeyStore.getLastConnectionTime(TEST_KEY_1); - Thread.sleep(10); + mFakeTicker.advance(10); disconnectKey(TEST_KEY_1); assertNotEquals( "The connection time for the key must be updated when the disconnected message is" @@ -628,11 +641,11 @@ public final class AdbDebuggingManagerTest { setAllowedConnectionTime(Settings.Global.DEFAULT_ADB_ALLOWED_CONNECTION_TIME); // The untracked keys should be added to the keystore as part of the constructor. - AdbDebuggingManager.AdbKeyStore adbKeyStore = mManager.new AdbKeyStore(mAdbKeyXmlFile); + AdbDebuggingManager.AdbKeyStore adbKeyStore = mManager.new AdbKeyStore(); // Verify that the connection time for each test key is within a small value of the current // time. - long time = System.currentTimeMillis(); + long time = mFakeTicker.currentTimeMillis(); for (String key : testKeys) { long connectionTime = adbKeyStore.getLastConnectionTime(key); if (Math.abs(time - connectionTime) > epsilon) { @@ -651,11 +664,11 @@ public final class AdbDebuggingManagerTest { runAdbTest(TEST_KEY_1, true, true, false); runAdbTest(TEST_KEY_2, true, true, false); - // Sleep a small amount of time to ensure the connection time is updated by the scheduled + // Advance a small amount of time to ensure the connection time is updated by the scheduled // job. long connectionTime1 = mKeyStore.getLastConnectionTime(TEST_KEY_1); long connectionTime2 = mKeyStore.getLastConnectionTime(TEST_KEY_2); - Thread.sleep(10); + mFakeTicker.advance(10); updateKeyStore(); assertNotEquals( "The connection time for test key 1 must be updated after the scheduled job runs", @@ -669,7 +682,7 @@ public final class AdbDebuggingManagerTest { disconnectKey(TEST_KEY_2); connectionTime1 = mKeyStore.getLastConnectionTime(TEST_KEY_1); connectionTime2 = mKeyStore.getLastConnectionTime(TEST_KEY_2); - Thread.sleep(10); + mFakeTicker.advance(10); updateKeyStore(); assertNotEquals( "The connection time for test key 1 must be updated after another key is " @@ -686,8 +699,6 @@ public final class AdbDebuggingManagerTest { // to clear the adb authorizations when adb is disabled after a boot a NullPointerException // was thrown as deleteKeyStore is invoked against the key store. This test ensures the // key store can be successfully cleared when adb is disabled. - mHandler = mManager.new AdbDebuggingHandler(FgThread.get().getLooper()); - clearKeyStore(); } @@ -723,12 +734,104 @@ public final class AdbDebuggingManagerTest { // Now remove one of the keys and make sure the other key is still there mKeyStore.removeKey(TEST_KEY_1); + // Wait for the handler queue to receive the MESSAGE_ADB_PERSIST_KEYSTORE + flushHandlerQueue(); + assertFalse("The key was still in the adb_keys file after removing the key", isKeyInFile(TEST_KEY_1, mAdbKeyFile)); assertTrue("The key was not in the adb_keys file after removing a different key", isKeyInFile(TEST_KEY_2, mAdbKeyFile)); } + @Test + public void testAdbKeyStore_addDuplicateKey_doesNotAddDuplicateToAdbKeyFile() throws Exception { + setAllowedConnectionTime(0); + + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + assertEquals("adb_keys contains duplicate keys", 1, adbKeyFileKeys(mAdbKeyFile).size()); + } + + @Test + public void testAdbKeyStore_adbTempKeysFile_readsLastConnectionTimeFromXml() throws Exception { + long insertTime = mFakeTicker.currentTimeMillis(); + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + mFakeTicker.advance(10); + AdbDebuggingManager.AdbKeyStore newKeyStore = mManager.new AdbKeyStore(); + + assertEquals( + "KeyStore not populated from the XML file.", + insertTime, + newKeyStore.getLastConnectionTime(TEST_KEY_1)); + } + + @Test + public void test_notifyKeyFilesUpdated_filesDeletedRemovesPreviouslyAddedKey() + throws Exception { + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + Files.delete(mAdbKeyXmlFile.toPath()); + Files.delete(mAdbKeyFile.toPath()); + + mManager.notifyKeyFilesUpdated(); + flushHandlerQueue(); + + assertFalse( + "Key is authorized after reloading deleted key files. Was state preserved?", + mKeyStore.isKeyAuthorized(TEST_KEY_1)); + } + + @Test + public void test_notifyKeyFilesUpdated_newKeyIsAuthorized() throws Exception { + runAdbTest(TEST_KEY_1, true, true, false); + persistKeyStore(); + + // Back up the existing key files + Path tempXmlFile = Files.createTempFile("adbKeyXmlFile", ".tmp"); + Path tempAdbKeysFile = Files.createTempFile("adb_keys", ".tmp"); + Files.copy(mAdbKeyXmlFile.toPath(), tempXmlFile, StandardCopyOption.REPLACE_EXISTING); + Files.copy(mAdbKeyFile.toPath(), tempAdbKeysFile, StandardCopyOption.REPLACE_EXISTING); + + // Delete the existing key files + Files.delete(mAdbKeyXmlFile.toPath()); + Files.delete(mAdbKeyFile.toPath()); + + // Notify the manager that adb key files have changed. + mManager.notifyKeyFilesUpdated(); + flushHandlerQueue(); + + // Copy the files back + Files.copy(tempXmlFile, mAdbKeyXmlFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + Files.copy(tempAdbKeysFile, mAdbKeyFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + + // Tell the manager that the key files have changed. + mManager.notifyKeyFilesUpdated(); + flushHandlerQueue(); + + assertTrue( + "Key is not authorized after reloading key files.", + mKeyStore.isKeyAuthorized(TEST_KEY_1)); + } + + @Test + public void testAdbKeyStore_adbWifiConnect_storesBssidWhenAlwaysAllow() throws Exception { + String trustedNetwork = "My Network"; + mKeyStore.addTrustedNetwork(trustedNetwork); + persistKeyStore(); + + AdbDebuggingManager.AdbKeyStore newKeyStore = mManager.new AdbKeyStore(); + + assertTrue( + "Persisted trusted network not found in new keystore instance.", + newKeyStore.isTrustedNetwork(trustedNetwork)); + } + @Test public void testIsValidMdnsServiceName() { // Longer than 15 characters @@ -1030,28 +1133,27 @@ public final class AdbDebuggingManagerTest { if (key == null) { return false; } + return adbKeyFileKeys(keyFile).contains(key); + } + + private static List adbKeyFileKeys(File keyFile) throws Exception { + List keys = new ArrayList<>(); if (keyFile.exists()) { try (BufferedReader in = new BufferedReader(new FileReader(keyFile))) { String currKey; while ((currKey = in.readLine()) != null) { - if (key.equals(currKey)) { - return true; - } + keys.add(currKey); } } } - return false; + return keys; } /** * Helper class that extends AdbDebuggingThread to receive the response from AdbDebuggingManager * indicating whether the key should be allowed to connect. */ - class AdbDebuggingThreadTest extends AdbDebuggingManager.AdbDebuggingThread { - AdbDebuggingThreadTest() { - mManager.super(); - } - + private class AdbDebuggingThreadTest extends AdbDebuggingManager.AdbDebuggingThread { @Override public void sendResponse(String msg) { TestResult result = new TestResult(TestResult.RESULT_RESPONSE_RECEIVED, msg); @@ -1091,4 +1193,17 @@ public final class AdbDebuggingManagerTest { return "{mReturnCode = " + mReturnCode + ", mMessage = " + mMessage + "}"; } } + + private static class FakeTicker implements AdbDebuggingManager.Ticker { + private long mCurrentTime; + + private void advance(long milliseconds) { + mCurrentTime += milliseconds; + } + + @Override + public long currentTimeMillis() { + return mCurrentTime; + } + } } From b50382982ce5f81bd7393f08f97efc9aaf9c58b4 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Wed, 15 Jun 2022 17:26:47 +0800 Subject: [PATCH 164/176] Fix exception in expandSplitContainerIfNeeded The exception is because the client side hasn't received TaskFragmentInfo yet, so we don't have WindowContainerToken to change the bounds of TaskFragments. This CL verifies if we have TaskFragmentInfo before calling expandTaskFragment. If there's no TaskFragmentInfo, fallback to create new SplitContainer that fills the task bounds. Test: atest WMJetpackUnitTests Test: manual: reproduce steps mentioned in bug Bug: 232871351 Merged-In: Id8d122f7d95d1c6a3574b02ddd2b6afbc548f853 Change-Id: I83ee6ea32df485bf78db3b50dec8c92d80be8912 (cherry picked from commit 8bf77af1a70e54a58fa22132e338cd827d8c6771) Merged-In: I83ee6ea32df485bf78db3b50dec8c92d80be8912 --- .../extensions/embedding/SplitController.java | 35 +++--- .../extensions/embedding/SplitPresenter.java | 69 +++++++++-- .../embedding/EmbeddingTestUtils.java | 18 ++- .../embedding/SplitControllerTest.java | 107 +++++++++++++++--- .../embedding/SplitPresenterTest.java | 27 +++-- 5 files changed, 209 insertions(+), 47 deletions(-) diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java index 8ffe0c12f8ca6..c9a0d7d99cc63 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java @@ -24,9 +24,9 @@ import static androidx.window.extensions.embedding.SplitContainer.getFinishSecon import static androidx.window.extensions.embedding.SplitContainer.isStickyPlaceholderRule; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenAdjacent; import static androidx.window.extensions.embedding.SplitContainer.shouldFinishAssociatedContainerWhenStacked; -import static androidx.window.extensions.embedding.SplitPresenter.boundsSmallerThanMinDimensions; +import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO; import static androidx.window.extensions.embedding.SplitPresenter.getActivityIntentMinDimensionsPair; -import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions; +import static androidx.window.extensions.embedding.SplitPresenter.getNonEmbeddedActivityBounds; import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide; import android.app.Activity; @@ -581,8 +581,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen } /** Finds the activity below the given activity. */ + @VisibleForTesting @Nullable - private Activity findActivityBelow(@NonNull Activity activity) { + Activity findActivityBelow(@NonNull Activity activity) { Activity activityBelow = null; final TaskFragmentContainer container = getContainerWithActivity(activity); if (container != null) { @@ -620,21 +621,21 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen // Can launch in the existing secondary container if the rules share the same // presentation. final TaskFragmentContainer secondaryContainer = splitContainer.getSecondaryContainer(); - if (secondaryContainer == getContainerWithActivity(secondaryActivity) - && !boundsSmallerThanMinDimensions(secondaryContainer.getLastRequestedBounds(), - getMinDimensions(secondaryActivity))) { + if (secondaryContainer == getContainerWithActivity(secondaryActivity)) { // The activity is already in the target TaskFragment. return true; } secondaryContainer.addPendingAppearedActivity(secondaryActivity); final WindowContainerTransaction wct = new WindowContainerTransaction(); - mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, - secondaryActivity, null /* secondaryIntent */); - wct.reparentActivityToTaskFragment( - secondaryContainer.getTaskFragmentToken(), - secondaryActivity.getActivityToken()); - mPresenter.applyTransaction(wct); - return true; + if (mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, + secondaryActivity, null /* secondaryIntent */) + != RESULT_EXPAND_FAILED_NO_TF_INFO) { + wct.reparentActivityToTaskFragment( + secondaryContainer.getTaskFragmentToken(), + secondaryActivity.getActivityToken()); + mPresenter.applyTransaction(wct); + return true; + } } // Create new split pair. mPresenter.createNewSplitContainer(primaryActivity, secondaryActivity, splitRule); @@ -805,9 +806,9 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen if (splitContainer != null && existingContainer == splitContainer.getPrimaryContainer() && (canReuseContainer(splitRule, splitContainer.getSplitRule()) // TODO(b/231845476) we should always respect clearTop. - || !respectClearTop)) { - mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, - null /* secondaryActivity */, intent); + || !respectClearTop) + && mPresenter.expandSplitContainerIfNeeded(wct, splitContainer, primaryActivity, + null /* secondaryActivity */, intent) != RESULT_EXPAND_FAILED_NO_TF_INFO) { // Can launch in the existing secondary container if the rules share the same // presentation. return splitContainer.getSecondaryContainer(); @@ -877,7 +878,7 @@ public class SplitController implements JetpackTaskFragmentOrganizer.TaskFragmen pendingAppearedIntent, taskContainer, this); if (!taskContainer.isTaskBoundsInitialized()) { // Get the initial bounds before the TaskFragment has appeared. - final Rect taskBounds = SplitPresenter.getTaskBoundsFromActivity(activityInTask); + final Rect taskBounds = getNonEmbeddedActivityBounds(activityInTask); if (!taskContainer.setTaskBounds(taskBounds)) { Log.w(TAG, "Can't find bounds from activity=" + activityInTask); } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java index 63be98ebe175b..a89847a30d20d 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java @@ -65,6 +65,41 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { }) private @interface Position {} + /** + * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer, + * Activity, Activity, Intent)}. + * No need to expand the splitContainer because screen is big enough to + * {@link #shouldShowSideBySide(Rect, SplitRule, Pair)} and minimum dimensions is satisfied. + */ + static final int RESULT_NOT_EXPANDED = 0; + /** + * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer, + * Activity, Activity, Intent)}. + * The splitContainer should be expanded. It is usually because minimum dimensions is not + * satisfied. + * @see #shouldShowSideBySide(Rect, SplitRule, Pair) + */ + static final int RESULT_EXPANDED = 1; + /** + * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer, + * Activity, Activity, Intent)}. + * The splitContainer should be expanded, but the client side hasn't received + * {@link android.window.TaskFragmentInfo} yet. Fallback to create new expanded SplitContainer + * instead. + */ + static final int RESULT_EXPAND_FAILED_NO_TF_INFO = 2; + + /** + * Result of {@link #expandSplitContainerIfNeeded(WindowContainerTransaction, SplitContainer, + * Activity, Activity, Intent)} + */ + @IntDef(value = { + RESULT_NOT_EXPANDED, + RESULT_EXPANDED, + RESULT_EXPAND_FAILED_NO_TF_INFO, + }) + private @interface ResultCode {} + private final SplitController mController; SplitPresenter(@NonNull Executor executor, SplitController controller) { @@ -399,15 +434,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { /** * Expands the split container if the current split bounds are smaller than the Activity or * Intent that is added to the container. + * + * @return the {@link ResultCode} based on {@link #shouldShowSideBySide(Rect, SplitRule, Pair)} + * and if {@link android.window.TaskFragmentInfo} has reported to the client side. */ - void expandSplitContainerIfNeeded(@NonNull WindowContainerTransaction wct, + @ResultCode + int expandSplitContainerIfNeeded(@NonNull WindowContainerTransaction wct, @NonNull SplitContainer splitContainer, @NonNull Activity primaryActivity, @Nullable Activity secondaryActivity, @Nullable Intent secondaryIntent) { if (secondaryActivity == null && secondaryIntent == null) { throw new IllegalArgumentException("Either secondaryActivity or secondaryIntent must be" + " non-null."); } - final Rect taskBounds = getTaskBoundsFromActivity(primaryActivity); + final Rect taskBounds = getParentContainerBounds(primaryActivity); final Pair minDimensionsPair; if (secondaryActivity != null) { minDimensionsPair = getActivitiesMinDimensionsPair(primaryActivity, secondaryActivity); @@ -417,11 +456,17 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { } // Expand the splitContainer if minimum dimensions are not satisfied. if (!shouldShowSideBySide(taskBounds, splitContainer.getSplitRule(), minDimensionsPair)) { - expandTaskFragment(wct, splitContainer.getPrimaryContainer() - .getTaskFragmentToken()); - expandTaskFragment(wct, splitContainer.getSecondaryContainer() - .getTaskFragmentToken()); + // If the client side hasn't received TaskFragmentInfo yet, we can't change TaskFragment + // bounds. Return failure to create a new SplitContainer which fills task bounds. + if (splitContainer.getPrimaryContainer().getInfo() == null + || splitContainer.getSecondaryContainer().getInfo() == null) { + return RESULT_EXPAND_FAILED_NO_TF_INFO; + } + expandTaskFragment(wct, splitContainer.getPrimaryContainer().getTaskFragmentToken()); + expandTaskFragment(wct, splitContainer.getSecondaryContainer().getTaskFragmentToken()); + return RESULT_EXPANDED; } + return RESULT_NOT_EXPANDED; } static boolean shouldShowSideBySide(@NonNull Rect parentBounds, @NonNull SplitRule rule) { @@ -593,11 +638,19 @@ class SplitPresenter extends JetpackTaskFragmentOrganizer { if (container != null) { return getParentContainerBounds(container); } - return getTaskBoundsFromActivity(activity); + // Obtain bounds from Activity instead because the Activity hasn't been embedded yet. + return getNonEmbeddedActivityBounds(activity); } + /** + * Obtains the bounds from a non-embedded Activity. + *

    + * Note that callers should use {@link #getParentContainerBounds(Activity)} instead for most + * cases unless we want to obtain task bounds before + * {@link TaskContainer#isTaskBoundsInitialized()}. + */ @NonNull - static Rect getTaskBoundsFromActivity(@NonNull Activity activity) { + static Rect getNonEmbeddedActivityBounds(@NonNull Activity activity) { final WindowConfiguration windowConfiguration = activity.getResources().getConfiguration().windowConfiguration; if (!activity.isInMultiWindowMode()) { diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java index 3ef328141907c..effc1a3ef3ea9 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/EmbeddingTestUtils.java @@ -58,13 +58,21 @@ public class EmbeddingTestUtils { /** Creates a rule to always split the given activity and the given intent. */ static SplitRule createSplitRule(@NonNull Activity primaryActivity, @NonNull Intent secondaryIntent) { + return createSplitRule(primaryActivity, secondaryIntent, true /* clearTop */); + } + + /** Creates a rule to always split the given activity and the given intent. */ + static SplitRule createSplitRule(@NonNull Activity primaryActivity, + @NonNull Intent secondaryIntent, boolean clearTop) { final Pair targetPair = new Pair<>(primaryActivity, secondaryIntent); return new SplitPairRule.Builder( activityPair -> false, targetPair::equals, w -> true) .setSplitRatio(SPLIT_RATIO) - .setShouldClearTop(true) + .setShouldClearTop(clearTop) + .setFinishPrimaryWithSecondary(DEFAULT_FINISH_PRIMARY_WITH_SECONDARY) + .setFinishSecondaryWithPrimary(DEFAULT_FINISH_SECONDARY_WITH_PRIMARY) .build(); } @@ -76,6 +84,14 @@ public class EmbeddingTestUtils { true /* clearTop */); } + /** Creates a rule to always split the given activities. */ + static SplitRule createSplitRule(@NonNull Activity primaryActivity, + @NonNull Activity secondaryActivity, boolean clearTop) { + return createSplitRule(primaryActivity, secondaryActivity, + DEFAULT_FINISH_PRIMARY_WITH_SECONDARY, DEFAULT_FINISH_SECONDARY_WITH_PRIMARY, + clearTop); + } + /** Creates a rule to always split the given activities with the given finish behaviors. */ static SplitRule createSplitRule(@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity, int finishPrimaryWithSecondary, diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java index 982ab8043bbc8..ad496a906a33e 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitControllerTest.java @@ -35,6 +35,7 @@ import static com.google.common.truth.Truth.assertWithMessage; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; @@ -436,6 +437,50 @@ public class SplitControllerTest { assertTrue(container.areLastRequestedBoundsEqual(null)); } + @Test + public void testResolveStartActivityIntent_shouldExpandSplitContainer() { + final Intent intent = new Intent().setComponent( + new ComponentName(ApplicationProvider.getApplicationContext(), + MinimumDimensionActivity.class)); + setupSplitRule(mActivity, intent, false /* clearTop */); + final Activity secondaryActivity = createMockActivity(); + addSplitTaskFragments(mActivity, secondaryActivity, false /* clearTop */); + + final TaskFragmentContainer container = mSplitController.resolveStartActivityIntent( + mTransaction, TASK_ID, intent, mActivity); + final TaskFragmentContainer primaryContainer = mSplitController.getContainerWithActivity( + mActivity); + + assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container)); + assertTrue(primaryContainer.areLastRequestedBoundsEqual(null)); + assertTrue(container.areLastRequestedBoundsEqual(null)); + assertEquals(container, mSplitController.getContainerWithActivity(secondaryActivity)); + } + + @Test + public void testResolveStartActivityIntent_noInfo_shouldCreateSplitContainer() { + final Intent intent = new Intent().setComponent( + new ComponentName(ApplicationProvider.getApplicationContext(), + MinimumDimensionActivity.class)); + setupSplitRule(mActivity, intent, false /* clearTop */); + final Activity secondaryActivity = createMockActivity(); + addSplitTaskFragments(mActivity, secondaryActivity, false /* clearTop */); + + final TaskFragmentContainer secondaryContainer = mSplitController + .getContainerWithActivity(secondaryActivity); + secondaryContainer.mInfo = null; + + final TaskFragmentContainer container = mSplitController.resolveStartActivityIntent( + mTransaction, TASK_ID, intent, mActivity); + final TaskFragmentContainer primaryContainer = mSplitController.getContainerWithActivity( + mActivity); + + assertNotNull(mSplitController.getActiveSplitForContainers(primaryContainer, container)); + assertTrue(primaryContainer.areLastRequestedBoundsEqual(null)); + assertTrue(container.areLastRequestedBoundsEqual(null)); + assertNotEquals(container, secondaryContainer); + } + @Test public void testPlaceActivityInTopContainer() { mSplitController.placeActivityInTopContainer(mActivity); @@ -807,17 +852,12 @@ public class SplitControllerTest { final Activity activityBelow = createMockActivity(); setupSplitRule(activityBelow, mActivity); - ActivityInfo aInfo = new ActivityInfo(); - final Rect secondaryBounds = getSplitBounds(false /* isPrimary */); - aInfo.windowLayout = new ActivityInfo.WindowLayout(0, 0, 0, 0, 0, - secondaryBounds.width() + 1, secondaryBounds.height() + 1); - doReturn(aInfo).when(mActivity).getActivityInfo(); + doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo(); final TaskFragmentContainer container = mSplitController.newContainer(activityBelow, TASK_ID); container.addPendingAppearedActivity(mActivity); - // Allow to split as primary. boolean result = mSplitController.resolveActivityToContainer(mActivity, false /* isOnReparent */); @@ -825,6 +865,27 @@ public class SplitControllerTest { assertSplitPair(activityBelow, mActivity, true /* matchParentBounds */); } + @Test + public void testResolveActivityToContainer_minDimensions_shouldExpandSplitContainer() { + final Activity primaryActivity = createMockActivity(); + final Activity secondaryActivity = createMockActivity(); + addSplitTaskFragments(primaryActivity, secondaryActivity, false /* clearTop */); + + setupSplitRule(primaryActivity, mActivity, false /* clearTop */); + doReturn(createActivityInfoWithMinDimensions()).when(mActivity).getActivityInfo(); + doReturn(secondaryActivity).when(mSplitController).findActivityBelow(eq(mActivity)); + + clearInvocations(mSplitPresenter); + boolean result = mSplitController.resolveActivityToContainer(mActivity, + false /* isOnReparent */); + + assertTrue(result); + assertSplitPair(primaryActivity, mActivity, true /* matchParentBounds */); + assertEquals(mSplitController.getContainerWithActivity(secondaryActivity), + mSplitController.getContainerWithActivity(mActivity)); + verify(mSplitPresenter, never()).createNewSplitContainer(any(), any(), any()); + } + @Test public void testResolveActivityToContainer_inUnknownTaskFragment() { doReturn(new Binder()).when(mSplitController).getInitialTaskFragmentToken(mActivity); @@ -941,23 +1002,41 @@ public class SplitControllerTest { /** Setups a rule to always split the given activities. */ private void setupSplitRule(@NonNull Activity primaryActivity, @NonNull Intent secondaryIntent) { - final SplitRule splitRule = createSplitRule(primaryActivity, secondaryIntent); + setupSplitRule(primaryActivity, secondaryIntent, true /* clearTop */); + } + + /** Setups a rule to always split the given activities. */ + private void setupSplitRule(@NonNull Activity primaryActivity, + @NonNull Intent secondaryIntent, boolean clearTop) { + final SplitRule splitRule = createSplitRule(primaryActivity, secondaryIntent, clearTop); mSplitController.setEmbeddingRules(Collections.singleton(splitRule)); } /** Setups a rule to always split the given activities. */ private void setupSplitRule(@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) { - final SplitRule splitRule = createSplitRule(primaryActivity, secondaryActivity); + setupSplitRule(primaryActivity, secondaryActivity, true /* clearTop */); + } + + /** Setups a rule to always split the given activities. */ + private void setupSplitRule(@NonNull Activity primaryActivity, + @NonNull Activity secondaryActivity, boolean clearTop) { + final SplitRule splitRule = createSplitRule(primaryActivity, secondaryActivity, clearTop); mSplitController.setEmbeddingRules(Collections.singleton(splitRule)); } /** Adds a pair of TaskFragments as split for the given activities. */ private void addSplitTaskFragments(@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) { + addSplitTaskFragments(primaryActivity, secondaryActivity, true /* clearTop */); + } + + /** Adds a pair of TaskFragments as split for the given activities. */ + private void addSplitTaskFragments(@NonNull Activity primaryActivity, + @NonNull Activity secondaryActivity, boolean clearTop) { registerSplitPair(createMockTaskFragmentContainer(primaryActivity), createMockTaskFragmentContainer(secondaryActivity), - createSplitRule(primaryActivity, secondaryActivity)); + createSplitRule(primaryActivity, secondaryActivity, clearTop)); } /** Registers the two given TaskFragments as split pair. */ @@ -1008,16 +1087,18 @@ public class SplitControllerTest { if (primaryContainer.mInfo != null) { final Rect primaryBounds = matchParentBounds ? new Rect() : getSplitBounds(true /* isPrimary */); + final int windowingMode = matchParentBounds ? WINDOWING_MODE_UNDEFINED + : WINDOWING_MODE_MULTI_WINDOW; assertTrue(primaryContainer.areLastRequestedBoundsEqual(primaryBounds)); - assertTrue(primaryContainer.isLastRequestedWindowingModeEqual( - WINDOWING_MODE_MULTI_WINDOW)); + assertTrue(primaryContainer.isLastRequestedWindowingModeEqual(windowingMode)); } if (secondaryContainer.mInfo != null) { final Rect secondaryBounds = matchParentBounds ? new Rect() : getSplitBounds(false /* isPrimary */); + final int windowingMode = matchParentBounds ? WINDOWING_MODE_UNDEFINED + : WINDOWING_MODE_MULTI_WINDOW; assertTrue(secondaryContainer.areLastRequestedBoundsEqual(secondaryBounds)); - assertTrue(secondaryContainer.isLastRequestedWindowingModeEqual( - WINDOWING_MODE_MULTI_WINDOW)); + assertTrue(secondaryContainer.isLastRequestedWindowingModeEqual(windowingMode)); } } } diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java index 029503cd70d2f..d79319666c017 100644 --- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java +++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java @@ -21,11 +21,15 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_BOUNDS; import static androidx.window.extensions.embedding.EmbeddingTestUtils.TASK_ID; import static androidx.window.extensions.embedding.EmbeddingTestUtils.createActivityInfoWithMinDimensions; +import static androidx.window.extensions.embedding.EmbeddingTestUtils.createMockTaskFragmentInfo; import static androidx.window.extensions.embedding.EmbeddingTestUtils.createSplitRule; import static androidx.window.extensions.embedding.EmbeddingTestUtils.getSplitBounds; import static androidx.window.extensions.embedding.SplitPresenter.POSITION_END; import static androidx.window.extensions.embedding.SplitPresenter.POSITION_FILL; import static androidx.window.extensions.embedding.SplitPresenter.POSITION_START; +import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPANDED; +import static androidx.window.extensions.embedding.SplitPresenter.RESULT_EXPAND_FAILED_NO_TF_INFO; +import static androidx.window.extensions.embedding.SplitPresenter.RESULT_NOT_EXPANDED; import static androidx.window.extensions.embedding.SplitPresenter.getBoundsForPosition; import static androidx.window.extensions.embedding.SplitPresenter.getMinDimensions; import static androidx.window.extensions.embedding.SplitPresenter.shouldShowSideBySide; @@ -51,6 +55,7 @@ import android.content.pm.ActivityInfo; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; +import android.os.IBinder; import android.platform.test.annotations.Presubmit; import android.util.Pair; import android.util.Size; @@ -212,26 +217,31 @@ public class SplitPresenterTest { mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity, null /* secondaryActivity */, null /* secondaryIntent */)); - mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity, - secondaryActivity, null /* secondaryIntent */); - + assertEquals(RESULT_NOT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction, + splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */)); verify(mPresenter, never()).expandTaskFragment(any(), any()); doReturn(createActivityInfoWithMinDimensions()).when(secondaryActivity).getActivityInfo(); + assertEquals(RESULT_EXPAND_FAILED_NO_TF_INFO, mPresenter.expandSplitContainerIfNeeded( + mTransaction, splitContainer, mActivity, secondaryActivity, + null /* secondaryIntent */)); - mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity, - secondaryActivity, null /* secondaryIntent */); + primaryTf.setInfo(createMockTaskFragmentInfo(primaryTf, mActivity)); + secondaryTf.setInfo(createMockTaskFragmentInfo(secondaryTf, secondaryActivity)); + assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction, + splitContainer, mActivity, secondaryActivity, null /* secondaryIntent */)); verify(mPresenter).expandTaskFragment(eq(mTransaction), eq(primaryTf.getTaskFragmentToken())); verify(mPresenter).expandTaskFragment(eq(mTransaction), eq(secondaryTf.getTaskFragmentToken())); clearInvocations(mPresenter); - mPresenter.expandSplitContainerIfNeeded(mTransaction, splitContainer, mActivity, - null /* secondaryActivity */, new Intent(ApplicationProvider - .getApplicationContext(), MinimumDimensionActivity.class)); + assertEquals(RESULT_EXPANDED, mPresenter.expandSplitContainerIfNeeded(mTransaction, + splitContainer, mActivity, null /* secondaryActivity */, + new Intent(ApplicationProvider.getApplicationContext(), + MinimumDimensionActivity.class))); verify(mPresenter).expandTaskFragment(eq(mTransaction), eq(primaryTf.getTaskFragmentToken())); verify(mPresenter).expandTaskFragment(eq(mTransaction), @@ -246,6 +256,7 @@ public class SplitPresenterTest { doReturn(mActivityResources).when(activity).getResources(); doReturn(activityConfig).when(mActivityResources).getConfiguration(); doReturn(new ActivityInfo()).when(activity).getActivityInfo(); + doReturn(mock(IBinder.class)).when(activity).getActivityToken(); return activity; } } From b927d9db6bff7fd2e61cc75199aefcd3a654a396 Mon Sep 17 00:00:00 2001 From: Alex Johnston Date: Thu, 23 Jun 2022 22:35:28 +0100 Subject: [PATCH 165/176] DPMS workaround to check the device owner type in PermissionController Context: * If the device is managed, then hibernation should not be handled unless the device is financed. * We need a way to check if a device is financed in PermissionController. However, PermissionController is a mainline module so cannot call the TestAPI Dpm.getDeviceOwnerType Change: * User Global Settings to let permission controller know if the device is financed Bug: 236283038 Test: Manual testing following go/hibernation-local-testing Change-Id: Ib9a1a9116014d041c9514752882cdd364bfe777b (cherry picked from commit 7d1eae2df6d3fb521fcfc0e5c9360e6e44da7299) Merged-In: Ib9a1a9116014d041c9514752882cdd364bfe777b --- .../devicepolicy/DevicePolicyManagerService.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 590de7b5e1191..9d708add5ca5d 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1982,6 +1982,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { mOwners.load(); setDeviceOwnershipSystemPropertyLocked(); + if (mOwners.hasDeviceOwner()) { + setGlobalSettingDeviceOwnerType( + mOwners.getDeviceOwnerType(mOwners.getDeviceOwnerPackageName())); + } } } @@ -8811,6 +8815,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { deleteTransferOwnershipBundleLocked(userId); toggleBackupServiceActive(UserHandle.USER_SYSTEM, true); pushUserControlDisabledPackagesLocked(userId); + setGlobalSettingDeviceOwnerType(DEVICE_OWNER_TYPE_DEFAULT); } private void clearApplicationRestrictions(int userId) { @@ -18377,6 +18382,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { "Test only admins can only set the device owner type more than once"); mOwners.setDeviceOwnerType(packageName, deviceOwnerType, isAdminTestOnly); + setGlobalSettingDeviceOwnerType(deviceOwnerType); + } + + // TODO(b/237065504): Allow mainline modules to get the device owner type. This is a workaround + // to get the device owner type in PermissionController. See HibernationPolicy.kt. + private void setGlobalSettingDeviceOwnerType(int deviceOwnerType) { + mInjector.binderWithCleanCallingIdentity( + () -> mInjector.settingsGlobalPutInt("device_owner_type", deviceOwnerType)); } @Override From 27cae49f7eecfea15240748852cc1a220e1009cb Mon Sep 17 00:00:00 2001 From: Winson Chiu Date: Mon, 27 Jun 2022 18:27:54 +0000 Subject: [PATCH 166/176] Correctly parse minSdk even when targetSdk is a codename The code that assigned target to min if min was not specified was only checking for min codenames, but if the manifest specified a numerical minSdkVersion, that is valid and would incorrectly prevent the package from installing. Bug: 237059024 Test: mts-tradefed > mts-eng-only -m ApkInApexTest Change-Id: I3a2b9baa82ebb8ca9031c9fa128ce12bff17226e (cherry picked from commit bcf5b69c41b2a5401682e424596c33d1900bf791) Merged-In: I3a2b9baa82ebb8ca9031c9fa128ce12bff17226e --- core/java/android/content/pm/parsing/ApkLiteParseUtils.java | 5 ++++- .../android/server/pm/pkg/parsing/ParsingPackageUtils.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java index 20a4fdf658c6c..10d6f2d6d04b2 100644 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java @@ -542,14 +542,17 @@ public class ApkLiteParseUtils { int minVer = DEFAULT_MIN_SDK_VERSION; String minCode = null; + boolean minAssigned = false; int targetVer = DEFAULT_TARGET_SDK_VERSION; String targetCode = null; if (!TextUtils.isEmpty(minSdkVersionString)) { try { minVer = Integer.parseInt(minSdkVersionString); + minAssigned = true; } catch (NumberFormatException ignored) { minCode = minSdkVersionString; + minAssigned = !TextUtils.isEmpty(minCode); } } @@ -558,7 +561,7 @@ public class ApkLiteParseUtils { targetVer = Integer.parseInt(targetSdkVersionString); } catch (NumberFormatException ignored) { targetCode = targetSdkVersionString; - if (minCode == null) { + if (!minAssigned) { minCode = targetCode; } } diff --git a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java index 06a54a461d5e2..9bfb40fe11f7d 100644 --- a/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java +++ b/services/core/java/com/android/server/pm/pkg/parsing/ParsingPackageUtils.java @@ -1540,6 +1540,7 @@ public class ParsingPackageUtils { try { int minVers = ParsingUtils.DEFAULT_MIN_SDK_VERSION; String minCode = null; + boolean minAssigned = false; int targetVers = ParsingUtils.DEFAULT_TARGET_SDK_VERSION; String targetCode = null; int maxVers = Integer.MAX_VALUE; @@ -1548,9 +1549,11 @@ public class ParsingPackageUtils { if (val != null) { if (val.type == TypedValue.TYPE_STRING && val.string != null) { minCode = val.string.toString(); + minAssigned = !TextUtils.isEmpty(minCode); } else { // If it's not a string, it's an integer. minVers = val.data; + minAssigned = true; } } @@ -1558,7 +1561,7 @@ public class ParsingPackageUtils { if (val != null) { if (val.type == TypedValue.TYPE_STRING && val.string != null) { targetCode = val.string.toString(); - if (minCode == null) { + if (!minAssigned) { minCode = targetCode; } } else { From 6c95f48d4b139fb453fbd8572e5db193025df0f9 Mon Sep 17 00:00:00 2001 From: Raphael Kim Date: Fri, 24 Jun 2022 12:08:35 -0700 Subject: [PATCH 167/176] Re-introduce ActivityTaskManager in CdmService Bug: 237039176 Test: Manually tested by reporter Change-Id: I2b61b6f88b5dc772d2b4333aa23fcae22c4eee9a (cherry picked from commit e4c67f63e88f0e37d64d7fd1a489086d2f937163) Merged-In: I2b61b6f88b5dc772d2b4333aa23fcae22c4eee9a --- .../server/companion/CompanionDeviceManagerService.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 3f7cba6a4d094..2714addaec9ef 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -100,6 +100,7 @@ import com.android.server.LocalServices; import com.android.server.SystemService; import com.android.server.companion.presence.CompanionDevicePresenceMonitor; import com.android.server.pm.UserManagerInternal; +import com.android.server.wm.ActivityTaskManagerInternal; import java.io.File; import java.io.FileDescriptor; @@ -135,6 +136,7 @@ public class CompanionDeviceManagerService extends SystemService { private CompanionDevicePresenceMonitor mDevicePresenceMonitor; private CompanionApplicationController mCompanionAppController; + private final ActivityTaskManagerInternal mAtmInternal; private final ActivityManagerInternal mAmInternal; private final IAppOpsService mAppOpsManager; private final PowerWhitelistManager mPowerWhitelistManager; @@ -159,6 +161,7 @@ public class CompanionDeviceManagerService extends SystemService { mPowerWhitelistManager = context.getSystemService(PowerWhitelistManager.class); mAppOpsManager = IAppOpsService.Stub.asInterface( ServiceManager.getService(Context.APP_OPS_SERVICE)); + mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class); mUserManager = context.getSystemService(UserManager.class); @@ -969,6 +972,9 @@ public class CompanionDeviceManagerService extends SystemService { companionAppUids.add(uid); } } + if (mAtmInternal != null) { + mAtmInternal.setCompanionAppUids(userId, companionAppUids); + } if (mAmInternal != null) { // Make a copy of the set and send it to ActivityManager. mAmInternal.setCompanionAppUids(userId, new ArraySet<>(companionAppUids)); From a49c0207fa90f5c1042c8db61724ef77f3d995d4 Mon Sep 17 00:00:00 2001 From: Issei Suzuki Date: Thu, 16 Jun 2022 15:24:40 +0000 Subject: [PATCH 168/176] Pass keyguard occluded status in onAnimationCancelled. Test: No visible changes yet. Pass existing tests. Bug: 235463625 Change-Id: Iabee71bc76e19f20702f8a2739f565aa915f9b52 Merged-In: Iabee71bc76e19f20702f8a2739f565aa915f9b52 (cherry picked from commit c77d9bda0428e8f84bfd3ee2acc92dd091f7cf18) Merged-In: Iabee71bc76e19f20702f8a2739f565aa915f9b52 --- .../android/view/IRemoteAnimationRunner.aidl | 2 +- .../embedding/TaskFragmentAnimationRunner.java | 4 ++-- .../wm/shell/splitscreen/StageCoordinator.java | 4 ++-- .../wm/shell/stagesplit/StageCoordinator.java | 4 ++-- .../wm/shell/transition/LegacyTransitions.java | 2 +- .../animation/ActivityLaunchAnimator.kt | 2 +- .../system/RemoteAnimationAdapterCompat.java | 2 +- .../systemui/keyguard/KeyguardService.java | 3 +-- .../systemui/keyguard/KeyguardViewMediator.java | 12 ++++++------ .../screenshot/ScreenshotController.java | 2 +- .../animation/ActivityLaunchAnimatorTest.kt | 2 +- .../com/android/server/wm/DisplayContent.java | 8 ++++++++ .../server/wm/RemoteAnimationController.java | 4 +++- .../android/server/wm/ActivityRecordTests.java | 2 +- .../server/wm/AppChangeTransitionTests.java | 2 +- .../server/wm/AppTransitionControllerTest.java | 2 +- .../android/server/wm/AppTransitionTests.java | 2 +- .../wm/RemoteAnimationControllerTest.java | 17 +++++++++-------- .../android/server/wm/WindowContainerTests.java | 2 +- 19 files changed, 44 insertions(+), 34 deletions(-) diff --git a/core/java/android/view/IRemoteAnimationRunner.aidl b/core/java/android/view/IRemoteAnimationRunner.aidl index 1f64fb8ca2ec4..1981c9d66c8bb 100644 --- a/core/java/android/view/IRemoteAnimationRunner.aidl +++ b/core/java/android/view/IRemoteAnimationRunner.aidl @@ -46,5 +46,5 @@ oneway interface IRemoteAnimationRunner { * won't have any effect anymore. */ @UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553) - void onAnimationCancelled(); + void onAnimationCancelled(boolean isKeyguardOccluded); } diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java index 1ac33173668be..c4f37091a4914 100644 --- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java +++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentAnimationRunner.java @@ -83,9 +83,9 @@ class TaskFragmentAnimationRunner extends IRemoteAnimationRunner.Stub { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { if (TaskFragmentAnimationController.DEBUG) { - Log.v(TAG, "onAnimationCancelled"); + Log.v(TAG, "onAnimationCancelled: isKeyguardOccluded=" + isKeyguardOccluded); } mHandler.post(this::cancelAnimation); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java index 41e23647a6a47..30f316efb2b37 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java @@ -456,10 +456,10 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { onRemoteAnimationFinishedOrCancelled(evictWct); try { - adapter.getRunner().onAnimationCancelled(); + adapter.getRunner().onAnimationCancelled(isKeyguardOccluded); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java index ac25c7510931c..de0feeecad4b4 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/stagesplit/StageCoordinator.java @@ -345,9 +345,9 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler, } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { try { - adapter.getRunner().onAnimationCancelled(); + adapter.getRunner().onAnimationCancelled(isKeyguardOccluded); } catch (RemoteException e) { Slog.e(TAG, "Error starting remote animation", e); } diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java index 61e11e877b907..61e92f355dc2e 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java @@ -107,7 +107,7 @@ public class LegacyTransitions { } @Override - public void onAnimationCancelled() throws RemoteException { + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { mCancelled = true; mApps = mWallpapers = mNonApps = null; checkApply(); diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt index f934b1f3ab99a..bb6eb78aac65c 100644 --- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt +++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityLaunchAnimator.kt @@ -596,7 +596,7 @@ class ActivityLaunchAnimator( controller.onLaunchAnimationCancelled() } - override fun onAnimationCancelled() { + override fun onAnimationCancelled(isKeyguardOccluded: Boolean) { if (timedOut) { return } diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java index 618d2d2f213a9..06f5372e5cce5 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RemoteAnimationAdapterCompat.java @@ -105,7 +105,7 @@ public class RemoteAnimationAdapterCompat { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { remoteAnimationAdapter.onAnimationCancelled(); } }; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index b96eee717260f..fb61948216cdc 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -220,7 +220,6 @@ public class KeyguardService extends Service { public void mergeAnimation(IBinder transition, TransitionInfo info, SurfaceControl.Transaction t, IBinder mergeTarget, IRemoteTransitionFinishedCallback finishCallback) { - } }; } @@ -349,7 +348,7 @@ public class KeyguardService extends Service { } @Override // Binder interface - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { mKeyguardViewMediator.cancelKeyguardExitAnimation(); } }; diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 3ad43ac32185f..66a210754330e 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -910,12 +910,12 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, private final Matrix mUnoccludeMatrix = new Matrix(); @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { if (mUnoccludeAnimator != null) { mUnoccludeAnimator.cancel(); } - setOccluded(false /* isOccluded */, false /* animate */); + setOccluded(isKeyguardOccluded, false /* animate */); Log.d(TAG, "Unocclude animation cancelled. Occluded state is now: " + mOccluded); } @@ -3150,9 +3150,9 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } @Override - public void onAnimationCancelled() throws RemoteException { + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { if (mRunner != null) { - mRunner.onAnimationCancelled(); + mRunner.onAnimationCancelled(isKeyguardOccluded); } } @@ -3193,8 +3193,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, } @Override - public void onAnimationCancelled() throws RemoteException { - super.onAnimationCancelled(); + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { + super.onAnimationCancelled(isKeyguardOccluded); Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded); } } diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java index 5b6e5ce95b148..c213f192291a8 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java @@ -142,7 +142,7 @@ public class ScreenshotController { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } }; diff --git a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt index d5df9fe0c2e84..c48cbb19b40a5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/animation/ActivityLaunchAnimatorTest.kt @@ -159,7 +159,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() { @Test fun doesNotStartIfAnimationIsCancelled() { val runner = activityLaunchAnimator.createRunner(controller) - runner.onAnimationCancelled() + runner.onAnimationCancelled(false /* isKeyguardOccluded */) runner.onAnimationStart(0, emptyArray(), emptyArray(), emptyArray(), iCallback) waitForIdleSync() diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 98c5d512be0e6..a03dce3642096 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -6175,6 +6175,14 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp .getKeyguardController().isAodShowing(mDisplayId); } + /** + * @return whether the keyguard is occluded on this display + */ + boolean isKeyguardOccluded() { + return mRootWindowContainer.mTaskSupervisor + .getKeyguardController().isDisplayOccluded(mDisplayId); + } + @VisibleForTesting void removeAllTasks() { forAllTasks((t) -> { t.getRootTask().removeChild(t, "removeAllTasks"); }); diff --git a/services/core/java/com/android/server/wm/RemoteAnimationController.java b/services/core/java/com/android/server/wm/RemoteAnimationController.java index 4a0a6e3c204be..871b4d8062c23 100644 --- a/services/core/java/com/android/server/wm/RemoteAnimationController.java +++ b/services/core/java/com/android/server/wm/RemoteAnimationController.java @@ -316,8 +316,10 @@ class RemoteAnimationController implements DeathRecipient { private void invokeAnimationCancelled(String reason) { ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "cancelAnimation(): reason=%s", reason); + final boolean isKeyguardOccluded = mDisplayContent.isKeyguardOccluded(); + try { - mRemoteAnimationAdapter.getRunner().onAnimationCancelled(); + mRemoteAnimationAdapter.getRunner().onAnimationCancelled(isKeyguardOccluded); } catch (RemoteException e) { Slog.e(TAG, "Failed to notify cancel", e); } 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 03d87749072db..6fafa491d0ca6 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java @@ -779,7 +779,7 @@ public class ActivityRecordTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } }, 0, 0)); activity.updateOptionsLocked(opts); diff --git a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java index 71f19148d6165..b5764f54ff920 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppChangeTransitionTests.java @@ -87,7 +87,7 @@ public class AppChangeTransitionTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } @Override diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java index 77f884c936824..890a5478602a8 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java @@ -777,7 +777,7 @@ public class AppTransitionControllerTest extends WindowTestsBase { } @Override - public void onAnimationCancelled() throws RemoteException { + public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { mFinishedCallback = null; } diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java index 436cf36587d8e..74154609b22e2 100644 --- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionTests.java @@ -522,7 +522,7 @@ public class AppTransitionTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { mCancelled = true; } diff --git a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java index a4851ad563d91..e6910c2c0eca1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/RemoteAnimationControllerTest.java @@ -43,6 +43,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; @@ -168,7 +169,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); adapter.onAnimationCancelled(mMockLeash); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); } @Test @@ -183,7 +184,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mClock.fastForward(10500); mHandler.timeAdvance(); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); } @@ -204,12 +205,12 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { mClock.fastForward(10500); mHandler.timeAdvance(); - verify(mMockRunner, never()).onAnimationCancelled(); + verify(mMockRunner, never()).onAnimationCancelled(anyBoolean()); mClock.fastForward(52500); mHandler.timeAdvance(); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); } finally { @@ -221,7 +222,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { public void testZeroAnimations() throws Exception { mController.goodToGo(TRANSIT_OLD_NONE); verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); } @Test @@ -231,7 +232,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { new Point(50, 100), null, new Rect(50, 100, 150, 150), null); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); } @Test @@ -271,7 +272,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { win.mActivityRecord.removeImmediately(); mController.goodToGo(TRANSIT_OLD_ACTIVITY_OPEN); verify(mMockRunner, never()).onAnimationStart(anyInt(), any(), any(), any(), any()); - verify(mMockRunner).onAnimationCancelled(); + verify(mMockRunner).onAnimationCancelled(anyBoolean()); verify(mFinishedCallback).onAnimationFinished(eq(ANIMATION_TYPE_APP_TRANSITION), eq(adapter)); } @@ -527,7 +528,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase { // Cancel the wallpaper window animator and ensure the runner is not canceled wallpaperWindowToken.cancelAnimation(); - verify(mMockRunner, never()).onAnimationCancelled(); + verify(mMockRunner, never()).onAnimationCancelled(anyBoolean()); } finally { mDisplayContent.mOpeningApps.clear(); } diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java index 5743922d0428e..1715a295ded3f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContainerTests.java @@ -979,7 +979,7 @@ public class WindowContainerTests extends WindowTestsBase { } @Override - public void onAnimationCancelled() { + public void onAnimationCancelled(boolean isKeyguardOccluded) { } }, 0, 0, false); adapter.setCallingPidUid(123, 456); From 56059b266eab7e3e7ff9cce4e357c69ab786596e Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Fri, 17 Jun 2022 16:07:40 -0700 Subject: [PATCH 169/176] Set occluded state on remote animation cancel. The launch animator cancel method can be called by other methods within the activity launch animator, which is very dangerous since it can set the occluded state incorrectly. Bug: 235463625 Test: occlude and unocclude repeatedly to trigger cancel/restart Change-Id: I1a8cc95876c2966009c9cfa8dbe2471a360930a7 (cherry picked from commit bdfb30745c55b8cce593c8fb0b9587b5a5896b32) Merged-In: I1a8cc95876c2966009c9cfa8dbe2471a360930a7 --- .../android/systemui/keyguard/KeyguardViewMediator.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 66a210754330e..94c594dd8a48a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -842,7 +842,6 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, @Override public void onLaunchAnimationCancelled() { - setOccluded(true /* occluded */, false /* animate */); Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded); } @@ -915,7 +914,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, mUnoccludeAnimator.cancel(); } - setOccluded(isKeyguardOccluded, false /* animate */); + setOccluded(isKeyguardOccluded /* isOccluded */, false /* animate */); Log.d(TAG, "Unocclude animation cancelled. Occluded state is now: " + mOccluded); } @@ -3195,7 +3194,10 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, @Override public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { super.onAnimationCancelled(isKeyguardOccluded); - Log.d(TAG, "Occlude launch animation cancelled. Occluded state is now: " + mOccluded); + setOccluded(isKeyguardOccluded /* occluded */, false /* animate */); + + Log.d(TAG, "Occlude animation cancelled by WM. " + + "Setting occluded state to: " + mOccluded); } } } From 6a76e2cb6c0cc46eff80674c69ab9c5edcf9acfa Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Wed, 29 Jun 2022 15:22:12 +0000 Subject: [PATCH 170/176] Revert "Get rid of double measure" This reverts commit 4234e6cea8c9aa34a778d21a35576e7a8d40f9a5. Reason for revert: b/231383951 Change-Id: I41cbc5b4c036109cf45463bddb5b5cc12d11f88e (cherry picked from commit 084bac819aa6af39bd471b27bfbd97edf2c071f1) Merged-In: I41cbc5b4c036109cf45463bddb5b5cc12d11f88e --- core/java/android/view/ViewRootImpl.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index e46e44b4115b3..a13872eef6b80 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -2802,10 +2802,6 @@ public final class ViewRootImpl implements ViewParent, // Execute enqueued actions on every traversal in case a detached view enqueued an action getRunQueue().executeActions(mAttachInfo.mHandler); - if (mApplyInsetsRequested) { - dispatchApplyInsets(host); - } - if (mFirst) { // make sure touch mode code executes by setting cached value // to opposite of the added touch mode. @@ -2869,6 +2865,18 @@ public final class ViewRootImpl implements ViewParent, } } + if (mApplyInsetsRequested) { + dispatchApplyInsets(host); + if (mLayoutRequested) { + // Short-circuit catching a new layout request here, so + // we don't need to go through two layout passes when things + // change due to fitting system windows, which can happen a lot. + windowSizeMayChange |= measureHierarchy(host, lp, + mView.getContext().getResources(), + desiredWindowWidth, desiredWindowHeight); + } + } + if (layoutRequested) { // Clear this now, so that if anything requests a layout in the // rest of this function we will catch it and re-run a full From 5652facc3b42768847468d230518bee20cbaa970 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 23 Jun 2022 07:23:25 +0000 Subject: [PATCH 171/176] Don't crash on illegal biometric states Bug: 233448368 Test: atest BiometricSchedulerOperationTest Change-Id: I81d648e584b90ad00f8200fe981a113dd44bd7c2 Merged-In: I81d648e584b90ad00f8200fe981a113dd44bd7c2 (cherry picked from commit 3c4ebbbbc117f3a567d162768a70331dc0278511) Merged-In: I81d648e584b90ad00f8200fe981a113dd44bd7c2 --- .../sensors/BiometricSchedulerOperation.java | 84 +++++++++++---- .../BiometricSchedulerOperationTest.java | 101 +++++++++++++++++- 2 files changed, 163 insertions(+), 22 deletions(-) diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java index 968146a166ed3..ef2931ff58506 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricSchedulerOperation.java @@ -20,14 +20,18 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.hardware.biometrics.BiometricConstants; +import android.os.Build; import android.os.Handler; import android.os.IBinder; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.Arrays; +import java.util.function.BooleanSupplier; /** * Contains all the necessary information for a HAL operation. @@ -84,6 +88,8 @@ public class BiometricSchedulerOperation { private final BaseClientMonitor mClientMonitor; @Nullable private final ClientMonitorCallback mClientCallback; + @NonNull + private final BooleanSupplier mIsDebuggable; @Nullable private ClientMonitorCallback mOnStartCallback; @OperationState @@ -99,14 +105,33 @@ public class BiometricSchedulerOperation { this(clientMonitor, callback, STATE_WAITING_IN_QUEUE); } + @VisibleForTesting + BiometricSchedulerOperation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable ClientMonitorCallback callback, + @NonNull BooleanSupplier isDebuggable + ) { + this(clientMonitor, callback, STATE_WAITING_IN_QUEUE, isDebuggable); + } + protected BiometricSchedulerOperation( @NonNull BaseClientMonitor clientMonitor, @Nullable ClientMonitorCallback callback, @OperationState int state + ) { + this(clientMonitor, callback, state, Build::isDebuggable); + } + + private BiometricSchedulerOperation( + @NonNull BaseClientMonitor clientMonitor, + @Nullable ClientMonitorCallback callback, + @OperationState int state, + @NonNull BooleanSupplier isDebuggable ) { mClientMonitor = clientMonitor; mClientCallback = callback; mState = state; + mIsDebuggable = isDebuggable; mCancelWatchdog = () -> { if (!isFinished()) { Slog.e(TAG, "[Watchdog Triggered]: " + this); @@ -144,13 +169,19 @@ public class BiometricSchedulerOperation { * @return if this operation started */ public boolean start(@NonNull ClientMonitorCallback callback) { - checkInState("start", + if (errorWhenNoneOf("start", STATE_WAITING_IN_QUEUE, STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); + STATE_WAITING_IN_QUEUE_CANCELING)) { + return false; + } if (mClientMonitor.getCookie() != 0) { - throw new IllegalStateException("operation requires cookie"); + String err = "operation requires cookie"; + if (mIsDebuggable.getAsBoolean()) { + throw new IllegalStateException(err); + } + Slog.e(TAG, err); } return doStart(callback); @@ -164,16 +195,18 @@ public class BiometricSchedulerOperation { * @return if this operation started */ public boolean startWithCookie(@NonNull ClientMonitorCallback callback, int cookie) { - checkInState("start", - STATE_WAITING_IN_QUEUE, - STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); - if (mClientMonitor.getCookie() != cookie) { Slog.e(TAG, "Mismatched cookie for operation: " + this + ", received: " + cookie); return false; } + if (errorWhenNoneOf("start", + STATE_WAITING_IN_QUEUE, + STATE_WAITING_FOR_COOKIE, + STATE_WAITING_IN_QUEUE_CANCELING)) { + return false; + } + return doStart(callback); } @@ -217,10 +250,12 @@ public class BiometricSchedulerOperation { * immediately abort the operation and notify the client that it has finished unsuccessfully. */ public void abort() { - checkInState("cannot abort a non-pending operation", + if (errorWhenNoneOf("abort", STATE_WAITING_IN_QUEUE, STATE_WAITING_FOR_COOKIE, - STATE_WAITING_IN_QUEUE_CANCELING); + STATE_WAITING_IN_QUEUE_CANCELING)) { + return; + } if (isHalOperation()) { ((HalClientMonitor) mClientMonitor).unableToStart(); @@ -247,7 +282,9 @@ public class BiometricSchedulerOperation { * the callback used from {@link #start(ClientMonitorCallback)} is used) */ public void cancel(@NonNull Handler handler, @NonNull ClientMonitorCallback callback) { - checkNotInState("cancel", STATE_FINISHED); + if (errorWhenOneOf("cancel", STATE_FINISHED)) { + return; + } final int currentState = mState; if (!isInterruptable()) { @@ -402,21 +439,28 @@ public class BiometricSchedulerOperation { return mClientMonitor; } - private void checkNotInState(String message, @OperationState int... states) { - for (int state : states) { - if (mState == state) { - throw new IllegalStateException(message + ": illegal state= " + state); + private boolean errorWhenOneOf(String op, @OperationState int... states) { + final boolean isError = ArrayUtils.contains(states, mState); + if (isError) { + String err = op + ": mState must not be " + mState; + if (mIsDebuggable.getAsBoolean()) { + throw new IllegalStateException(err); } + Slog.e(TAG, err); } + return isError; } - private void checkInState(String message, @OperationState int... states) { - for (int state : states) { - if (mState == state) { - return; + private boolean errorWhenNoneOf(String op, @OperationState int... states) { + final boolean isError = !ArrayUtils.contains(states, mState); + if (isError) { + String err = op + ": mState=" + mState + " must be one of " + Arrays.toString(states); + if (mIsDebuggable.getAsBoolean()) { + throw new IllegalStateException(err); } + Slog.e(TAG, err); } - throw new IllegalStateException(message + ": illegal state= " + mState); + return isError; } @Override diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java index c17347320f524..9e9d70332f002 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerOperationTest.java @@ -80,11 +80,14 @@ public class BiometricSchedulerOperationTest { private Handler mHandler; private BiometricSchedulerOperation mOperation; + private boolean mIsDebuggable; @Before public void setUp() { mHandler = new Handler(TestableLooper.get(this).getLooper()); - mOperation = new BiometricSchedulerOperation(mClientMonitor, mClientCallback); + mIsDebuggable = false; + mOperation = new BiometricSchedulerOperation(mClientMonitor, mClientCallback, + () -> mIsDebuggable); } @Test @@ -125,6 +128,34 @@ public class BiometricSchedulerOperationTest { verify(mClientMonitor, never()).start(any()); } + @Test + public void testSecondStartWithCookieCrashesWhenDebuggable() { + final int cookie = 5; + mIsDebuggable = true; + when(mClientMonitor.getCookie()).thenReturn(cookie); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.startWithCookie(mOnStartCallback, cookie); + assertThat(started).isTrue(); + + assertThrows(IllegalStateException.class, + () -> mOperation.startWithCookie(mOnStartCallback, cookie)); + } + + @Test + public void testSecondStartWithCookieFailsNicelyWhenNotDebuggable() { + final int cookie = 5; + mIsDebuggable = false; + when(mClientMonitor.getCookie()).thenReturn(cookie); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.startWithCookie(mOnStartCallback, cookie); + assertThat(started).isTrue(); + + final boolean startedAgain = mOperation.startWithCookie(mOnStartCallback, cookie); + assertThat(startedAgain).isFalse(); + } + @Test public void startsWhenReadyAndHalAvailable() { when(mClientMonitor.getCookie()).thenReturn(0); @@ -169,8 +200,35 @@ public class BiometricSchedulerOperationTest { verify(mOnStartCallback).onClientFinished(eq(mClientMonitor), eq(false)); } + @Test + public void secondStartCrashesWhenDebuggable() { + mIsDebuggable = true; + when(mClientMonitor.getCookie()).thenReturn(0); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.start(mOnStartCallback); + assertThat(started).isTrue(); + + assertThrows(IllegalStateException.class, () -> mOperation.start(mOnStartCallback)); + } + + @Test + public void secondStartFailsNicelyWhenNotDebuggable() { + mIsDebuggable = false; + when(mClientMonitor.getCookie()).thenReturn(0); + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + final boolean started = mOperation.start(mOnStartCallback); + assertThat(started).isTrue(); + + final boolean startedAgain = mOperation.start(mOnStartCallback); + assertThat(startedAgain).isFalse(); + } + @Test public void doesNotStartWithCookie() { + // This class only throws exceptions when debuggable. + mIsDebuggable = true; when(mClientMonitor.getCookie()).thenReturn(9); assertThrows(IllegalStateException.class, () -> mOperation.start(mock(ClientMonitorCallback.class))); @@ -178,6 +236,8 @@ public class BiometricSchedulerOperationTest { @Test public void cannotRestart() { + // This class only throws exceptions when debuggable. + mIsDebuggable = true; when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); mOperation.start(mOnStartCallback); @@ -188,6 +248,8 @@ public class BiometricSchedulerOperationTest { @Test public void abortsNotRunning() { + // This class only throws exceptions when debuggable. + mIsDebuggable = true; when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); mOperation.abort(); @@ -200,7 +262,8 @@ public class BiometricSchedulerOperationTest { } @Test - public void cannotAbortRunning() { + public void abortCrashesWhenDebuggableIfOperationIsRunning() { + mIsDebuggable = true; when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); mOperation.start(mOnStartCallback); @@ -208,6 +271,16 @@ public class BiometricSchedulerOperationTest { assertThrows(IllegalStateException.class, () -> mOperation.abort()); } + @Test + public void abortFailsNicelyWhenNotDebuggableIfOperationIsRunning() { + mIsDebuggable = false; + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + mOperation.start(mOnStartCallback); + + mOperation.abort(); + } + @Test public void cancel() { when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); @@ -253,6 +326,30 @@ public class BiometricSchedulerOperationTest { verify(mClientMonitor).destroy(); } + @Test + public void cancelCrashesWhenDebuggableIfOperationIsFinished() { + mIsDebuggable = true; + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + mOperation.abort(); + assertThat(mOperation.isFinished()).isTrue(); + + final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class); + assertThrows(IllegalStateException.class, () -> mOperation.cancel(mHandler, cancelCb)); + } + + @Test + public void cancelFailsNicelyWhenNotDebuggableIfOperationIsFinished() { + mIsDebuggable = false; + when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); + + mOperation.abort(); + assertThat(mOperation.isFinished()).isTrue(); + + final ClientMonitorCallback cancelCb = mock(ClientMonitorCallback.class); + mOperation.cancel(mHandler, cancelCb); + } + @Test public void markCanceling() { when(mClientMonitor.getFreshDaemon()).thenReturn(mHal); From fd00dbf126b6050a56ec1b5933399ca4f25e4ecd Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Thu, 23 Jun 2022 07:40:59 +0000 Subject: [PATCH 172/176] Do nothing in duplicate onDialogAnimatedIn calls Bug: 233448368 Test: atest AuthSessionTest Change-Id: I171604ee6dc40f1d44ac65525c32ff97f1fa1d76 Merged-In: I171604ee6dc40f1d44ac65525c32ff97f1fa1d76 (cherry picked from commit 8f803aea46db62c94269e779a57b573545802090) Merged-In: I171604ee6dc40f1d44ac65525c32ff97f1fa1d76 --- .../server/biometrics/AuthSession.java | 5 +-- .../server/biometrics/AuthSessionTest.java | 43 ++++++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java index cc49f07dd0e5d..41ca13f5d5f54 100644 --- a/services/core/java/com/android/server/biometrics/AuthSession.java +++ b/services/core/java/com/android/server/biometrics/AuthSession.java @@ -538,13 +538,12 @@ public final class AuthSession implements IBinder.DeathRecipient { void onDialogAnimatedIn() { if (mState != STATE_AUTH_STARTED) { - Slog.w(TAG, "onDialogAnimatedIn, unexpected state: " + mState); + Slog.e(TAG, "onDialogAnimatedIn, unexpected state: " + mState); + return; } mState = STATE_AUTH_STARTED_UI_SHOWING; - startAllPreparedFingerprintSensors(); - mState = STATE_AUTH_STARTED_UI_SHOWING; } void onTryAgainPressed() { diff --git a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java index 25cf8a86baadd..e95924ad71096 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/AuthSessionTest.java @@ -20,7 +20,9 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricPrompt.DISMISSED_REASON_NEGATIVE; -import static com.android.server.biometrics.BiometricServiceStateProto.*; +import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_CALLED; +import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED; +import static com.android.server.biometrics.BiometricServiceStateProto.STATE_AUTH_STARTED_UI_SHOWING; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; @@ -32,6 +34,8 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -279,6 +283,43 @@ public class AuthSessionTest { session.mPreAuthInfo.eligibleSensors.get(fingerprintSensorId).getSensorState()); } + @Test + public void testOnDialogAnimatedInDoesNothingDuringInvalidState() throws Exception { + setupFingerprint(0 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL); + final long operationId = 123; + final int userId = 10; + + final AuthSession session = createAuthSession(mSensors, + false /* checkDevicePolicyManager */, + Authenticators.BIOMETRIC_STRONG, + TEST_REQUEST_ID, + operationId, + userId); + final IBiometricAuthenticator impl = session.mPreAuthInfo.eligibleSensors.get(0).impl; + + session.goToInitialState(); + for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) { + assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState()); + session.onCookieReceived( + session.mPreAuthInfo.eligibleSensors.get(sensor.id).getCookie()); + } + assertTrue(session.allCookiesReceived()); + assertEquals(STATE_AUTH_STARTED, session.getState()); + verify(impl, never()).startPreparedClient(anyInt()); + + // First invocation should start the client monitor. + session.onDialogAnimatedIn(); + assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState()); + verify(impl).startPreparedClient(anyInt()); + + // Subsequent invocations should not start the client monitor again. + session.onDialogAnimatedIn(); + session.onDialogAnimatedIn(); + session.onDialogAnimatedIn(); + assertEquals(STATE_AUTH_STARTED_UI_SHOWING, session.getState()); + verify(impl, times(1)).startPreparedClient(anyInt()); + } + @Test public void testCancelAuthentication_whenStateAuthCalled_invokesCancel() throws RemoteException { From 7d7ee57b4dbbe4723c19cf5308eee10d6c6cf2a6 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Thu, 30 Jun 2022 16:15:46 -0700 Subject: [PATCH 173/176] Don't freeze apps in the power exemption allow list. Set the "should not freeze" flag in oom adjuster if the app is in the power exemption allow list, as it doesn't make sense to freeze such kind of apps. There is an existing call to update the oom adj when the power exemption list changes. Bug: 237178259 Bug: 231253560 Test: Manual - see b/237178259#comment20 Test: atest CachedAppOptimizerTest Change-Id: I5fd1e623f60680b34096f0e58a088f72bf1089cb (cherry picked from commit 60e35ca3df2a91923b62f3533bda1f10b671e46b) Merged-In: I5fd1e623f60680b34096f0e58a088f72bf1089cb --- services/core/java/com/android/server/am/OomAdjuster.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index e7fcc59894672..f7fbbe4ebead4 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -1482,7 +1482,9 @@ public class OomAdjuster { if (!cycleReEval) { // Don't reset this flag when doing cycles re-evaluation. state.setNoKillOnBgRestrictedAndIdle(false); - app.mOptRecord.setShouldNotFreeze(false); + // If this UID is currently allowlisted, it should not be frozen. + final UidRecord uidRec = app.getUidRecord(); + app.mOptRecord.setShouldNotFreeze(uidRec != null && uidRec.isCurAllowListed()); } final int appUid = app.info.uid; From ddcd7479aab585acbf0618c2f4448776b693225b Mon Sep 17 00:00:00 2001 From: Josh Tsuji Date: Fri, 1 Jul 2022 14:58:05 -0400 Subject: [PATCH 174/176] Don't setOccluded in onLaunchAnimationStart. After recent fixes, WM exclusively communicates occluded state by calling the occlude/unocclude animators' onAnimationStart and onAnimationCancelled methods. We call KeyguardViewMediator#setOccluded there to officially set System UI's occluded state. Those methods are guaranteed to be called prior to the launch animator methods. This means that the setOccluded call in onLaunchAnimationStart should always be redundant. However, a series of race conditions (see https://buganizer.corp.google.com/issues/235463625#comment85) could cause this to be called after WM called the unocclude animator's onAnimationStart. Also, add logging to places where we set occluded state to aid in future debugging. These logs are only called during activity launch so should not be frequently logged. Fixes: 235463625 Test: launch and kill the Android Auto head unit ~50 times until onLaunchAnimationStarted ends up being called after the unocclude onAnimationStart, verify that we don't end up in the black screen state Test: launch/kill camera repeatedly to verify no regressions with camera occluding lockscreen Test: launch device controls, with and without controls added, to verify that we are not regressing other trampoline occluding actvities Change-Id: Ia71eb5fb0f85eb5fb494e66a270c68d7df5e1629 Merged-In: Ia71eb5fb0f85eb5fb494e66a270c68d7df5e1629 (cherry picked from commit 1454274680f6d43dc8a37ea4df7cf4699348d039) Merged-In: Ia71eb5fb0f85eb5fb494e66a270c68d7df5e1629 --- .../android/systemui/keyguard/KeyguardService.java | 2 ++ .../systemui/keyguard/KeyguardViewMediator.java | 14 +++++++++----- .../statusbar/phone/CentralSurfacesImpl.java | 1 + 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index fb61948216cdc..a724d87e5c083 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -405,6 +405,8 @@ public class KeyguardService extends Service { @Override // Binder interface public void setOccluded(boolean isOccluded, boolean animate) { + Log.d(TAG, "setOccluded(" + isOccluded + ")"); + Trace.beginSection("KeyguardService.mBinder#setOccluded"); checkPermission(); mKeyguardViewMediator.setOccluded(isOccluded, animate); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 94c594dd8a48a..0783eeec176f8 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -836,9 +836,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, private final ActivityLaunchAnimator.Controller mOccludeAnimationController = new ActivityLaunchAnimator.Controller() { @Override - public void onLaunchAnimationStart(boolean isExpandingFullyAbove) { - setOccluded(true /* occluded */, false /* animate */); - } + public void onLaunchAnimationStart(boolean isExpandingFullyAbove) {} @Override public void onLaunchAnimationCancelled() { @@ -924,6 +922,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException { + Log.d(TAG, "UnoccludeAnimator#onAnimationStart. Set occluded = false."); setOccluded(false /* isOccluded */, true /* animate */); if (apps == null || apps.length == 0 || apps[0] == null) { @@ -1669,6 +1668,8 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, * Notify us when the keyguard is occluded by another window */ public void setOccluded(boolean isOccluded, boolean animate) { + Log.d(TAG, "setOccluded(" + isOccluded + ")"); + Trace.beginSection("KeyguardViewMediator#setOccluded"); if (DEBUG) Log.d(TAG, "setOccluded " + isOccluded); mInteractionJankMonitor.cancel(CUJ_LOCKSCREEN_TRANSITION_FROM_AOD); @@ -1699,6 +1700,7 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, */ private void handleSetOccluded(boolean isOccluded, boolean animate) { Trace.beginSection("KeyguardViewMediator#handleSetOccluded"); + Log.d(TAG, "handleSetOccluded(" + isOccluded + ")"); synchronized (KeyguardViewMediator.this) { if (mHiding && isOccluded) { // We're in the process of going away but WindowManager wants to show a @@ -3188,16 +3190,18 @@ public class KeyguardViewMediator extends CoreStartable implements Dumpable, // internal state to reflect that immediately, vs. waiting for the launch animator to // begin. Otherwise, calls to setShowingLocked, etc. will not know that we're about to // be occluded and might re-show the keyguard. + Log.d(TAG, "OccludeAnimator#onAnimationStart. Set occluded = true."); setOccluded(true /* isOccluded */, false /* animate */); } @Override public void onAnimationCancelled(boolean isKeyguardOccluded) throws RemoteException { super.onAnimationCancelled(isKeyguardOccluded); - setOccluded(isKeyguardOccluded /* occluded */, false /* animate */); Log.d(TAG, "Occlude animation cancelled by WM. " - + "Setting occluded state to: " + mOccluded); + + "Setting occluded state to: " + isKeyguardOccluded); + setOccluded(isKeyguardOccluded /* occluded */, false /* animate */); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java index 705de9b43ed0c..7e57dd452cb8c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java @@ -1760,6 +1760,7 @@ public class CentralSurfacesImpl extends CoreStartable implements // activity is exited. if (mKeyguardStateController.isShowing() && !mKeyguardStateController.isKeyguardGoingAway()) { + Log.d(TAG, "Setting occluded = true in #startActivity."); mKeyguardViewMediator.setOccluded(true /* isOccluded */, true /* animate */); } From d02830802a24ce42ce14ffca13c6931feab10c23 Mon Sep 17 00:00:00 2001 From: Charles Chen Date: Thu, 23 Jun 2022 17:02:37 +0800 Subject: [PATCH 175/176] Fix exception when opening App info on work profile The root cause is that the target intent was intercepted to ConfirmDeviceCredentialIntent and ActivityStarter tried to embed the credential intent unexpectedly. This CL fixes the issue by, instead throwing exception, start Activity to the new Task if the parent Task of target TaskFragment is different than the target Task. This CL also removes the remaining embedded Task as tracked in b/234351413. TODO: 1. With this CL, the app detail info page after intercepted shows in fullscreen. It will be embed back to the right TaskFragment as follow-up CL. 2. Fix the layout issue of ConfirmDeviceCredential Activity. The layout is flaky at the first time to launch device. Bug: 233578672 Bug: 231972879 fixes: 234351413 Test: atest ActivityStarterTests Test: atest CtsWindowManagerJetpackTestCases Test: atest TaskFragmentOrganizerControllerTest Test: atest TaskFragmentOrganizerPolicyTest TaskFragmentOrganizerTest Test: atest SplitActivityLifecycleTest Change-Id: Ibcb40521a5a8374e485932f006049ba676213da1 Merged-In: Ibcb40521a5a8374e485932f006049ba676213da1 (cherry picked from commit 8e4028329473a54c16fda4233a9fc10807375464) Merged-In: Ibcb40521a5a8374e485932f006049ba676213da1 --- .../android/server/wm/ActivityStarter.java | 93 +++++++++++-------- .../com/android/server/wm/TaskFragment.java | 67 +++++++++++-- .../wm/TaskFragmentOrganizerController.java | 3 +- .../server/wm/WindowOrganizerController.java | 7 +- .../server/wm/ActivityStarterTests.java | 61 ++++++++++++ .../TaskFragmentOrganizerControllerTest.java | 5 +- 6 files changed, 180 insertions(+), 56 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 84cd63424cd16..ec9babf09ef32 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -78,6 +78,10 @@ import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_BOUNDS; import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.PHASE_DISPLAY; import static com.android.server.wm.Task.REPARENT_MOVE_ROOT_TASK_TO_FRONT; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_TOP; import android.annotation.NonNull; @@ -131,6 +135,7 @@ import com.android.server.statusbar.StatusBarManagerInternal; import com.android.server.uri.NeededUriGrants; import com.android.server.wm.ActivityMetricsLogger.LaunchingState; import com.android.server.wm.LaunchParamsController.LaunchParams; +import com.android.server.wm.TaskFragment.EmbeddingCheckResult; import java.io.PrintWriter; import java.text.DateFormat; @@ -2038,12 +2043,6 @@ class ActivityStarter { } } - if (mInTaskFragment != null && !canEmbedActivity(mInTaskFragment, r, newTask, targetTask)) { - Slog.e(TAG, "Permission denied: Cannot embed " + r + " to " + mInTaskFragment.getTask() - + " targetTask= " + targetTask); - return START_PERMISSION_DENIED; - } - // Do not start the activity if target display's DWPC does not allow it. // We can't return fatal error code here because it will crash the caller of // startActivity() if they don't catch the exception. We don't expect 3P apps to make @@ -2070,19 +2069,21 @@ class ActivityStarter { } /** - * Return {@code true} if an activity can be embedded to the TaskFragment. + * Returns whether embedding of {@code starting} is allowed. + * * @param taskFragment the TaskFragment for embedding. * @param starting the starting activity. - * @param newTask whether the starting activity is going to be launched on a new task. * @param targetTask the target task for launching activity, which could be different from * the one who hosting the embedding. */ - private boolean canEmbedActivity(@NonNull TaskFragment taskFragment, - @NonNull ActivityRecord starting, boolean newTask, Task targetTask) { + @VisibleForTesting + @EmbeddingCheckResult + static int canEmbedActivity(@NonNull TaskFragment taskFragment, + @NonNull ActivityRecord starting, @NonNull Task targetTask) { final Task hostTask = taskFragment.getTask(); // Not allowed embedding a separate task or without host task. - if (hostTask == null || newTask || targetTask != hostTask) { - return false; + if (hostTask == null || targetTask != hostTask) { + return EMBEDDING_DISALLOWED_NEW_TASK; } return taskFragment.isAllowedToEmbedActivity(starting); @@ -2894,19 +2895,16 @@ class ActivityStarter { mIntentDelivered = true; } + /** Places {@link #mStartActivity} in {@code task} or an embedded {@link TaskFragment}. */ private void addOrReparentStartingActivity(@NonNull Task task, String reason) { TaskFragment newParent = task; if (mInTaskFragment != null) { - // TODO(b/234351413): remove remaining embedded Task logic. - // mInTaskFragment is created and added to the leaf task by task fragment organizer's - // request. If the task was resolved and different than mInTaskFragment, reparent the - // task to mInTaskFragment for embedding. - if (mInTaskFragment.getTask() != task) { - if (shouldReparentInTaskFragment(task)) { - task.reparent(mInTaskFragment, POSITION_TOP); - } - } else { + int embeddingCheckResult = canEmbedActivity(mInTaskFragment, mStartActivity, task); + if (embeddingCheckResult == EMBEDDING_ALLOWED) { newParent = mInTaskFragment; + } else { + // Start mStartActivity to task instead if it can't be embedded to mInTaskFragment. + sendCanNotEmbedActivityError(mInTaskFragment, embeddingCheckResult); } } else { TaskFragment candidateTf = mAddingToTaskFragment != null ? mAddingToTaskFragment : null; @@ -2918,20 +2916,12 @@ class ActivityStarter { } } if (candidateTf != null && candidateTf.isEmbedded() - && canEmbedActivity(candidateTf, mStartActivity, false /* newTask */, task)) { + && canEmbedActivity(candidateTf, mStartActivity, task) == EMBEDDING_ALLOWED) { // Use the embedded TaskFragment of the top activity as the new parent if the // activity can be embedded. newParent = candidateTf; } } - // Start Activity to the Task if mStartActivity's min dimensions are not satisfied. - if (newParent.isEmbedded() && newParent.smallerThanMinDimension(mStartActivity)) { - reason += " - MinimumDimensionViolation"; - mService.mWindowOrganizerController.sendMinimumDimensionViolation( - newParent, mStartActivity.getMinDimensions(), mRequest.errorCallbackToken, - reason); - newParent = task; - } if (mStartActivity.getTaskFragment() == null || mStartActivity.getTaskFragment() == newParent) { newParent.addChild(mStartActivity, POSITION_TOP); @@ -2940,16 +2930,41 @@ class ActivityStarter { } } - private boolean shouldReparentInTaskFragment(Task task) { - // The task has not been embedded. We should reparent the task to TaskFragment. - if (!task.isEmbedded()) { - return true; + /** + * Notifies the client side that {@link #mStartActivity} cannot be embedded to + * {@code taskFragment}. + */ + private void sendCanNotEmbedActivityError(TaskFragment taskFragment, + @EmbeddingCheckResult int result) { + final String errMsg; + switch(result) { + case EMBEDDING_DISALLOWED_NEW_TASK: { + errMsg = "Cannot embed " + mStartActivity + " that launched on another task" + + ",mLaunchMode=" + mLaunchMode + + ",mLaunchFlag=" + Integer.toHexString(mLaunchFlags); + break; + } + case EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION: { + errMsg = "Cannot embed " + mStartActivity + + ". TaskFragment's bounds:" + taskFragment.getBounds() + + ", minimum dimensions:" + mStartActivity.getMinDimensions(); + break; + } + case EMBEDDING_DISALLOWED_UNTRUSTED_HOST: { + errMsg = "The app:" + mCallingUid + "is not trusted to " + mStartActivity; + break; + } + default: + errMsg = "Unhandled embed result:" + result; + } + if (taskFragment.isOrganized()) { + mService.mWindowOrganizerController.sendTaskFragmentOperationFailure( + taskFragment.getTaskFragmentOrganizer(), mRequest.errorCallbackToken, + new SecurityException(errMsg)); + } else { + // If the taskFragment is not organized, just dump error message as warning logs. + Slog.w(TAG, errMsg); } - WindowContainer parent = task.getParent(); - // If the Activity is going to launch on top of embedded Task in the same TaskFragment, - // we don't need to reparent the Task. Otherwise, the embedded Task should reparent to - // another TaskFragment. - return parent.asTaskFragment() != mInTaskFragment; } private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance, diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java index 1d328671876f7..1b0c01816f739 100644 --- a/services/core/java/com/android/server/wm/TaskFragment.java +++ b/services/core/java/com/android/server/wm/TaskFragment.java @@ -139,6 +139,45 @@ class TaskFragment extends WindowContainer { /** Set to false to disable the preview that is shown while a new activity is being started. */ static final boolean SHOW_APP_STARTING_PREVIEW = true; + /** + * An embedding check result of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can be embedded successfully. + */ + static final int EMBEDDING_ALLOWED = 0; + /** + * An embedding check result of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can't be embedded because either the Activity does not allow + * untrusted embedding, and the embedding host app is not trusted. + */ + static final int EMBEDDING_DISALLOWED_UNTRUSTED_HOST = 1; + /** + * An embedding check result of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can't be embedded because this taskFragment's bounds are + * {@link #smallerThanMinDimension(ActivityRecord)}. + */ + static final int EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION = 2; + /** + * An embedding check result of + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}: + * indicate that an Activity can't be embedded because the Activity is started on a new task. + */ + static final int EMBEDDING_DISALLOWED_NEW_TASK = 3; + + /** + * Embedding check results of {@link #isAllowedToEmbedActivity(ActivityRecord)} or + * {@link ActivityStarter#canEmbedActivity(TaskFragment, ActivityRecord, Task)}. + */ + @IntDef(prefix = {"EMBEDDING_"}, value = { + EMBEDDING_ALLOWED, + EMBEDDING_DISALLOWED_UNTRUSTED_HOST, + EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, + EMBEDDING_DISALLOWED_NEW_TASK, + }) + @interface EmbeddingCheckResult {} + /** * Indicate that the minimal width/height should use the default value. * @@ -520,20 +559,29 @@ class TaskFragment extends WindowContainer { return false; } - boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a) { + @EmbeddingCheckResult + int isAllowedToEmbedActivity(@NonNull ActivityRecord a) { return isAllowedToEmbedActivity(a, mTaskFragmentOrganizerUid); } /** * Checks if the organized task fragment is allowed to have the specified activity, which is - * allowed if an activity allows embedding in untrusted mode, or if the trusted mode can be - * enabled. - * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord) + * allowed if an activity allows embedding in untrusted mode, if the trusted mode can be + * enabled, or if the organized task fragment bounds are not + * {@link #smallerThanMinDimension(ActivityRecord)}. + * * @param uid uid of the TaskFragment organizer. + * @see #isAllowedToEmbedActivityInTrustedMode(ActivityRecord) */ - boolean isAllowedToEmbedActivity(@NonNull ActivityRecord a, int uid) { - return isAllowedToEmbedActivityInUntrustedMode(a) - || isAllowedToEmbedActivityInTrustedMode(a, uid); + @EmbeddingCheckResult + int isAllowedToEmbedActivity(@NonNull ActivityRecord a, int uid) { + if (!isAllowedToEmbedActivityInUntrustedMode(a) + && !isAllowedToEmbedActivityInTrustedMode(a, uid)) { + return EMBEDDING_DISALLOWED_UNTRUSTED_HOST; + } else if (smallerThanMinDimension(a)) { + return EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; + } + return EMBEDDING_ALLOWED; } boolean smallerThanMinDimension(@NonNull ActivityRecord activity) { @@ -550,9 +598,8 @@ class TaskFragment extends WindowContainer { } final int minWidth = minDimensions.x; final int minHeight = minDimensions.y; - final boolean smaller = taskFragBounds.width() < minWidth + return taskFragBounds.width() < minWidth || taskFragBounds.height() < minHeight; - return smaller; } /** @@ -609,7 +656,7 @@ class TaskFragment extends WindowContainer { // The system is trusted to embed other apps securely and for all users. return UserHandle.getAppId(uid) == SYSTEM_UID // Activities from the same UID can be embedded freely by the host. - || uid == a.getUid(); + || a.isUid(uid); } /** diff --git a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java index b4d1cf77919a8..2546177ec367c 100644 --- a/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java +++ b/services/core/java/com/android/server/wm/TaskFragmentOrganizerController.java @@ -19,6 +19,7 @@ package com.android.server.wm; import static android.window.TaskFragmentOrganizer.putExceptionInBundle; import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANIZER; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.WindowOrganizerController.configurationsAreEqualForOrganizer; import android.annotation.IntDef; @@ -235,7 +236,7 @@ public class TaskFragmentOrganizerController extends ITaskFragmentOrganizerContr + " is not in a task belong to the organizer app."); return; } - if (!task.isAllowedToEmbedActivity(activity, mOrganizerUid)) { + if (task.isAllowedToEmbedActivity(activity, mOrganizerUid) != EMBEDDING_ALLOWED) { Slog.d(TAG, "Reparent activity=" + activity.token + " is not allowed to be embedded."); return; diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java index 22d6237411f3a..64a5deb32fcba 100644 --- a/services/core/java/com/android/server/wm/WindowOrganizerController.java +++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java @@ -44,6 +44,7 @@ import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WINDOW_ORGANI import static com.android.server.wm.ActivityTaskManagerService.LAYOUT_REASON_CONFIG_CHANGED; import static com.android.server.wm.ActivityTaskSupervisor.PRESERVE_WINDOWS; import static com.android.server.wm.Task.FLAG_FORCE_HIDDEN_FOR_TASK_ORG; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -756,7 +757,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception); break; } - if (!parent.isAllowedToEmbedActivity(activity)) { + if (parent.isAllowedToEmbedActivity(activity) != EMBEDDING_ALLOWED) { final Throwable exception = new SecurityException( "The task fragment is not trusted to embed the given activity."); sendTaskFragmentOperationFailure(organizer, errorCallbackToken, exception); @@ -988,7 +989,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub } /** A helper method to send minimum dimension violation error to the client. */ - void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions, + private void sendMinimumDimensionViolation(TaskFragment taskFragment, Point minDimensions, IBinder errorCallbackToken, String reason) { if (taskFragment == null || taskFragment.getTaskFragmentOrganizer() == null) { return; @@ -1582,7 +1583,7 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub // We are reparenting activities to a new embedded TaskFragment, this operation is only // allowed if the new parent is trusted by all reparent activities. final boolean isEmbeddingDisallowed = oldParent.forAllActivities(activity -> - !newParentTF.isAllowedToEmbedActivity(activity)); + newParentTF.isAllowedToEmbedActivity(activity) == EMBEDDING_ALLOWED); if (isEmbeddingDisallowed) { final Throwable exception = new SecurityException( "The new parent is not trusted to embed the activities."); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java index b9432753c17fb..4ca14ddbd96f1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java @@ -37,6 +37,7 @@ import static android.content.Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; +import static android.content.pm.ActivityInfo.FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE; import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK; @@ -52,6 +53,11 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.times; import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; +import static com.android.server.wm.ActivityStarter.canEmbedActivity; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_NEW_TASK; +import static com.android.server.wm.TaskFragment.EMBEDDING_DISALLOWED_UNTRUSTED_HOST; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -59,6 +65,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -87,6 +94,7 @@ import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.service.voice.IVoiceInteractionSession; import android.util.Pair; +import android.util.Size; import android.view.Gravity; import android.window.TaskFragmentOrganizerToken; @@ -1172,6 +1180,7 @@ public class ActivityStarterTests extends WindowTestsBase { null /* inTask */, taskFragment); assertFalse(taskFragment.hasChild()); + assertNotNull("Target record must be started on Task.", targetRecord.getParent().asTask()); } @Test @@ -1342,6 +1351,58 @@ public class ActivityStarterTests extends WindowTestsBase { any()); } + @Test + public void testCanEmbedActivity() { + final Size minDimensions = new Size(1000, 1000); + final WindowLayout windowLayout = new WindowLayout(0, 0, 0, 0, 0, + minDimensions.getWidth(), minDimensions.getHeight()); + final ActivityRecord starting = new ActivityBuilder(mAtm) + .setUid(UNIMPORTANT_UID) + .setWindowLayout(windowLayout) + .build(); + + // Task fragment hasn't attached to a task yet. Start activity to a new task. + TaskFragment taskFragment = new TaskFragmentBuilder(mAtm).build(); + final Task task = new TaskBuilder(mSupervisor).build(); + + assertEquals(EMBEDDING_DISALLOWED_NEW_TASK, + canEmbedActivity(taskFragment, starting, task)); + + // Starting activity is going to be started on a task different from task fragment's parent + // task. Start activity to a new task. + task.addChild(taskFragment, POSITION_TOP); + final Task newTask = new TaskBuilder(mSupervisor).build(); + + assertEquals(EMBEDDING_DISALLOWED_NEW_TASK, + canEmbedActivity(taskFragment, starting, newTask)); + + // Make task fragment bounds exceed task bounds. + final Rect taskBounds = task.getBounds(); + taskFragment.setBounds(taskBounds.left, taskBounds.top, taskBounds.right + 1, + taskBounds.bottom + 1); + + assertEquals(EMBEDDING_DISALLOWED_UNTRUSTED_HOST, + canEmbedActivity(taskFragment, starting, task)); + + taskFragment.setBounds(taskBounds); + starting.info.flags |= FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; + + assertEquals(EMBEDDING_ALLOWED, canEmbedActivity(taskFragment, starting, task)); + + starting.info.flags &= ~FLAG_ALLOW_UNTRUSTED_ACTIVITY_EMBEDDING; + // Set task fragment's uid as the same as starting activity's uid. + taskFragment.setTaskFragmentOrganizer(mock(TaskFragmentOrganizerToken.class), + UNIMPORTANT_UID, "test"); + + assertEquals(EMBEDDING_ALLOWED, canEmbedActivity(taskFragment, starting, task)); + + // Make task fragment bounds smaller than starting activity's minimum dimensions + taskFragment.setBounds(0, 0, minDimensions.getWidth() - 1, minDimensions.getHeight() - 1); + + assertEquals(EMBEDDING_DISALLOWED_MIN_DIMENSION_VIOLATION, + canEmbedActivity(taskFragment, starting, task)); + } + private static void startActivityInner(ActivityStarter starter, ActivityRecord target, ActivityRecord source, ActivityOptions options, Task inTask, TaskFragment inTaskFragment) { diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java index 8202cd915527b..ed8440027bdc1 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java @@ -21,6 +21,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; +import static com.android.server.wm.TaskFragment.EMBEDDING_ALLOWED; import static com.android.server.wm.WindowContainer.POSITION_TOP; import static com.android.server.wm.testing.Assert.assertThrows; @@ -531,7 +532,7 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { mWindowOrganizerController.mLaunchTaskFragments .put(mFragmentToken, mTaskFragment); mTransaction.reparentActivityToTaskFragment(mFragmentToken, activity.token); - doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity); + doReturn(EMBEDDING_ALLOWED).when(mTaskFragment).isAllowedToEmbedActivity(activity); clearInvocations(mAtm.mRootWindowContainer); mAtm.getWindowOrganizerController().applyTransaction(mTransaction); @@ -921,7 +922,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .setOrganizer(mOrganizer) .setBounds(mTaskFragBounds) .build(); - doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity); mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); clearInvocations(mAtm.mRootWindowContainer); @@ -956,7 +956,6 @@ public class TaskFragmentOrganizerControllerTest extends WindowTestsBase { .setOrganizer(mOrganizer) .setBounds(mTaskFragBounds) .build(); - doReturn(true).when(mTaskFragment).isAllowedToEmbedActivity(activity); mWindowOrganizerController.mLaunchTaskFragments.put(oldFragToken, oldTaskFrag); mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment); clearInvocations(mAtm.mRootWindowContainer); From a07cc7613785458436d3b70576881abdbacaf284 Mon Sep 17 00:00:00 2001 From: Jernej Virag Date: Fri, 10 Jun 2022 10:56:05 +0200 Subject: [PATCH 176/176] Size restrict right icon size in notification This is to prevent large bitmaps from using too much memory in notifications. Bug:210690571 Bug:218845090 Test: Tested on device atest android.app.cts.NotificationTemplateTest Change-Id: I2f3d04546af58edbe7bae2b7d856ab3d87365fdf (cherry picked from commit d6842211884147a8cad9473ba44baa392919c476) Merged-In: I2f3d04546af58edbe7bae2b7d856ab3d87365fdf --- core/res/res/layout/notification_template_material_base.xml | 4 +++- core/res/res/layout/notification_template_right_icon.xml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index 0756d68063f5e..fd787f6ea470d 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -138,7 +138,7 @@ - -