AppOpsManager.java revision 72e3983d38f656cfa8c7a038eb80bdd9ea06768e
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
19import com.android.internal.app.IAppOpsService;
20
21import java.util.ArrayList;
22import java.util.List;
23
24import android.content.Context;
25import android.os.Parcel;
26import android.os.Parcelable;
27import android.os.Process;
28import android.os.RemoteException;
29
30/** @hide */
31public class AppOpsManager {
32    final Context mContext;
33    final IAppOpsService mService;
34
35    public static final int MODE_ALLOWED = 0;
36    public static final int MODE_IGNORED = 1;
37    public static final int MODE_ERRORED = 2;
38
39    public static final int OP_COARSE_LOCATION = 0;
40    public static final int OP_FINE_LOCATION = 1;
41    public static final int OP_GPS = 2;
42    public static final int OP_VIBRATE = 3;
43    public static final int OP_READ_CONTACTS = 4;
44    public static final int OP_WRITE_CONTACTS = 5;
45    public static final int OP_READ_CALL_LOG = 6;
46    public static final int OP_WRITE_CALL_LOG = 7;
47
48    public static String opToString(int op) {
49        switch (op) {
50            case OP_COARSE_LOCATION: return "COARSE_LOCATION";
51            case OP_FINE_LOCATION: return "FINE_LOCATION";
52            case OP_GPS: return "GPS";
53            case OP_VIBRATE: return "VIBRATE";
54            case OP_READ_CONTACTS: return "READ_CONTACTS";
55            case OP_WRITE_CONTACTS: return "WRITE_CONTACTS";
56            case OP_READ_CALL_LOG: return "READ_CALL_LOG";
57            case OP_WRITE_CALL_LOG: return "WRITE_CALL_LOG";
58            default: return "Unknown(" + op + ")";
59        }
60    }
61
62    public static class PackageOps implements Parcelable {
63        private final String mPackageName;
64        private final int mUid;
65        private final List<OpEntry> mEntries;
66
67        public PackageOps(String packageName, int uid, List<OpEntry> entries) {
68            mPackageName = packageName;
69            mUid = uid;
70            mEntries = entries;
71        }
72
73        public String getPackageName() {
74            return mPackageName;
75        }
76
77        public int getUid() {
78            return mUid;
79        }
80
81        public List<OpEntry> getOps() {
82            return mEntries;
83        }
84
85        @Override
86        public int describeContents() {
87            return 0;
88        }
89
90        @Override
91        public void writeToParcel(Parcel dest, int flags) {
92            dest.writeString(mPackageName);
93            dest.writeInt(mUid);
94            dest.writeInt(mEntries.size());
95            for (int i=0; i<mEntries.size(); i++) {
96                mEntries.get(i).writeToParcel(dest, flags);
97            }
98        }
99
100        PackageOps(Parcel source) {
101            mPackageName = source.readString();
102            mUid = source.readInt();
103            mEntries = new ArrayList<OpEntry>();
104            final int N = source.readInt();
105            for (int i=0; i<N; i++) {
106                mEntries.add(OpEntry.CREATOR.createFromParcel(source));
107            }
108        }
109
110        public static final Creator<PackageOps> CREATOR = new Creator<PackageOps>() {
111            @Override public PackageOps createFromParcel(Parcel source) {
112                return new PackageOps(source);
113            }
114
115            @Override public PackageOps[] newArray(int size) {
116                return new PackageOps[size];
117            }
118        };
119    }
120
121    public static class OpEntry implements Parcelable {
122        private final int mOp;
123        private final long mTime;
124        private final int mDuration;
125
126        public OpEntry(int op, long time, int duration) {
127            mOp = op;
128            mTime = time;
129            mDuration = duration;
130        }
131
132        public int getOp() {
133            return mOp;
134        }
135
136        public long getTime() {
137            return mTime;
138        }
139
140        public boolean isRunning() {
141            return mDuration == -1;
142        }
143
144        public int getDuration() {
145            return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
146        }
147
148        @Override
149        public int describeContents() {
150            return 0;
151        }
152
153        @Override
154        public void writeToParcel(Parcel dest, int flags) {
155            dest.writeInt(mOp);
156            dest.writeLong(mTime);
157            dest.writeInt(mDuration);
158        }
159
160        OpEntry(Parcel source) {
161            mOp = source.readInt();
162            mTime = source.readLong();
163            mDuration = source.readInt();
164        }
165
166        public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() {
167            @Override public OpEntry createFromParcel(Parcel source) {
168                return new OpEntry(source);
169            }
170
171            @Override public OpEntry[] newArray(int size) {
172                return new OpEntry[size];
173            }
174        };
175    }
176
177    public AppOpsManager(Context context, IAppOpsService service) {
178        mContext = context;
179        mService = service;
180    }
181
182    public List<AppOpsManager.PackageOps> getPackagesForOps(int[] ops) {
183        try {
184            return mService.getPackagesForOps(ops);
185        } catch (RemoteException e) {
186        }
187        return null;
188    }
189
190    public List<AppOpsManager.PackageOps> getOpsForPackage(int uid, String packageName, int[] ops) {
191        try {
192            return mService.getOpsForPackage(uid, packageName, ops);
193        } catch (RemoteException e) {
194        }
195        return null;
196    }
197
198    public int checkOp(int op, int uid, String packageName) {
199        try {
200            int mode = mService.checkOperation(op, uid, packageName);
201            if (mode == MODE_ERRORED) {
202                throw new SecurityException("Operation not allowed");
203            }
204            return mode;
205        } catch (RemoteException e) {
206        }
207        return MODE_IGNORED;
208    }
209
210    public int checkOpNoThrow(int op, int uid, String packageName) {
211        try {
212            return mService.checkOperation(op, uid, packageName);
213        } catch (RemoteException e) {
214        }
215        return MODE_IGNORED;
216    }
217
218    public int noteOp(int op, int uid, String packageName) {
219        try {
220            int mode = mService.noteOperation(op, uid, packageName);
221            if (mode == MODE_ERRORED) {
222                throw new SecurityException("Operation not allowed");
223            }
224            return mode;
225        } catch (RemoteException e) {
226        }
227        return MODE_IGNORED;
228    }
229
230    public int noteOpNoThrow(int op, int uid, String packageName) {
231        try {
232            return mService.noteOperation(op, uid, packageName);
233        } catch (RemoteException e) {
234        }
235        return MODE_IGNORED;
236    }
237
238    public int noteOp(int op) {
239        return noteOp(op, Process.myUid(), mContext.getBasePackageName());
240    }
241
242    public int startOp(int op, int uid, String packageName) {
243        try {
244            int mode = mService.startOperation(op, uid, packageName);
245            if (mode == MODE_ERRORED) {
246                throw new SecurityException("Operation not allowed");
247            }
248            return mode;
249        } catch (RemoteException e) {
250        }
251        return MODE_IGNORED;
252    }
253
254    public int startOpNoThrow(int op, int uid, String packageName) {
255        try {
256            return mService.startOperation(op, uid, packageName);
257        } catch (RemoteException e) {
258        }
259        return MODE_IGNORED;
260    }
261
262    public int startOp(int op) {
263        return startOp(op, Process.myUid(), mContext.getBasePackageName());
264    }
265
266    public void finishOp(int op, int uid, String packageName) {
267        try {
268            mService.finishOperation(op, uid, packageName);
269        } catch (RemoteException e) {
270        }
271    }
272
273    public void finishOp(int op) {
274        finishOp(op, Process.myUid(), mContext.getBasePackageName());
275    }
276}
277