AppOpsService.java revision 002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062
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;
21a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.io.PrintWriter;
22a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport java.util.HashMap;
23a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
24a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.app.AppOpsManager;
25a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.Context;
26a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager;
27a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.content.pm.PackageManager.NameNotFoundException;
28a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Binder;
29a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Environment;
30a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.Process;
31a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.ServiceManager;
32a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.os.UserHandle;
33a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.AtomicFile;
34a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.Slog;
35a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.SparseArray;
36a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.util.TimeUtils;
37a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
38a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport com.android.internal.app.IAppOpsService;
39a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
40a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornpublic class AppOpsService extends IAppOpsService.Stub {
41a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    static final String TAG = "AppOps";
42a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
43a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    Context mContext;
44a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    final AtomicFile mFile;
45a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
46a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    final SparseArray<HashMap<String, Ops>> mUidOps
47a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            = new SparseArray<HashMap<String, Ops>>();
48a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
49a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    final static class Ops extends SparseArray<Op> {
50a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        public final String packageName;
51a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
52a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        public Ops(String _packageName) {
53a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            packageName = _packageName;
54a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
55a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
56a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
57a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    final static class Op {
58a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        public final int op;
59a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        public int duration;
60a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        public long time;
61a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
62a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        public Op(int _op) {
63a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op = _op;
64a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
65a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
66a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
67a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public AppOpsService() {
68a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        mFile = new AtomicFile(new File(Environment.getSecureDataDirectory(), "appops.xml"));
69a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
70a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
71a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public void publish(Context context) {
72a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        mContext = context;
73a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        ServiceManager.addService(Context.APP_OPS_SERVICE, asBinder());
74a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
75a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
76a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public void shutdown() {
77a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        Slog.w(TAG, "Writing app ops before shutdown...");
78a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
79a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
80a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    @Override
81a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public int noteOperation(int code, int uid, String packageName) {
82a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        uid = handleIncomingUid(uid);
83a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        synchronized (this) {
84a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            Op op = getOpLocked(code, uid, packageName);
85a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op == null) {
86a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                return AppOpsManager.MODE_IGNORED;
87a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
88a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op.duration == -1) {
89a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
90a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
91a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
92a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.time = System.currentTimeMillis();
93a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.duration = 0;
94a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
95a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        return AppOpsManager.MODE_ALLOWED;
96a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
97a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
98a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    @Override
99a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public int startOperation(int code, int uid, String packageName) {
100a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        uid = handleIncomingUid(uid);
101a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        synchronized (this) {
102a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            Op op = getOpLocked(code, uid, packageName);
103a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op == null) {
104a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                return AppOpsManager.MODE_IGNORED;
105a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
106a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op.duration == -1) {
107a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                Slog.w(TAG, "Starting op not finished: uid " + uid + " pkg " + packageName
108a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
109a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
110a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.time = System.currentTimeMillis();
111a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.duration = -1;
112a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
113a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        return AppOpsManager.MODE_ALLOWED;
114a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
115a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
116a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    @Override
117a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public void finishOperation(int code, int uid, String packageName) {
118a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        uid = handleIncomingUid(uid);
119a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        synchronized (this) {
120a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            Op op = getOpLocked(code, uid, packageName);
121a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op == null) {
122a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                return;
123a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
124a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op.duration != -1) {
125a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                Slog.w(TAG, "Ignoring finishing op not started: uid " + uid + " pkg " + packageName
126a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
127a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                return;
128a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
129a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.duration = (int)(System.currentTimeMillis() - op.time);
130a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
131a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
132a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
133a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    @Override
134a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public int noteTimedOperation(int code, int uid, String packageName, int duration) {
135a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        uid = handleIncomingUid(uid);
136a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        synchronized (this) {
137a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            Op op = getOpLocked(code, uid, packageName);
138a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op == null) {
139a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                return AppOpsManager.MODE_IGNORED;
140a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
141a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op.duration == -1) {
142a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
143a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
144a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
145a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.time = System.currentTimeMillis();
146a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op.duration = duration;
147a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
148a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        return AppOpsManager.MODE_ALLOWED;
149a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
150a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
151a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    @Override
152a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    public void earlyFinishOperation(int code, int uid, String packageName) {
153a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        uid = handleIncomingUid(uid);
154a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        synchronized (this) {
155a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            Op op = getOpLocked(code, uid, packageName);
156a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op == null) {
157a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                return;
158a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
159a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (op.duration != -1) {
160a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                Slog.w(TAG, "Noting timed op not finished: uid " + uid + " pkg " + packageName
161a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
162a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
163a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            int newDuration = (int)(System.currentTimeMillis() - op.time);
164a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            if (newDuration < op.duration) {
165a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                op.duration = newDuration;
166a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
167a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
168a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
169a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
170a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    private int handleIncomingUid(int uid) {
171a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (uid == Binder.getCallingUid()) {
172a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            return uid;
173a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
174a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (Binder.getCallingPid() == Process.myPid()) {
175a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            return uid;
176a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
177a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
178a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                Binder.getCallingPid(), Binder.getCallingUid(), null);
179a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        return uid;
180a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
181a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
182a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    private Op getOpLocked(int code, int uid, String packageName) {
183a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        HashMap<String, Ops> pkgOps = mUidOps.get(uid);
184a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (pkgOps == null) {
185a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pkgOps = new HashMap<String, Ops>();
186a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            mUidOps.put(uid, pkgOps);
187a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
188a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        Ops ops = pkgOps.get(packageName);
189a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (ops == null) {
190a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            // This is the first time we have seen this package name under this uid,
191a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            // so let's make sure it is valid.
192002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn            final long ident = Binder.clearCallingIdentity();
193002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn            try {
194002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                int pkgUid = -1;
195a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                try {
196002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                    pkgUid = mContext.getPackageManager().getPackageUid(packageName,
197002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                            UserHandle.getUserId(uid));
198002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                } catch (NameNotFoundException e) {
199a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                }
200002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                if (pkgUid != uid) {
201002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                    // Oops!  The package name is not valid for the uid they are calling
202002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                    // under.  Abort.
203002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                    Slog.w(TAG, "Bad call: specified package " + packageName
204002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                            + " under uid " + uid + " but it is really " + pkgUid);
205002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                    return null;
206002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                }
207002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn            } finally {
208002a54e2291eeb3a3fd0b6b3f9dbc96a7c805062Dianne Hackborn                Binder.restoreCallingIdentity(ident);
209a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
210a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            ops = new Ops(packageName);
211a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pkgOps.put(packageName, ops);
212a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
213a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        Op op = ops.get(code);
214a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (op == null) {
215a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            op = new Op(code);
216a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            ops.put(code, op);
217a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
218a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        return op;
219a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
220a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
221a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    @Override
222a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
223a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
224a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                != PackageManager.PERMISSION_GRANTED) {
225a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pw.println("Permission Denial: can't dump ApOps service from from pid="
226a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                    + Binder.getCallingPid()
227a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                    + ", uid=" + Binder.getCallingUid());
228a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            return;
229a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
230a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn
231a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        synchronized (this) {
232a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            pw.println("Current AppOps Service state:");
233a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            for (int i=0; i<mUidOps.size(); i++) {
234a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                pw.print("  Uid "); UserHandle.formatUid(pw, mUidOps.keyAt(i)); pw.println(":");
235a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                HashMap<String, Ops> pkgOps = mUidOps.valueAt(i);
236a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                for (Ops ops : pkgOps.values()) {
237a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                    pw.print("    Package "); pw.print(ops.packageName); pw.println(":");
238a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                    for (int j=0; j<ops.size(); j++) {
239a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        Op op = ops.valueAt(j);
240a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        pw.print("      "); pw.print(AppOpsManager.opToString(op.op));
241a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        pw.print(": time=");
242a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        TimeUtils.formatDuration(System.currentTimeMillis()-op.time, pw);
243a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        pw.print(" ago");
244a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        if (op.duration == -1) {
245a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                            pw.println(" (running)");
246a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        } else {
247a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                            pw.print("; duration=");
248a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                                    TimeUtils.formatDuration(op.duration, pw);
249a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                                    pw.println();
250a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                        }
251a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                    }
252a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn                }
253a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn            }
254a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn        }
255a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn    }
256a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn}
257