From 11b706c77b0ac2a98aed438f67a05b3a968a5ca1 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Wed, 28 Aug 2019 14:28:32 -0700 Subject: [PATCH] Copy appop modes on write to avoid locked IO Test: presubmit Bug: 137528177 Change-Id: I229b361f4950f2184f56f4cd60d45f495fa832f7 --- .../android/server/appop/AppOpsService.java | 51 +++++++++++++------ 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 6d6a148c105d0..cc8e3f097450f 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -2973,28 +2973,49 @@ public class AppOpsService extends IAppOpsService.Stub { out.startTag(null, "app-ops"); out.attribute(null, "v", String.valueOf(CURRENT_VERSION)); + SparseArray uidStatesClone; synchronized (this) { + uidStatesClone = new SparseArray<>(mUidStates.size()); + final int uidStateCount = mUidStates.size(); - for (int i = 0; i < uidStateCount; i++) { - UidState uidState = mUidStates.valueAt(i); - if (uidState.opModes != null && uidState.opModes.size() > 0) { - out.startTag(null, "uid"); - out.attribute(null, "n", Integer.toString(uidState.uid)); - SparseIntArray uidOpModes = uidState.opModes; - final int opCount = uidOpModes.size(); - for (int j = 0; j < opCount; j++) { - final int op = uidOpModes.keyAt(j); - final int mode = uidOpModes.valueAt(j); - out.startTag(null, "op"); - out.attribute(null, "n", Integer.toString(op)); - out.attribute(null, "m", Integer.toString(mode)); - out.endTag(null, "op"); + for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) { + UidState uidState = mUidStates.valueAt(uidStateNum); + int uid = mUidStates.keyAt(uidStateNum); + + SparseIntArray opModes = uidState.opModes; + if (opModes != null && opModes.size() > 0) { + uidStatesClone.put(uid, new SparseIntArray(opModes.size())); + + final int opCount = opModes.size(); + for (int opCountNum = 0; opCountNum < opCount; opCountNum++) { + uidStatesClone.get(uid).put( + opModes.keyAt(opCountNum), + opModes.valueAt(opCountNum)); } - out.endTag(null, "uid"); } } } + final int uidStateCount = uidStatesClone.size(); + for (int uidStateNum = 0; uidStateNum < uidStateCount; uidStateNum++) { + SparseIntArray opModes = uidStatesClone.valueAt(uidStateNum); + if (opModes != null && opModes.size() > 0) { + out.startTag(null, "uid"); + out.attribute(null, "n", + Integer.toString(uidStatesClone.keyAt(uidStateNum))); + final int opCount = opModes.size(); + for (int opCountNum = 0; opCountNum < opCount; opCountNum++) { + final int op = opModes.keyAt(opCountNum); + final int mode = opModes.valueAt(opCountNum); + out.startTag(null, "op"); + out.attribute(null, "n", Integer.toString(op)); + out.attribute(null, "m", Integer.toString(mode)); + out.endTag(null, "op"); + } + out.endTag(null, "uid"); + } + } + if (allOps != null) { String lastPkg = null; for (int i=0; i