强制执行分区存储
权限单次授权
- com.google.android.permissioncontroller
- com.android.permissioncontroller
PermissionController
packages/apps/PermissionController/src/com/android/permissioncontroller/permission/ui/GrantPermissionsActivity.java
public class GrantPermissionsActivity extends Activity
implements GrantPermissionsViewHandler.ResultListener {
@Override
public void onPermissionGrantResult(String name,
@GrantPermissionsViewHandler.Result int result) {
GroupState foregroundGroupState = getForegroundGroupState(name);
GroupState backgroundGroupState = getBackgroundGroupState(name);
--------------------------------------------------------------------------
logGrantPermissionActivityButtons(name, result);
switch (result) {
case CANCELED:
if (foregroundGroupState != null) {
reportRequestResult(foregroundGroupState.affectedPermissions,
PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_IGNORED);
}
if (backgroundGroupState != null) {
reportRequestResult(backgroundGroupState.affectedPermissions,
PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_IGNORED);
}
setResultAndFinish();
return;
case GRANTED_ALWAYS :
if (foregroundGroupState != null) {
onPermissionGrantResultSingleState(foregroundGroupState, true, false, false);
}
if (backgroundGroupState != null) {
onPermissionGrantResultSingleState(backgroundGroupState, true, false, false);
}
break;
case GRANTED_FOREGROUND_ONLY :
if (foregroundGroupState != null) {
onPermissionGrantResultSingleState(foregroundGroupState, true, false, false);
}
if (backgroundGroupState != null) {
onPermissionGrantResultSingleState(backgroundGroupState, false, false, false);
}
break;
case GRANTED_ONE_TIME:
if (foregroundGroupState != null) {
onPermissionGrantResultSingleState(foregroundGroupState, true, true, false);
}
if (backgroundGroupState != null) {
onPermissionGrantResultSingleState(backgroundGroupState, false, true, false);
}
break;
case DENIED :
if (foregroundGroupState != null) {
onPermissionGrantResultSingleState(foregroundGroupState, false, false, false);
}
if (backgroundGroupState != null) {
onPermissionGrantResultSingleState(backgroundGroupState, false, false, false);
}
break;
case DENIED_DO_NOT_ASK_AGAIN :
if (foregroundGroupState != null) {
onPermissionGrantResultSingleState(foregroundGroupState, false, false, true);
}
if (backgroundGroupState != null) {
onPermissionGrantResultSingleState(backgroundGroupState, false, false, true);
}
break;
}
------------------------------------------------------------------------------------------
}
}
PackageManager
public abstract class PackageManager {
/** {@hide} */
@NonNull
public static String permissionFlagToString(int flag) {
switch (flag) {
case FLAG_PERMISSION_GRANTED_BY_DEFAULT: return "GRANTED_BY_DEFAULT";
case FLAG_PERMISSION_POLICY_FIXED: return "POLICY_FIXED";
case FLAG_PERMISSION_SYSTEM_FIXED: return "SYSTEM_FIXED";
case FLAG_PERMISSION_USER_SET: return "USER_SET";
case FLAG_PERMISSION_USER_FIXED: return "USER_FIXED";
case FLAG_PERMISSION_REVIEW_REQUIRED: return "REVIEW_REQUIRED";
case FLAG_PERMISSION_REVOKE_WHEN_REQUESTED: return "REVOKE_WHEN_REQUESTED";
case FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED: return "USER_SENSITIVE_WHEN_GRANTED";
case FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED: return "USER_SENSITIVE_WHEN_DENIED";
case FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT: return "RESTRICTION_INSTALLER_EXEMPT";
case FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT: return "RESTRICTION_SYSTEM_EXEMPT";
case FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT: return "RESTRICTION_UPGRADE_EXEMPT";
case FLAG_PERMISSION_APPLY_RESTRICTION: return "APPLY_RESTRICTION";
case FLAG_PERMISSION_GRANTED_BY_ROLE: return "GRANTED_BY_ROLE";
case FLAG_PERMISSION_REVOKED_COMPAT: return "REVOKED_COMPAT";
case FLAG_PERMISSION_ONE_TIME: return "ONE_TIME";
case FLAG_PERMISSION_AUTO_REVOKED: return "AUTO_REVOKED";
default: return Integer.toString(flag);
}
}
}
权限自动重置
packages/apps/PermissionController/tests/mocking/src/com/android/permissioncontroller/permission/utils/GrantRevokeTests.kt
fun setAutoRevoke(enabled: Boolean) {
GlobalScope.launch(IPC) {
val aom = PermissionControllerApplication.get()
.getSystemService(AppOpsManager::class.java)!!
val uid = LightPackageInfoLiveData[packageName, user].getInitializedValue()?.uid
if (uid != null) {
Log.i(LOG_TAG, "sessionId $sessionId setting auto revoke enabled to $enabled for" +
"$packageName $user")
val tag = if (enabled) {
APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__SWITCH_ENABLED
} else {
APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION__ACTION__SWITCH_DISABLED
}
PermissionControllerStatsLog.write(
APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION, sessionId, uid, packageName,
tag)
val mode = if (enabled) {
MODE_ALLOWED
} else {
MODE_IGNORED
}
aom.setUidMode(OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, uid, mode)
}
}
}
后台位置信息限制
为降低耗电量,Android 8.0(API 级别 26)会对后台应用检索用户当前位置信息的频率进行限制。应用每小时仅接收几次位置信息更新。
<!-- Used for permissions that allow accessing the device location. -->
<permission-group android:name="android.permission-group.LOCATION"
android:icon="@drawable/perm_group_location"
android:label="@string/permgrouplab_location"
android:description="@string/permgroupdesc_location"
android:priority="400" />
<!-- Allows an app to access precise location.
Alternatively, you might want {@link #ACCESS_COARSE_LOCATION}.
<p>Protection level: dangerous
-->
<permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_accessFineLocation"
android:description="@string/permdesc_accessFineLocation"
android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
android:protectionLevel="dangerous|instant" />
<!-- Allows an app to access approximate location.
Alternatively, you might want {@link #ACCESS_FINE_LOCATION}.
<p>Protection level: dangerous
-->
<permission android:name="android.permission.ACCESS_COARSE_LOCATION"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_accessCoarseLocation"
android:description="@string/permdesc_accessCoarseLocation"
android:backgroundPermission="android.permission.ACCESS_BACKGROUND_LOCATION"
android:protectionLevel="dangerous|instant" />
<!-- Allows an app to access location in the background. If you're requesting this permission,
you must also request either {@link #ACCESS_COARSE_LOCATION} or
{@link #ACCESS_FINE_LOCATION}. Requesting this permission by itself doesn't give you
location access.
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_accessBackgroundLocation"
android:permissionFlags="hardRestricted"
android:description="@string/permdesc_accessBackgroundLocation"
android:protectionLevel="dangerous|instant" />
Android 11 中的软件包可见性
Android 11 更改了应用查询用户已在设备上安装的其他应用以及与之交互的方式。使用新的
如果您的应用以 Android 11 为目标平台,您可能需要在应用的清单文件中添加
<!-- Allows query of any normal app on the device, regardless of manifest declarations.
<p>Protection level: normal -->
<permission android:name="android.permission.QUERY_ALL_PACKAGES"
android:protectionLevel="normal" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
Android 11 中的前台服务
在 Android 11(API 级别 30)中,前台服务何时可以访问设备的位置信息、摄像头和麦克风发生了一些变化。这些变更有助于保护敏感的用户数据。
确定应用中的哪些服务受到影响 测试您的应用时,请启动其前台服务。如果启动的服务对位置信息、麦克风和摄像头的访问受到限制,Logcat 中就会显示以下消息:
Foreground service started from background can not have location/camera/microphone access: service SERVICE_NAME