Loading apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -32,8 +32,8 @@ import org.junit.Test; @LargeTest public class TextClassificationManagerPerfTest { private static final String ALLOWLISTED_WRITE_DEVICE_CONFIG_PERMISSION = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"; private static final String WRITE_DEVICE_CONFIG_PERMISSION = "android.permission.WRITE_DEVICE_CONFIG"; @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); Loading @@ -44,7 +44,7 @@ public class TextClassificationManagerPerfTest { public static void setUpClass() { InstrumentationRegistry.getInstrumentation().getUiAutomation() .adoptShellPermissionIdentity( ALLOWLISTED_WRITE_DEVICE_CONFIG_PERMISSION); WRITE_DEVICE_CONFIG_PERMISSION); } @AfterClass Loading core/api/system-current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -33,7 +33,6 @@ package android { field public static final String ADD_TRUSTED_DISPLAY = "android.permission.ADD_TRUSTED_DISPLAY"; field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY"; field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE"; field public static final String ALLOWLISTED_WRITE_DEVICE_CONFIG = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"; field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; field public static final String ALLOW_PLACE_IN_MULTI_PANE_SETTINGS = "android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS"; field public static final String ALLOW_SLIPPERY_TOUCHES = "android.permission.ALLOW_SLIPPERY_TOUCHES"; Loading Loading @@ -285,7 +284,6 @@ package android { field public static final String READ_SYSTEM_UPDATE_INFO = "android.permission.READ_SYSTEM_UPDATE_INFO"; field public static final String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL"; field public static final String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL"; field public static final String READ_WRITE_SYNC_DISABLED_MODE_CONFIG = "android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG"; field public static final String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS"; field public static final String RECEIVE_BLUETOOTH_MAP = "android.permission.RECEIVE_BLUETOOTH_MAP"; field public static final String RECEIVE_DATA_ACTIVITY_CHANGE = "android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"; core/api/test-current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ package android { field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY"; field public static final String ALLOWLISTED_WRITE_DEVICE_CONFIG = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"; field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA"; field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE"; Loading Loading @@ -40,7 +39,6 @@ package android { field public static final String QUERY_AUDIO_STATE = "android.permission.QUERY_AUDIO_STATE"; field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS"; field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE"; field public static final String READ_WRITE_SYNC_DISABLED_MODE_CONFIG = "android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG"; field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO"; field public static final String REMAP_MODIFIER_KEYS = "android.permission.REMAP_MODIFIER_KEYS"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; Loading core/res/AndroidManifest.xml +0 −10 Original line number Diff line number Diff line Loading @@ -4187,16 +4187,6 @@ <permission android:name="android.permission.WRITE_DEVICE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> <!-- @SystemApi @TestApi @hide Allows an application to modify only allowlisted settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> <!-- @SystemApi @TestApi @hide Allows an application to read/write sync disabled mode config. <p>Not for use by third-party applications. --> <permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> <!-- @SystemApi @hide Allows an application to read config settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.READ_DEVICE_CONFIG" Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +11 −65 Original line number Diff line number Diff line Loading @@ -1175,7 +1175,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix); } enforceDeviceConfigWritePermission(getContext(), keyValues.keySet()); enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); final String callingPackage = resolveCallingPackage(); synchronized (mLock) { Loading @@ -1194,8 +1194,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "setSyncDisabledModeConfig(" + syncDisabledMode + ")"); } enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG, Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG); enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); synchronized (mLock) { setSyncDisabledModeConfigLocked(syncDisabledMode); Loading @@ -1207,8 +1206,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "getSyncDisabledModeConfig"); } enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG, Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG); enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); synchronized (mLock) { return getSyncDisabledModeConfigLocked(); Loading Loading @@ -1293,14 +1291,13 @@ public class SettingsProvider extends ContentProvider { private boolean mutateConfigSetting(String name, String value, String prefix, boolean makeDefault, int operation, int mode) { enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); final String callingPackage = resolveCallingPackage(); boolean someSettingChanged = false; // Perform the mutation. synchronized (mLock) { switch (operation) { case MUTATION_OPERATION_INSERT: { enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name)); someSettingChanged = mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM, name, value, null, makeDefault, true, callingPackage, false, null, Loading @@ -1309,17 +1306,12 @@ public class SettingsProvider extends ContentProvider { } case MUTATION_OPERATION_DELETE: { enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name)); someSettingChanged = mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM, name, false, null); break; } case MUTATION_OPERATION_RESET: { enforceDeviceConfigWritePermission(getContext(), getAllConfigFlags(prefix).keySet()); someSettingChanged = mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM, callingPackage, mode, null, prefix); break; Loading Loading @@ -1483,7 +1475,7 @@ public class SettingsProvider extends ContentProvider { boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode, boolean overrideableByRestore) { // Make sure the caller can change the settings - treated as secure. enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId); Loading Loading @@ -1780,7 +1772,7 @@ public class SettingsProvider extends ContentProvider { boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode, boolean overrideableByRestore) { // Make sure the caller can change the settings. enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId); Loading Loading @@ -2313,57 +2305,11 @@ public class SettingsProvider extends ContentProvider { } } private void enforceHasAtLeastOnePermission(String ...permissions) { for (String permission : permissions) { private void enforceWritePermission(String permission) { if (getContext().checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("Permission denial, must have one of: " + Arrays.toString(permissions)); } /** * Throws an exception if write permissions are not granted for {@code flags}. * <p> * Write permissions are granted if the calling UID is root, or the * WRITE_DEVICE_CONFIG permission is granted, or the WRITE_DEVICE_CONFIG_ALLOWLIST * permission is granted and each flag in {@code flags} is allowlisted in {@code * WRITABLE_FLAG_ALLOWLIST_FLAG}. * * @param context the {@link Context} this is called in * @param flags a list of flags to check, each one of the form 'namespace/flagName' * * @throws SecurityException if the above criteria are not met. * @hide */ private void enforceDeviceConfigWritePermission( @NonNull Context context, @NonNull Set<String> flags) { boolean hasAllowlistPermission = context.checkCallingOrSelfPermission( Manifest.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG) == PackageManager.PERMISSION_GRANTED; boolean hasWritePermission = context.checkCallingOrSelfPermission( Manifest.permission.WRITE_DEVICE_CONFIG) == PackageManager.PERMISSION_GRANTED; boolean isRoot = Binder.getCallingUid() == Process.ROOT_UID; if (isRoot || hasWritePermission) { return; } else if (hasAllowlistPermission) { for (String flag : flags) { if (!DeviceConfig.getAdbWritableFlags().contains(flag)) { throw new SecurityException("Permission denial for flag '" + flag + "'; allowlist permission granted, but must add flag to the allowlist."); } } } else { throw new SecurityException("Permission denial to mutate flag, must have root, " + "WRITE_DEVICE_CONFIG, or ALLOWLISTED_WRITE_DEVICE_CONFIG"); != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Permission denial: writing to settings requires:" + permission); } } Loading Loading
apct-tests/perftests/textclassifier/src/android/view/textclassifier/TextClassificationManagerPerfTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -32,8 +32,8 @@ import org.junit.Test; @LargeTest public class TextClassificationManagerPerfTest { private static final String ALLOWLISTED_WRITE_DEVICE_CONFIG_PERMISSION = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"; private static final String WRITE_DEVICE_CONFIG_PERMISSION = "android.permission.WRITE_DEVICE_CONFIG"; @Rule public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); Loading @@ -44,7 +44,7 @@ public class TextClassificationManagerPerfTest { public static void setUpClass() { InstrumentationRegistry.getInstrumentation().getUiAutomation() .adoptShellPermissionIdentity( ALLOWLISTED_WRITE_DEVICE_CONFIG_PERMISSION); WRITE_DEVICE_CONFIG_PERMISSION); } @AfterClass Loading
core/api/system-current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -33,7 +33,6 @@ package android { field public static final String ADD_TRUSTED_DISPLAY = "android.permission.ADD_TRUSTED_DISPLAY"; field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY"; field public static final String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE"; field public static final String ALLOWLISTED_WRITE_DEVICE_CONFIG = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"; field public static final String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; field public static final String ALLOW_PLACE_IN_MULTI_PANE_SETTINGS = "android.permission.ALLOW_PLACE_IN_MULTI_PANE_SETTINGS"; field public static final String ALLOW_SLIPPERY_TOUCHES = "android.permission.ALLOW_SLIPPERY_TOUCHES"; Loading Loading @@ -285,7 +284,6 @@ package android { field public static final String READ_SYSTEM_UPDATE_INFO = "android.permission.READ_SYSTEM_UPDATE_INFO"; field public static final String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL"; field public static final String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL"; field public static final String READ_WRITE_SYNC_DISABLED_MODE_CONFIG = "android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG"; field public static final String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS"; field public static final String RECEIVE_BLUETOOTH_MAP = "android.permission.RECEIVE_BLUETOOTH_MAP"; field public static final String RECEIVE_DATA_ACTIVITY_CHANGE = "android.permission.RECEIVE_DATA_ACTIVITY_CHANGE";
core/api/test-current.txt +0 −2 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ package android { field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; field public static final String ADJUST_RUNTIME_PERMISSIONS_POLICY = "android.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY"; field public static final String ALLOWLISTED_WRITE_DEVICE_CONFIG = "android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG"; field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS"; field public static final String BACKGROUND_CAMERA = "android.permission.BACKGROUND_CAMERA"; field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE"; Loading Loading @@ -40,7 +39,6 @@ package android { field public static final String QUERY_AUDIO_STATE = "android.permission.QUERY_AUDIO_STATE"; field public static final String READ_CELL_BROADCASTS = "android.permission.READ_CELL_BROADCASTS"; field public static final String READ_PRIVILEGED_PHONE_STATE = "android.permission.READ_PRIVILEGED_PHONE_STATE"; field public static final String READ_WRITE_SYNC_DISABLED_MODE_CONFIG = "android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG"; field public static final String RECORD_BACKGROUND_AUDIO = "android.permission.RECORD_BACKGROUND_AUDIO"; field public static final String REMAP_MODIFIER_KEYS = "android.permission.REMAP_MODIFIER_KEYS"; field public static final String REMOVE_TASKS = "android.permission.REMOVE_TASKS"; Loading
core/res/AndroidManifest.xml +0 −10 Original line number Diff line number Diff line Loading @@ -4187,16 +4187,6 @@ <permission android:name="android.permission.WRITE_DEVICE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> <!-- @SystemApi @TestApi @hide Allows an application to modify only allowlisted settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> <!-- @SystemApi @TestApi @hide Allows an application to read/write sync disabled mode config. <p>Not for use by third-party applications. --> <permission android:name="android.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG" android:protectionLevel="signature|verifier|configurator"/> <!-- @SystemApi @hide Allows an application to read config settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.READ_DEVICE_CONFIG" Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +11 −65 Original line number Diff line number Diff line Loading @@ -1175,7 +1175,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "setAllConfigSettings for prefix: " + prefix); } enforceDeviceConfigWritePermission(getContext(), keyValues.keySet()); enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); final String callingPackage = resolveCallingPackage(); synchronized (mLock) { Loading @@ -1194,8 +1194,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "setSyncDisabledModeConfig(" + syncDisabledMode + ")"); } enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG, Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG); enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); synchronized (mLock) { setSyncDisabledModeConfigLocked(syncDisabledMode); Loading @@ -1207,8 +1206,7 @@ public class SettingsProvider extends ContentProvider { Slog.v(LOG_TAG, "getSyncDisabledModeConfig"); } enforceHasAtLeastOnePermission(Manifest.permission.WRITE_DEVICE_CONFIG, Manifest.permission.READ_WRITE_SYNC_DISABLED_MODE_CONFIG); enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); synchronized (mLock) { return getSyncDisabledModeConfigLocked(); Loading Loading @@ -1293,14 +1291,13 @@ public class SettingsProvider extends ContentProvider { private boolean mutateConfigSetting(String name, String value, String prefix, boolean makeDefault, int operation, int mode) { enforceWritePermission(Manifest.permission.WRITE_DEVICE_CONFIG); final String callingPackage = resolveCallingPackage(); boolean someSettingChanged = false; // Perform the mutation. synchronized (mLock) { switch (operation) { case MUTATION_OPERATION_INSERT: { enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name)); someSettingChanged = mSettingsRegistry.insertSettingLocked(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM, name, value, null, makeDefault, true, callingPackage, false, null, Loading @@ -1309,17 +1306,12 @@ public class SettingsProvider extends ContentProvider { } case MUTATION_OPERATION_DELETE: { enforceDeviceConfigWritePermission(getContext(), Collections.singleton(name)); someSettingChanged = mSettingsRegistry.deleteSettingLocked(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM, name, false, null); break; } case MUTATION_OPERATION_RESET: { enforceDeviceConfigWritePermission(getContext(), getAllConfigFlags(prefix).keySet()); someSettingChanged = mSettingsRegistry.resetSettingsLocked(SETTINGS_TYPE_CONFIG, UserHandle.USER_SYSTEM, callingPackage, mode, null, prefix); break; Loading Loading @@ -1483,7 +1475,7 @@ public class SettingsProvider extends ContentProvider { boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode, boolean overrideableByRestore) { // Make sure the caller can change the settings - treated as secure. enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId); Loading Loading @@ -1780,7 +1772,7 @@ public class SettingsProvider extends ContentProvider { boolean makeDefault, int requestingUserId, int operation, boolean forceNotify, int mode, boolean overrideableByRestore) { // Make sure the caller can change the settings. enforceHasAtLeastOnePermission(Manifest.permission.WRITE_SECURE_SETTINGS); enforceWritePermission(Manifest.permission.WRITE_SECURE_SETTINGS); // Resolve the userId on whose behalf the call is made. final int callingUserId = resolveCallingUserIdEnforcingPermissionsLocked(requestingUserId); Loading Loading @@ -2313,57 +2305,11 @@ public class SettingsProvider extends ContentProvider { } } private void enforceHasAtLeastOnePermission(String ...permissions) { for (String permission : permissions) { private void enforceWritePermission(String permission) { if (getContext().checkCallingOrSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { return; } } throw new SecurityException("Permission denial, must have one of: " + Arrays.toString(permissions)); } /** * Throws an exception if write permissions are not granted for {@code flags}. * <p> * Write permissions are granted if the calling UID is root, or the * WRITE_DEVICE_CONFIG permission is granted, or the WRITE_DEVICE_CONFIG_ALLOWLIST * permission is granted and each flag in {@code flags} is allowlisted in {@code * WRITABLE_FLAG_ALLOWLIST_FLAG}. * * @param context the {@link Context} this is called in * @param flags a list of flags to check, each one of the form 'namespace/flagName' * * @throws SecurityException if the above criteria are not met. * @hide */ private void enforceDeviceConfigWritePermission( @NonNull Context context, @NonNull Set<String> flags) { boolean hasAllowlistPermission = context.checkCallingOrSelfPermission( Manifest.permission.ALLOWLISTED_WRITE_DEVICE_CONFIG) == PackageManager.PERMISSION_GRANTED; boolean hasWritePermission = context.checkCallingOrSelfPermission( Manifest.permission.WRITE_DEVICE_CONFIG) == PackageManager.PERMISSION_GRANTED; boolean isRoot = Binder.getCallingUid() == Process.ROOT_UID; if (isRoot || hasWritePermission) { return; } else if (hasAllowlistPermission) { for (String flag : flags) { if (!DeviceConfig.getAdbWritableFlags().contains(flag)) { throw new SecurityException("Permission denial for flag '" + flag + "'; allowlist permission granted, but must add flag to the allowlist."); } } } else { throw new SecurityException("Permission denial to mutate flag, must have root, " + "WRITE_DEVICE_CONFIG, or ALLOWLISTED_WRITE_DEVICE_CONFIG"); != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Permission denial: writing to settings requires:" + permission); } } Loading