AppOpsService.java revision f5d831915dd11e77cdcf5669228c55fe17a21c5e
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); 438f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun if (curOp.mode != AppOpsManager.opToDefaultMode(curOp.op)) { 439f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun curOp.mode = AppOpsManager.opToDefaultMode(curOp.op); 440607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn changed = true; 441607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks = addCallbacks(callbacks, packageName, curOp.op, 442607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mOpModeWatchers.get(curOp.op)); 443607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn callbacks = addCallbacks(callbacks, packageName, curOp.op, 444607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn mPackageModeWatchers.get(packageName)); 4457f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (curOp.time == 0 && curOp.rejectTime == 0) { 4467f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn pkgOps.removeAt(j); 4477f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 448607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 449607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 4507f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (pkgOps.size() == 0) { 4517f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn it.remove(); 4527f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 4537f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn } 4547f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn if (packages.size() == 0) { 4557f09ec39b6fd7f24751f814649f12ea686cb28d4Dianne Hackborn mUidOps.removeAt(i); 456607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 457607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 458607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (changed) { 459607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn scheduleWriteNowLocked(); 460607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 461607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 462607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn if (callbacks != null) { 463607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn for (Map.Entry<Callback, ArrayList<Pair<String, Integer>>> ent : callbacks.entrySet()) { 464607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Callback cb = ent.getKey(); 465607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn ArrayList<Pair<String, Integer>> reports = ent.getValue(); 466607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn for (int i=0; i<reports.size(); i++) { 467607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn Pair<String, Integer> rep = reports.get(i); 468607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn try { 469607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn cb.mCallback.opChanged(rep.second, rep.first); 470607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } catch (RemoteException e) { 471607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 472607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 473607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 474607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 475607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn } 476607b414d0444067e166fa54d8ea37563f2715ea3Dianne Hackborn 477c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 478c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { 479c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 480c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn op = AppOpsManager.opToSwitch(op); 481c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.get(callback.asBinder()); 482c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb == null) { 483c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb = new Callback(callback); 484c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mModeWatchers.put(callback.asBinder(), cb); 485c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 486c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (op != AppOpsManager.OP_NONE) { 487c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(op); 488c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 489c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 490c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.put(op, cbs); 491c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 492c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 493c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 494c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (packageName != null) { 495c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.get(packageName); 496c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 497c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 498c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mPackageModeWatchers.put(packageName, cbs); 499c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 500c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 501c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 502c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 503c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 504c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 505c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 506c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void stopWatchingMode(IAppOpsCallback callback) { 507c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 508c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.remove(callback.asBinder()); 509c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb != null) { 510c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb.unlinkToDeath(); 511e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mOpModeWatchers.size()-1; i>=0; i--) { 512c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i); 513c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.remove(cb); 514c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs.size() <= 0) { 515c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.removeAt(i); 516c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 517c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 518e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mPackageModeWatchers.size()-1; i>=0; i--) { 519e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.valueAt(i); 520e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cbs.remove(cb); 521e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cbs.size() <= 0) { 522e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPackageModeWatchers.removeAt(i); 523c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 524c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 525c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 526c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 5275e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 5285e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 5295e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn @Override 530e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public IBinder getToken(IBinder clientToken) { 531e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (this) { 532e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.get(clientToken); 533e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs == null) { 534e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cs = new ClientState(clientToken); 535e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.put(clientToken, cs); 536e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 537e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return cs; 538e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 539e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 540e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 541e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 54235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int checkOperation(int code, int uid, String packageName) { 543f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 544961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 545a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 546f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false); 547a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 548f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun return AppOpsManager.opToDefaultMode(code); 549a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 5505e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return op.mode; 551a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 552a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 553a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 554a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 555911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey public int checkPackage(int uid, String packageName) { 556911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey synchronized (this) { 557911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey if (getOpsLocked(uid, packageName, true) != null) { 558911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ALLOWED; 559911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } else { 560911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 561911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 562911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 563911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey } 564911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey 565911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey @Override 56635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int noteOperation(int code, int uid, String packageName) { 567f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 568961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 569a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 570f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 571f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 5725e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid 5735e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 574911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 575a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 576f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 57735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.duration == -1) { 57835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName 579a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + " code " + code + " time=" + op.time + " duration=" + op.duration); 580a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 58135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = 0; 582f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 583f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 584f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 585f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " 586f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 5875e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 588f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 5895e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 5905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid 5915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 5925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = System.currentTimeMillis(); 593514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn op.rejectTime = 0; 5945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 595a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 596a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 597a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 598a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 599e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public int startOperation(IBinder token, int code, int uid, String packageName) { 600f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 601961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 602e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 603a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 604f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 605f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 6065e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid 6075e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 608911d7f411f36f2279aae44c89ff1d33a29140046Jeff Sharkey return AppOpsManager.MODE_ERRORED; 609a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 610f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 611f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 612f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 613f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 614f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " 615f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 6165e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 617f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 6185e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6195e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid 6205e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 62135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.nesting == 0) { 62235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.time = System.currentTimeMillis(); 623514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn op.rejectTime = 0; 62435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = -1; 625a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 62635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.nesting++; 627e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 628e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn client.mStartedOps.add(op); 629e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 6305e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 631a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 632a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 633a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 634a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 635e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void finishOperation(IBinder token, int code, int uid, String packageName) { 636f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 637961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 638e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 639a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 64035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 641a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 642a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 643a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 644e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 645e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (!client.mStartedOps.remove(op)) { 646e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn throw new IllegalStateException("Operation not started: uid" + op.uid 647e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + " pkg=" + op.packageName + " op=" + op.op); 64835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 649e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 650e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn finishOperationLocked(op); 651e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 652e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 653e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 654e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn void finishOperationLocked(Op op) { 655e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (op.nesting <= 1) { 656e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (op.nesting == 1) { 657e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.duration = (int)(System.currentTimeMillis() - op.time); 658e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.time += op.duration; 65935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 660e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg " 661e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + op.packageName + " code " + op.op + " time=" + op.time 662e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + " duration=" + op.duration + " nesting=" + op.nesting); 663a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 664e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.nesting = 0; 665e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } else { 666e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.nesting--; 667a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 668a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 669a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 670f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private void verifyIncomingUid(int uid) { 671a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (uid == Binder.getCallingUid()) { 672f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 673a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 674a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (Binder.getCallingPid() == Process.myPid()) { 675f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 676a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 677a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, 678a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 679a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 680a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 681961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn private void verifyIncomingOp(int op) { 682961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn if (op >= 0 && op < AppOpsManager._NUM_OP) { 683961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn return; 684961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 685961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn throw new IllegalArgumentException("Bad operation #" + op); 686961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 687961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn 68872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Ops getOpsLocked(int uid, String packageName, boolean edit) { 689a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 690a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (pkgOps == null) { 69135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 69235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 69335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 694a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps = new HashMap<String, Ops>(); 695a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mUidOps.put(uid, pkgOps); 696a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 697514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid == 0) { 698514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn packageName = "root"; 699514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } else if (uid == Process.SHELL_UID) { 700514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn packageName = "com.android.shell"; 701514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 702a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Ops ops = pkgOps.get(packageName); 703a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (ops == null) { 70435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 70535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 70635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 707a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // This is the first time we have seen this package name under this uid, 708a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // so let's make sure it is valid. 709514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid != 0) { 710514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 711a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn try { 712514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn int pkgUid = -1; 713514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 714514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn pkgUid = mContext.getPackageManager().getPackageUid(packageName, 715514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn UserHandle.getUserId(uid)); 716514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } catch (NameNotFoundException e) { 717713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn if ("media".equals(packageName)) { 718713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn pkgUid = Process.MEDIA_UID; 719713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn } 720514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 721514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgUid != uid) { 722514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // Oops! The package name is not valid for the uid they are calling 723514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // under. Abort. 724514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Slog.w(TAG, "Bad call: specified package " + packageName 725514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn + " under uid " + uid + " but it is really " + pkgUid); 726514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn return null; 727514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 728514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } finally { 729514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Binder.restoreCallingIdentity(ident); 730002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } 731a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 73235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(packageName, uid); 733a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps.put(packageName, ops); 734a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 73572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return ops; 73672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 73772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 7385e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteLocked() { 7395e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 7405e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 7415e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.postDelayed(mWriteRunner, WRITE_DELAY); 7425e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7435e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7445e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 7455e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteNowLocked() { 7465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 7475e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 7485e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7495e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.removeCallbacks(mWriteRunner); 7505e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.post(mWriteRunner); 7515e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7525e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 75372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Op getOpLocked(int code, int uid, String packageName, boolean edit) { 75472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, edit); 75572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 75672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 75772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 758f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return getOpLocked(ops, code, edit); 759f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn } 760f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn 761f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private Op getOpLocked(Ops ops, int code, boolean edit) { 762a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.get(code); 763a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 76435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 76535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 76635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 767e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op = new Op(ops.uid, ops.packageName, code); 768a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ops.put(code, op); 769a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 7705e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (edit) { 7715e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteLocked(); 77235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 773a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return op; 774a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 775a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 77635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readState() { 77735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 77835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 77935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileInputStream stream; 78035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 78135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.openRead(); 78235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (FileNotFoundException e) { 78335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty"); 78435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 78535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 78635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean success = false; 78735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 78835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 78935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn parser.setInput(stream, null); 79035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 79135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.START_TAG 79235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && type != XmlPullParser.END_DOCUMENT) { 79335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ; 79435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 79535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 79635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type != XmlPullParser.START_TAG) { 79735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn throw new IllegalStateException("no start tag found"); 79835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 79935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 80035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 80135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 80235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 80335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 80435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 80535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 80635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 80735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 80835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("pkg")) { 8090997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke readPackage(parser); 81035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 81135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <app-ops>: " 81235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 81335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 81435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn success = true; 81735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IllegalStateException e) { 81835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 81935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NullPointerException e) { 82035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NumberFormatException e) { 82235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (XmlPullParserException e) { 82435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 82635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IndexOutOfBoundsException e) { 82835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 82935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } finally { 83035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!success) { 83135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.clear(); 83235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 83435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream.close(); 83535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 83635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 84035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 84135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 8420997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke void readPackage(XmlPullParser parser) throws NumberFormatException, 84335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 84435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String pkgName = parser.getAttributeValue(null, "n"); 84535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 84635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 84735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 84835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 84935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 85035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 85135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 85235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 85335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 85435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("uid")) { 8550997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke readUid(parser, pkgName); 85635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 85735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 85835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 85935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 86035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 86135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 86235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 86335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 8640997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException, 86535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 86635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); 86735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 86835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 86935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 87035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 87135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 87235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 87335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 87435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 87535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 87635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("op")) { 877e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n"))); 8785e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String mode = parser.getAttributeValue(null, "m"); 8795e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (mode != null) { 8800997c5bd79d11e6ecb11970bfd9b9b911001ac0aDave Burke op.mode = Integer.parseInt(mode); 8815e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8825e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String time = parser.getAttributeValue(null, "t"); 8835e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 8845e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = Long.parseLong(time); 8855e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8865e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = parser.getAttributeValue(null, "r"); 8875e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 8885e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = Long.parseLong(time); 8895e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String dur = parser.getAttributeValue(null, "d"); 8915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != null) { 8925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.duration = Integer.parseInt(dur); 8935e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 89435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 89535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (pkgOps == null) { 89635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps = new HashMap<String, Ops>(); 89735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.put(uid, pkgOps); 89835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 89935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Ops ops = pkgOps.get(pkgName); 90035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (ops == null) { 90135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(pkgName, uid); 90235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.put(pkgName, ops); 90335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 90435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops.put(op.op, op); 90535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 90635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 90735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 90835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 90935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 91035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 91135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 91235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 91335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void writeState() { 91435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 91535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); 91635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 91735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileOutputStream stream; 91835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 91935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.startWrite(); 92035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 92135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state: " + e); 92235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 92335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 92435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 92535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 92635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 92735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.setOutput(stream, "utf-8"); 92835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startDocument(null, true); 92935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "app-ops"); 93035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 93135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allOps != null) { 93235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String lastPkg = null; 93335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<allOps.size(); i++) { 93435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps pkg = allOps.get(i); 93535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!pkg.getPackageName().equals(lastPkg)) { 93635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 93735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 93835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 93935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn lastPkg = pkg.getPackageName(); 94035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "pkg"); 94135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", lastPkg); 94235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 94335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "uid"); 94435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(pkg.getUid())); 94535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.OpEntry> ops = pkg.getOps(); 94635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int j=0; j<ops.size(); j++) { 94735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.OpEntry op = ops.get(j); 94835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "op"); 94935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(op.getOp())); 950f5d831915dd11e77cdcf5669228c55fe17a21c5eDavid Braun if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) { 9515e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "m", Integer.toString(op.getMode())); 9525e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9535e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn long time = op.getTime(); 9545e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 9555e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "t", Long.toString(time)); 9565e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9575e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = op.getRejectTime(); 9585e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 9595e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "r", Long.toString(time)); 9605e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int dur = op.getDuration(); 9625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != 0) { 9635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "d", Integer.toString(dur)); 9645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 96535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "op"); 96635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 96735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "uid"); 96835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 96935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 97035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 97135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 97235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 97335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 97435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "app-ops"); 97535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endDocument(); 97635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.finishWrite(stream); 97735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 97835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state, restoring backup.", e); 97935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.failWrite(stream); 98035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 98135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 98235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 98335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 984a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 985a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 986a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 987a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn != PackageManager.PERMISSION_GRANTED) { 988a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Permission Denial: can't dump ApOps service from from pid=" 989a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + Binder.getCallingPid() 990a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + ", uid=" + Binder.getCallingUid()); 991a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 992a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 993a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 994a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 995a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Current AppOps Service state:"); 9965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn final long now = System.currentTimeMillis(); 997e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn boolean needSep = false; 998e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mOpModeWatchers.size() > 0) { 999e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1000e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Op mode watchers:"); 1001e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mOpModeWatchers.size(); i++) { 1002e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Op "); pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i))); 1003e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 1004e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> callbacks = mOpModeWatchers.valueAt(i); 1005e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 1006e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 1007e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(callbacks.get(j)); 1008e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1009e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1010e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1011e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mPackageModeWatchers.size() > 0) { 1012e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1013e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Package mode watchers:"); 1014e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mPackageModeWatchers.size(); i++) { 1015e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Pkg "); pw.print(mPackageModeWatchers.keyAt(i)); 1016e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 1017e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> callbacks = mPackageModeWatchers.valueAt(i); 1018e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 1019e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 1020e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(callbacks.get(j)); 1021e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1022e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1023e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1024e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mModeWatchers.size() > 0) { 1025e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1026e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" All mode watchers:"); 1027e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mModeWatchers.size(); i++) { 1028e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print(mModeWatchers.keyAt(i)); 1029e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" -> "); pw.println(mModeWatchers.valueAt(i)); 1030e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1031e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1032e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mClients.size() > 0) { 1033e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 1034e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Clients:"); 1035e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mClients.size(); i++) { 1036e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print(mClients.keyAt(i)); pw.println(":"); 1037e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.valueAt(i); 1038e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.println(cs); 1039e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) { 1040e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Started ops:"); 1041e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<cs.mStartedOps.size(); j++) { 1042e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = cs.mStartedOps.get(j); 1043e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print("uid="); pw.print(op.uid); 1044e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" pkg="); pw.print(op.packageName); 1045e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" op="); pw.println(AppOpsManager.opToName(op.op)); 1046e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1047e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1048e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1049e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1050e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (needSep) { 1051e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(); 1052e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 1053a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 1054a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":"); 1055a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.valueAt(i); 1056a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (Ops ops : pkgOps.values()) { 1057a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Package "); pw.print(ops.packageName); pw.println(":"); 1058a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int j=0; j<ops.size(); j++) { 1059a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.valueAt(j); 10605e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" "); pw.print(AppOpsManager.opToName(op.op)); 10615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(": mode="); pw.print(op.mode); 10625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.time != 0) { 10635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; time="); TimeUtils.formatDuration(now-op.time, pw); 10645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 10655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 10665e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.rejectTime != 0) { 10675e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; rejectTime="); TimeUtils.formatDuration(now-op.rejectTime, pw); 10685e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 10695e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 1070a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op.duration == -1) { 1071a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(" (running)"); 1072a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } else { 1073a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print("; duration="); 1074a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn TimeUtils.formatDuration(op.duration, pw); 1075a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(); 1076a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1077a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1078a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1079a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1080a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1081a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1082a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn} 1083