AppOpsService.java revision 8828d3a153e28fe631edcd5145e6cc706e0b34c8
1a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn/* 2a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * Copyright (C) 2012 The Android Open Source Project 3a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * 4a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 5a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * you may not use this file except in compliance with the License. 6a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * You may obtain a copy of the License at 7a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * 8a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 9a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * 10a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 11a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 12a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * See the License for the specific language governing permissions and 14a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn * limitations under the License. 15a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn */ 16a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 17a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpackage com.android.server; 18a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 19a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.io.File; 20a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.io.FileDescriptor; 2135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport java.io.FileInputStream; 2235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport java.io.FileNotFoundException; 2335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport java.io.FileOutputStream; 2435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport java.io.IOException; 25a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.io.PrintWriter; 2635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport java.util.ArrayList; 27a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.util.HashMap; 28c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport java.util.Iterator; 2935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport java.util.List; 30607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackbornimport java.util.Map; 31a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 32a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.app.AppOpsManager; 33a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.Context; 34a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager; 35a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException; 3635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.os.AsyncTask; 37a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Binder; 3835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.os.Handler; 39c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport android.os.IBinder; 40a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Process; 41c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport android.os.RemoteException; 42a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.ServiceManager; 43a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.UserHandle; 44e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackbornimport android.util.ArrayMap; 45a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.AtomicFile; 465e45ee6752528791deb66b83d76250685de15d47Dianne Hackbornimport android.util.Log; 47607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackbornimport android.util.Pair; 48a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.Slog; 49a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.SparseArray; 50a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.TimeUtils; 5135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.util.Xml; 52a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 53a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport com.android.internal.app.IAppOpsService; 54c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport com.android.internal.app.IAppOpsCallback; 5535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 5635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.XmlUtils; 5735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 5835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParser; 5935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 6035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlSerializer; 61a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 62a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpublic class AppOpsService extends IAppOpsService.Stub { 63a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn static final String TAG = "AppOps"; 6435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final boolean DEBUG = false; 6535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 6635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn // Write at most every 30 minutes. 6735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000; 68a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 69a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Context mContext; 70a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final AtomicFile mFile; 7135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Handler mHandler; 7235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 7335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean mWriteScheduled; 7435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Runnable mWriteRunner = new Runnable() { 7535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public void run() { 7635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (AppOpsService.this) { 7735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 7835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 7935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn @Override protected Void doInBackground(Void... params) { 8035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 8135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 8235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 8435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); 8535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 88a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 89a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final SparseArray<HashMap<String, Ops>> mUidOps 90a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn = new SparseArray<HashMap<String, Ops>>(); 91a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 92c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final static class Ops extends SparseArray<Op> { 93a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public final String packageName; 9435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public final int uid; 95a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 9635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public Ops(String _packageName, int _uid) { 97a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn packageName = _packageName; 9835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn uid = _uid; 99a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 100a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 101a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 102c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final static class Op { 103e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public final int uid; 104e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public final String packageName; 105a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public final int op; 1065e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public int mode; 107a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public int duration; 108a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public long time; 1095e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public long rejectTime; 11035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int nesting; 111a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 112e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public Op(int _uid, String _packageName, int _op) { 113e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn uid = _uid; 114e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn packageName = _packageName; 115a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn op = _op; 116f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun mode = AppOpsManager.opToDefaultMode(op); 117a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 118a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 119a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 120c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final SparseArray<ArrayList<Callback>> mOpModeWatchers 121c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn = new SparseArray<ArrayList<Callback>>(); 122e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayMap<String, ArrayList<Callback>> mPackageModeWatchers 123e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn = new ArrayMap<String, ArrayList<Callback>>(); 124e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayMap<IBinder, Callback> mModeWatchers 125e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn = new ArrayMap<IBinder, Callback>(); 126c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 127c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final class Callback implements DeathRecipient { 128c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final IAppOpsCallback mCallback; 129c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 130c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public Callback(IAppOpsCallback callback) { 131c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback = callback; 132c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 133c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().linkToDeath(this, 0); 134c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 135c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 136c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 137c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 138c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void unlinkToDeath() { 139c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().unlinkToDeath(this, 0); 140c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 141c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 142c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 143c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void binderDied() { 144c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn stopWatchingMode(mCallback); 145c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 146c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 147c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 148e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<IBinder, ClientState>(); 149e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 150e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public final class ClientState extends Binder implements DeathRecipient { 151e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final IBinder mAppToken; 152e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final int mPid; 153e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayList<Op> mStartedOps; 154e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 155e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public ClientState(IBinder appToken) { 156e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mAppToken = appToken; 157e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPid = Binder.getCallingPid(); 158e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (appToken instanceof Binder) { 159e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn // For local clients, there is no reason to track them. 160e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mStartedOps = null; 161e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } else { 162e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mStartedOps = new ArrayList<Op>(); 163e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn try { 164e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mAppToken.linkToDeath(this, 0); 165e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } catch (RemoteException e) { 166e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 167e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 168e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 169e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 170e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 171e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public String toString() { 172e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return "ClientState{" + 173e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn "mAppToken=" + mAppToken + 174e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ", " + (mStartedOps != null ? ("pid=" + mPid) : "local") + 175e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn '}'; 176e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 177e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 178e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 179e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void binderDied() { 180e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (AppOpsService.this) { 181e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mStartedOps.size()-1; i>=0; i--) { 182e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn finishOperationLocked(mStartedOps.get(i)); 183e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 184e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.remove(mAppToken); 185e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 186e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 187e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 188e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 18935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public AppOpsService(File storagePath) { 19035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile = new AtomicFile(storagePath); 19135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mHandler = new Handler(); 19235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readState(); 193a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 194f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun 195a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void publish(Context context) { 196a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext = context; 197a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder()); 198a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 199a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 200514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void systemReady() { 201514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 202514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn boolean changed = false; 203514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 204514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn HashMap<String, Ops> pkgs = mUidOps.valueAt(i); 205514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Iterator<Ops> it = pkgs.values().iterator(); 206514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn while (it.hasNext()) { 207514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Ops ops = it.next(); 208514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn int curUid; 209514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 210514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn curUid = mContext.getPackageManager().getPackageUid(ops.packageName, 211514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn UserHandle.getUserId(ops.uid)); 212514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } catch (NameNotFoundException e) { 213514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn curUid = -1; 214514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 215514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (curUid != ops.uid) { 216514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Slog.i(TAG, "Pruning old package " + ops.packageName 217514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn + "/" + ops.uid + ": new uid=" + curUid); 218514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn it.remove(); 219514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn changed = true; 220514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 221514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 222514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs.size() <= 0) { 223514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.removeAt(i); 224514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 225514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 226514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (changed) { 227514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn scheduleWriteLocked(); 228514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 229514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 230514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 231514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 232514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void packageRemoved(int uid, String packageName) { 233514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 234514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn HashMap<String, Ops> pkgs = mUidOps.get(uid); 235514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs != null) { 236514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs.remove(packageName) != null) { 237514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs.size() <= 0) { 238514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.remove(uid); 239514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 240514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn scheduleWriteLocked(); 241514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 242514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 243514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 244514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 245514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 246514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void uidRemoved(int uid) { 247514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 248514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (mUidOps.indexOfKey(uid) >= 0) { 249514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.remove(uid); 250514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn scheduleWriteLocked(); 251514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 252514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 253514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 254514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 255a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void shutdown() { 256a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Slog.w(TAG, "Writing app ops before shutdown..."); 25735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean doWrite = false; 25835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 25935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mWriteScheduled) { 26035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 26135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn doWrite = true; 26235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 26335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 26435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (doWrite) { 26535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 26635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 267a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 268a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 26972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) { 27072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = null; 27172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 27272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn resOps = new ArrayList<AppOpsManager.OpEntry>(); 27372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<pkgOps.size(); j++) { 27472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.valueAt(j); 2755e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 2765e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn curOp.rejectTime, curOp.duration)); 27772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 27872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } else { 27972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<ops.length; j++) { 28072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.get(ops[j]); 28172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (curOp != null) { 28272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 28372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn resOps = new ArrayList<AppOpsManager.OpEntry>(); 28472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 2855e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 2865e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn curOp.rejectTime, curOp.duration)); 28772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 28872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 28972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 29072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return resOps; 29172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 29272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 293a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 29435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 29535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 29635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 29735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = null; 298a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 29935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 30035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> packages = mUidOps.valueAt(i); 30135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (Ops pkgOps : packages.values()) { 30272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 30335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (resOps != null) { 30435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (res == null) { 30535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res = new ArrayList<AppOpsManager.PackageOps>(); 30635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 30735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 30835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.packageName, pkgOps.uid, resOps); 30935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res.add(resPackage); 31035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 31135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 312a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 313a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 31435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return res; 315a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 316a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 317a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 31872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, 31972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn int[] ops) { 32072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 32172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 32272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn synchronized (this) { 32372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops pkgOps = getOpsLocked(uid, packageName, false); 32472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (pkgOps == null) { 32572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 32672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 32772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 32872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 32972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 33072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 33172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); 33272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 33372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn pkgOps.packageName, pkgOps.uid, resOps); 33472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn res.add(resPackage); 33572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return res; 33672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 33772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 33872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 339607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn private void pruneOp(Op op, int uid, String packageName) { 340607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (op.time == 0 && op.rejectTime == 0) { 341607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Ops ops = getOpsLocked(uid, packageName, false); 342607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (ops != null) { 343607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn ops.remove(op.op); 344607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (ops.size() <= 0) { 345607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 346607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (pkgOps != null) { 347607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn pkgOps.remove(ops.packageName); 348607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (pkgOps.size() <= 0) { 349607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mUidOps.remove(uid); 350607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 351607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 352607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 353607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 354607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 355607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 356607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 35772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn @Override 3585e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public void setMode(int code, int uid, String packageName, int mode) { 359f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 360961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 361c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> repCbs = null; 362c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn code = AppOpsManager.opToSwitch(code); 3635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn synchronized (this) { 364c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 3655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op != null) { 3665e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.mode != mode) { 3675e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.mode = mode; 368c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(code); 369c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 370c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 371c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs = new ArrayList<Callback>(); 372c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 373c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 374c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 375c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = mPackageModeWatchers.get(packageName); 376c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 377c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 378c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs = new ArrayList<Callback>(); 379c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 380c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 381c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 382f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun if (mode == AppOpsManager.opToDefaultMode(op.op)) { 383514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // If going into the default mode, prune this op 384514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // if there is nothing else interesting in it. 385607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn pruneOp(op, uid, packageName); 386514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 3875e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteNowLocked(); 3885e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3895e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 391c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs != null) { 392c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn for (int i=0; i<repCbs.size(); i++) { 393c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 394c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.get(i).mCallback.opChanged(code, packageName); 395c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 396c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 397c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 398c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 399c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 400c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 401607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn private static HashMap<Callback, ArrayList<Pair<String, Integer>>> addCallbacks( 402607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks, 403607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn String packageName, int op, ArrayList<Callback> cbs) { 404607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (cbs == null) { 405607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn return callbacks; 406607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 407607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (callbacks == null) { 408607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks = new HashMap<Callback, ArrayList<Pair<String, Integer>>>(); 409607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 410607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn for (int i=0; i<cbs.size(); i++) { 411607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Callback cb = cbs.get(i); 412607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn ArrayList<Pair<String, Integer>> reports = callbacks.get(cb); 413607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (reports == null) { 414607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn reports = new ArrayList<Pair<String, Integer>>(); 415607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks.put(cb, reports); 416607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 417607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn reports.add(new Pair<String, Integer>(packageName, op)); 418607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 419607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn return callbacks; 420607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 421607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 422607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn @Override 423607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn public void resetAllModes() { 424607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, 425607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 426607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn HashMap<Callback, ArrayList<Pair<String, Integer>>> callbacks = null; 427607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn synchronized (this) { 428607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn boolean changed = false; 4297f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn for (int i=mUidOps.size()-1; i>=0; i--) { 430607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn HashMap<String, Ops> packages = mUidOps.valueAt(i); 4317f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn Iterator<Map.Entry<String, Ops>> it = packages.entrySet().iterator(); 4327f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn while (it.hasNext()) { 4337f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn Map.Entry<String, Ops> ent = it.next(); 434607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn String packageName = ent.getKey(); 435607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Ops pkgOps = ent.getValue(); 4367f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn for (int j=pkgOps.size()-1; j>=0; j--) { 437607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Op curOp = pkgOps.valueAt(j); 4388828d3a153e28fe631edcd5145e6cc706e0b34c8Dianne Hackborn if (AppOpsManager.opAllowsReset(curOp.op) 4398828d3a153e28fe631edcd5145e6cc706e0b34c8Dianne Hackborn && curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) { 440f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun curOp.mode = AppOpsManager.opToDefaultMode(curOp.op); 441607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn changed = true; 442607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks = addCallbacks(callbacks, packageName, curOp.op, 443607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mOpModeWatchers.get(curOp.op)); 444607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks = addCallbacks(callbacks, packageName, curOp.op, 445607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mPackageModeWatchers.get(packageName)); 4467f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (curOp.time == 0 && curOp.rejectTime == 0) { 4477f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn pkgOps.removeAt(j); 4487f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 449607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 450607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 4517f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (pkgOps.size() == 0) { 4527f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn it.remove(); 4537f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 4547f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 4557f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (packages.size() == 0) { 4567f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn mUidOps.removeAt(i); 457607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 458607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 459607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (changed) { 460607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn scheduleWriteNowLocked(); 461607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 462607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 463607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (callbacks != null) { 464607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn for (Map.Entry<Callback, ArrayList<Pair<String, Integer>>> ent : callbacks.entrySet()) { 465607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Callback cb = ent.getKey(); 466607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn ArrayList<Pair<String, Integer>> reports = ent.getValue(); 467607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn for (int i=0; i<reports.size(); i++) { 468607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Pair<String, Integer> rep = reports.get(i); 469607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn try { 470607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn cb.mCallback.opChanged(rep.second, rep.first); 471607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } catch (RemoteException e) { 472607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 473607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 474607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 475607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 476607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 477607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 478c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 479c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { 480c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 481c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn op = AppOpsManager.opToSwitch(op); 482c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.get(callback.asBinder()); 483c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb == null) { 484c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb = new Callback(callback); 485c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mModeWatchers.put(callback.asBinder(), cb); 486c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 487c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (op != AppOpsManager.OP_NONE) { 488c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(op); 489c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 490c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 491c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.put(op, cbs); 492c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 493c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 494c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 495c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (packageName != null) { 496c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.get(packageName); 497c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 498c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 499c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mPackageModeWatchers.put(packageName, cbs); 500c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 501c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 502c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 503c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 504c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 505c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 506c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 507c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void stopWatchingMode(IAppOpsCallback callback) { 508c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 509c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.remove(callback.asBinder()); 510c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb != null) { 511c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb.unlinkToDeath(); 512e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mOpModeWatchers.size()-1; i>=0; i--) { 513c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i); 514c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.remove(cb); 515c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs.size() <= 0) { 516c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.removeAt(i); 517c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 518c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 519e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mPackageModeWatchers.size()-1; i>=0; i--) { 520e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.valueAt(i); 521e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cbs.remove(cb); 522e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cbs.size() <= 0) { 523e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPackageModeWatchers.removeAt(i); 524c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 525c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 526c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 527c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 5285e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 5295e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 5305e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn @Override 531e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public IBinder getToken(IBinder clientToken) { 532e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (this) { 533e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.get(clientToken); 534e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs == null) { 535e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cs = new ClientState(clientToken); 536e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.put(clientToken, cs); 537e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 538e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return cs; 539e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 540e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 541e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 542e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 54335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int checkOperation(int code, int uid, String packageName) { 544f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 545961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 546a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 547f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false); 548a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 549f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun return AppOpsManager.opToDefaultMode(code); 550a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 5515e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return op.mode; 552a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 553a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 554a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 555a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 556911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey public int checkPackage(int uid, String packageName) { 557911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey synchronized (this) { 558911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey if (getOpsLocked(uid, packageName, true) != null) { 559911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ALLOWED; 560911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } else { 561911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 562911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 563911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 564911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 565911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey 566911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey @Override 56735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int noteOperation(int code, int uid, String packageName) { 568f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 569961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 570a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 571f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 572f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 5735e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid 5745e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 575911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 576a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 577f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 57835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.duration == -1) { 57935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName 580a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + " code " + code + " time=" + op.time + " duration=" + op.duration); 581a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 58235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = 0; 583f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 584f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 585f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 586f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " 587f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 5885e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 589f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 5905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 5915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid 5925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 5935e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = System.currentTimeMillis(); 594514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn op.rejectTime = 0; 5955e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 596a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 597a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 598a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 599a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 600e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public int startOperation(IBinder token, int code, int uid, String packageName) { 601f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 602961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 603e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 604a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 605f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 606f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 6075e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid 6085e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 609911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 610a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 611f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 612f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 613f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 614f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 615f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " 616f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 6175e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 618f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 6195e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6205e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid 6215e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 62235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.nesting == 0) { 62335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.time = System.currentTimeMillis(); 624514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn op.rejectTime = 0; 62535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = -1; 626a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 62735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.nesting++; 628e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 629e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn client.mStartedOps.add(op); 630e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 6315e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 632a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 633a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 634a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 635a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 636e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void finishOperation(IBinder token, int code, int uid, String packageName) { 637f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 638961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 639e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 640a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 64135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 642a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 643a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 644a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 645e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 646e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (!client.mStartedOps.remove(op)) { 647e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn throw new IllegalStateException("Operation not started: uid" + op.uid 648e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + " pkg=" + op.packageName + " op=" + op.op); 64935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 650e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 651e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn finishOperationLocked(op); 652e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 653e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 654e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 655e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn void finishOperationLocked(Op op) { 656e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (op.nesting <= 1) { 657e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (op.nesting == 1) { 658e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.duration = (int)(System.currentTimeMillis() - op.time); 659e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.time += op.duration; 66035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 661e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg " 662e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + op.packageName + " code " + op.op + " time=" + op.time 663e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + " duration=" + op.duration + " nesting=" + op.nesting); 664a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 665e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.nesting = 0; 666e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } else { 667e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.nesting--; 668a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 669a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 670a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 671f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private void verifyIncomingUid(int uid) { 672a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (uid == Binder.getCallingUid()) { 673f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 674a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 675a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (Binder.getCallingPid() == Process.myPid()) { 676f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 677a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 678a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, 679a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 680a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 681a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 682961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn private void verifyIncomingOp(int op) { 683961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn if (op >= 0 && op < AppOpsManager._NUM_OP) { 684961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn return; 685961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 686961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn throw new IllegalArgumentException("Bad operation #" + op); 687961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 688961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn 68972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Ops getOpsLocked(int uid, String packageName, boolean edit) { 690a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 691a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (pkgOps == null) { 69235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 69335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 69435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 695a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps = new HashMap<String, Ops>(); 696a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mUidOps.put(uid, pkgOps); 697a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 698514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid == 0) { 699514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn packageName = "root"; 700514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } else if (uid == Process.SHELL_UID) { 701514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn packageName = "com.android.shell"; 702514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 703a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Ops ops = pkgOps.get(packageName); 704a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (ops == null) { 70535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 70635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 70735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 708a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // This is the first time we have seen this package name under this uid, 709a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // so let's make sure it is valid. 710514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid != 0) { 711514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 712a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn try { 713514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn int pkgUid = -1; 714514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 715514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn pkgUid = mContext.getPackageManager().getPackageUid(packageName, 716514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn UserHandle.getUserId(uid)); 717514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } catch (NameNotFoundException e) { 718713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn if ("media".equals(packageName)) { 719713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn pkgUid = Process.MEDIA_UID; 720713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn } 721514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 722514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgUid != uid) { 723514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // Oops! The package name is not valid for the uid they are calling 724514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // under. Abort. 725514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Slog.w(TAG, "Bad call: specified package " + packageName 726514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn + " under uid " + uid + " but it is really " + pkgUid); 727514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn return null; 728514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 729514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } finally { 730514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Binder.restoreCallingIdentity(ident); 731002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } 732a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 73335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(packageName, uid); 734a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps.put(packageName, ops); 735a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 73672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return ops; 73772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 73872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 7395e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteLocked() { 7405e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 7415e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 7425e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.postDelayed(mWriteRunner, WRITE_DELAY); 7435e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7445e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7455e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 7465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteNowLocked() { 7475e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 7485e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 7495e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7505e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.removeCallbacks(mWriteRunner); 7515e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.post(mWriteRunner); 7525e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7535e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 75472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Op getOpLocked(int code, int uid, String packageName, boolean edit) { 75572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, edit); 75672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 75772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 75872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 759f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return getOpLocked(ops, code, edit); 760f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn } 761f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn 762f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private Op getOpLocked(Ops ops, int code, boolean edit) { 763a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.get(code); 764a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 76535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 76635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 76735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 768e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op = new Op(ops.uid, ops.packageName, code); 769a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ops.put(code, op); 770a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 7715e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (edit) { 7725e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteLocked(); 77335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 774a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return op; 775a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 776a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 77735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readState() { 77835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 77935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 78035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileInputStream stream; 78135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 78235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.openRead(); 78335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (FileNotFoundException e) { 78435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty"); 78535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 78635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 78735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean success = false; 78835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 78935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 79035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn parser.setInput(stream, null); 79135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 79235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.START_TAG 79335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && type != XmlPullParser.END_DOCUMENT) { 79435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ; 79535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 79635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 79735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type != XmlPullParser.START_TAG) { 79835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn throw new IllegalStateException("no start tag found"); 79935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 80035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 80135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 80235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 80335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 80435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 80535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 80635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 80735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 80835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 80935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("pkg")) { 8100997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke readPackage(parser); 81135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 81235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <app-ops>: " 81335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 81435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 81535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn success = true; 81835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IllegalStateException e) { 81935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NullPointerException e) { 82135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NumberFormatException e) { 82335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (XmlPullParserException e) { 82535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 82735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IndexOutOfBoundsException e) { 82935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 83035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } finally { 83135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!success) { 83235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.clear(); 83335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 83535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream.close(); 83635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 83735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 84035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 84135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 84235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 8430997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke void readPackage(XmlPullParser parser) throws NumberFormatException, 84435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 84535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String pkgName = parser.getAttributeValue(null, "n"); 84635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 84735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 84835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 84935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 85035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 85135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 85235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 85335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 85435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 85535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("uid")) { 8560997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke readUid(parser, pkgName); 85735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 85835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 85935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 86035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 86135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 86235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 86335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 86435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 8650997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException, 86635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 86735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); 86835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 86935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 87035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 87135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 87235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 87335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 87435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 87535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 87635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 87735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("op")) { 878e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n"))); 8795e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String mode = parser.getAttributeValue(null, "m"); 8805e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (mode != null) { 8810997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke op.mode = Integer.parseInt(mode); 8825e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8835e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String time = parser.getAttributeValue(null, "t"); 8845e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 8855e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = Long.parseLong(time); 8865e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8875e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = parser.getAttributeValue(null, "r"); 8885e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 8895e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = Long.parseLong(time); 8905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String dur = parser.getAttributeValue(null, "d"); 8925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != null) { 8935e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.duration = Integer.parseInt(dur); 8945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 89535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 89635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (pkgOps == null) { 89735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps = new HashMap<String, Ops>(); 89835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.put(uid, pkgOps); 89935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 90035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Ops ops = pkgOps.get(pkgName); 90135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (ops == null) { 90235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(pkgName, uid); 90335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.put(pkgName, ops); 90435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 90535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops.put(op.op, op); 90635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 90735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 90835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 90935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 91035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 91135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 91235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 91335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 91435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void writeState() { 91535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 91635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); 91735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 91835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileOutputStream stream; 91935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 92035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.startWrite(); 92135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 92235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state: " + e); 92335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 92435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 92535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 92635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 92735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 92835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.setOutput(stream, "utf-8"); 92935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startDocument(null, true); 93035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "app-ops"); 93135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 93235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allOps != null) { 93335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String lastPkg = null; 93435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<allOps.size(); i++) { 93535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps pkg = allOps.get(i); 93635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!pkg.getPackageName().equals(lastPkg)) { 93735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 93835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 93935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 94035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn lastPkg = pkg.getPackageName(); 94135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "pkg"); 94235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", lastPkg); 94335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 94435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "uid"); 94535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(pkg.getUid())); 94635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.OpEntry> ops = pkg.getOps(); 94735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int j=0; j<ops.size(); j++) { 94835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.OpEntry op = ops.get(j); 94935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "op"); 95035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(op.getOp())); 951f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) { 9525e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "m", Integer.toString(op.getMode())); 9535e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9545e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn long time = op.getTime(); 9555e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 9565e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "t", Long.toString(time)); 9575e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9585e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = op.getRejectTime(); 9595e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 9605e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "r", Long.toString(time)); 9615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int dur = op.getDuration(); 9635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != 0) { 9645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "d", Integer.toString(dur)); 9655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 96635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "op"); 96735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 96835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "uid"); 96935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 97035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 97135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 97235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 97335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 97435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 97535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "app-ops"); 97635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endDocument(); 97735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.finishWrite(stream); 97835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 97935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state, restoring backup.", e); 98035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.failWrite(stream); 98135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 98235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 98335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 98435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 985a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 986a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 987a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 988a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn != PackageManager.PERMISSION_GRANTED) { 989a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Permission Denial: can't dump ApOps service from from pid=" 990a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + Binder.getCallingPid() 991a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + ", uid=" + Binder.getCallingUid()); 992a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 993a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 994a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 995a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 996a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Current AppOps Service state:"); 9975e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn final long now = System.currentTimeMillis(); 998e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn boolean needSep = false; 999e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mOpModeWatchers.size() > 0) { 1000e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1001e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Op mode watchers:"); 1002e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mOpModeWatchers.size(); i++) { 1003e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Op "); pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i))); 1004e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 1005e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> callbacks = mOpModeWatchers.valueAt(i); 1006e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 1007e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 1008e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(callbacks.get(j)); 1009e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1010e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1011e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1012e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mPackageModeWatchers.size() > 0) { 1013e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1014e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Package mode watchers:"); 1015e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mPackageModeWatchers.size(); i++) { 1016e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Pkg "); pw.print(mPackageModeWatchers.keyAt(i)); 1017e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 1018e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> callbacks = mPackageModeWatchers.valueAt(i); 1019e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 1020e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 1021e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(callbacks.get(j)); 1022e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1023e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1024e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1025e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mModeWatchers.size() > 0) { 1026e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1027e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" All mode watchers:"); 1028e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mModeWatchers.size(); i++) { 1029e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print(mModeWatchers.keyAt(i)); 1030e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" -> "); pw.println(mModeWatchers.valueAt(i)); 1031e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1032e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1033e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mClients.size() > 0) { 1034e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1035e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Clients:"); 1036e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mClients.size(); i++) { 1037e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print(mClients.keyAt(i)); pw.println(":"); 1038e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.valueAt(i); 1039e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.println(cs); 1040e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) { 1041e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Started ops:"); 1042e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<cs.mStartedOps.size(); j++) { 1043e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = cs.mStartedOps.get(j); 1044e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print("uid="); pw.print(op.uid); 1045e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" pkg="); pw.print(op.packageName); 1046e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" op="); pw.println(AppOpsManager.opToName(op.op)); 1047e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1048e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1049e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1050e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1051e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (needSep) { 1052e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(); 1053e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1054a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 1055a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":"); 1056a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.valueAt(i); 1057a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (Ops ops : pkgOps.values()) { 1058a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Package "); pw.print(ops.packageName); pw.println(":"); 1059a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int j=0; j<ops.size(); j++) { 1060a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.valueAt(j); 10615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" "); pw.print(AppOpsManager.opToName(op.op)); 10625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(": mode="); pw.print(op.mode); 10635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.time != 0) { 10645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; time="); TimeUtils.formatDuration(now-op.time, pw); 10655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 10665e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 10675e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.rejectTime != 0) { 10685e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; rejectTime="); TimeUtils.formatDuration(now-op.rejectTime, pw); 10695e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 10705e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 1071a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op.duration == -1) { 1072a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(" (running)"); 1073a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } else { 1074a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print("; duration="); 1075a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn TimeUtils.formatDuration(op.duration, pw); 1076a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(); 1077a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1078a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1079a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1080a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1081a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1082a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1083a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn} 1084