diff options
Diffstat (limited to 'core/java/android/app/AppOpsManager.java')
-rw-r--r-- | core/java/android/app/AppOpsManager.java | 364 |
1 files changed, 358 insertions, 6 deletions
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 8e9e284700c..66ab8ec0662 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1,5 +1,7 @@ /* * Copyright (C) 2012 The Android Open Source Project + * Copyright (c) 2013-2016, The CyanogenMod Project + * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +30,7 @@ import android.os.Parcelable; import android.os.Process; import android.os.RemoteException; import android.os.UserHandle; +import android.os.SystemProperties; import android.os.UserManager; import android.util.ArrayMap; @@ -69,6 +72,10 @@ public class AppOpsManager { * will do this for you). */ + /** {@hide} */ + public static final String ACTION_SU_SESSION_CHANGED = + "android.intent.action.SU_SESSION_CHANGED"; + final Context mContext; final IAppOpsService mService; final ArrayMap<OnOpChangedListener, IAppOpsCallback> mModeWatchers @@ -103,9 +110,17 @@ public class AppOpsManager { */ public static final int MODE_DEFAULT = 3; + /** + * @hide Result from {@link #checkOp}, {@link #noteOp}, {@link #startOp}: + * AppOps Service should show a dialog box on screen to get user + * permission. + */ + public static final int MODE_ASK = 4; + // when adding one of these: // - increment _NUM_OP - // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault + // - add rows to sOpToSwitch, sOpToString, sOpNames, sOpToPerms, sOpDefault, + // sOpDefaultStrictMode, sOpToOpString, sOpStrictMode. // - add descriptive strings to Settings/res/values/arrays.xml // - add the op to the appropriate template in AppOpsState.OpsTemplate (settings app) @@ -239,8 +254,20 @@ public class AppOpsManager { public static final int OP_GET_ACCOUNTS = 62; /** @hide Control whether an application is allowed to run in the background. */ public static final int OP_RUN_IN_BACKGROUND = 63; + /** @hide Wifi state change **/ + public static final int OP_CHANGE_WIFI_STATE = 64; + /** @hide */ + public static final int OP_BLUETOOTH_CHANGE = 65; + /** @hide */ + public static final int OP_BOOT_COMPLETED = 66; /** @hide */ - public static final int _NUM_OP = 64; + public static final int OP_NFC_CHANGE = 67; + /** @hide */ + public static final int OP_DATA_CONNECT_CHANGE = 68; + /** @hide */ + public static final int OP_SU = 69; + /** @hide */ + public static final int _NUM_OP = 70; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -338,6 +365,19 @@ public class AppOpsManager { /** @hide Get device accounts. */ public static final String OPSTR_GET_ACCOUNTS = "android:get_accounts"; + /** @hide **/ + private static final String OPSTR_WIFI_CHANGE = + "android:wifi_change"; + private static final String OPSTR_BLUETOOTH_CHANGE = + "android:bluetooth_change"; + private static final String OPSTR_BOOT_COMPLETED = + "android:boot_completed"; + private static final String OPSTR_NFC_CHANGE = + "android:nfc_change"; + private static final String OPSTR_DATA_CONNECT_CHANGE = + "android:data_connect_change"; + private static final String OPSTR_SU = + "android:su"; private static final int[] RUNTIME_PERMISSIONS_OPS = { // Contacts @@ -395,7 +435,7 @@ public class AppOpsManager { OP_WRITE_CALL_LOG, OP_READ_CALENDAR, OP_WRITE_CALENDAR, - OP_COARSE_LOCATION, + OP_WIFI_SCAN, OP_POST_NOTIFICATION, OP_COARSE_LOCATION, OP_CALL_PHONE, @@ -449,6 +489,12 @@ public class AppOpsManager { OP_TURN_SCREEN_ON, OP_GET_ACCOUNTS, OP_RUN_IN_BACKGROUND, + OP_CHANGE_WIFI_STATE, + OP_BLUETOOTH_CHANGE, + OP_BOOT_COMPLETED, + OP_NFC_CHANGE, + OP_DATA_CONNECT_CHANGE, + OP_SU }; /** @@ -520,6 +566,12 @@ public class AppOpsManager { null, OPSTR_GET_ACCOUNTS, null, + OPSTR_WIFI_CHANGE, + OPSTR_BLUETOOTH_CHANGE, + OPSTR_BOOT_COMPLETED, + OPSTR_NFC_CHANGE, + OPSTR_DATA_CONNECT_CHANGE, + OPSTR_SU, }; /** @@ -591,6 +643,12 @@ public class AppOpsManager { "TURN_ON_SCREEN", "GET_ACCOUNTS", "RUN_IN_BACKGROUND", + "WIFI_CHANGE", + "BLUETOOTH_CHANGE", + "BOOT_COMPLETED", + "NFC_CHANGE", + "DATA_CONNECT_CHANGE", + "SU", }; /** @@ -608,7 +666,7 @@ public class AppOpsManager { android.Manifest.permission.WRITE_CALL_LOG, android.Manifest.permission.READ_CALENDAR, android.Manifest.permission.WRITE_CALENDAR, - android.Manifest.permission.ACCESS_WIFI_STATE, + null, // no permission for wifi scan available null, // no permission required for notifications null, // neighboring cells shares the coarse location perm android.Manifest.permission.CALL_PHONE, @@ -662,6 +720,12 @@ public class AppOpsManager { null, // no permission for turning the screen on Manifest.permission.GET_ACCOUNTS, null, // no permission for running in background + Manifest.permission.CHANGE_WIFI_STATE, + null, + Manifest.permission.RECEIVE_BOOT_COMPLETED, + Manifest.permission.NFC, + Manifest.permission.MODIFY_PHONE_STATE, + null, }; /** @@ -734,6 +798,12 @@ public class AppOpsManager { null, // TURN_ON_SCREEN null, // GET_ACCOUNTS null, // RUN_IN_BACKGROUND + null, //WIFI_CHANGE + null, //BLUETOOTH_CHANGE + null, //BOOT_COMPLETED + null, //NFC_CHANGE + null, //DATA_CONNECT_CHANGE + UserManager.DISALLOW_SU, //SU TODO: this should really be investigated. }; /** @@ -805,6 +875,12 @@ public class AppOpsManager { false, // TURN_ON_SCREEN false, // GET_ACCOUNTS false, // RUN_IN_BACKGROUND + true, // WIFI_CHANGE + true, // BLUETOOTH_CHANGE + true, // BOOT_COMPLETED + true, // NFC_CHANGE + true, //DATA_CONNECT_CHANGE + false, //SU }; /** @@ -875,6 +951,165 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, // OP_RUN_IN_BACKGROUND + AppOpsManager.MODE_ALLOWED, // OP_CHANGE_WIFI_STATE + AppOpsManager.MODE_ALLOWED, // OP_BLUETOOTH_CHANGE + AppOpsManager.MODE_ALLOWED, // OP_BOOT_COMPLETED + AppOpsManager.MODE_ALLOWED, // OP_NFC_CHANGE + AppOpsManager.MODE_ALLOWED, + AppOpsManager.MODE_ASK, // OP_SU + }; + + /** + * This specifies the default mode for each strict operation. + */ + + private static int[] sOpDefaultStrictMode = new int[] { + AppOpsManager.MODE_ASK, // OP_COARSE_LOCATION + AppOpsManager.MODE_ASK, // OP_FINE_LOCATION + AppOpsManager.MODE_ASK, // OP_GPS + AppOpsManager.MODE_ALLOWED, // OP_VIBRATE + AppOpsManager.MODE_ASK, // OP_READ_CONTACTS + AppOpsManager.MODE_ASK, // OP_WRITE_CONTACTS + AppOpsManager.MODE_ASK, // OP_READ_CALL_LOG + AppOpsManager.MODE_ASK, // OP_WRITE_CALL_LOG + AppOpsManager.MODE_ALLOWED, // OP_READ_CALENDAR + AppOpsManager.MODE_ALLOWED, // OP_WRITE_CALENDAR + AppOpsManager.MODE_ASK, // OP_WIFI_SCAN + AppOpsManager.MODE_ALLOWED, // OP_POST_NOTIFICATION + AppOpsManager.MODE_ALLOWED, // OP_NEIGHBORING_CELLS + AppOpsManager.MODE_ASK, // OP_CALL_PHONE + AppOpsManager.MODE_ASK, // OP_READ_SMS + AppOpsManager.MODE_ASK, // OP_WRITE_SMS + AppOpsManager.MODE_ASK, // OP_RECEIVE_SMS + AppOpsManager.MODE_ALLOWED, // OP_RECEIVE_EMERGECY_SMS + AppOpsManager.MODE_ASK, // OP_RECEIVE_MMS + AppOpsManager.MODE_ALLOWED, // OP_RECEIVE_WAP_PUSH + AppOpsManager.MODE_ASK, // OP_SEND_SMS + AppOpsManager.MODE_ALLOWED, // OP_READ_ICC_SMS + AppOpsManager.MODE_ALLOWED, // OP_WRITE_ICC_SMS + AppOpsManager.MODE_ALLOWED, // OP_WRITE_SETTINGS + AppOpsManager.MODE_ALLOWED, // OP_SYSTEM_ALERT_WINDOW + AppOpsManager.MODE_ALLOWED, // OP_ACCESS_NOTIFICATIONS + AppOpsManager.MODE_ASK, // OP_CAMERA + AppOpsManager.MODE_ASK, // OP_RECORD_AUDIO + AppOpsManager.MODE_ALLOWED, // OP_PLAY_AUDIO + AppOpsManager.MODE_ALLOWED, // OP_READ_CLIPBOARD + AppOpsManager.MODE_ALLOWED, // OP_WRITE_CLIPBOARD + AppOpsManager.MODE_ALLOWED, // OP_TAKE_MEDIA_BUTTONS + AppOpsManager.MODE_ALLOWED, // OP_TAKE_AUDIO_FOCUS + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_MASTER_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_VOICE_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_RING_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_MEDIA_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_ALARM_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_NOTIFICATION_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_AUDIO_BLUETOOTH_VOLUME + AppOpsManager.MODE_ALLOWED, // OP_WAKE_LOCK + AppOpsManager.MODE_ALLOWED, // OP_MONITOR_LOCATION + AppOpsManager.MODE_ASK, // OP_MONITOR_HIGH_POWER_LOCATION + AppOpsManager.MODE_DEFAULT, // OP_GET_USAGE_STATS + AppOpsManager.MODE_ALLOWED, // OP_MUTE_MICROPHONE + AppOpsManager.MODE_ALLOWED, // OP_TOAST_WINDOW + AppOpsManager.MODE_IGNORED, // OP_PROJECT_MEDIA + AppOpsManager.MODE_IGNORED, // OP_ACTIVATE_VPN + AppOpsManager.MODE_ALLOWED, // OP WALLPAPER + AppOpsManager.MODE_ALLOWED, // OP_ASSIST_STRUCTURE + AppOpsManager.MODE_ALLOWED, // OP_ASSIST_SCREENSHOT + AppOpsManager.MODE_ALLOWED, // OP_READ_PHONE_STATE + AppOpsManager.MODE_ALLOWED, // OP_ADD_VOICEMAIL + AppOpsManager.MODE_ALLOWED, // OP_USE_SIP + AppOpsManager.MODE_ALLOWED, // OP_PROCESS_OUTGOING_CALLS + AppOpsManager.MODE_ALLOWED, // OP_USE_FINGERPRINT + AppOpsManager.MODE_ALLOWED, // OP_BODY_SENSORS + AppOpsManager.MODE_ALLOWED, // OP_READ_CELL_BROADCASTS + AppOpsManager.MODE_ERRORED, // OP_MOCK_LOCATION + AppOpsManager.MODE_ALLOWED, // OP_READ_EXTERNAL_STORAGE + AppOpsManager.MODE_ALLOWED, // OP_WRITE_EXTERNAL_STORAGE + AppOpsManager.MODE_ALLOWED, // OP_TURN_ON_SCREEN + AppOpsManager.MODE_ALLOWED, // OP_GET_ACCOUNTS + AppOpsManager.MODE_ALLOWED, // MODE_RUN_IN_BACKGROUND + AppOpsManager.MODE_ASK, // OP_CHANGE_WIFI_STATE + AppOpsManager.MODE_ASK, // OP_BLUETOOTH_CHANGE + AppOpsManager.MODE_ALLOWED, // OP_BOOT_COMPLETED + AppOpsManager.MODE_ASK, // OP_NFC_CHANGE + AppOpsManager.MODE_ASK, // OP_DATA_CONNECT_CHANGE + AppOpsManager.MODE_ASK, // OP_SU + }; + + /** + * This specifies if operation is in strict mode. + */ + private final static boolean[] sOpStrictMode = new boolean[] { + true, // OP_COARSE_LOCATION + true, // OP_FINE_LOCATION + true, // OP_GPS + false, // OP_VIBRATE + true, // OP_READ_CONTACTS + true, // OP_WRITE_CONTACTS + true, // OP_READ_CALL_LOG + true, // OP_WRITE_CALL_LOG + false, // OP_READ_CALENDAR + false, // OP_WRITE_CALENDAR + true, // OP_WIFI_SCAN + false, // OP_POST_NOTIFICATION + false, // OP_NEIGHBORING_CELLS + true, // OP_CALL_PHONE + true, // OP_READ_SMS + true, // OP_WRITE_SMS + false, // OP_RECEIVE_SMS + false, // OP_RECEIVE_EMERGECY_SMS + true, // OP_RECEIVE_MMS + false, // OP_RECEIVE_WAP_PUSH + true, // OP_SEND_SMS + false, // OP_READ_ICC_SMS + false, // OP_WRITE_ICC_SMS + false, // OP_WRITE_SETTINGS + false, // OP_SYSTEM_ALERT_WINDOW + false, // OP_ACCESS_NOTIFICATIONS + true, // OP_CAMERA + true, // OP_RECORD_AUDIO + false, // OP_PLAY_AUDIO + false, // OP_READ_CLIPBOARD + false, // OP_WRITE_CLIPBOARD + false, // OP_TAKE_MEDIA_BUTTONS + false, // OP_TAKE_AUDIO_FOCUS + false, // OP_AUDIO_MASTER_VOLUME + false, // OP_AUDIO_VOICE_VOLUME + false, // OP_AUDIO_RING_VOLUME + false, // OP_AUDIO_MEDIA_VOLUME + false, // OP_AUDIO_ALARM_VOLUME + false, // OP_AUDIO_NOTIFICATION_VOLUME + false, // OP_AUDIO_BLUETOOTH_VOLUME + false, // OP_WAKE_LOCK + false, // OP_MONITOR_LOCATION + true, // OP_MONITOR_HIGH_POWER_LOCATION + false, // OP_GET_USAGE_STATS + false, // OP_MUTE_MICROPHONE + false, // OP_TOAST_WINDOW + false, // OP_PROJECT_MEDIA + false, // OP_ACTIVATE_VPN + true, // OP WALLPAPER + false, //ASSIST_STRUCTURE + false, //ASSIST_SCREENSHOT + false, //READ_PHONE_STATE + false, //ADD_VOICEMAIL + false, // USE_SIP + false, // PROCESS_OUTGOING_CALLS + false, // USE_FINGERPRINT + false, // BODY_SENSORS + false, // READ_CELL_BROADCASTS + false, // MOCK_LOCATION + true, // READ_EXTERNAL_STORAGE + true, // WRITE_EXTERNAL_STORAGE + false, // TURN_ON_SCREEN + false, // GET_ACCOUNTS + false, // RUN_IN_BACKGROUND + true, // OP_CHANGE_WIFI_STATE + true, // OP_BLUETOOTH_CHANGE + false, // OP_BOOT_COMPLETED + true, // OP_NFC_CHANGE + true, // OP_DATA_CONNECT_CHANGE + true, // OP_SU }; /** @@ -949,6 +1184,12 @@ public class AppOpsManager { false, false, false, + false, // OP_CHANGE_WIFI_STATE + false, // OP_BLUETOOTH_CHANGE + false, // OP_BOOT_COMPLETED + false, // OP_NFC_CHANGE + false, // OP_DATA_CONNECT_CHANGE + false, // OP_SU }; /** @@ -961,6 +1202,8 @@ public class AppOpsManager { */ private static HashMap<String, Integer> sRuntimePermToOp = new HashMap<>(); + private static HashMap<String, Integer> sNameToOp = new HashMap<String, Integer>(); + static { if (sOpToSwitch.length != _NUM_OP) { throw new IllegalStateException("sOpToSwitch length " + sOpToSwitch.length @@ -982,6 +1225,10 @@ public class AppOpsManager { throw new IllegalStateException("sOpDefaultMode length " + sOpDefaultMode.length + " should be " + _NUM_OP); } + if (sOpDefaultStrictMode.length != _NUM_OP) { + throw new IllegalStateException("sOpDefaultStrictMode length " + sOpDefaultStrictMode.length + + " should be " + _NUM_OP); + } if (sOpDisableReset.length != _NUM_OP) { throw new IllegalStateException("sOpDisableReset length " + sOpDisableReset.length + " should be " + _NUM_OP); @@ -994,6 +1241,10 @@ public class AppOpsManager { throw new IllegalStateException("sOpAllowSYstemRestrictionsBypass length " + sOpRestrictions.length + " should be " + _NUM_OP); } + if (sOpStrictMode.length != _NUM_OP) { + throw new IllegalStateException("sOpStrictMode length " + + sOpStrictMode.length + " should be " + _NUM_OP); + } for (int i=0; i<_NUM_OP; i++) { if (sOpToString[i] != null) { sOpStrToOp.put(sOpToString[i], i); @@ -1004,6 +1255,9 @@ public class AppOpsManager { sRuntimePermToOp.put(sOpPerms[op], op); } } + for (int i=0; i<_NUM_OP; i++) { + sNameToOp.put(sOpNames[i], i); + } } /** @@ -1036,6 +1290,15 @@ public class AppOpsManager { } /** + * Map a non-localized name for the operation back to the Op number + * @hide + */ + public static int nameToOp(String name) { + Integer val = sNameToOp.get(name); + return val != null ? val : OP_NONE; + } + + /** * Retrieve the permission associated with an operation, or null if there is not one. * @hide */ @@ -1075,7 +1338,9 @@ public class AppOpsManager { * Retrieve the default mode for the operation. * @hide */ - public static int opToDefaultMode(int op) { + public static int opToDefaultMode(int op, boolean isStrict) { + if (isStrict) + return sOpDefaultStrictMode[op]; return sOpDefaultMode[op]; } @@ -1162,9 +1427,11 @@ public class AppOpsManager { private final int mDuration; private final int mProxyUid; private final String mProxyPackageName; + private final int mAllowedCount; + private final int mIgnoredCount; public OpEntry(int op, int mode, long time, long rejectTime, int duration, - int proxyUid, String proxyPackage) { + int proxyUid, String proxyPackage, int allowedCount, int ignoredCount) { mOp = op; mMode = mode; mTime = time; @@ -1172,6 +1439,8 @@ public class AppOpsManager { mDuration = duration; mProxyUid = proxyUid; mProxyPackageName = proxyPackage; + mAllowedCount = allowedCount; + mIgnoredCount = ignoredCount; } public int getOp() { @@ -1206,6 +1475,14 @@ public class AppOpsManager { return mProxyPackageName; } + public int getAllowedCount() { + return mAllowedCount; + } + + public int getIgnoredCount() { + return mIgnoredCount; + } + @Override public int describeContents() { return 0; @@ -1220,6 +1497,8 @@ public class AppOpsManager { dest.writeInt(mDuration); dest.writeInt(mProxyUid); dest.writeString(mProxyPackageName); + dest.writeInt(mAllowedCount); + dest.writeInt(mIgnoredCount); } OpEntry(Parcel source) { @@ -1230,6 +1509,8 @@ public class AppOpsManager { mDuration = source.readInt(); mProxyUid = source.readInt(); mProxyPackageName = source.readString(); + mAllowedCount = source.readInt(); + mIgnoredCount = source.readInt(); } public static final Creator<OpEntry> CREATOR = new Creator<OpEntry>() { @@ -1860,4 +2141,75 @@ public class AppOpsManager { public void finishOp(int op) { finishOp(op, Process.myUid(), mContext.getOpPackageName()); } + + /** @hide */ + public static boolean isStrictEnable() { + return SystemProperties.getBoolean("persist.sys.strict_op_enable", false); + } + + /** + * Check if op in strict mode + * @hide + */ + public static boolean isStrictOp(int code) { + return sOpStrictMode[code]; + } + + + /** @hide */ + public static int stringToMode(String permission) { + if ("allowed".equalsIgnoreCase(permission)) { + return AppOpsManager.MODE_ALLOWED; + } else if ("ignored".equalsIgnoreCase(permission)) { + return AppOpsManager.MODE_IGNORED; + } else if ("ask".equalsIgnoreCase(permission)) { + return AppOpsManager.MODE_ASK; + } + return AppOpsManager.MODE_ERRORED; + } + + /** @hide */ + public static int stringOpToOp (String op) { + Integer val = sOpStrToOp.get(op); + if (val == null) { + val = OP_NONE; + } + return val; + } + + /** @hide */ + public boolean isControlAllowed(int op, String packageName) { + boolean isShow = true; + try { + isShow = mService.isControlAllowed(op, packageName); + } catch (RemoteException e) { + } + return isShow; + } + + /** @hide */ + public boolean getPrivacyGuardSettingForPackage(int uid, String packageName) { + try { + return mService.getPrivacyGuardSettingForPackage(uid, packageName); + } catch (RemoteException e) { + } + return false; + } + + /** @hide */ + public void setPrivacyGuardSettingForPackage(int uid, String packageName, + boolean state) { + try { + mService.setPrivacyGuardSettingForPackage(uid, packageName, state); + } catch (RemoteException e) { + } + } + + /** @hide */ + public void resetCounters() { + try { + mService.resetCounters(); + } catch (RemoteException e) { + } + } } |