Throw SecurityException regarding sampling rates.

When apps target SDK >= S, run in debug mode, request a sampling rate greater than 200 Hz and do not have the HIGH_SAMPLING_RATE_SENSORS permission, the SystemSensorManager throws a SecurityException  when the apps try to establish a (direct or event) connection.

Test: atest CtsSensorTestCases CtsSensorRatePermissionTestCases
Bug: 136069189
Change-Id: I33893c93949f0f055ce5ded1a5ed9d188de709ed
This commit is contained in:
Anh Pham
2021-02-08 13:38:46 +01:00
parent f437e35728
commit 97f66fd20c

View File

@@ -16,11 +16,18 @@
package android.hardware;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -54,6 +61,19 @@ public class SystemSensorManager extends SensorManager {
private static final boolean DEBUG_DYNAMIC_SENSOR = true;
private static final int MIN_DIRECT_CHANNEL_BUFFER_SIZE = 104;
private static final int MAX_LISTENER_COUNT = 128;
private static final int CAPPED_SAMPLING_PERIOD_US = 5000;
private static final int CAPPED_SAMPLING_RATE_LEVEL = SensorDirectChannel.RATE_NORMAL;
private static final String HIGH_SAMPLING_RATE_SENSORS_PERMISSION =
"android.permisison.HIGH_SAMPLING_RATE_SENSORS";
/**
* For apps targeting S and above, a SecurityException is thrown when they do not have
* HIGH_SAMPLING_RATE_SENSORS permission, run in debug mode, and request sampling rates that
* are faster than 200 Hz.
*/
@ChangeId
@EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R)
static final long CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION = 136069189L;
private static native void nativeClassInit();
private static native long nativeCreate(String opPackageName);
@@ -98,6 +118,8 @@ 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 boolean mIsPackageDebuggable;
private final boolean mHasHighSamplingRateSensorsPermission;
private final Context mContext;
private final long mNativeInstance;
@@ -111,9 +133,16 @@ public class SystemSensorManager extends SensorManager {
}
mMainLooper = mainLooper;
mTargetSdkLevel = context.getApplicationInfo().targetSdkVersion;
ApplicationInfo appInfo = context.getApplicationInfo();
mTargetSdkLevel = appInfo.targetSdkVersion;
mContext = context;
mNativeInstance = nativeCreate(context.getOpPackageName());
mIsPackageDebuggable = (0 != (appInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE));
PackageManager packageManager = context.getPackageManager();
mHasHighSamplingRateSensorsPermission =
(PERMISSION_GRANTED == packageManager.checkPermission(
HIGH_SAMPLING_RATE_SENSORS_PERMISSION,
appInfo.packageName));
// initialize the sensor list
for (int index = 0;; ++index) {
@@ -542,10 +571,18 @@ public class SystemSensorManager extends SensorManager {
}
int sensorHandle = (sensor == null) ? -1 : sensor.getHandle();
if (Compatibility.isChangeEnabled(CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION)
&& rate > CAPPED_SAMPLING_RATE_LEVEL
&& mIsPackageDebuggable
&& !mHasHighSamplingRateSensorsPermission) {
Compatibility.reportChange(CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION);
throw new SecurityException("To use the sampling rate level " + rate
+ ", app needs to declare the normal permission"
+ " HIGH_SAMPLING_RATE_SENSORS.");
}
int ret = nativeConfigDirectChannel(
mNativeInstance, channel.getNativeHandle(), sensorHandle, rate);
if (rate == SensorDirectChannel.RATE_STOP) {
return (ret == 0) ? 1 : 0;
} else {
@@ -745,6 +782,15 @@ public class SystemSensorManager extends SensorManager {
Sensor sensor, int rateUs, int maxBatchReportLatencyUs) {
if (mNativeSensorEventQueue == 0) throw new NullPointerException();
if (sensor == null) throw new NullPointerException();
if (Compatibility.isChangeEnabled(CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION)
&& rateUs < CAPPED_SAMPLING_PERIOD_US
&& mManager.mIsPackageDebuggable
&& !mManager.mHasHighSamplingRateSensorsPermission) {
Compatibility.reportChange(CHANGE_ID_SAMPLING_RATE_SENSORS_PERMISSION);
throw new SecurityException("To use the sampling rate of " + rateUs
+ " microseconds, app needs to declare the normal permission"
+ " HIGH_SAMPLING_RATE_SENSORS.");
}
return nativeEnableSensor(mNativeSensorEventQueue, sensor.getHandle(), rateUs,
maxBatchReportLatencyUs);
}