From 40473c4632a5e5803280058dfd29c3db7f13c406 Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Sat, 25 Jan 2020 06:57:04 -0800 Subject: [PATCH] Force update uid state when pending uid state is applied Before the state was update lazily when someone interacted with appopsmanager. Since Q the the uid state might change depending on the procState and hence we might need to trigger the opChanged callbacks when the procState is applied. Bug: 148180766 Test: (on master) atest CtsAppOpsTestCases:android.app.appops.cts.ForegroundModeTest Change-Id: I99720a372db6e79eaba30e4563c09e009cffe86f Merged-In: Id974769a4e9d89c01890b7557dd93f8444a3908f (cherry picked from commit ab9be4fdb63bf30831fd2e05be1315e6c7f067ae) --- .../android/server/appop/AppOpsService.java | 35 +++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index f0fac67f3494e..4e4fff969c7b4 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -35,6 +35,8 @@ import static android.app.AppOpsManager.modeToName; import static android.app.AppOpsManager.opToName; import static android.app.AppOpsManager.resolveFirstUnrestrictedUidState; +import static java.lang.Long.max; + import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; @@ -929,6 +931,19 @@ public class AppOpsService extends IAppOpsService.Stub { } } + /** + * Update the pending state for the uid + * + * @param currentTime The current elapsed real time + * @param uid The uid that has a pending state + */ + private void updatePendingState(long currentTime, int uid) { + synchronized (this) { + mLastRealtime = max(currentTime, mLastRealtime); + updatePendingStateIfNeededLocked(mUidStates.get(uid)); + } + } + public void updateUidProcState(int uid, int procState) { synchronized (this) { final UidState uidState = getUidStateLocked(uid, true); @@ -954,7 +969,12 @@ public class AppOpsService extends IAppOpsService.Stub { } else { settleTime = mConstants.BG_STATE_SETTLE_TIME; } - uidState.pendingStateCommitTime = SystemClock.elapsedRealtime() + settleTime; + final long commitTime = SystemClock.elapsedRealtime() + settleTime; + uidState.pendingStateCommitTime = commitTime; + + mHandler.sendMessageDelayed( + PooledLambda.obtainMessage(AppOpsService::updatePendingState, this, + commitTime + 1, uid), settleTime + 1); } if (uidState.startNesting != 0) { // There is some actively running operation... need to find it @@ -2442,6 +2462,18 @@ public class AppOpsService extends IAppOpsService.Stub { uidState = new UidState(uid); mUidStates.put(uid, uidState); } else { + updatePendingStateIfNeededLocked(uidState); + } + return uidState; + } + + /** + * Check if the pending state should be updated and do so if needed + * + * @param uidState The uidState that might have a pending state + */ + private void updatePendingStateIfNeededLocked(@NonNull UidState uidState) { + if (uidState != null) { if (uidState.pendingStateCommitTime != 0) { if (uidState.pendingStateCommitTime < mLastRealtime) { commitUidPendingStateLocked(uidState); @@ -2453,7 +2485,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } } - return uidState; } private void commitUidPendingStateLocked(UidState uidState) {