diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 8a3c9c8a865a4..6b161b910f052 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -223,8 +223,10 @@ public class AppOpsManager { public static final int OP_PROCESS_OUTGOING_CALLS = 54; /** @hide User the fingerprint API. */ public static final int OP_USE_FINGERPRINT = 55; + /** @hide Access to body sensors such as heart rate, etc. */ + public static final int OP_BODY_SENSORS = 56; /** @hide */ - public static final int _NUM_OP = 56; + public static final int _NUM_OP = 57; /** Access to coarse location information. */ public static final String OPSTR_COARSE_LOCATION = "android:coarse_location"; @@ -280,9 +282,6 @@ public class AppOpsManager { /** @hide Allows an application to send SMS messages. */ public static final String OPSTR_SEND_SMS = "android:send_sms"; - /** @hide Allows an application to add system alert windows. */ - public static final String OPSTR_SYSTEM_ALERT_WINDOW - = "android:system_alert_window"; /** @hide Required to be able to access the camera device. */ public static final String OPSTR_CAMERA = "android:camera"; @@ -295,6 +294,15 @@ public class AppOpsManager { /** @hide Required to access phone state related information. */ public static final String OPSTR_ADD_VOICEMAIL = "android:add_voicemail"; + /** @hide Access APIs for SIP calling over VOIP or WiFi */ + public static final String OPSTR_USE_SIP + = "android:use_sip"; + /** @hide Use the fingerprint API. */ + public static final String OPSTR_USE_FINGERPRINT + = "android:use_fingerprint"; + /** @hide Access to body sensors such as heart rate, etc. */ + public static final String OPSTR_BODY_SENSORS + = "android:body_sensors"; /** * This maps each operation to the operation that serves as the @@ -360,7 +368,8 @@ public class AppOpsManager { OP_ADD_VOICEMAIL, OP_USE_SIP, OP_PROCESS_OUTGOING_CALLS, - OP_USE_FINGERPRINT + OP_USE_FINGERPRINT, + OP_BODY_SENSORS }; /** @@ -372,30 +381,30 @@ public class AppOpsManager { OPSTR_FINE_LOCATION, null, null, + OPSTR_READ_CONTACTS, + OPSTR_WRITE_CONTACTS, + OPSTR_READ_CALL_LOG, + OPSTR_WRITE_CALL_LOG, + OPSTR_READ_CALENDAR, + OPSTR_WRITE_CALENDAR, + null, + null, + null, + OPSTR_CALL_PHONE, + OPSTR_READ_SMS, + null, + OPSTR_RECEIVE_SMS, + null, + OPSTR_RECEIVE_MMS, + OPSTR_RECEIVE_WAP_PUSH, + OPSTR_SEND_SMS, null, null, null, null, null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, + OPSTR_CAMERA, + OPSTR_RECORD_AUDIO, null, null, null, @@ -419,11 +428,12 @@ public class AppOpsManager { null, null, null, + OPSTR_READ_PHONE_STATE, + OPSTR_ADD_VOICEMAIL, + OPSTR_USE_SIP, null, - null, - null, - null, - null + OPSTR_USE_FINGERPRINT, + OPSTR_BODY_SENSORS }; /** @@ -486,7 +496,8 @@ public class AppOpsManager { "ADD_VOICEMAIL", "USE_SIP", "PROCESS_OUTGOING_CALLS", - "USE_FINGERPRINT" + "USE_FINGERPRINT", + "BODY_SENSORS" }; /** @@ -549,7 +560,8 @@ public class AppOpsManager { Manifest.permission.ADD_VOICEMAIL, Manifest.permission.USE_SIP, Manifest.permission.PROCESS_OUTGOING_CALLS, - Manifest.permission.USE_FINGERPRINT + Manifest.permission.USE_FINGERPRINT, + Manifest.permission.BODY_SENSORS }; /** @@ -613,7 +625,8 @@ public class AppOpsManager { null, // ADD_VOICEMAIL null, // USE_SIP null, // PROCESS_OUTGOING_CALLS - null // USE_FINGERPRINT + null, // USE_FINGERPRINT + null // BODY_SENSORS }; /** @@ -676,7 +689,8 @@ public class AppOpsManager { false, //ADD_VOICEMAIL false, // USE_SIP false, // PROCESS_OUTGOING_CALLS - false // USE_FINGERPRINT + false, // USE_FINGERPRINT + false // BODY_SENSORS }; /** @@ -738,6 +752,7 @@ public class AppOpsManager { AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED, + AppOpsManager.MODE_ALLOWED, AppOpsManager.MODE_ALLOWED }; @@ -804,37 +819,19 @@ public class AppOpsManager { false, false, false, + false, false }; /** - * This is a mapping from a permission name to public app op name. + * Mapping from an app op name to the app op code. */ - private static final ArrayMap sPermToOp = new ArrayMap<>(); - static { - sPermToOp.put(Manifest.permission.ACCESS_COARSE_LOCATION, OPSTR_COARSE_LOCATION); - sPermToOp.put(Manifest.permission.ACCESS_FINE_LOCATION, OPSTR_FINE_LOCATION); - sPermToOp.put(Manifest.permission.PACKAGE_USAGE_STATS, OPSTR_GET_USAGE_STATS); - sPermToOp.put(Manifest.permission.READ_CONTACTS, OPSTR_READ_CONTACTS); - sPermToOp.put(Manifest.permission.WRITE_CONTACTS, OPSTR_WRITE_CONTACTS); - sPermToOp.put(Manifest.permission.READ_CALL_LOG, OPSTR_READ_CALL_LOG); - sPermToOp.put(Manifest.permission.WRITE_CALL_LOG, OPSTR_WRITE_CALL_LOG); - sPermToOp.put(Manifest.permission.READ_CALENDAR, OPSTR_READ_CALENDAR); - sPermToOp.put(Manifest.permission.WRITE_CALENDAR, OPSTR_WRITE_CALENDAR); - sPermToOp.put(Manifest.permission.CALL_PHONE, OPSTR_CALL_PHONE); - sPermToOp.put(Manifest.permission.READ_SMS, OPSTR_READ_SMS); - sPermToOp.put(Manifest.permission.RECEIVE_SMS, OPSTR_RECEIVE_SMS); - sPermToOp.put(Manifest.permission.RECEIVE_MMS, OPSTR_RECEIVE_MMS); - sPermToOp.put(Manifest.permission.RECEIVE_WAP_PUSH, OPSTR_RECEIVE_WAP_PUSH); - sPermToOp.put(Manifest.permission.SEND_SMS, OPSTR_SEND_SMS); - sPermToOp.put(Manifest.permission.SYSTEM_ALERT_WINDOW, OPSTR_SYSTEM_ALERT_WINDOW); - sPermToOp.put(Manifest.permission.CAMERA, OPSTR_CAMERA); - sPermToOp.put(Manifest.permission.RECORD_AUDIO, OPSTR_RECORD_AUDIO); - sPermToOp.put(Manifest.permission.READ_PHONE_STATE, OPSTR_READ_PHONE_STATE); - sPermToOp.put(Manifest.permission.ADD_VOICEMAIL, OPSTR_ADD_VOICEMAIL); - } + private static HashMap sOpStrToOp = new HashMap<>(); - private static HashMap sOpStrToOp = new HashMap(); + /** + * Mapping from a permission to the corresponding app op. + */ + private static HashMap sPermToOp = new HashMap<>(); static { if (sOpToSwitch.length != _NUM_OP) { @@ -874,6 +871,11 @@ public class AppOpsManager { sOpStrToOp.put(sOpToString[i], i); } } + for (int i=0; i<_NUM_OP; i++) { + if (sOpPerms[i] != null) { + sPermToOp.put(sOpPerms[i], i); + } + } } /** @@ -921,6 +923,14 @@ public class AppOpsManager { return sOpRestrictions[op]; } + /** + * Retrieve the app op code for a permission, or null if there is not one. + * @hide + */ + public static int permissionToOpCode(String permission) { + return sPermToOp.get(permission); + } + /** * Retrieve whether the op allows the system (and system ui) to * bypass the user restriction. @@ -1185,7 +1195,11 @@ public class AppOpsManager { */ @SystemApi public static String permissionToOp(String permission) { - return sPermToOp.get(permission); + final Integer opCode = sPermToOp.get(permission); + if (opCode == null) { + return null; + } + return sOpToString[opCode]; } /** diff --git a/core/java/android/hardware/SystemSensorManager.java b/core/java/android/hardware/SystemSensorManager.java index 11037fd69604b..22a9e9c8a1c8a 100644 --- a/core/java/android/hardware/SystemSensorManager.java +++ b/core/java/android/hardware/SystemSensorManager.java @@ -41,16 +41,19 @@ import java.util.List; */ public class SystemSensorManager extends SensorManager { private static native void nativeClassInit(); - private static native int nativeGetNextSensor(Sensor sensor, int next); - private static native int nativeEnableDataInjection(boolean enable); + private static native long nativeCreate(String opPackageName); + private static native int nativeGetNextSensor(long nativeInstance, Sensor sensor, int next); + private static native int nativeEnableDataInjection(long nativeInstance, boolean enable); private static boolean sSensorModuleInitialized = false; - private static final Object sSensorModuleLock = new Object(); - private static final ArrayList sFullSensorsList = new ArrayList(); - private static final SparseArray sHandleToSensor = new SparseArray(); private static InjectEventQueue mInjectEventQueue = null; private static boolean mDataInjectionMode = false; + private final Object mLock = new Object(); + + private final ArrayList mFullSensorsList = new ArrayList<>(); + private final SparseArray mHandleToSensor = new SparseArray<>(); + // Listener list private final HashMap mSensorListeners = new HashMap(); @@ -60,44 +63,44 @@ public class SystemSensorManager extends SensorManager { // Looper associated with the context in which this instance was created. private final Looper mMainLooper; private final int mTargetSdkLevel; - private final String mPackageName; + private final Context mContext; private final boolean mHasDataInjectionPermissions; + private final long mNativeInstance; /** {@hide} */ public SystemSensorManager(Context context, Looper mainLooper) { mMainLooper = mainLooper; mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion; - mPackageName = context.getPackageName(); - synchronized(sSensorModuleLock) { + mContext = context; + mNativeInstance = nativeCreate(context.getOpPackageName()); + + synchronized(mLock) { if (!sSensorModuleInitialized) { sSensorModuleInitialized = true; - nativeClassInit(); - - // initialize the sensor list - final ArrayList fullList = sFullSensorsList; - int i = 0; - do { - Sensor sensor = new Sensor(); - i = nativeGetNextSensor(sensor, i); - if (i>=0) { - //Log.d(TAG, "found sensor: " + sensor.getName() + - // ", handle=" + sensor.getHandle()); - fullList.add(sensor); - sHandleToSensor.append(sensor.getHandle(), sensor); - } - } while (i>0); } mHasDataInjectionPermissions = context.checkSelfPermission( Manifest.permission.HARDWARE_TEST) == PackageManager.PERMISSION_GRANTED; } + + // initialize the sensor list + int i = 0; + while(true) { + Sensor sensor = new Sensor(); + i = nativeGetNextSensor(mNativeInstance, sensor, i); + if (i <= 0) { + break; + } + mFullSensorsList.add(sensor); + mHandleToSensor.append(sensor.getHandle(), sensor); + } } /** @hide */ @Override protected List getFullSensorList() { - return sFullSensorsList; + return mFullSensorsList; } @@ -232,8 +235,8 @@ public class SystemSensorManager extends SensorManager { throw new SecurityException("Permission denial. Calling enableDataInjection without " + Manifest.permission.HARDWARE_TEST); } - synchronized (sSensorModuleLock) { - int ret = nativeEnableDataInjection(enable); + synchronized (mLock) { + int ret = nativeEnableDataInjection(mNativeInstance, enable); // The HAL does not support injection. Ignore. if (ret != 0) { Log.e(TAG, "HAL does not support data injection"); @@ -255,7 +258,7 @@ public class SystemSensorManager extends SensorManager { throw new SecurityException("Permission denial. Calling injectSensorData without " + Manifest.permission.HARDWARE_TEST); } - synchronized (sSensorModuleLock) { + synchronized (mLock) { if (!mDataInjectionMode) { Log.e(TAG, "Data injection mode not activated before calling injectSensorData"); return false; @@ -284,15 +287,17 @@ public class SystemSensorManager extends SensorManager { * SensorManager instance. */ private static abstract class BaseEventQueue { - private native long nativeInitBaseEventQueue(WeakReference eventQWeak, - MessageQueue msgQ, float[] scratch, String packageName, int mode); + private static native long nativeInitBaseEventQueue(long nativeManager, + WeakReference eventQWeak, MessageQueue msgQ, float[] scratch, + String packageName, int mode, String opPackageName); private static native int nativeEnableSensor(long eventQ, int handle, int rateUs, int maxBatchReportLatencyUs); private static native int nativeDisableSensor(long eventQ, int handle); private static native void nativeDestroySensorEventQueue(long eventQ); private static native int nativeFlushSensor(long eventQ); private static native int nativeInjectSensorData(long eventQ, int handle, - float[] values,int accuracy, long timestamp); + float[] values,int accuracy, long timestamp); + private long nSensorEventQueue; private final SparseBooleanArray mActiveSensors = new SparseBooleanArray(); protected final SparseIntArray mSensorAccuracies = new SparseIntArray(); @@ -305,8 +310,9 @@ public class SystemSensorManager extends SensorManager { protected static final int OPERATING_MODE_DATA_INJECTION = 1; BaseEventQueue(Looper looper, SystemSensorManager manager, int mode) { - nSensorEventQueue = nativeInitBaseEventQueue(new WeakReference(this), - looper.getQueue(), mScratch, manager.mPackageName, mode); + nSensorEventQueue = nativeInitBaseEventQueue(manager.mNativeInstance, + new WeakReference<>(this), looper.getQueue(), mScratch, + manager.mContext.getPackageName(), mode, manager.mContext.getOpPackageName()); mCloseGuard.open("dispose"); mManager = manager; } @@ -339,7 +345,7 @@ public class SystemSensorManager extends SensorManager { for (int i=0 ; i(sensorManager); Sensor const* const* sensorList; - size_t count = mgr.getSensorList(&sensorList); + size_t count = mgr->getSensorList(&sensorList); if (size_t(next) >= count) { return -1; } @@ -174,9 +182,10 @@ nativeGetNextSensor(JNIEnv *env, jclass clazz, jobject sensor, jint next) return size_t(next) < count ? next : 0; } -static int nativeEnableDataInjection(JNIEnv *_env, jclass _this, jboolean enable) { - SensorManager& mgr(SensorManager::getInstance()); - return mgr.enableDataInjection(enable); +static int nativeEnableDataInjection(JNIEnv *_env, jclass _this, jlong sensorManager, + jboolean enable) { + SensorManager* mgr = reinterpret_cast(sensorManager); + return mgr->enableDataInjection(enable); } //---------------------------------------------------------------------------- @@ -281,12 +290,12 @@ private: } }; -static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jobject eventQWeak, jobject msgQ, - jfloatArray scratch, jstring packageName, jint mode) { - SensorManager& mgr(SensorManager::getInstance()); +static jlong nativeInitSensorEventQueue(JNIEnv *env, jclass clazz, jlong sensorManager, + jobject eventQWeak, jobject msgQ, jfloatArray scratch, jstring packageName, jint mode) { + SensorManager* mgr = reinterpret_cast(sensorManager); ScopedUtfChars packageUtf(env, packageName); String8 clientName(packageUtf.c_str()); - sp queue(mgr.createEventQueue(clientName, mode)); + sp queue(mgr->createEventQueue(clientName, mode)); sp messageQueue = android_os_MessageQueue_getMessageQueue(env, msgQ); if (messageQueue == NULL) { @@ -339,20 +348,23 @@ static JNINativeMethod gSystemSensorManagerMethods[] = { {"nativeClassInit", "()V", (void*)nativeClassInit }, + {"nativeCreate", + "(Ljava/lang/String;)J", + (void*)nativeCreate }, {"nativeGetNextSensor", - "(Landroid/hardware/Sensor;I)I", + "(JLandroid/hardware/Sensor;I)I", (void*)nativeGetNextSensor }, {"nativeEnableDataInjection", - "(Z)I", + "(JZ)I", (void*)nativeEnableDataInjection }, }; static JNINativeMethod gBaseEventQueueMethods[] = { {"nativeInitBaseEventQueue", - "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;[FLjava/lang/String;I)J", - (void*)nativeInitSensorEventQueue }, + "(JLjava/lang/ref/WeakReference;Landroid/os/MessageQueue;[FLjava/lang/String;ILjava/lang/String;)J", + (void*)nativeInitSensorEventQueue }, {"nativeEnableSensor", "(JIII)I", diff --git a/native/android/sensor.cpp b/native/android/sensor.cpp index 73b52aa2c6043..4e7c6bededbab 100644 --- a/native/android/sensor.cpp +++ b/native/android/sensor.cpp @@ -38,11 +38,6 @@ using android::String8; /*****************************************************************************/ -ASensorManager* ASensorManager_getInstance() -{ - return &SensorManager::getInstance(); -} - int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list) { diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 17b49399356a7..1366149a1c62e 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -744,6 +744,11 @@ public class AppOpsService extends IAppOpsService.Stub { } } + @Override + public int permissionToOpCode(String permission) { + return AppOpsManager.permissionToOpCode(permission); + } + void finishOperationLocked(Op op) { if (op.nesting <= 1) { if (op.nesting == 1) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 069878e91a8cc..eea6234cf3ca1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -47,6 +47,7 @@ import android.app.ProfilerInfo; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; +import android.content.pm.PermissionInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Point; @@ -6619,6 +6620,18 @@ public final class ActivityManagerService extends ActivityManagerNative return mActivityManagerService.mContext.getPackageManager() .getPackagesForUid(uid); } + + @Override + public boolean isRuntimePermission(String permission) { + try { + PermissionInfo info = mActivityManagerService.mContext.getPackageManager() + .getPermissionInfo(permission, 0); + return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS; + } catch (NameNotFoundException nnfe) { + Slog.e(TAG, "No such permission: "+ permission, nnfe); + } + return false; + } } class IntentFirewallInterface implements IntentFirewall.AMSInterface { diff --git a/services/core/jni/com_android_server_SystemServer.cpp b/services/core/jni/com_android_server_SystemServer.cpp index c50d63c58dd6d..64514a9f72e86 100644 --- a/services/core/jni/com_android_server_SystemServer.cpp +++ b/services/core/jni/com_android_server_SystemServer.cpp @@ -25,7 +25,7 @@ namespace android { -static void android_server_SystemServer_nativeInit(JNIEnv* /* env */, jobject /* clazz */) { +static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) { char propBuf[PROPERTY_VALUE_MAX]; property_get("system_init.startsensorservice", propBuf, "1"); if (strcmp(propBuf, "1") == 0) { @@ -39,7 +39,7 @@ static void android_server_SystemServer_nativeInit(JNIEnv* /* env */, jobject /* */ static JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ - { "nativeInit", "()V", (void*) android_server_SystemServer_nativeInit }, + { "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService }, }; int register_android_server_SystemServer(JNIEnv* env) diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 958bec488b3f2..2d265e2446f95 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -156,9 +156,9 @@ public final class SystemServer { private boolean mFirstBoot; /** - * Called to initialize native system services. + * Start the sensor service. */ - private static native void nativeInit(); + private static native void startSensorService(); /** * The main entry point from zygote. @@ -233,7 +233,6 @@ public final class SystemServer { // Initialize native services. System.loadLibrary("android_servers"); - nativeInit(); // Check whether we failed to shut down last time we tried. // This call may not return. @@ -359,6 +358,10 @@ public final class SystemServer { // Set up the Application instance for the system process and get started. mActivityManagerService.setSystemProcess(); + + // The sensor service needs access to package manager service, app ops + // service, and permissions service, therefore we start it after them. + startSensorService(); } /** diff --git a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java index 30d204f211795..4098b989a16bb 100644 --- a/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java +++ b/tests/permission/src/com/android/framework/permission/tests/ServiceManagerPermissionTests.java @@ -57,6 +57,11 @@ public class ServiceManagerPermissionTests extends TestCase { public String[] getPackagesForUid(int uid) { return new String[0]; } + + @Override + public boolean isRuntimePermission(String permission) { + return false; + } }; ServiceManagerNative.asInterface(BinderInternal.getContextObject()) .setPermissionController(pc);