xref: /frameworks/base/core/java/android/app/Activity.java5076
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
5077 if (requestCode < 0) {
5078 throw new IllegalArgumentException("requestCode should be >= 0");
5079 }
5080 if (mHasCurrentPermissionsRequest) {
5081 (TAG, "Can request only one set of permissions at a time");
5082 // Dispatch the callback with empty arrays which means a cancellation.
5083 onRequestPermissionsResult(requestCode, new String[0], new int[0]);
5084 return;
5085 }
5086 Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
5087 startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
5088 mHasCurrentPermissionsRequest = true;
5089 }
xref: /frameworks/base/core/java/android/content/pm/
2968 @SystemApi
2969 public static final String ACTION_REQUEST_PERMISSIONS =
2970 ".REQUEST_PERMISSIONS";
4263 @NonNull
4264 @UnsupportedAppUsage
4265 public Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {
4266 if ((permissions)) {
4267 throw new IllegalArgumentException("permission cannot be null or empty");
4268 }
4269 Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);
4270 (EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);
4271 (getPermissionControllerPackageName());
4272 return intent;
4273 }
xref: /packages/apps/PermissionController/
82 <activity android:name=""
83 android:configChanges="keyboardHidden|screenSize"
84 android:excludeFromRecents="true"
85 android:theme="@style/GrantPermissions"
86 android:visibleToInstantApps="true"
87 android:inheritShowWhenLocked="true">
88 <intent-filter android:priority="1">
89 <action android:name=".REQUEST_PERMISSIONS" />
90 <category android:name="" />
91 </intent-filter>
92 </activity>
通过隐式意图跳转到GrantPermissionsActivity。
xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/ui/
256 @Override
257 public void onCreate(Bundle icicle) {
258 (icicle);
259
260 if (icicle == null) {
261 mRequestId = new Random().nextLong();
262 } else {
263 mRequestId = (KEY_REQUEST_ID);
264 }
265
266 getWindow().addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
267
268 // Cache this as this can only read on onCreate, not later.
269 mCallingPackage = getCallingPackage();
270
271 (getPackageManager(), mCallingPackage);
272
273 setFinishOnTouchOutside(false);
274
275 setTitle(.permission_request_title);
276
277 mRequestedPermissions = getIntent().getStringArrayExtra(
278 PackageManager.EXTRA_REQUEST_PERMISSIONS_NAMES);
279 if (mRequestedPermissions == null) {
280 mRequestedPermissions = new String[0];
281 }
282
283 final int requestedPermCount = ;
284
285 if (requestedPermCount == 0) {
286 setResultAndFinish();
287 return;
288 }
289
290 PackageInfo callingPackageInfo = getCallingPackageInfo();
291
292 if (callingPackageInfo == null || == null
293 || <= 0) {
294 setResultAndFinish();
295 return;
296 }
297
298 // Don't allow legacy apps to request runtime permissions.
299 if ( < Build.VERSION_CODES.M) {
300 // Returning empty arrays means a cancellation.
301 mRequestedPermissions = new String[0];
302 setResultAndFinish();
303 return;
304 }
305
306 mCallingUid = ;
307
308 UserHandle userHandle = (mCallingUid);
309
310 if ((this)) {
311 mViewHandler = new
312 .GrantPermissionsViewHandlerImpl(this,
313 mCallingPackage).setResultListener(this);
314 } else if ((this)) {
315 mViewHandler = new GrantPermissionsWatchViewHandler(this).setResultListener(this);
316 } else if ((this)) {
317 mViewHandler = new GrantPermissionsAutoViewHandler(this, mCallingPackage, userHandle)
318 .setResultListener(this);
319 } else {
320 mViewHandler = new
321 .GrantPermissionsViewHandlerImpl(this, mCallingPackage, userHandle)
322 .setResultListener(this);
323 }
324
325 mAppPermissions = new AppPermissions(this, callingPackageInfo, false,
326 new Runnable() {
327 @Override
328 public void run() {
329 setResultAndFinish();
330 }
331 });
332
333 for (String requestedPermission : mRequestedPermissions) {
334 if (requestedPermission == null) {
335 continue;
336 }
337
338 ArrayList<String> affectedPermissions =
339 computeAffectedPermissions(requestedPermission);
340
341 int numAffectedPermissions = ();
342 for (int i = 0; i < numAffectedPermissions; i++) {
343 AppPermissionGroup group =
344 ((i));
345 if (group == null) {
346 reportRequestResult((i),
347 PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED);
348
349 continue;
350 }
351
352 addRequestedPermissions(group, (i), icicle == null);
353 }
354 }
355
356 int numGroupStates = ();
357 for (int groupStateNum = 0; groupStateNum < numGroupStates; groupStateNum++) {
358 GroupState groupState = (groupStateNum);
359 AppPermissionGroup group = ;
360
361 // Restore permission group state after lifecycle events
362 if (icicle != null) {
363 = (
364 getInstanceStateKey((groupStateNum)),
365 );
366 }
367
368 // Do not attempt to grant background access if foreground access is not either already
369 // granted or requested
370 if (()) {
371 // Check if a foreground permission is already granted
372 boolean foregroundGroupAlreadyGranted = (
373 ()).areRuntimePermissionsGranted();
374 boolean hasForegroundRequest = (getForegroundGroupState(()) != null);
375
376 if (!foregroundGroupAlreadyGranted && !hasForegroundRequest) {
377 // The background permission cannot be granted at this time
378 int numPermissions = ;
379 for (int permissionNum = 0; permissionNum < numPermissions; permissionNum++) {
380 (LOG_TAG,
381 "Cannot grant " + [permissionNum]
382 + " as the matching foreground permission is not already "
383 + "granted.");
384 }
385
386 = GroupState.STATE_SKIPPED;
387
388 reportRequestResult(,
389 PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__IGNORED);
390 }
391 }
392 }
393
394 setContentView(());
395
396 Window window = getWindow();
397 layoutParams = ();
398 (layoutParams);
399 (layoutParams);
400
401 // Restore UI state after lifecycle events. This has to be before
402 // showNextPermissionGroupGrantRequest is called. showNextPermissionGroupGrantRequest might
403 // update the UI and the UI behaves differently for updates and initial creations.
404 if (icicle != null) {
405 (icicle);
406 }
407
408 if (!showNextPermissionGroupGrantRequest()) {
409 setResultAndFinish();
410 }
411 }
396 Window window = getWindow();
397 layoutParams = ();
398 (layoutParams);
399 (layoutParams);
弹出授权的dialog界面。
xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/ui/
803 /**
804 * Grants or revoked the affected permissions for a single {@link groupState}.
805 *
806 * @param groupState The group state with the permissions to grant/revoke
807 * @param granted {@code true} if the permissions should be granted, {@code false} if they
808 * should be revoked
809 * @param doNotAskAgain if the permissions should be revoked should be app be allowed to ask
810 * again for the same permissions?
811 */
812 private void onPermissionGrantResultSingleState(GroupState groupState, boolean granted,
813 boolean doNotAskAgain) {
814 if (groupState != null && != null
815 && == GroupState.STATE_UNKNOWN) {
816 if (granted) {
817 (doNotAskAgain,
818 );
819 = GroupState.STATE_ALLOWED;
820
821 reportRequestResult(,
822 PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_GRANTED);
823 } else {
824 (doNotAskAgain,
825 );
826 = GroupState.STATE_DENIED;
827
828 reportRequestResult(, doNotAskAgain
829 ?
830 PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED_WITH_PREJUDICE
831 : PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__USER_DENIED);
832 }
833 }
834 }
用户选择授权与否会在onPermissionGrantResultSingleState方法中处理。方法最终会调用到类中的grantRuntimePermissions方法。
xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/model/
754 /**
755 * Grant permissions of the group.
756 *
757 * <p>This also automatically grants all app ops for permissions that have app ops.
758 * <p>This does <u>only</u> grant permissions in {@link #mPermissions}, . usually not
759 * the background permissions.
760 *
761 * @param fixedByTheUser If the user requested that she/he does not want to be asked again
762 * @param filterPermissions If {@code null} all permissions of the group will be granted.
763 * Otherwise only permissions in {@code filterPermissions} will be
764 * granted.
765 *
766 * @return {@code true} iff all permissions of this group could be granted.
767 */
768 public boolean grantRuntimePermissions(boolean fixedByTheUser, String[] filterPermissions) {
769 boolean killApp = false;
770 boolean wasAllGranted = true;
771
772 // We toggle permissions only to apps that support runtime
773 // permissions, otherwise we toggle the app op corresponding
774 // to the permission if the permission is granted to the app.
775 for (Permission permission : ()) {
776 if (filterPermissions != null
777 && !(filterPermissions, ())) {
778 continue;
779 }
780
781 if (!(mIsEphemeralApp, mAppSupportsRuntimePermissions)) {
782 // Skip unallowed permissions.
783 continue;
784 }
785
786 boolean wasGranted = ();
787
788 if (mAppSupportsRuntimePermissions) {
789 // Do not touch permissions fixed by the system.
790 if (()) {
791 wasAllGranted = false;
792 break;
793 }
794
795 // Ensure the permission app op enabled before the permission grant.
796 if (() && !()) {
797 (true);
798 }
799
800 // Grant the permission if needed.
801 if (!()) {
802 (true);
803 }
804
805 // Update the permission flags.
806 if (!fixedByTheUser) {
807 // Now the apps can ask for the permission as the user
808 // no longer has it fixed in a denied state.
809 if (() || ()) {
810 (false);
811 (false);
812 }
813 }
814 } else {
815 // Legacy apps cannot have a not granted permission but just in case.
816 if (!()) {
817 continue;
818 }
819
820 // If the permissions has no corresponding app op, then it is a
821 // third-party one and we do not offer toggling of such permissions.
822 if (()) {
823 if (!()) {
824 (true);
825
826 // Legacy apps do not know that they have to retry access to a
827 // resource due to changes in runtime permissions (app ops in this
828 // case). Therefore, we restart them on app op change, so they
829 // can pick up the change.
830 killApp = true;
831 }
832
833 // Mark that the permission should not be be granted on upgrade
834 // when the app begins supporting runtime permissions.
835 if (()) {
836 (false);
837 }
838 }
839
840 // Granting a permission explicitly means the user already
841 // reviewed it so clear the review flag on every grant.
842 if (()) {
843 ();
844 }
845 }
846
847 // If we newly grant background access to the fine location, double-guess the user some
848 // time later if this was really the right choice.
849 if (!wasGranted && ()) {
850 if (().equals(ACCESS_FINE_LOCATION)) {
851 Permission bgPerm = ();
852 if (bgPerm != null) {
853 if (()) {
854 mTriggerLocationAccessCheckOnPersist = true;
855 }
856 }
857 } else if (().equals(ACCESS_BACKGROUND_LOCATION)) {
858 ArrayList<Permission> fgPerms = ();
859 if (fgPerms != null) {
860 int numFgPerms = ();
861 for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) {
862 Permission fgPerm = (fgPermNum);
863
864 if (().equals(ACCESS_FINE_LOCATION)) {
865 if (()) {
866 mTriggerLocationAccessCheckOnPersist = true;
867 }
868
869 break;
870 }
871 }
872 }
873 }
874 }
875 }
876
877 if (!mDelayChanges) {
878 persistChanges(false);
879
880 if (killApp) {
881 killApp(KILL_REASON_APP_OP_CHANGE);
882 }
883 }
884
885 return wasAllGranted;
886 }
如果不延迟改变就调用persistChanges方法。
xref: /packages/apps/PermissionController/src/com/android/packageinstaller/permission/model/
1214 /**
1215 * If the changes to this group were delayed, persist them to the platform.
1216 *
1217 * @param mayKillBecauseOfAppOpsChange If the app these permissions belong to may be killed if
1218 * app ops change. If this is set to {@code false} the
1219 * caller has to make sure to kill the app if needed.
1220 */
1221 void persistChanges(boolean mayKillBecauseOfAppOpsChange) {
1222 int uid = ;
1223
1224 int numPermissions = ();
1225 boolean shouldKillApp = false;
1226
1227 for (int i = 0; i < numPermissions; i++) {
1228 Permission permission = (i);
1229
1230 if (!()) {
1231 if (()) {
1232 (,
1233 (), mUserHandle);
1234 } else {
1235 boolean isCurrentlyGranted = ((), -1,
1236 uid) == PERMISSION_GRANTED;
1237
1238 if (isCurrentlyGranted) {
1239 (,
1240 (), mUserHandle);
1241 }
1242 }
1243 }
1244
1245 int flags = (() ? PackageManager.FLAG_PERMISSION_USER_SET : 0)
1246 | (() ? PackageManager.FLAG_PERMISSION_USER_FIXED : 0)
1247 | (()
1248 ? PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE : 0)
1249 | (() ? PackageManager.FLAG_PERMISSION_POLICY_FIXED : 0)
1250 | (()
1251 ? PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED : 0);
1252
1253 ((),
1254 ,
1255 PackageManager.FLAG_PERMISSION_USER_SET
1256 | PackageManager.FLAG_PERMISSION_USER_FIXED
1257 | PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE
1258 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
1259 | PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED,
1260 flags, mUserHandle);
1261
1262 if (()) {
1263 if (!()) {
1264 // Enabling/Disabling an app op may put the app in a situation in which it has
1265 // a handle to state it shouldn't have, so we have to kill the app. This matches
1266 // the revoke runtime permission behavior.
1267 if (()) {
1268 shouldKillApp |= allowAppOp(permission, uid);
1269 } else {
1270 shouldKillApp |= disallowAppOp(permission, uid);
1271 }
1272 }
1273 }
1274 }
1275
1276 if (mayKillBecauseOfAppOpsChange && shouldKillApp) {
1277 killApp(KILL_REASON_APP_OP_CHANGE);
1278 }
1279
1280 if (mTriggerLocationAccessCheckOnPersist) {
1281 new LocationAccessCheck(mContext, null).checkLocationAccessSoon();
1282 mTriggerLocationAccessCheckOnPersist = false;
1283 }
1284 }
;调用PackageManager的grantRuntimePermission。PackageManager是抽象类需要调用它的实现类ApplicationPackageManager里面的grantRuntimePermission方法,然后通过AIDL跨进程通信调用到类中的grantRuntimePermission。
xref: /frameworks/base/services/core/java/com/android/server/pm/
5721 @Override
5722 public void grantRuntimePermission(String packageName, String permName, final int userId) {
5723 boolean overridePolicy = (checkUidPermission(
5724 .ADJUST_RUNTIME_PERMISSIONS_POLICY, ())
5725 == PackageManager.PERMISSION_GRANTED);
5726
5727 (permName, packageName, overridePolicy,
5728 getCallingUid(), userId, mPermissionCallback);
5729 }
调用PermissionManager类的grantRuntimePermission方法,最终会调用到PermissionManagerService类中的grantRuntimePermission方法。
xref: /frameworks/base/services/core/java/com/android/server/pm/permission/
2083 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
2084 int callingUid, final int userId, PermissionCallback callback) {
2085 if (!(userId)) {
2086 (TAG, "No such user:" + userId);
2087 return;
2088 }
2089
2090 (
2091 .GRANT_RUNTIME_PERMISSIONS,
2092 "grantRuntimePermission");
2093
2094 enforceCrossUserPermission(callingUid, userId,
2095 true, // requireFullPermission
2096 true, // checkShell
2097 false, // requirePermissionWhenSameUser
2098 "grantRuntimePermission");
2099
2100 final pkg = (packageName);
2101 if (pkg == null || == null) {
2102 throw new IllegalArgumentException("Unknown package: " + packageName);
2103 }
2104 final BasePermission bp;
2105 synchronized(mLock) {
2106 bp = (permName);
2107 }
2108 if (bp == null) {
2109 throw new IllegalArgumentException("Unknown permission: " + permName);
2110 }
2111 if ((pkg, callingUid, userId)) {
2112 throw new IllegalArgumentException("Unknown package: " + packageName);
2113 }
2114
2115 (pkg);
2116
2117 // If a permission review is required for legacy apps we represent
2118 // their permissions as always granted runtime ones since we need
2119 // to keep the review required permission flag per user while an
2120 // install permission's state is shared across all users.
2121 if ( < Build.VERSION_CODES.M
2122 && ()) {
2123 return;
2124 }
2125
2126 final int uid = (userId, );
2127
2128 final PackageSetting ps = (PackageSetting) ;
2129 final PermissionsState permissionsState = ();
2130
2131 final int flags = (permName, userId);
2132 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
2133 (TAG, "Cannot grant system fixed permission "
2134 + permName + " for package " + packageName);
2135 return;
2136 }
2137 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2138 (TAG, "Cannot grant policy fixed permission "
2139 + permName + " for package " + packageName);
2140 return;
2141 }
2142
2143 if (()
2144 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
2145 (TAG, "Cannot grant hard restricted non-exempt permission "
2146 + permName + " for package " + packageName);
2147 return;
2148 }
2149
2150 if (() && !(mContext,
2151 , (userId), permName).canBeGranted()) {
2152 (TAG, "Cannot grant soft restricted permission " + permName + " for package "
2153 + packageName);
2154 return;
2155 }
2156
2157 if (()) {
2158 // Development permissions must be handled specially, since they are not
2159 // normal runtime permissions. For now they apply to all users.
2160 if ((bp) !=
2161 PERMISSION_OPERATION_FAILURE) {
2162 if (callback != null) {
2163 ();
2164 }
2165 }
2166 return;
2167 }
2168
2169 if ((userId) && !()) {
2170 throw new SecurityException("Cannot grant non-ephemeral permission"
2171 + permName + " for package " + packageName);
2172 }
2173
2174 if ( < Build.VERSION_CODES.M) {
2175 (TAG, "Cannot grant runtime permission to a legacy app");
2176 return;
2177 }
2178
2179 final int result = (bp, userId);
2180 switch (result) {
2181 case PERMISSION_OPERATION_FAILURE: {
2182 return;
2183 }
2184
2185 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2186 if (callback != null) {
2187 ((), userId);
2188 }
2189 }
2190 break;
2191 }
2192
2193 if (()) {
2194 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
2195 }
2196
2197 if (callback != null) {
2198 (uid, userId);
2199 }
2200
2201 if (()) {
2202 notifyRuntimePermissionStateChanged(packageName, userId);
2203 }
2204
2205 // Only need to do this if user is initialized. Otherwise it's a new user
2206 // and there are no processes running as the user yet and there's no need
2207 // to make an expensive call to remount processes for the changed permissions.
2208 if (READ_EXTERNAL_STORAGE.equals(permName)
2209 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2210 final long token = ();
2211 try {
2212 if ((userId)) {
2213 StorageManagerInternal storageManagerInternal = (
2214 );
2215 (uid, packageName);
2216 }
2217 } finally {
2218 (token);
2219 }
2220 }
2221
2222 }
2197 if (callback != null) {
2198 (uid, userId);
2199 }
通过callback将处理结果回调给PackageManagerService。
xref: /frameworks/base/services/core/java/com/android/server/pm/
1758 private PermissionCallback mPermissionCallback = new PermissionCallback() {
1759 @Override
1760 public void onGidsChanged(int appId, int userId) {
1761 (() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
1762 }
1763 @Override
1764 public void onPermissionGranted(int uid, int userId) {
1765 (uid);
1766
1767 // Not critical; if this is lost, the application has to request again.
1768 synchronized (mPackages) {
1769 (userId, false);
1770 }
1771 }
1772 @Override
1773 public void onInstallPermissionGranted() {
1774 synchronized (mPackages) {
1775 scheduleWriteSettingsLocked();
1776 }
1777 }
1778 @Override
1779 public void onPermissionRevoked(int uid, int userId) {
1780 (uid);
1781
1782 synchronized (mPackages) {
1783 // Critical; after this call the application should never have the permission
1784 (userId, true);
1785 }
1786
1787 final int appId = (uid);
1788 killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
1789 }
1790 @Override
1791 public void onInstallPermissionRevoked() {
1792 synchronized (mPackages) {
1793 scheduleWriteSettingsLocked();
1794 }
1795 }
1796 @Override
1797 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1798 synchronized (mPackages) {
1799 for (int userId : updatedUserIds) {
1800 (userId, sync);
1801 }
1802 }
1803 }
1804 @Override
1805 public void onInstallPermissionUpdated() {
1806 synchronized (mPackages) {
1807 scheduleWriteSettingsLocked();
1808 }
1809 }
1810 @Override
1811 public void onPermissionRemoved() {
1812 synchronized (mPackages) {
1813 ();
1814 }
1815 }
1816 };
(uid);将处理结果回调给用户。mSettings.writeRuntimePermissionsForUserLPr(userId, false);把修改权限的结果写到文件里面
xref: /frameworks/base/services/core/java/com/android/server/pm/
5200 private void writePermissionsSync(int userId) {
5201 AtomicFile destination = new AtomicFile(getUserRuntimePermissionsFile(userId),
5202 "package-perms-" + userId);
5203
5204 ArrayMap<String, List<PermissionState>> permissionsForPackage = new ArrayMap<>();
5205 ArrayMap<String, List<PermissionState>> permissionsForSharedUser = new ArrayMap<>();
5206
5207 synchronized (mPersistenceLock) {
5208 (userId);
5209
5210 final int packageCount = ();
5211 for (int i = 0; i < packageCount; i++) {
5212 String packageName = (i);
5213 PackageSetting packageSetting = (i);
5214 if ( == null) {
5215 PermissionsState permissionsState = ();
5216 List<PermissionState> permissionsStates = permissionsState
5217 .getRuntimePermissionStates(userId);
5218 if (!()) {
5219 (packageName, permissionsStates);
5220 }
5221 }
5222 }
5223
5224 final int sharedUserCount = ();
5225 for (int i = 0; i < sharedUserCount; i++) {
5226 String sharedUserName = (i);
5227 SharedUserSetting sharedUser = (i);
5228 PermissionsState permissionsState = ();
5229 List<PermissionState> permissionsStates = permissionsState
5230 .getRuntimePermissionStates(userId);
5231 if (!()) {
5232 (sharedUserName, permissionsStates);
5233 }
5234 }
5235 }
5236
5237 FileOutputStream out = null;
5238 try {
5239 out = ();
5240
5241 XmlSerializer serializer = ();
5242 (out, StandardCharsets.UTF_8.name());
5243 (
5244 "/v1/doc/#indent-output", true);
5245 (null, true);
5246
5247 (null, TAG_RUNTIME_PERMISSIONS);
5248
5249 final int version = (userId, INITIAL_VERSION);
5250 (null, ATTR_VERSION, (version));
5251
5252 String fingerprint = (userId);
5253 if (fingerprint != null) {
5254 (null, ATTR_FINGERPRINT, fingerprint);
5255 }
5256
5257 final int packageCount = ();
5258 for (int i = 0; i < packageCount; i++) {
5259 String packageName = (i);
5260 List<PermissionState> permissionStates = (i);
5261 (null, TAG_PACKAGE);
5262 (null, ATTR_NAME, packageName);
5263 writePermissions(serializer, permissionStates);
5264 (null, TAG_PACKAGE);
5265 }
5266
5267 final int sharedUserCount = ();
5268 for (int i = 0; i < sharedUserCount; i++) {
5269 String packageName = (i);
5270 List<PermissionState> permissionStates = (i);
5271 (null, TAG_SHARED_USER);
5272 (null, ATTR_NAME, packageName);
5273 writePermissions(serializer, permissionStates);
5274 (null, TAG_SHARED_USER);
5275 }
5276
5277 (null, TAG_RUNTIME_PERMISSIONS);
5278
5279 ();
5280 (out);
5281
5282 if ((fingerprint)) {
5283 (userId, true);
5284 }
5285 // Any error while writing is fatal.
5286 } catch (Throwable t) {
5287 (,
5288 "Failed to write settings, restoring backup", t);
5289 (out);
5290 } finally {
5291 (out);
5292 }
5293 }