Loading core/java/android/provider/Settings.java +21 −0 Original line number Diff line number Diff line Loading @@ -6363,6 +6363,27 @@ public final class Settings { @Readable public static final String ALLOW_MOCK_LOCATION = "mock_location"; /** * This is used by Bluetooth Manager to store adapter name * @hide */ @Readable(maxTargetSdk = Build.VERSION_CODES.S) public static final String BLUETOOTH_NAME = "bluetooth_name"; /** * This is used by Bluetooth Manager to store adapter address * @hide */ @Readable(maxTargetSdk = Build.VERSION_CODES.S) public static final String BLUETOOTH_ADDRESS = "bluetooth_address"; /** * This is used by Bluetooth Manager to store whether adapter address is valid * @hide */ @Readable(maxTargetSdk = Build.VERSION_CODES.S) public static final String BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid"; /** * Setting to indicate that on device captions are enabled. * Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +1 −1 Original line number Diff line number Diff line Loading @@ -2102,7 +2102,7 @@ public class SettingsProvider extends ContentProvider { } if ((ai.flags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { // Skip checking readable annotations for test_only apps checkReadableAnnotation(settingsType, settingName, ai.targetSandboxVersion); checkReadableAnnotation(settingsType, settingName, ai.targetSdkVersion); } /** * some settings need additional permission check, this is to have a matching security Loading services/core/java/com/android/server/BluetoothManagerService.java +8 −12 Original line number Diff line number Diff line Loading @@ -110,10 +110,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final String BLUETOOTH_PRIVILEGED = android.Manifest.permission.BLUETOOTH_PRIVILEGED; private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid"; private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address"; private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name"; private static final int ACTIVE_LOG_MAX_SIZE = 20; private static final int CRASH_LOG_MAX_SIZE = 100; Loading Loading @@ -636,7 +632,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mContext.getResources() .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation) && Settings.Secure.getIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0, mUserId) Settings.Secure.BLUETOOTH_NAME, 0, mUserId) == 0) { // if the valid flag is not set, don't load the address and name if (DBG) { Loading @@ -645,9 +641,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return; } mName = Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mUserId); mContentResolver, Settings.Secure.BLUETOOTH_NAME, mUserId); mAddress = Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mUserId); mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, mUserId); if (DBG) { Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress); } Loading @@ -661,30 +657,30 @@ class BluetoothManagerService extends IBluetoothManager.Stub { */ private void storeNameAndAddress(String name, String address) { if (name != null) { Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name, Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_NAME, name, mUserId); mName = name; if (DBG) { Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mContentResolver, Settings.Secure.BLUETOOTH_NAME, mUserId)); } } if (address != null) { Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, address, mUserId); mAddress = address; if (DBG) { Slog.d(TAG, "Stored Bluetoothaddress: " + Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, mUserId)); } } if ((name != null) && (address != null)) { Settings.Secure.putIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1, Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDR_VALID, 1, mUserId); } } Loading services/core/java/com/android/server/policy/AppOpsPolicy.java +2 −3 Original line number Diff line number Diff line Loading @@ -196,9 +196,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat } private static boolean isHotwordDetectionServiceRequired(PackageManager pm) { // The HotwordDetectionService APIs aren't ready yet for Auto or TV. return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)); // Usage of the HotwordDetectionService won't be enforced until a later release. return false; } @Override Loading services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java +26 −10 Original line number Diff line number Diff line Loading @@ -125,16 +125,27 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware * originator temporarily doesn't have the right permissions to use this service. */ private void enforcePermissionsForPreflight(@NonNull Identity identity) { enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO); enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD); enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, /* allowSoftDenial= */ true); enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD, /* allowSoftDenial= */ true); } /** * Throws a {@link SecurityException} iff the originator has permission to receive data. */ void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) { enforcePermissionForDataDelivery(mContext, identity, RECORD_AUDIO, reason); // SoundTrigger data is treated the same as Hotword-source audio. This should incur the // HOTWORD op instead of the RECORD_AUDIO op. The RECORD_AUDIO permission is still required, // and since this is a data delivery check, soft denials aren't accepted. // TODO(b/212458940): Find a better approach for checking the permission that doesn't // require the client to know such details about the permissions logic. enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, /* allowSoftDenial= */ false); int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD); mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, identity.uid, identity.packageName, identity.attributionTag, reason); enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD, reason); } Loading Loading @@ -163,20 +174,25 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware /** * Throws a {@link SecurityException} if originator permanently doesn't have the given * permission. * Soft (temporary) denials are considered OK for preflight purposes. * * @param context A {@link Context}, used for permission checks. * @param identity The identity to check. * @param permission The identifier of the permission we want to check. * @param allowSoftDenial If true, the operation succeeds even for soft (temporary) denials. */ // TODO: Consider splitting up this method instead of using `allowSoftDenial`, to make it // clearer when soft denials are not allowed. private static void enforcePermissionForPreflight(@NonNull Context context, @NonNull Identity identity, @NonNull String permission) { @NonNull Identity identity, @NonNull String permission, boolean allowSoftDenial) { final int status = PermissionUtil.checkPermissionForPreflight(context, identity, permission); switch (status) { case PermissionChecker.PERMISSION_GRANTED: return; case PermissionChecker.PERMISSION_SOFT_DENIED: if (allowSoftDenial) { return; } // else fall through case PermissionChecker.PERMISSION_HARD_DENIED: throw new SecurityException( String.format("Failed to obtain permission %s for identity %s", permission, Loading Loading
core/java/android/provider/Settings.java +21 −0 Original line number Diff line number Diff line Loading @@ -6363,6 +6363,27 @@ public final class Settings { @Readable public static final String ALLOW_MOCK_LOCATION = "mock_location"; /** * This is used by Bluetooth Manager to store adapter name * @hide */ @Readable(maxTargetSdk = Build.VERSION_CODES.S) public static final String BLUETOOTH_NAME = "bluetooth_name"; /** * This is used by Bluetooth Manager to store adapter address * @hide */ @Readable(maxTargetSdk = Build.VERSION_CODES.S) public static final String BLUETOOTH_ADDRESS = "bluetooth_address"; /** * This is used by Bluetooth Manager to store whether adapter address is valid * @hide */ @Readable(maxTargetSdk = Build.VERSION_CODES.S) public static final String BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid"; /** * Setting to indicate that on device captions are enabled. * Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +1 −1 Original line number Diff line number Diff line Loading @@ -2102,7 +2102,7 @@ public class SettingsProvider extends ContentProvider { } if ((ai.flags & ApplicationInfo.FLAG_TEST_ONLY) == 0) { // Skip checking readable annotations for test_only apps checkReadableAnnotation(settingsType, settingName, ai.targetSandboxVersion); checkReadableAnnotation(settingsType, settingName, ai.targetSdkVersion); } /** * some settings need additional permission check, this is to have a matching security Loading
services/core/java/com/android/server/BluetoothManagerService.java +8 −12 Original line number Diff line number Diff line Loading @@ -110,10 +110,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub { private static final String BLUETOOTH_PRIVILEGED = android.Manifest.permission.BLUETOOTH_PRIVILEGED; private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID = "bluetooth_addr_valid"; private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS = "bluetooth_address"; private static final String SECURE_SETTINGS_BLUETOOTH_NAME = "bluetooth_name"; private static final int ACTIVE_LOG_MAX_SIZE = 20; private static final int CRASH_LOG_MAX_SIZE = 100; Loading Loading @@ -636,7 +632,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub { if (mContext.getResources() .getBoolean(com.android.internal.R.bool.config_bluetooth_address_validation) && Settings.Secure.getIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 0, mUserId) Settings.Secure.BLUETOOTH_NAME, 0, mUserId) == 0) { // if the valid flag is not set, don't load the address and name if (DBG) { Loading @@ -645,9 +641,9 @@ class BluetoothManagerService extends IBluetoothManager.Stub { return; } mName = Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mUserId); mContentResolver, Settings.Secure.BLUETOOTH_NAME, mUserId); mAddress = Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mUserId); mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, mUserId); if (DBG) { Slog.d(TAG, "Stored bluetooth Name=" + mName + ",Address=" + mAddress); } Loading @@ -661,30 +657,30 @@ class BluetoothManagerService extends IBluetoothManager.Stub { */ private void storeNameAndAddress(String name, String address) { if (name != null) { Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, name, Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_NAME, name, mUserId); mName = name; if (DBG) { Slog.d(TAG, "Stored Bluetooth name: " + Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_NAME, mContentResolver, Settings.Secure.BLUETOOTH_NAME, mUserId)); } } if (address != null) { Settings.Secure.putStringForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, Settings.Secure.putStringForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, address, mUserId); mAddress = address; if (DBG) { Slog.d(TAG, "Stored Bluetoothaddress: " + Settings.Secure.getStringForUser( mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDRESS, mContentResolver, Settings.Secure.BLUETOOTH_ADDRESS, mUserId)); } } if ((name != null) && (address != null)) { Settings.Secure.putIntForUser(mContentResolver, SECURE_SETTINGS_BLUETOOTH_ADDR_VALID, 1, Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.BLUETOOTH_ADDR_VALID, 1, mUserId); } } Loading
services/core/java/com/android/server/policy/AppOpsPolicy.java +2 −3 Original line number Diff line number Diff line Loading @@ -196,9 +196,8 @@ public final class AppOpsPolicy implements AppOpsManagerInternal.CheckOpsDelegat } private static boolean isHotwordDetectionServiceRequired(PackageManager pm) { // The HotwordDetectionService APIs aren't ready yet for Auto or TV. return !(pm.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) || pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)); // Usage of the HotwordDetectionService won't be enforced until a later release. return false; } @Override Loading
services/core/java/com/android/server/soundtrigger_middleware/SoundTriggerMiddlewarePermission.java +26 −10 Original line number Diff line number Diff line Loading @@ -125,16 +125,27 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware * originator temporarily doesn't have the right permissions to use this service. */ private void enforcePermissionsForPreflight(@NonNull Identity identity) { enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO); enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD); enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, /* allowSoftDenial= */ true); enforcePermissionForPreflight(mContext, identity, CAPTURE_AUDIO_HOTWORD, /* allowSoftDenial= */ true); } /** * Throws a {@link SecurityException} iff the originator has permission to receive data. */ void enforcePermissionsForDataDelivery(@NonNull Identity identity, @NonNull String reason) { enforcePermissionForDataDelivery(mContext, identity, RECORD_AUDIO, reason); // SoundTrigger data is treated the same as Hotword-source audio. This should incur the // HOTWORD op instead of the RECORD_AUDIO op. The RECORD_AUDIO permission is still required, // and since this is a data delivery check, soft denials aren't accepted. // TODO(b/212458940): Find a better approach for checking the permission that doesn't // require the client to know such details about the permissions logic. enforcePermissionForPreflight(mContext, identity, RECORD_AUDIO, /* allowSoftDenial= */ false); int hotwordOp = AppOpsManager.strOpToOp(AppOpsManager.OPSTR_RECORD_AUDIO_HOTWORD); mContext.getSystemService(AppOpsManager.class).noteOpNoThrow(hotwordOp, identity.uid, identity.packageName, identity.attributionTag, reason); enforcePermissionForDataDelivery(mContext, identity, CAPTURE_AUDIO_HOTWORD, reason); } Loading Loading @@ -163,20 +174,25 @@ public class SoundTriggerMiddlewarePermission implements ISoundTriggerMiddleware /** * Throws a {@link SecurityException} if originator permanently doesn't have the given * permission. * Soft (temporary) denials are considered OK for preflight purposes. * * @param context A {@link Context}, used for permission checks. * @param identity The identity to check. * @param permission The identifier of the permission we want to check. * @param allowSoftDenial If true, the operation succeeds even for soft (temporary) denials. */ // TODO: Consider splitting up this method instead of using `allowSoftDenial`, to make it // clearer when soft denials are not allowed. private static void enforcePermissionForPreflight(@NonNull Context context, @NonNull Identity identity, @NonNull String permission) { @NonNull Identity identity, @NonNull String permission, boolean allowSoftDenial) { final int status = PermissionUtil.checkPermissionForPreflight(context, identity, permission); switch (status) { case PermissionChecker.PERMISSION_GRANTED: return; case PermissionChecker.PERMISSION_SOFT_DENIED: if (allowSoftDenial) { return; } // else fall through case PermissionChecker.PERMISSION_HARD_DENIED: throw new SecurityException( String.format("Failed to obtain permission %s for identity %s", permission, Loading