AppOpsService.java revision e98f5dbe6b6f9f2cb6a73ee750faacda2596b34f
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; 30a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 31a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.app.AppOpsManager; 32a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.Context; 33a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager; 34a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException; 3535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.os.AsyncTask; 36a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Binder; 3735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.os.Handler; 38c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport android.os.IBinder; 39a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Process; 40c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport android.os.RemoteException; 41a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.ServiceManager; 42a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.UserHandle; 43e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackbornimport android.util.ArrayMap; 44a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.AtomicFile; 455e45ee6752528791deb66b83d76250685de15d47Dianne Hackbornimport android.util.Log; 46a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.Slog; 47a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.SparseArray; 48a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.TimeUtils; 4935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.util.Xml; 50a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 51a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport com.android.internal.app.IAppOpsService; 52c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport com.android.internal.app.IAppOpsCallback; 5335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 5435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.XmlUtils; 5535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 5635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParser; 5735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 5835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlSerializer; 59a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 60a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpublic class AppOpsService extends IAppOpsService.Stub { 61a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn static final String TAG = "AppOps"; 6235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final boolean DEBUG = false; 6335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 6435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn // Write at most every 30 minutes. 6535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000; 66a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 67a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Context mContext; 68a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final AtomicFile mFile; 6935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Handler mHandler; 7035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 7135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean mWriteScheduled; 7235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Runnable mWriteRunner = new Runnable() { 7335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public void run() { 7435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (AppOpsService.this) { 7535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 7635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 7735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn @Override protected Void doInBackground(Void... params) { 7835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 7935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 8035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 8235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); 8335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 86a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 87a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final SparseArray<HashMap<String, Ops>> mUidOps 88a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn = new SparseArray<HashMap<String, Ops>>(); 89a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 90c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final static class Ops extends SparseArray<Op> { 91a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public final String packageName; 9235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public final int uid; 93a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 9435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public Ops(String _packageName, int _uid) { 95a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn packageName = _packageName; 9635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn uid = _uid; 97a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 98a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 99a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 100c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final static class Op { 101e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public final int uid; 102e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public final String packageName; 103a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public final int op; 1045e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public int mode; 105a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public int duration; 106a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public long time; 1075e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public long rejectTime; 10835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int nesting; 109a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 110e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public Op(int _uid, String _packageName, int _op) { 111e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn uid = _uid; 112e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn packageName = _packageName; 113a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn op = _op; 1145e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mode = AppOpsManager.MODE_ALLOWED; 115a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 116a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 117a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 118c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final SparseArray<ArrayList<Callback>> mOpModeWatchers 119c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn = new SparseArray<ArrayList<Callback>>(); 120e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayMap<String, ArrayList<Callback>> mPackageModeWatchers 121e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn = new ArrayMap<String, ArrayList<Callback>>(); 122e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayMap<IBinder, Callback> mModeWatchers 123e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn = new ArrayMap<IBinder, Callback>(); 124c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 125c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final class Callback implements DeathRecipient { 126c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final IAppOpsCallback mCallback; 127c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 128c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public Callback(IAppOpsCallback callback) { 129c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback = callback; 130c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 131c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().linkToDeath(this, 0); 132c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 133c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 134c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 135c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 136c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void unlinkToDeath() { 137c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().unlinkToDeath(this, 0); 138c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 139c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 140c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 141c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void binderDied() { 142c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn stopWatchingMode(mCallback); 143c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 144c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 145c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 146e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<IBinder, ClientState>(); 147e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 148e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public final class ClientState extends Binder implements DeathRecipient { 149e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final IBinder mAppToken; 150e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final int mPid; 151e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn final ArrayList<Op> mStartedOps; 152e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 153e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public ClientState(IBinder appToken) { 154e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mAppToken = appToken; 155e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPid = Binder.getCallingPid(); 156e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (appToken instanceof Binder) { 157e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn // For local clients, there is no reason to track them. 158e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mStartedOps = null; 159e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } else { 160e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mStartedOps = new ArrayList<Op>(); 161e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn try { 162e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mAppToken.linkToDeath(this, 0); 163e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } catch (RemoteException e) { 164e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 165e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 166e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 167e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 168e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 169e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public String toString() { 170e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return "ClientState{" + 171e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn "mAppToken=" + mAppToken + 172e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ", " + (mStartedOps != null ? ("pid=" + mPid) : "local") + 173e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn '}'; 174e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 175e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 176e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 177e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void binderDied() { 178e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (AppOpsService.this) { 179e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mStartedOps.size()-1; i>=0; i--) { 180e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn finishOperationLocked(mStartedOps.get(i)); 181e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 182e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.remove(mAppToken); 183e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 184e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 185e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 186e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 18735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public AppOpsService(File storagePath) { 18835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile = new AtomicFile(storagePath); 18935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mHandler = new Handler(); 19035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readState(); 191a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 192a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 193a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void publish(Context context) { 194a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext = context; 195a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder()); 196a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 197a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 198514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void systemReady() { 199514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 200514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn boolean changed = false; 201514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 202514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn HashMap<String, Ops> pkgs = mUidOps.valueAt(i); 203514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Iterator<Ops> it = pkgs.values().iterator(); 204514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn while (it.hasNext()) { 205514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Ops ops = it.next(); 206514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn int curUid; 207514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 208514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn curUid = mContext.getPackageManager().getPackageUid(ops.packageName, 209514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn UserHandle.getUserId(ops.uid)); 210514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } catch (NameNotFoundException e) { 211514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn curUid = -1; 212514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 213514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (curUid != ops.uid) { 214514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Slog.i(TAG, "Pruning old package " + ops.packageName 215514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn + "/" + ops.uid + ": new uid=" + curUid); 216514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn it.remove(); 217514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn changed = true; 218514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 219514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 220514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs.size() <= 0) { 221514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.removeAt(i); 222514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 223514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 224514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (changed) { 225514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn scheduleWriteLocked(); 226514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 227514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 228514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 229514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 230514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void packageRemoved(int uid, String packageName) { 231514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 232514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn HashMap<String, Ops> pkgs = mUidOps.get(uid); 233514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs != null) { 234514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs.remove(packageName) != null) { 235514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgs.size() <= 0) { 236514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.remove(uid); 237514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 238514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn scheduleWriteLocked(); 239514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 240514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 241514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 242514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 243514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 244514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn public void uidRemoved(int uid) { 245514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn synchronized (this) { 246514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (mUidOps.indexOfKey(uid) >= 0) { 247514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.remove(uid); 248514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn scheduleWriteLocked(); 249514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 250514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 251514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 252514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn 253a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void shutdown() { 254a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Slog.w(TAG, "Writing app ops before shutdown..."); 25535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean doWrite = false; 25635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 25735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mWriteScheduled) { 25835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 25935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn doWrite = true; 26035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 26135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 26235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (doWrite) { 26335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 26435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 265a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 266a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 26772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) { 26872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = null; 26972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 27072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn resOps = new ArrayList<AppOpsManager.OpEntry>(); 27172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<pkgOps.size(); j++) { 27272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.valueAt(j); 2735e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 2745e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn curOp.rejectTime, curOp.duration)); 27572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 27672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } else { 27772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<ops.length; j++) { 27872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.get(ops[j]); 27972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (curOp != null) { 28072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 28172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn resOps = new ArrayList<AppOpsManager.OpEntry>(); 28272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 2835e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 2845e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn curOp.rejectTime, curOp.duration)); 28572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 28672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 28772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 28872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return resOps; 28972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 29072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 291a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 29235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 29335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 29435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 29535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = null; 296a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 29735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 29835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> packages = mUidOps.valueAt(i); 29935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (Ops pkgOps : packages.values()) { 30072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 30135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (resOps != null) { 30235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (res == null) { 30335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res = new ArrayList<AppOpsManager.PackageOps>(); 30435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 30535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 30635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.packageName, pkgOps.uid, resOps); 30735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res.add(resPackage); 30835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 30935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 310a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 311a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 31235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return res; 313a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 314a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 315a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 31672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, 31772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn int[] ops) { 31872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 31972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 32072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn synchronized (this) { 32172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops pkgOps = getOpsLocked(uid, packageName, false); 32272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (pkgOps == null) { 32372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 32472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 32572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 32672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 32772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 32872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 32972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); 33072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 33172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn pkgOps.packageName, pkgOps.uid, resOps); 33272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn res.add(resPackage); 33372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return res; 33472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 33572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 33672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 33772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn @Override 3385e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public void setMode(int code, int uid, String packageName, int mode) { 339f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 340961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 341c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> repCbs = null; 342c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn code = AppOpsManager.opToSwitch(code); 3435e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn synchronized (this) { 344c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 3455e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op != null) { 3465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.mode != mode) { 3475e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.mode = mode; 348c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(code); 349c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 350c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 351c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs = new ArrayList<Callback>(); 352c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 353c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 354c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 355c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = mPackageModeWatchers.get(packageName); 356c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 357c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 358c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs = new ArrayList<Callback>(); 359c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 360c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 361c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 362514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (mode == AppOpsManager.MODE_ALLOWED) { 363514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // If going into the default mode, prune this op 364514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // if there is nothing else interesting in it. 365514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (op.time == 0 && op.rejectTime == 0) { 366514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Ops ops = getOpsLocked(uid, packageName, false); 367514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (ops != null) { 368514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn ops.remove(op.op); 369514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (ops.size() <= 0) { 370514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 371514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgOps != null) { 372514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn pkgOps.remove(ops.packageName); 373514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgOps.size() <= 0) { 374514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn mUidOps.remove(uid); 375514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 376514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 377514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 378514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 379514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 380514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 3815e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteNowLocked(); 3825e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3835e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3845e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 385c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs != null) { 386c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn for (int i=0; i<repCbs.size(); i++) { 387c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 388c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.get(i).mCallback.opChanged(code, packageName); 389c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 390c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 391c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 392c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 393c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 394c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 395c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 396c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { 397c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 398c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn op = AppOpsManager.opToSwitch(op); 399c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.get(callback.asBinder()); 400c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb == null) { 401c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb = new Callback(callback); 402c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mModeWatchers.put(callback.asBinder(), cb); 403c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 404c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (op != AppOpsManager.OP_NONE) { 405c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(op); 406c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 407c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 408c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.put(op, cbs); 409c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 410c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 411c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 412c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (packageName != null) { 413c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.get(packageName); 414c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 415c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 416c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mPackageModeWatchers.put(packageName, cbs); 417c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 418c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 419c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 420c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 421c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 422c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 423c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 424c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void stopWatchingMode(IAppOpsCallback callback) { 425c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 426c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.remove(callback.asBinder()); 427c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb != null) { 428c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb.unlinkToDeath(); 429e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mOpModeWatchers.size()-1; i>=0; i--) { 430c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i); 431c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.remove(cb); 432c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs.size() <= 0) { 433c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.removeAt(i); 434c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 435c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 436e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=mPackageModeWatchers.size()-1; i>=0; i--) { 437e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.valueAt(i); 438e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cbs.remove(cb); 439e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cbs.size() <= 0) { 440e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mPackageModeWatchers.removeAt(i); 441c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 442c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 443c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 444c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 4455e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 4465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 4475e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn @Override 448e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public IBinder getToken(IBinder clientToken) { 449e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn synchronized (this) { 450e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.get(clientToken); 451e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs == null) { 452e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn cs = new ClientState(clientToken); 453e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn mClients.put(clientToken, cs); 454e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 455e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn return cs; 456e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 457e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 458e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 459e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn @Override 46035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int checkOperation(int code, int uid, String packageName) { 461f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 462961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 463a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 464f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false); 465a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 46635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return AppOpsManager.MODE_ALLOWED; 467a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 4685e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return op.mode; 469a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 470a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 471a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 472a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 47335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int noteOperation(int code, int uid, String packageName) { 474f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 475961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 476a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 477f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 478f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 4795e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid 4805e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 48135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return AppOpsManager.MODE_IGNORED; 482a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 483f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 48435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.duration == -1) { 48535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName 486a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + " code " + code + " time=" + op.time + " duration=" + op.duration); 487a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 48835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = 0; 489f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 490f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 491f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 492f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " 493f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 4945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 495f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 4965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 4975e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid 4985e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 4995e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = System.currentTimeMillis(); 500514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn op.rejectTime = 0; 5015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 502a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 503a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 504a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 505a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 506e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public int startOperation(IBinder token, int code, int uid, String packageName) { 507f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 508961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 509e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 510a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 511f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 512f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 5135e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid 5145e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 515a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return AppOpsManager.MODE_IGNORED; 516a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 517f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 518f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 519f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 520f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 521f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " 522f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 5235e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 524f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 5255e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 5265e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid 5275e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 52835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.nesting == 0) { 52935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.time = System.currentTimeMillis(); 530514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn op.rejectTime = 0; 53135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = -1; 532a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 53335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.nesting++; 534e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 535e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn client.mStartedOps.add(op); 536e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 5375e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 538a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 539a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 540a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 541a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 542e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn public void finishOperation(IBinder token, int code, int uid, String packageName) { 543f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 544961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 545e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState client = (ClientState)token; 546a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 54735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 548a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 549a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 550a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 551e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (client.mStartedOps != null) { 552e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (!client.mStartedOps.remove(op)) { 553e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn throw new IllegalStateException("Operation not started: uid" + op.uid 554e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + " pkg=" + op.packageName + " op=" + op.op); 55535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 556e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 557e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn finishOperationLocked(op); 558e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 559e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 560e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn 561e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn void finishOperationLocked(Op op) { 562e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (op.nesting <= 1) { 563e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (op.nesting == 1) { 564e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.duration = (int)(System.currentTimeMillis() - op.time); 565e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.time += op.duration; 56635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 567e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg " 568e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + op.packageName + " code " + op.op + " time=" + op.time 569e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn + " duration=" + op.duration + " nesting=" + op.nesting); 570a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 571e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.nesting = 0; 572e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } else { 573e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op.nesting--; 574a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 575a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 576a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 577f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private void verifyIncomingUid(int uid) { 578a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (uid == Binder.getCallingUid()) { 579f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 580a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 581a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (Binder.getCallingPid() == Process.myPid()) { 582f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 583a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 584a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, 585a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 586a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 587a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 588961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn private void verifyIncomingOp(int op) { 589961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn if (op >= 0 && op < AppOpsManager._NUM_OP) { 590961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn return; 591961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 592961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn throw new IllegalArgumentException("Bad operation #" + op); 593961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 594961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn 59572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Ops getOpsLocked(int uid, String packageName, boolean edit) { 596a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 597a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (pkgOps == null) { 59835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 59935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 60035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 601a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps = new HashMap<String, Ops>(); 602a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mUidOps.put(uid, pkgOps); 603a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 604514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid == 0) { 605514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn packageName = "root"; 606514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } else if (uid == Process.SHELL_UID) { 607514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn packageName = "com.android.shell"; 608514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 609a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Ops ops = pkgOps.get(packageName); 610a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (ops == null) { 61135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 61235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 61335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 614a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // This is the first time we have seen this package name under this uid, 615a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // so let's make sure it is valid. 616514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (uid != 0) { 617514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 618a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn try { 619514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn int pkgUid = -1; 620514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn try { 621514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn pkgUid = mContext.getPackageManager().getPackageUid(packageName, 622514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn UserHandle.getUserId(uid)); 623514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } catch (NameNotFoundException e) { 624713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn if ("media".equals(packageName)) { 625713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn pkgUid = Process.MEDIA_UID; 626713df150b92a0a5eea877f99405e31eefbf93a09Dianne Hackborn } 627514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 628514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn if (pkgUid != uid) { 629514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // Oops! The package name is not valid for the uid they are calling 630514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn // under. Abort. 631514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Slog.w(TAG, "Bad call: specified package " + packageName 632514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn + " under uid " + uid + " but it is really " + pkgUid); 633514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn return null; 634514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } 635514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn } finally { 636514074fae81028937eda29e782c92e8ea78d85d2Dianne Hackborn Binder.restoreCallingIdentity(ident); 637002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } 638a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 63935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(packageName, uid); 640a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps.put(packageName, ops); 641a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 64272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return ops; 64372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 64472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 6455e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteLocked() { 6465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 6475e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 6485e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.postDelayed(mWriteRunner, WRITE_DELAY); 6495e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6505e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6515e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 6525e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteNowLocked() { 6535e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 6545e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 6555e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6565e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.removeCallbacks(mWriteRunner); 6575e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.post(mWriteRunner); 6585e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6595e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 66072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Op getOpLocked(int code, int uid, String packageName, boolean edit) { 66172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, edit); 66272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 66372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 66472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 665f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return getOpLocked(ops, code, edit); 666f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn } 667f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn 668f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private Op getOpLocked(Ops ops, int code, boolean edit) { 669a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.get(code); 670a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 67135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 67235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 67335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 674e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn op = new Op(ops.uid, ops.packageName, code); 675a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ops.put(code, op); 676a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 6775e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (edit) { 6785e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteLocked(); 67935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 680a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return op; 681a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 682a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 68335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readState() { 68435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 68535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 68635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileInputStream stream; 68735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 68835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.openRead(); 68935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (FileNotFoundException e) { 69035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty"); 69135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 69235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 69335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean success = false; 69435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 69535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 69635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn parser.setInput(stream, null); 69735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 69835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.START_TAG 69935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && type != XmlPullParser.END_DOCUMENT) { 70035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ; 70135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 70235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 70335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type != XmlPullParser.START_TAG) { 70435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn throw new IllegalStateException("no start tag found"); 70535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 70635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 70735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 70835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 70935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 71035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 71135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 71235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 71335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 71435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 71535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("pkg")) { 71635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readPackage(parser); 71735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 71835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <app-ops>: " 71935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 72035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 72135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 72235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 72335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn success = true; 72435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IllegalStateException e) { 72535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 72635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NullPointerException e) { 72735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 72835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NumberFormatException e) { 72935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 73035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (XmlPullParserException e) { 73135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 73235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 73335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 73435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IndexOutOfBoundsException e) { 73535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 73635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } finally { 73735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!success) { 73835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.clear(); 73935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 74035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 74135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream.close(); 74235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 74335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 74435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 74535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 74635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 74735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 74835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 74935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readPackage(XmlPullParser parser) throws NumberFormatException, 75035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 75135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String pkgName = parser.getAttributeValue(null, "n"); 75235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 75335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 75435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 75535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 75635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 75735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 75835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 75935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 76035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 76135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("uid")) { 76235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readUid(parser, pkgName); 76335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 76435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 76535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 76635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 76735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 76835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 76935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 77035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 77135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException, 77235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 77335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); 77435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 77535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 77635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 77735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 77835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 77935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 78035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 78135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 78235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 78335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("op")) { 784e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n"))); 7855e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String mode = parser.getAttributeValue(null, "m"); 7865e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (mode != null) { 7875e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.mode = Integer.parseInt(mode); 7885e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7895e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String time = parser.getAttributeValue(null, "t"); 7905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 7915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = Long.parseLong(time); 7925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7935e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = parser.getAttributeValue(null, "r"); 7945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 7955e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = Long.parseLong(time); 7965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7975e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String dur = parser.getAttributeValue(null, "d"); 7985e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != null) { 7995e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.duration = Integer.parseInt(dur); 8005e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 80135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 80235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (pkgOps == null) { 80335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps = new HashMap<String, Ops>(); 80435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.put(uid, pkgOps); 80535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 80635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Ops ops = pkgOps.get(pkgName); 80735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (ops == null) { 80835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(pkgName, uid); 80935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.put(pkgName, ops); 81035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops.put(op.op, op); 81235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 81335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 81435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 81535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 81635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 81935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 82035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void writeState() { 82135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 82235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); 82335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 82435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileOutputStream stream; 82535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 82635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.startWrite(); 82735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 82835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state: " + e); 82935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 83035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 83135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 83235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 83335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 83435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.setOutput(stream, "utf-8"); 83535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startDocument(null, true); 83635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "app-ops"); 83735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 83835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allOps != null) { 83935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String lastPkg = null; 84035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<allOps.size(); i++) { 84135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps pkg = allOps.get(i); 84235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!pkg.getPackageName().equals(lastPkg)) { 84335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 84435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 84535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 84635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn lastPkg = pkg.getPackageName(); 84735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "pkg"); 84835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", lastPkg); 84935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 85035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "uid"); 85135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(pkg.getUid())); 85235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.OpEntry> ops = pkg.getOps(); 85335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int j=0; j<ops.size(); j++) { 85435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.OpEntry op = ops.get(j); 85535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "op"); 85635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(op.getOp())); 8575e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.getMode() != AppOpsManager.MODE_ALLOWED) { 8585e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "m", Integer.toString(op.getMode())); 8595e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8605e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn long time = op.getTime(); 8615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 8625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "t", Long.toString(time)); 8635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = op.getRejectTime(); 8655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 8665e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "r", Long.toString(time)); 8675e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 8685e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int dur = op.getDuration(); 8695e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != 0) { 8705e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "d", Integer.toString(dur)); 8715e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 87235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "op"); 87335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 87435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "uid"); 87535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 87635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 87735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 87835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 87935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 88035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 88135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "app-ops"); 88235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endDocument(); 88335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.finishWrite(stream); 88435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 88535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state, restoring backup.", e); 88635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.failWrite(stream); 88735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 88835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 88935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 89035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 891a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 892a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 893a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 894a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn != PackageManager.PERMISSION_GRANTED) { 895a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Permission Denial: can't dump ApOps service from from pid=" 896a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + Binder.getCallingPid() 897a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + ", uid=" + Binder.getCallingUid()); 898a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 899a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 900a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 901a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 902a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Current AppOps Service state:"); 9035e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn final long now = System.currentTimeMillis(); 904e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn boolean needSep = false; 905e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mOpModeWatchers.size() > 0) { 906e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 907e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Op mode watchers:"); 908e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mOpModeWatchers.size(); i++) { 909e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Op "); pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i))); 910e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 911e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> callbacks = mOpModeWatchers.valueAt(i); 912e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 913e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 914e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(callbacks.get(j)); 915e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 916e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 917e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 918e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mPackageModeWatchers.size() > 0) { 919e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 920e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Package mode watchers:"); 921e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mPackageModeWatchers.size(); i++) { 922e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" Pkg "); pw.print(mPackageModeWatchers.keyAt(i)); 923e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(":"); 924e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ArrayList<Callback> callbacks = mPackageModeWatchers.valueAt(i); 925e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<callbacks.size(); j++) { 926e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" #"); pw.print(j); pw.print(": "); 927e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(callbacks.get(j)); 928e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 929e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 930e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 931e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mModeWatchers.size() > 0) { 932e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 933e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" All mode watchers:"); 934e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mModeWatchers.size(); i++) { 935e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print(mModeWatchers.keyAt(i)); 936e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" -> "); pw.println(mModeWatchers.valueAt(i)); 937e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 938e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 939e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (mClients.size() > 0) { 940e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn needSep = true; 941e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Clients:"); 942e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int i=0; i<mClients.size(); i++) { 943e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print(mClients.keyAt(i)); pw.println(":"); 944e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn ClientState cs = mClients.valueAt(i); 945e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.println(cs); 946e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) { 947e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(" Started ops:"); 948e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn for (int j=0; j<cs.mStartedOps.size(); j++) { 949e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn Op op = cs.mStartedOps.get(j); 950e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" "); pw.print("uid="); pw.print(op.uid); 951e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" pkg="); pw.print(op.packageName); 952e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.print(" op="); pw.println(AppOpsManager.opToName(op.op)); 953e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 954e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 955e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 956e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 957e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn if (needSep) { 958e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn pw.println(); 959e98f5dbe6b6f9f2cb6a73ee750faacda2596b34fDianne Hackborn } 960a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 961a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":"); 962a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.valueAt(i); 963a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (Ops ops : pkgOps.values()) { 964a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Package "); pw.print(ops.packageName); pw.println(":"); 965a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int j=0; j<ops.size(); j++) { 966a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.valueAt(j); 9675e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" "); pw.print(AppOpsManager.opToName(op.op)); 9685e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(": mode="); pw.print(op.mode); 9695e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.time != 0) { 9705e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; time="); TimeUtils.formatDuration(now-op.time, pw); 9715e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 9725e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 9735e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.rejectTime != 0) { 9745e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; rejectTime="); TimeUtils.formatDuration(now-op.rejectTime, pw); 9755e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 9765e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 977a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op.duration == -1) { 978a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(" (running)"); 979a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } else { 980a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print("; duration="); 981a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn TimeUtils.formatDuration(op.duration, pw); 982a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(); 983a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 984a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 985a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 986a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 987a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 988a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 989a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn} 990