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