From 494b4ab56ffc60bb75ea3966bd3bf6e633a5cf7c Mon Sep 17 00:00:00 2001 From: "Philip P. Moltmann" Date: Fri, 31 Jan 2020 09:33:20 -0800 Subject: Correctly update in-progress events when switching uidStates A in-progress event might have been started multiple times. So to remove the event and then re-add it we have to temporarily reduce the number of unfinished started (== the nesting count) to 1 so that finish() actually removes the event. Test: atest android.app.appops.cts.AppOpEventCollectionTest#switchUidStateWhileOpsAreRunning Fixes: 148527247 Change-Id: I40afd83946be202be048c69611f62974a762bdc6 --- .../java/com/android/server/appop/AppOpsService.java | 17 +++++++++++++++-- 1 file changed, 15 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 1d714a2c99c7..38afcf51d0a9 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -847,7 +847,12 @@ public class AppOpsService extends IAppOpsService.Stub { */ public void started(@NonNull IBinder clientId, @AppOpsManager.UidState int uidState) throws RemoteException { - if (!parent.isRunning()) { + started(clientId, uidState, true); + } + + private void started(@NonNull IBinder clientId, @AppOpsManager.UidState int uidState, + boolean triggerCallbackIfNeeded) throws RemoteException { + if (triggerCallbackIfNeeded && !parent.isRunning()) { scheduleOpActiveChangedIfNeededLocked(parent.op, parent.uid, parent.packageName, true); } @@ -966,8 +971,16 @@ public class AppOpsService extends IAppOpsService.Stub { if (event.getUidState() != newState) { try { + // Remove all but one unfinished start count and then call finished() to + // remove start event object + int numPreviousUnfinishedStarts = event.numUnfinishedStarts; + event.numUnfinishedStarts = 1; finished(event.getClientId(), false); - started(event.getClientId(), newState); + + // Call started() to add a new start event object and then add the + // previously removed unfinished start counts back + started(event.getClientId(), newState, false); + event.numUnfinishedStarts += numPreviousUnfinishedStarts - 1; } catch (RemoteException e) { if (DEBUG) Slog.e(TAG, "Cannot switch to new uidState " + newState); } -- cgit v1.2.3-59-g8ed1b