AppOpsService.java revision c2293025a25e04b26bf53713d71f85fd9ca5e8e9
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; 43a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.AtomicFile; 445e45ee6752528791deb66b83d76250685de15d47Dianne Hackbornimport android.util.Log; 45a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.Slog; 46a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.SparseArray; 47a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.TimeUtils; 4835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport android.util.Xml; 49a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 50a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport com.android.internal.app.IAppOpsService; 51c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackbornimport com.android.internal.app.IAppOpsCallback; 5235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.FastXmlSerializer; 5335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport com.android.internal.util.XmlUtils; 5435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 5535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParser; 5635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlPullParserException; 5735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackbornimport org.xmlpull.v1.XmlSerializer; 58a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 59a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpublic class AppOpsService extends IAppOpsService.Stub { 60a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn static final String TAG = "AppOps"; 6135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final boolean DEBUG = false; 6235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 6335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn // Write at most every 30 minutes. 6435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn static final long WRITE_DELAY = DEBUG ? 1000 : 30*60*1000; 65a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 66a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Context mContext; 67a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final AtomicFile mFile; 6835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Handler mHandler; 6935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 7035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean mWriteScheduled; 7135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn final Runnable mWriteRunner = new Runnable() { 7235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public void run() { 7335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (AppOpsService.this) { 7435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 7535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 7635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn @Override protected Void doInBackground(Void... params) { 7735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 7835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 7935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 8135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[])null); 8235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 8435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn }; 85a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 86a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final SparseArray<HashMap<String, Ops>> mUidOps 87a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn = new SparseArray<HashMap<String, Ops>>(); 88a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 89c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final static class Ops extends SparseArray<Op> { 90a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public final String packageName; 9135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public final int uid; 92a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 9335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public Ops(String _packageName, int _uid) { 94a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn packageName = _packageName; 9535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn uid = _uid; 96a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 97a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 98a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 99c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final static class Op { 100a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public final int op; 1015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public int mode; 102a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public int duration; 103a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public long time; 1045e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public long rejectTime; 10535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int nesting; 106a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 107a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public Op(int _op) { 108a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn op = _op; 1095e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mode = AppOpsManager.MODE_ALLOWED; 110a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 111a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 112a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 113c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final SparseArray<ArrayList<Callback>> mOpModeWatchers 114c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn = new SparseArray<ArrayList<Callback>>(); 115c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final HashMap<String, ArrayList<Callback>> mPackageModeWatchers 116c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn = new HashMap<String, ArrayList<Callback>>(); 117c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final HashMap<IBinder, Callback> mModeWatchers 118c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn = new HashMap<IBinder, Callback>(); 119c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 120c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public final class Callback implements DeathRecipient { 121c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn final IAppOpsCallback mCallback; 122c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 123c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public Callback(IAppOpsCallback callback) { 124c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback = callback; 125c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 126c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().linkToDeath(this, 0); 127c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 128c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 129c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 130c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 131c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void unlinkToDeath() { 132c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mCallback.asBinder().unlinkToDeath(this, 0); 133c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 134c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 135c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 136c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void binderDied() { 137c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn stopWatchingMode(mCallback); 138c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 139c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 140c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 14135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public AppOpsService(File storagePath) { 14235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile = new AtomicFile(storagePath); 14335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mHandler = new Handler(); 14435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readState(); 145a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 146a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 147a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void publish(Context context) { 148a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext = context; 149a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder()); 150a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 151a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 152a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public void shutdown() { 153a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Slog.w(TAG, "Writing app ops before shutdown..."); 15435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean doWrite = false; 15535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 15635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mWriteScheduled) { 15735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mWriteScheduled = false; 15835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn doWrite = true; 15935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 16035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 16135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (doWrite) { 16235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn writeState(); 16335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 164a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 165a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 16672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) { 16772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = null; 16872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 16972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn resOps = new ArrayList<AppOpsManager.OpEntry>(); 17072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<pkgOps.size(); j++) { 17172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.valueAt(j); 1725e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 1735e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn curOp.rejectTime, curOp.duration)); 17472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 17572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } else { 17672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn for (int j=0; j<ops.length; j++) { 17772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Op curOp = pkgOps.get(ops[j]); 17872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (curOp != null) { 17972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 18072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn resOps = new ArrayList<AppOpsManager.OpEntry>(); 18172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 1825e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time, 1835e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn curOp.rejectTime, curOp.duration)); 18472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 18572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 18672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 18772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return resOps; 18872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 18972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 190a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 19135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) { 19235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 19335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 19435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = null; 195a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 19635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 19735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> packages = mUidOps.valueAt(i); 19835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (Ops pkgOps : packages.values()) { 19972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 20035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (resOps != null) { 20135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (res == null) { 20235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res = new ArrayList<AppOpsManager.PackageOps>(); 20335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 20435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 20535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.packageName, pkgOps.uid, resOps); 20635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn res.add(resPackage); 20735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 20835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 209a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 210a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 21135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return res; 212a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 213a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 214a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 21572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, 21672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn int[] ops) { 21772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn mContext.enforcePermission(android.Manifest.permission.GET_APP_OPS_STATS, 21872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 21972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn synchronized (this) { 22072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops pkgOps = getOpsLocked(uid, packageName, false); 22172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (pkgOps == null) { 22272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 22372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 22472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.OpEntry> resOps = collectOps(pkgOps, ops); 22572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (resOps == null) { 22672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 22772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 22872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn ArrayList<AppOpsManager.PackageOps> res = new ArrayList<AppOpsManager.PackageOps>(); 22972e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn AppOpsManager.PackageOps resPackage = new AppOpsManager.PackageOps( 23072e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn pkgOps.packageName, pkgOps.uid, resOps); 23172e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn res.add(resPackage); 23272e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return res; 23372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 23472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 23572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 23672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn @Override 2375e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public void setMode(int code, int uid, String packageName, int mode) { 238f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 239961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 240c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> repCbs = null; 241c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn code = AppOpsManager.opToSwitch(code); 2425e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn synchronized (this) { 243c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 2445e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op != null) { 2455e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.mode != mode) { 2465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.mode = mode; 247c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(code); 248c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 249c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 250c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs = new ArrayList<Callback>(); 251c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 252c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 253c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 254c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = mPackageModeWatchers.get(packageName); 255c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs != null) { 256c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs == null) { 257c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs = new ArrayList<Callback>(); 258c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 259c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.addAll(cbs); 260c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 2615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteNowLocked(); 2625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 2635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 2645e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 265c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (repCbs != null) { 266c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn for (int i=0; i<repCbs.size(); i++) { 267c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn try { 268c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn repCbs.get(i).mCallback.opChanged(code, packageName); 269c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } catch (RemoteException e) { 270c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 271c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 272c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 273c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 274c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 275c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 276c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void startWatchingMode(int op, String packageName, IAppOpsCallback callback) { 277c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 278c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn op = AppOpsManager.opToSwitch(op); 279c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.get(callback.asBinder()); 280c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb == null) { 281c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb = new Callback(callback); 282c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mModeWatchers.put(callback.asBinder(), cb); 283c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 284c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (op != AppOpsManager.OP_NONE) { 285c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.get(op); 286c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 287c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 288c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.put(op, cbs); 289c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 290c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 291c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 292c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (packageName != null) { 293c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mPackageModeWatchers.get(packageName); 294c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs == null) { 295c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs = new ArrayList<Callback>(); 296c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mPackageModeWatchers.put(packageName, cbs); 297c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 298c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.add(cb); 299c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 300c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 301c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 302c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 303c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn @Override 304c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn public void stopWatchingMode(IAppOpsCallback callback) { 305c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (this) { 306c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Callback cb = mModeWatchers.remove(callback.asBinder()); 307c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cb != null) { 308c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cb.unlinkToDeath(); 309c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn for (int i=0; i<mOpModeWatchers.size(); i++) { 310c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = mOpModeWatchers.valueAt(i); 311c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.remove(cb); 312c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs.size() <= 0) { 313c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mOpModeWatchers.removeAt(i); 314c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 315c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 316c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (mPackageModeWatchers.size() > 0) { 317c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn Iterator<ArrayList<Callback>> it = mPackageModeWatchers.values().iterator(); 318c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn while (it.hasNext()) { 319c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn ArrayList<Callback> cbs = it.next(); 320c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn cbs.remove(cb); 321c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn if (cbs.size() <= 0) { 322c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn it.remove(); 323c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 324c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 325c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 326c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 327c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 3285e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3295e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 3305e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn @Override 33135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int checkOperation(int code, int uid, String packageName) { 332f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 333961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 334a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 335f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(AppOpsManager.opToSwitch(code), uid, packageName, false); 336a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 33735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return AppOpsManager.MODE_ALLOWED; 338a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 3395e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return op.mode; 340a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 341a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 342a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 343a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 34435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int noteOperation(int code, int uid, String packageName) { 345f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 346961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 347a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 348f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 349f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 3505e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: no op for code " + code + " uid " + uid 3515e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 35235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return AppOpsManager.MODE_IGNORED; 353a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 354f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 35535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.duration == -1) { 35635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName 357a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + " code " + code + " time=" + op.time + " duration=" + op.duration); 358a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 35935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = 0; 360f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 361f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 362f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 363f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " 364f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 3655e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 366f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 3675e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3685e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid 3695e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 3705e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = System.currentTimeMillis(); 3715e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 372a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 373a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 374a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 375a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 37635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public int startOperation(int code, int uid, String packageName) { 377f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 378961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 379a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 380f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, true); 381f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (ops == null) { 3825e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: no op for code " + code + " uid " + uid 3835e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 384a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return AppOpsManager.MODE_IGNORED; 385a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 386f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn Op op = getOpLocked(ops, code, true); 387f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final int switchCode = AppOpsManager.opToSwitch(code); 388f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; 389f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { 390f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: reject #" + op.mode + " for code " 391f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn + switchCode + " (" + code + ") uid " + uid + " package " + packageName); 3925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = System.currentTimeMillis(); 393f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return switchOp.mode; 3945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 3955e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (DEBUG) Log.d(TAG, "startOperation: allowing code " + code + " uid " + uid 3965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn + " package " + packageName); 39735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.nesting == 0) { 39835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.time = System.currentTimeMillis(); 39935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = -1; 400a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 40135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.nesting++; 4025e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.MODE_ALLOWED; 403a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 404a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 405a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 406a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 40735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn public void finishOperation(int code, int uid, String packageName) { 408f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn verifyIncomingUid(uid); 409961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn verifyIncomingOp(code); 410a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 41135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Op op = getOpLocked(code, uid, packageName, true); 412a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 413a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 414a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 41535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.nesting <= 1) { 41635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (op.nesting == 1) { 41735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.duration = (int)(System.currentTimeMillis() - op.time); 41835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 41935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Finishing op nesting under-run: uid " + uid + " pkg " + packageName 42035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + " code " + code + " time=" + op.time + " duration=" + op.duration 42135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + " nesting=" + op.nesting); 42235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 423e799175b6ba3aadd972f4b861758d675d1f93987Dianne Hackborn op.nesting = 0; 42435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 42535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn op.nesting--; 426a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 427a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 428a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 429a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 430f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private void verifyIncomingUid(int uid) { 431a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (uid == Binder.getCallingUid()) { 432f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 433a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 434a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (Binder.getCallingPid() == Process.myPid()) { 435f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return; 436a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 437a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, 438a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Binder.getCallingPid(), Binder.getCallingUid(), null); 439a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 440a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 441961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn private void verifyIncomingOp(int op) { 442961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn if (op >= 0 && op < AppOpsManager._NUM_OP) { 443961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn return; 444961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 445961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn throw new IllegalArgumentException("Bad operation #" + op); 446961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn } 447961321fe4ed4431a6362d729d9e4ea26bdecde61Dianne Hackborn 44872e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Ops getOpsLocked(int uid, String packageName, boolean edit) { 449a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 450a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (pkgOps == null) { 45135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 45235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 45335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 454a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps = new HashMap<String, Ops>(); 455a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mUidOps.put(uid, pkgOps); 456a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 457a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Ops ops = pkgOps.get(packageName); 458a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (ops == null) { 45935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 46035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 46135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 462a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // This is the first time we have seen this package name under this uid, 463a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // so let's make sure it is valid. 464002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 465002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn try { 466002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn int pkgUid = -1; 467a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn try { 468002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn pkgUid = mContext.getPackageManager().getPackageUid(packageName, 469002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn UserHandle.getUserId(uid)); 470002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } catch (NameNotFoundException e) { 471a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 472002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn if (pkgUid != uid) { 473002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn // Oops! The package name is not valid for the uid they are calling 474002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn // under. Abort. 475002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn Slog.w(TAG, "Bad call: specified package " + packageName 476002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn + " under uid " + uid + " but it is really " + pkgUid); 477002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn return null; 478002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } 479002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn } finally { 480002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn Binder.restoreCallingIdentity(ident); 481a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 48235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(packageName, uid); 483a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pkgOps.put(packageName, ops); 484a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 48572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return ops; 48672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 48772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn 4885e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteLocked() { 4895e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 4905e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 4915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.postDelayed(mWriteRunner, WRITE_DELAY); 4925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 4935e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 4945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 4955e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn private void scheduleWriteNowLocked() { 4965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!mWriteScheduled) { 4975e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mWriteScheduled = true; 4985e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 4995e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.removeCallbacks(mWriteRunner); 5005e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mHandler.post(mWriteRunner); 5015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 5025e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 50372e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn private Op getOpLocked(int code, int uid, String packageName, boolean edit) { 50472e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn Ops ops = getOpsLocked(uid, packageName, edit); 50572e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn if (ops == null) { 50672e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn return null; 50772e3983d38f656cfa8c7a038eb80bdd9ea06768eDianne Hackborn } 508f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn return getOpLocked(ops, code, edit); 509f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn } 510f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn 511f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn private Op getOpLocked(Ops ops, int code, boolean edit) { 512a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.get(code); 513a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op == null) { 51435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!edit) { 51535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return null; 51635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 517a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn op = new Op(code); 518a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn ops.put(code, op); 519a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 5205e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (edit) { 5215e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn scheduleWriteLocked(); 52235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 523a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return op; 524a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 525a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 52635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readState() { 52735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 52835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (this) { 52935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileInputStream stream; 53035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 53135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.openRead(); 53235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (FileNotFoundException e) { 53335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.i(TAG, "No existing app ops " + mFile.getBaseFile() + "; starting empty"); 53435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 53535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 53635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean success = false; 53735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 53835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParser parser = Xml.newPullParser(); 53935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn parser.setInput(stream, null); 54035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 54135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.START_TAG 54235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && type != XmlPullParser.END_DOCUMENT) { 54335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ; 54435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 54535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 54635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type != XmlPullParser.START_TAG) { 54735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn throw new IllegalStateException("no start tag found"); 54835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 54935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 55035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 55135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 55235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 55335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 55435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 55535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 55635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 55735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 55835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("pkg")) { 55935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readPackage(parser); 56035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 56135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <app-ops>: " 56235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 56335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 56435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 56535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 56635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn success = true; 56735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IllegalStateException e) { 56835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 56935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NullPointerException e) { 57035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 57135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (NumberFormatException e) { 57235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 57335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (XmlPullParserException e) { 57435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 57535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 57635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 57735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IndexOutOfBoundsException e) { 57835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed parsing " + e); 57935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } finally { 58035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!success) { 58135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.clear(); 58235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 58335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 58435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream.close(); 58535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 58635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 58735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 58835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 58935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 59035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 59135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 59235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readPackage(XmlPullParser parser) throws NumberFormatException, 59335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 59435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String pkgName = parser.getAttributeValue(null, "n"); 59535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 59635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 59735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 59835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 59935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 60035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 60135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 60235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 60335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 60435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("uid")) { 60535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn readUid(parser, pkgName); 60635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 60735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 60835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 60935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 61035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 61135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 61235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 61335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 61435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void readUid(XmlPullParser parser, String pkgName) throws NumberFormatException, 61535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlPullParserException, IOException { 61635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int uid = Integer.parseInt(parser.getAttributeValue(null, "n")); 61735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int outerDepth = parser.getDepth(); 61835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int type; 61935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn while ((type = parser.next()) != XmlPullParser.END_DOCUMENT 62035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 62135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 62235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn continue; 62335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 62435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 62535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String tagName = parser.getName(); 62635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (tagName.equals("op")) { 62735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Op op = new Op(Integer.parseInt(parser.getAttributeValue(null, "n"))); 6285e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String mode = parser.getAttributeValue(null, "m"); 6295e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (mode != null) { 6305e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.mode = Integer.parseInt(mode); 6315e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6325e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String time = parser.getAttributeValue(null, "t"); 6335e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 6345e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.time = Long.parseLong(time); 6355e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6365e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = parser.getAttributeValue(null, "r"); 6375e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != null) { 6385e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.rejectTime = Long.parseLong(time); 6395e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 6405e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn String dur = parser.getAttributeValue(null, "d"); 6415e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != null) { 6425e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn op.duration = Integer.parseInt(dur); 6435e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 64435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.get(uid); 64535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (pkgOps == null) { 64635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps = new HashMap<String, Ops>(); 64735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mUidOps.put(uid, pkgOps); 64835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 64935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Ops ops = pkgOps.get(pkgName); 65035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (ops == null) { 65135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops = new Ops(pkgName, uid); 65235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn pkgOps.put(pkgName, ops); 65335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 65435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn ops.put(op.op, op); 65535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 65635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Unknown element under <pkg>: " 65735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn + parser.getName()); 65835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlUtils.skipCurrentTag(parser); 65935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 66035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 66135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 66235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 66335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn void writeState() { 66435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn synchronized (mFile) { 66535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null); 66635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 66735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn FileOutputStream stream; 66835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 66935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn stream = mFile.startWrite(); 67035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 67135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state: " + e); 67235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return; 67335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 67435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 67535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn try { 67635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn XmlSerializer out = new FastXmlSerializer(); 67735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.setOutput(stream, "utf-8"); 67835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startDocument(null, true); 67935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "app-ops"); 68035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 68135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allOps != null) { 68235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn String lastPkg = null; 68335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int i=0; i<allOps.size(); i++) { 68435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.PackageOps pkg = allOps.get(i); 68535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (!pkg.getPackageName().equals(lastPkg)) { 68635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 68735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 68835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 68935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn lastPkg = pkg.getPackageName(); 69035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "pkg"); 69135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", lastPkg); 69235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 69335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "uid"); 69435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(pkg.getUid())); 69535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn List<AppOpsManager.OpEntry> ops = pkg.getOps(); 69635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn for (int j=0; j<ops.size(); j++) { 69735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn AppOpsManager.OpEntry op = ops.get(j); 69835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.startTag(null, "op"); 69935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.attribute(null, "n", Integer.toString(op.getOp())); 7005e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.getMode() != AppOpsManager.MODE_ALLOWED) { 7015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "m", Integer.toString(op.getMode())); 7025e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7035e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn long time = op.getTime(); 7045e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 7055e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "t", Long.toString(time)); 7065e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7075e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn time = op.getRejectTime(); 7085e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (time != 0) { 7095e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "r", Long.toString(time)); 7105e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7115e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int dur = op.getDuration(); 7125e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (dur != 0) { 7135e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn out.attribute(null, "d", Integer.toString(dur)); 7145e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 71535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "op"); 71635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 71735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "uid"); 71835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 71935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (lastPkg != null) { 72035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "pkg"); 72135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 72235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 72335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 72435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endTag(null, "app-ops"); 72535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn out.endDocument(); 72635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.finishWrite(stream); 72735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } catch (IOException e) { 72835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn Slog.w(TAG, "Failed to write state, restoring backup.", e); 72935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn mFile.failWrite(stream); 73035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 73135654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 73235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 73335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 734a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn @Override 735a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 736a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 737a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn != PackageManager.PERMISSION_GRANTED) { 738a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Permission Denial: can't dump ApOps service from from pid=" 739a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + Binder.getCallingPid() 740a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn + ", uid=" + Binder.getCallingUid()); 741a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return; 742a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 743a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 744a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn synchronized (this) { 745a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println("Current AppOps Service state:"); 7465e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn final long now = System.currentTimeMillis(); 747a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int i=0; i<mUidOps.size(); i++) { 748a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":"); 749a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn HashMap<String, Ops> pkgOps = mUidOps.valueAt(i); 750a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (Ops ops : pkgOps.values()) { 751a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print(" Package "); pw.print(ops.packageName); pw.println(":"); 752a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn for (int j=0; j<ops.size(); j++) { 753a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Op op = ops.valueAt(j); 7545e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" "); pw.print(AppOpsManager.opToName(op.op)); 7555e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(": mode="); pw.print(op.mode); 7565e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.time != 0) { 7575e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; time="); TimeUtils.formatDuration(now-op.time, pw); 7585e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 7595e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 7605e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op.rejectTime != 0) { 7615e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print("; rejectTime="); TimeUtils.formatDuration(now-op.rejectTime, pw); 7625e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn pw.print(" ago"); 7635e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 764a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn if (op.duration == -1) { 765a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(" (running)"); 766a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } else { 767a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.print("; duration="); 768a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn TimeUtils.formatDuration(op.duration, pw); 769a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn pw.println(); 770a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 771a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 772a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 773a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 774a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 775a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 776a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn} 777