blob: 6a7c622b7e33bad8fc5ad568e5c4269504d8a702 [file] [log] [blame]
Todd Kennedy0eb97382017-10-03 16:57:22 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.pm.permission;
18
19import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
20import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070021import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
22import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070023import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
24import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070025import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann48456672019-01-20 13:14:03 -080026import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070027import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
28import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070031import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
32import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070034import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Hongwei Wangf391b552018-04-06 13:52:46 -070035import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
36
Todd Kennedyc29b11a2017-10-23 15:55:59 -070037import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
38import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
39import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
40import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
41import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080042import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
43
44import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070045
46import android.Manifest;
47import android.annotation.NonNull;
48import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070049import android.annotation.UserIdInt;
Todd Kennedy0eb97382017-10-03 16:57:22 -070050import android.content.Context;
51import android.content.pm.PackageManager;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070052import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070053import android.content.pm.PackageManagerInternal;
54import android.content.pm.PackageParser;
Hongwei Wangf391b552018-04-06 13:52:46 -070055import android.content.pm.PackageParser.Package;
Todd Kennedy460f28c2017-10-06 13:46:22 -070056import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070057import android.content.pm.PermissionInfo;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070058import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070059import android.os.Binder;
60import android.os.Build;
61import android.os.Handler;
62import android.os.HandlerThread;
63import android.os.Process;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070064import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070065import android.os.UserHandle;
66import android.os.UserManager;
67import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070068import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070069import android.os.storage.StorageManagerInternal;
Philip P. Moltmann48456672019-01-20 13:14:03 -080070import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070071import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080072import android.permission.PermissionManagerInternal;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070073import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070074import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -070075import android.util.ArrayMap;
76import android.util.ArraySet;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -070077import android.util.EventLog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070078import android.util.Log;
79import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -070080import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -080081import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -070082
Todd Kennedyc29b11a2017-10-23 15:55:59 -070083import com.android.internal.annotations.GuardedBy;
Todd Kennedy0eb97382017-10-03 16:57:22 -070084import com.android.internal.logging.MetricsLogger;
85import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070086import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -070087import com.android.internal.util.ArrayUtils;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070088import com.android.internal.util.function.pooled.PooledLambda;
89import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -070090import com.android.server.LocalServices;
91import com.android.server.ServiceThread;
92import com.android.server.SystemConfig;
93import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -070094import com.android.server.pm.PackageManagerServiceUtils;
95import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -070096import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -070097import com.android.server.pm.UserManagerService;
Philip P. Moltmann48456672019-01-20 13:14:03 -080098import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -070099import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov0b41c892019-07-26 17:45:56 -0700100import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700101import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700102
103import libcore.util.EmptyArray;
104
105import java.util.ArrayList;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700106import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700107import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700108import java.util.Iterator;
109import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700110import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700111import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700112import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800113import java.util.concurrent.CompletableFuture;
114import java.util.concurrent.ExecutionException;
115import java.util.concurrent.TimeUnit;
116import java.util.concurrent.TimeoutException;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700117
118/**
119 * Manages all permissions and handles permissions related tasks.
120 */
121public class PermissionManagerService {
122 private static final String TAG = "PackageManager";
123
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700124 /** Permission grant: not grant the permission. */
125 private static final int GRANT_DENIED = 1;
126 /** Permission grant: grant the permission as an install permission. */
127 private static final int GRANT_INSTALL = 2;
128 /** Permission grant: grant the permission as a runtime one. */
129 private static final int GRANT_RUNTIME = 3;
130 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
131 private static final int GRANT_UPGRADE = 4;
132
Philip P. Moltmann48456672019-01-20 13:14:03 -0800133 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
134
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700135 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
136 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
137 /** Empty array to avoid allocations */
138 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700139
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800140 /**
141 * When these flags are set, the system should not automatically modify the permission grant
142 * state.
143 */
144 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
145 | FLAG_PERMISSION_POLICY_FIXED
146 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
147
148 /** Permission flags set by the user */
149 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
150 | FLAG_PERMISSION_USER_FIXED;
151
Hongwei Wangf391b552018-04-06 13:52:46 -0700152 /** If the permission of the value is granted, so is the key */
153 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
154
155 static {
156 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
157 Manifest.permission.ACCESS_FINE_LOCATION);
158 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
159 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
160 }
161
Todd Kennedy0eb97382017-10-03 16:57:22 -0700162 /** Lock to protect internal data access */
163 private final Object mLock;
164
165 /** Internal connection to the package manager */
166 private final PackageManagerInternal mPackageManagerInt;
167
168 /** Internal connection to the user manager */
169 private final UserManagerInternal mUserManagerInt;
170
Philip P. Moltmann48456672019-01-20 13:14:03 -0800171 /** Permission controller: User space permission management */
172 private PermissionControllerManager mPermissionControllerManager;
173
Todd Kennedy0eb97382017-10-03 16:57:22 -0700174 /** Default permission policy to provide proper behaviour out-of-the-box */
175 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
176
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700177 /**
178 * Built-in permissions. Read from system configuration files. Mapping is from
179 * UID to permission name.
180 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700181 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700182
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700183 /** Built-in group IDs given to all packages. Read from system configuration files. */
184 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700185
186 private final HandlerThread mHandlerThread;
187 private final Handler mHandler;
188 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700189 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700190
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700191 /** Internal storage for permissions and related settings */
192 @GuardedBy("mLock")
193 private final PermissionSettings mSettings;
194
195 @GuardedBy("mLock")
196 private ArraySet<String> mPrivappPermissionsViolations;
197
198 @GuardedBy("mLock")
199 private boolean mSystemReady;
200
Svet Ganov0b41c892019-07-26 17:45:56 -0700201 @GuardedBy("mLock")
202 private PermissionPolicyInternal mPermissionPolicyInternal;
203
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700204 /**
205 * For each foreground/background permission the mapping:
206 * Background permission -> foreground permissions
207 */
208 @GuardedBy("mLock")
209 private ArrayMap<String, List<String>> mBackgroundPermissions;
210
Philip P. Moltmann48456672019-01-20 13:14:03 -0800211 /**
212 * A permission backup might contain apps that are not installed. In this case we delay the
213 * restoration until the app is installed.
214 *
215 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
216 * there is <u>no more</u> delayed backup left.
217 */
218 @GuardedBy("mLock")
219 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
220
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700221 /** Listeners for permission state (granting and flags) changes */
222 @GuardedBy("mLock")
223 final private ArrayList<OnRuntimePermissionStateChangedListener>
224 mRuntimePermissionStateChangedListeners = new ArrayList<>();
225
Todd Kennedy0eb97382017-10-03 16:57:22 -0700226 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700227 @NonNull Object externalLock) {
228 mContext = context;
229 mLock = externalLock;
230 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
231 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700232 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700233
234 mHandlerThread = new ServiceThread(TAG,
235 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
236 mHandlerThread.start();
237 mHandler = new Handler(mHandlerThread.getLooper());
238 Watchdog.getInstance().addThread(mHandler);
239
240 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700241 context, mHandlerThread.getLooper(), this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700242 SystemConfig systemConfig = SystemConfig.getInstance();
243 mSystemPermissions = systemConfig.getSystemPermissions();
244 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy0eb97382017-10-03 16:57:22 -0700245
246 // propagate permission configuration
247 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
248 SystemConfig.getInstance().getPermissions();
249 synchronized (mLock) {
250 for (int i=0; i<permConfig.size(); i++) {
251 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
252 BasePermission bp = mSettings.getPermissionLocked(perm.name);
253 if (bp == null) {
254 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
255 mSettings.putPermissionLocked(perm.name, bp);
256 }
257 if (perm.gids != null) {
258 bp.setGids(perm.gids, perm.perUser);
259 }
260 }
261 }
262
Philip P. Moltmann48456672019-01-20 13:14:03 -0800263 PermissionManagerServiceInternalImpl localService =
264 new PermissionManagerServiceInternalImpl();
265 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
266 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700267 }
268
269 /**
270 * Creates and returns an initialized, internal service for use by other components.
271 * <p>
272 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800273 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700274 * <p>
275 * NOTE: The external lock is temporary and should be removed. This needs to be a
276 * lock created by the permission manager itself.
277 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800278 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700279 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800280 final PermissionManagerServiceInternal permMgrInt =
281 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700282 if (permMgrInt != null) {
283 return permMgrInt;
284 }
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700285 new PermissionManagerService(context, externalLock);
Philip P. Moltmann48456672019-01-20 13:14:03 -0800286 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700287 }
288
289 @Nullable BasePermission getPermission(String permName) {
290 synchronized (mLock) {
291 return mSettings.getPermissionLocked(permName);
292 }
293 }
294
295 private int checkPermission(String permName, String pkgName, int callingUid, int userId) {
296 if (!mUserManagerInt.exists(userId)) {
297 return PackageManager.PERMISSION_DENIED;
298 }
299
Patrick Baumann97b9b532018-04-11 14:51:30 +0000300 final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
301 if (pkg != null && pkg.mExtras != null) {
302 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700303 return PackageManager.PERMISSION_DENIED;
304 }
Patrick Baumann97b9b532018-04-11 14:51:30 +0000305 final PackageSetting ps = (PackageSetting) pkg.mExtras;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700306 final boolean instantApp = ps.getInstantApp(userId);
307 final PermissionsState permissionsState = ps.getPermissionsState();
308 if (permissionsState.hasPermission(permName, userId)) {
309 if (instantApp) {
310 synchronized (mLock) {
311 BasePermission bp = mSettings.getPermissionLocked(permName);
312 if (bp != null && bp.isInstant()) {
313 return PackageManager.PERMISSION_GRANTED;
314 }
315 }
316 } else {
317 return PackageManager.PERMISSION_GRANTED;
318 }
319 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700320 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700321 return PackageManager.PERMISSION_GRANTED;
322 }
323 }
324
325 return PackageManager.PERMISSION_DENIED;
326 }
327
Todd Kennedy3c714492017-10-27 09:12:50 -0700328 private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
329 int callingUid) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700330 final int callingUserId = UserHandle.getUserId(callingUid);
331 final boolean isCallerInstantApp =
332 mPackageManagerInt.getInstantAppPackageName(callingUid) != null;
333 final boolean isUidInstantApp =
334 mPackageManagerInt.getInstantAppPackageName(uid) != null;
335 final int userId = UserHandle.getUserId(uid);
336 if (!mUserManagerInt.exists(userId)) {
337 return PackageManager.PERMISSION_DENIED;
338 }
339
Todd Kennedy3c714492017-10-27 09:12:50 -0700340 if (pkg != null) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700341 if (pkg.mSharedUserId != null) {
342 if (isCallerInstantApp) {
343 return PackageManager.PERMISSION_DENIED;
344 }
Todd Kennedy3c714492017-10-27 09:12:50 -0700345 } else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {
346 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700347 }
348 final PermissionsState permissionsState =
349 ((PackageSetting) pkg.mExtras).getPermissionsState();
350 if (permissionsState.hasPermission(permName, userId)) {
351 if (isUidInstantApp) {
352 if (mSettings.isPermissionInstant(permName)) {
353 return PackageManager.PERMISSION_GRANTED;
354 }
355 } else {
356 return PackageManager.PERMISSION_GRANTED;
357 }
358 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700359 if (isImpliedPermissionGranted(permissionsState, permName, userId)) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700360 return PackageManager.PERMISSION_GRANTED;
361 }
362 } else {
363 ArraySet<String> perms = mSystemPermissions.get(uid);
364 if (perms != null) {
365 if (perms.contains(permName)) {
366 return PackageManager.PERMISSION_GRANTED;
367 }
Hongwei Wangf391b552018-04-06 13:52:46 -0700368 if (FULLER_PERMISSION_MAP.containsKey(permName)
369 && perms.contains(FULLER_PERMISSION_MAP.get(permName))) {
Todd Kennedy3bc94722017-10-10 09:55:53 -0700370 return PackageManager.PERMISSION_GRANTED;
371 }
372 }
373 }
374 return PackageManager.PERMISSION_DENIED;
375 }
376
Hongwei Wangf391b552018-04-06 13:52:46 -0700377 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -0800378 * Get the state of the runtime permissions as xml file.
379 *
380 * <p>Can not be called on main thread.
381 *
382 * @param user The user the data should be extracted for
383 *
384 * @return The state as a xml file
385 */
386 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
387 CompletableFuture<byte[]> backup = new CompletableFuture<>();
388 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
389 backup::complete);
390
391 try {
392 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
393 } catch (InterruptedException | ExecutionException | TimeoutException e) {
394 Slog.e(TAG, "Cannot create permission backup for " + user, e);
395 return null;
396 }
397 }
398
399 /**
400 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
401 *
402 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
403 * applied via {@link #restoreDelayedRuntimePermissions}.
404 *
405 * @param backup The state as an xml file
406 * @param user The user the data should be restored for
407 */
408 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
409 synchronized (mLock) {
410 mHasNoDelayedPermBackup.delete(user.getIdentifier());
411 mPermissionControllerManager.restoreRuntimePermissionBackup(backup, user);
412 }
413 }
414
415 /**
416 * Try to apply permission backup that was previously not applied.
417 *
418 * <p>Can not be called on main thread.
419 *
420 * @param packageName The package that is newly installed
421 * @param user The user the package is installed for
422 *
423 * @see #restoreRuntimePermissions
424 */
425 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
426 @NonNull UserHandle user) {
427 synchronized (mLock) {
428 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
429 return;
430 }
431
432 mPermissionControllerManager.restoreDelayedRuntimePermissionBackup(packageName, user,
433 mContext.getMainExecutor(), (hasMoreBackup) -> {
434 if (hasMoreBackup) {
435 return;
436 }
437
438 synchronized (mLock) {
439 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
440 }
441 });
442 }
443 }
444
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700445 private void addOnRuntimePermissionStateChangedListener(@NonNull
446 OnRuntimePermissionStateChangedListener listener) {
447 synchronized (mLock) {
448 mRuntimePermissionStateChangedListeners.add(listener);
449 }
450 }
451
452 private void removeOnRuntimePermissionStateChangedListener(@NonNull
453 OnRuntimePermissionStateChangedListener listener) {
454 synchronized (mLock) {
455 mRuntimePermissionStateChangedListeners.remove(listener);
456 }
457 }
458
459 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
460 @UserIdInt int userId) {
461 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
462 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
463 PermissionManagerService.this, packageName, userId));
464 }
465
466 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
467 @UserIdInt int userId) {
468 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
469 synchronized (mLock) {
470 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
471 return;
472 }
473 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
474 }
475 final int listenerCount = listeners.size();
476 for (int i = 0; i < listenerCount; i++) {
477 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
478 }
479 }
480
Philip P. Moltmann48456672019-01-20 13:14:03 -0800481 /**
Hongwei Wangf391b552018-04-06 13:52:46 -0700482 * Returns {@code true} if the permission can be implied from another granted permission.
483 * <p>Some permissions, such as ACCESS_FINE_LOCATION, imply other permissions,
484 * such as ACCESS_COURSE_LOCATION. If the caller holds an umbrella permission, give
485 * it access to any implied permissions.
486 */
487 private static boolean isImpliedPermissionGranted(PermissionsState permissionsState,
488 String permName, int userId) {
489 return FULLER_PERMISSION_MAP.containsKey(permName)
490 && permissionsState.hasPermission(FULLER_PERMISSION_MAP.get(permName), userId);
491 }
492
Todd Kennedy460f28c2017-10-06 13:46:22 -0700493 private PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
494 int callingUid) {
495 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
496 return null;
497 }
498 synchronized (mLock) {
499 return PackageParser.generatePermissionGroupInfo(
500 mSettings.mPermissionGroups.get(groupName), flags);
501 }
502 }
503
504 private List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
505 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
506 return null;
507 }
508 synchronized (mLock) {
509 final int N = mSettings.mPermissionGroups.size();
510 final ArrayList<PermissionGroupInfo> out
511 = new ArrayList<PermissionGroupInfo>(N);
512 for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
513 out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
514 }
515 return out;
516 }
517 }
518
519 private PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700520 int callingUid) {
521 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
522 return null;
523 }
524 // reader
525 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700526 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700527 if (bp == null) {
528 return null;
529 }
530 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
531 bp.getProtectionLevel(), packageName, callingUid);
532 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
533 }
534 }
535
536 private List<PermissionInfo> getPermissionInfoByGroup(
537 String groupName, int flags, int callingUid) {
538 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
539 return null;
540 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700541 synchronized (mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700542 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
543 return null;
544 }
Todd Kennedy0eb97382017-10-03 16:57:22 -0700545 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
Todd Kennedyc8423932017-10-05 08:58:36 -0700546 for (BasePermission bp : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700547 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
548 if (pi != null) {
549 out.add(pi);
550 }
551 }
552 return out;
553 }
554 }
555
556 private int adjustPermissionProtectionFlagsLocked(
557 int protectionLevel, String packageName, int uid) {
558 // Signature permission flags area always reported
559 final int protectionLevelMasked = protectionLevel
560 & (PermissionInfo.PROTECTION_NORMAL
561 | PermissionInfo.PROTECTION_DANGEROUS
562 | PermissionInfo.PROTECTION_SIGNATURE);
563 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
564 return protectionLevel;
565 }
566 // System sees all flags.
567 final int appId = UserHandle.getAppId(uid);
568 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
569 || appId == Process.SHELL_UID) {
570 return protectionLevel;
571 }
572 // Normalize package name to handle renamed packages and static libs
573 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
574 if (pkg == null) {
575 return protectionLevel;
576 }
577 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
578 return protectionLevelMasked;
579 }
580 // Apps that target O see flags for all protection levels.
581 final PackageSetting ps = (PackageSetting) pkg.mExtras;
582 if (ps == null) {
583 return protectionLevel;
584 }
585 if (ps.getAppId() != appId) {
586 return protectionLevel;
587 }
588 return protectionLevel;
589 }
590
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700591 /**
592 * We might auto-grant permissions if any permission of the group is already granted. Hence if
593 * the group of a granted permission changes we need to revoke it to avoid having permissions of
594 * the new group auto-granted.
595 *
596 * @param newPackage The new package that was installed
597 * @param oldPackage The old package that was updated
598 * @param allPackageNames All package names
599 * @param permissionCallback Callback for permission changed
600 */
601 private void revokeRuntimePermissionsIfGroupChanged(
602 @NonNull PackageParser.Package newPackage,
603 @NonNull PackageParser.Package oldPackage,
604 @NonNull ArrayList<String> allPackageNames,
605 @NonNull PermissionCallback permissionCallback) {
606 final int numOldPackagePermissions = oldPackage.permissions.size();
607 final ArrayMap<String, String> oldPermissionNameToGroupName
608 = new ArrayMap<>(numOldPackagePermissions);
609
610 for (int i = 0; i < numOldPackagePermissions; i++) {
611 final PackageParser.Permission permission = oldPackage.permissions.get(i);
612
613 if (permission.group != null) {
614 oldPermissionNameToGroupName.put(permission.info.name,
615 permission.group.info.name);
616 }
617 }
618
619 final int numNewPackagePermissions = newPackage.permissions.size();
620 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
621 newPermissionNum++) {
622 final PackageParser.Permission newPermission =
623 newPackage.permissions.get(newPermissionNum);
624 final int newProtection = newPermission.info.getProtection();
625
626 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
627 final String permissionName = newPermission.info.name;
628 final String newPermissionGroupName =
629 newPermission.group == null ? null : newPermission.group.info.name;
630 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
631 permissionName);
632
633 if (newPermissionGroupName != null
634 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
635 final int[] userIds = mUserManagerInt.getUserIds();
636 final int numUserIds = userIds.length;
637 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
638 final int userId = userIds[userIdNum];
639
640 final int numPackages = allPackageNames.size();
641 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
642 final String packageName = allPackageNames.get(packageNum);
643
644 if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
645 userId) == PackageManager.PERMISSION_GRANTED) {
646 EventLog.writeEvent(0x534e4554, "72710897",
647 newPackage.applicationInfo.uid,
Koji Fukuiacae3ef2018-05-09 11:38:01 +0900648 "Revoking permission " + permissionName +
649 " from package " + packageName +
650 " as the group changed from " + oldPermissionGroupName +
651 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700652
653 try {
Hongming Jinae750fb2018-09-27 23:00:20 +0000654 revokeRuntimePermission(permissionName, packageName, false,
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700655 userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700656 } catch (IllegalArgumentException e) {
657 Slog.e(TAG, "Could not revoke " + permissionName + " from "
658 + packageName, e);
659 }
660 }
661 }
662 }
663 }
664 }
665 }
666 }
667
Todd Kennedyc8423932017-10-05 08:58:36 -0700668 private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
669 final int N = pkg.permissions.size();
670 for (int i=0; i<N; i++) {
671 PackageParser.Permission p = pkg.permissions.get(i);
672
673 // Assume by default that we did not install this permission into the system.
674 p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
675
Todd Kennedyc8423932017-10-05 08:58:36 -0700676 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700677 // Now that permission groups have a special meaning, we ignore permission
678 // groups for legacy apps to prevent unexpected behavior. In particular,
679 // permissions for one app being granted to someone just because they happen
680 // to be in a group defined by another app (before this had no implications).
681 if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
682 p.group = mSettings.mPermissionGroups.get(p.info.group);
683 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700684 if (DEBUG_PERMISSIONS
Todd Kennedy460f28c2017-10-06 13:46:22 -0700685 && p.info.group != null && p.group == null) {
686 Slog.i(TAG, "Permission " + p.info.name + " from package "
687 + p.info.packageName + " in an unknown group " + p.info.group);
688 }
689 }
690
Todd Kennedyc8423932017-10-05 08:58:36 -0700691 if (p.tree) {
692 final BasePermission bp = BasePermission.createOrUpdate(
693 mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
694 mSettings.getAllPermissionTreesLocked(), chatty);
695 mSettings.putPermissionTreeLocked(p.info.name, bp);
696 } else {
697 final BasePermission bp = BasePermission.createOrUpdate(
698 mSettings.getPermissionLocked(p.info.name),
699 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
700 mSettings.putPermissionLocked(p.info.name, bp);
701 }
702 }
703 }
704 }
705
Todd Kennedy460f28c2017-10-06 13:46:22 -0700706 private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
707 final int N = pkg.permissionGroups.size();
708 StringBuilder r = null;
709 for (int i=0; i<N; i++) {
710 final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
711 final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
712 final String curPackageName = (cur == null) ? null : cur.info.packageName;
713 final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
714 if (cur == null || isPackageUpdate) {
715 mSettings.mPermissionGroups.put(pg.info.name, pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700716 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700717 if (r == null) {
718 r = new StringBuilder(256);
719 } else {
720 r.append(' ');
721 }
722 if (isPackageUpdate) {
723 r.append("UPD:");
724 }
725 r.append(pg.info.name);
726 }
727 } else {
728 Slog.w(TAG, "Permission group " + pg.info.name + " from package "
729 + pg.info.packageName + " ignored: original from "
730 + cur.info.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700731 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700732 if (r == null) {
733 r = new StringBuilder(256);
734 } else {
735 r.append(' ');
736 }
737 r.append("DUP:");
738 r.append(pg.info.name);
739 }
740 }
741 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700742 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -0700743 Log.d(TAG, " Permission Groups: " + r);
744 }
745
746 }
747
Hongming Jinae750fb2018-09-27 23:00:20 +0000748 private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700749 synchronized (mLock) {
750 int N = pkg.permissions.size();
751 StringBuilder r = null;
752 for (int i=0; i<N; i++) {
753 PackageParser.Permission p = pkg.permissions.get(i);
754 BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
755 if (bp == null) {
756 bp = mSettings.mPermissionTrees.get(p.info.name);
757 }
758 if (bp != null && bp.isPermission(p)) {
759 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700760 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -0700761 if (r == null) {
762 r = new StringBuilder(256);
763 } else {
764 r.append(' ');
765 }
766 r.append(p.info.name);
767 }
768 }
769 if (p.isAppOp()) {
770 ArraySet<String> appOpPkgs =
771 mSettings.mAppOpPermissionPackages.get(p.info.name);
772 if (appOpPkgs != null) {
773 appOpPkgs.remove(pkg.packageName);
774 }
775 }
776 }
777 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700778 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700779 }
780
781 N = pkg.requestedPermissions.size();
782 r = null;
783 for (int i=0; i<N; i++) {
784 String perm = pkg.requestedPermissions.get(i);
785 if (mSettings.isPermissionAppOp(perm)) {
786 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
787 if (appOpPkgs != null) {
788 appOpPkgs.remove(pkg.packageName);
789 if (appOpPkgs.isEmpty()) {
790 mSettings.mAppOpPermissionPackages.remove(perm);
791 }
792 }
793 }
794 }
795 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700796 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -0700797 }
798 }
799 }
800
801 private boolean addDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700802 PermissionInfo info, int callingUid, PermissionCallback callback) {
803 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
804 throw new SecurityException("Instant apps can't add permissions");
805 }
806 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
807 throw new SecurityException("Label must be specified in permission");
808 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700809 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700810 final boolean added;
811 final boolean changed;
812 synchronized (mLock) {
813 BasePermission bp = mSettings.getPermissionLocked(info.name);
814 added = bp == null;
815 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
816 if (added) {
817 enforcePermissionCapLocked(info, tree);
818 bp = new BasePermission(info.name, tree.getSourcePackageName(),
819 BasePermission.TYPE_DYNAMIC);
Svet Ganov2808cbc2018-05-09 15:27:43 -0700820 } else if (!bp.isDynamic()) {
821 throw new SecurityException("Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700822 + info.name);
823 }
824 changed = bp.addToTree(fixedLevel, info, tree);
825 if (added) {
826 mSettings.putPermissionLocked(info.name, bp);
827 }
828 }
829 if (changed && callback != null) {
830 callback.onPermissionChanged();
831 }
832 return added;
833 }
834
Todd Kennedyc8423932017-10-05 08:58:36 -0700835 private void removeDynamicPermission(
Todd Kennedy0eb97382017-10-03 16:57:22 -0700836 String permName, int callingUid, PermissionCallback callback) {
837 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
838 throw new SecurityException("Instant applications don't have access to this method");
839 }
Todd Kennedyc8423932017-10-05 08:58:36 -0700840 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700841 synchronized (mLock) {
842 final BasePermission bp = mSettings.getPermissionLocked(permName);
843 if (bp == null) {
844 return;
845 }
846 if (bp.isDynamic()) {
Jeff Sharkey4dc50522017-10-17 15:29:41 -0600847 // TODO: switch this back to SecurityException
848 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -0700849 + permName);
850 }
851 mSettings.removePermissionLocked(permName);
852 if (callback != null) {
853 callback.onPermissionRemoved();
854 }
855 }
856 }
857
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -0700858 /**
859 * Restore the permission state for a package.
860 *
861 * <ul>
862 * <li>During boot the state gets restored from the disk</li>
863 * <li>During app update the state gets restored from the last version of the app</li>
864 * </ul>
865 *
866 * <p>This restores the permission state for all users.
867 *
868 * @param pkg the package the permissions belong to
869 * @param replace if the package is getting replaced (this might change the requested
870 * permissions of this package)
871 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
872 * @param callback Result call back
873 */
874 private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
875 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700876 // IMPORTANT: There are two types of permissions: install and runtime.
877 // Install time permissions are granted when the app is installed to
878 // all device users and users added in the future. Runtime permissions
879 // are granted at runtime explicitly to specific users. Normal and signature
880 // protected permissions are install time permissions. Dangerous permissions
881 // are install permissions if the app's target SDK is Lollipop MR1 or older,
882 // otherwise they are runtime permissions. This function does not manage
883 // runtime permissions except for the case an app targeting Lollipop MR1
884 // being upgraded to target a newer SDK, in which case dangerous permissions
885 // are transformed from install time to runtime ones.
886
887 final PackageSetting ps = (PackageSetting) pkg.mExtras;
888 if (ps == null) {
889 return;
890 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700891
892 final PermissionsState permissionsState = ps.getPermissionsState();
893 PermissionsState origPermissions = permissionsState;
894
895 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
896
897 boolean runtimePermissionsRevoked = false;
898 int[] updatedUserIds = EMPTY_INT_ARRAY;
899
900 boolean changedInstallPermission = false;
901
902 if (replace) {
903 ps.setInstallPermissionsFixed(false);
904 if (!ps.isSharedUser()) {
905 origPermissions = new PermissionsState(permissionsState);
906 permissionsState.reset();
907 } else {
908 // We need to know only about runtime permission changes since the
909 // calling code always writes the install permissions state but
910 // the runtime ones are written only if changed. The only cases of
911 // changed runtime permissions here are promotion of an install to
912 // runtime and revocation of a runtime from a shared user.
913 synchronized (mLock) {
914 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
915 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
916 if (!ArrayUtils.isEmpty(updatedUserIds)) {
917 runtimePermissionsRevoked = true;
918 }
919 }
920 }
921 }
922
923 permissionsState.setGlobalGids(mGlobalGids);
924
925 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700926 ArraySet<String> newImplicitPermissions = new ArraySet<>();
927
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700928 final int N = pkg.requestedPermissions.size();
929 for (int i = 0; i < N; i++) {
930 final String permName = pkg.requestedPermissions.get(i);
931 final BasePermission bp = mSettings.getPermissionLocked(permName);
932 final boolean appSupportsRuntimePermissions =
933 pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +0100934 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700935
936 if (DEBUG_INSTALL) {
937 Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
938 }
939
940 if (bp == null || bp.getSourcePackageSetting() == null) {
941 if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
942 if (DEBUG_PERMISSIONS) {
943 Slog.i(TAG, "Unknown permission " + permName
944 + " in package " + pkg.packageName);
945 }
946 }
947 continue;
948 }
949
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700950 // Cache newImplicitPermissions before modifing permissionsState as for the shared
951 // uids the original and new state are the same object
952 if (!origPermissions.hasRequestedPermission(permName)
Zimuzoe6411402019-05-13 16:32:57 +0100953 && (pkg.implicitPermissions.contains(permName)
954 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
955 if (pkg.implicitPermissions.contains(permName)) {
956 // If permName is an implicit permission, try to auto-grant
957 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700958
Zimuzoe6411402019-05-13 16:32:57 +0100959 if (DEBUG_PERMISSIONS) {
960 Slog.i(TAG, permName + " is newly added for " + pkg.packageName);
961 }
962 } else {
963 // Special case for Activity Recognition permission. Even if AR permission
964 // is not an implicit permission we want to add it to the list (try to
965 // auto-grant it) if the app was installed on a device before AR permission
966 // was split, regardless of if the app now requests the new AR permission
967 // or has updated its target SDK and AR is no longer implicit to it.
968 // This is a compatibility workaround for apps when AR permission was
969 // split in Q.
970 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
971 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
972 PermissionManager.SplitPermissionInfo sp =
973 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
974 String splitPermName = sp.getSplitPermission();
975 if (sp.getNewPermissions().contains(permName)
976 && origPermissions.hasInstallPermission(splitPermName)) {
977 upgradedActivityRecognitionPermission = splitPermName;
978 newImplicitPermissions.add(permName);
979
980 if (DEBUG_PERMISSIONS) {
981 Slog.i(TAG, permName + " is newly added for "
982 + pkg.packageName);
983 }
984 break;
985 }
986 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -0700987 }
988 }
989
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700990 // Limit ephemeral apps to ephemeral allowed permissions.
991 if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
992 if (DEBUG_PERMISSIONS) {
993 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
994 + " for package " + pkg.packageName);
995 }
996 continue;
997 }
998
999 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
1000 if (DEBUG_PERMISSIONS) {
1001 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
1002 + " for package " + pkg.packageName);
1003 }
1004 continue;
1005 }
1006
1007 final String perm = bp.getName();
1008 boolean allowedSig = false;
1009 int grant = GRANT_DENIED;
1010
1011 // Keep track of app op permissions.
1012 if (bp.isAppOp()) {
1013 mSettings.addAppOpPackage(perm, pkg.packageName);
1014 }
1015
1016 if (bp.isNormal()) {
1017 // For all apps normal permissions are install time ones.
1018 grant = GRANT_INSTALL;
1019 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01001020 if (origPermissions.hasInstallPermission(bp.getName())
1021 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001022 // Before Q we represented some runtime permissions as install permissions,
1023 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001024 grant = GRANT_UPGRADE;
1025 } else {
1026 // For modern apps keep runtime permissions unchanged.
1027 grant = GRANT_RUNTIME;
1028 }
1029 } else if (bp.isSignature()) {
1030 // For all apps signature permissions are install time ones.
1031 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
1032 if (allowedSig) {
1033 grant = GRANT_INSTALL;
1034 }
1035 }
1036
1037 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001038 Slog.i(TAG, "Considering granting permission " + perm + " to package "
1039 + pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001040 }
1041
1042 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001043 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001044 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001045 // we can't add any new permissions to it. Runtime
1046 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001047 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
1048 // Except... if this is a permission that was added
1049 // to the platform (note: need to only do this when
1050 // updating the platform).
1051 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
1052 grant = GRANT_DENIED;
1053 }
1054 }
1055 }
1056
1057 switch (grant) {
1058 case GRANT_INSTALL: {
1059 // Revoke this as runtime permission to handle the case of
1060 // a runtime permission being downgraded to an install one.
1061 // Also in permission review mode we keep dangerous permissions
1062 // for legacy apps
1063 for (int userId : UserManagerService.getInstance().getUserIds()) {
1064 if (origPermissions.getRuntimePermissionState(
1065 perm, userId) != null) {
1066 // Revoke the runtime permission and clear the flags.
1067 origPermissions.revokeRuntimePermission(bp, userId);
1068 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001069 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001070 // If we revoked a permission permission, we have to write.
1071 updatedUserIds = ArrayUtils.appendInt(
1072 updatedUserIds, userId);
1073 }
1074 }
1075 // Grant an install permission.
1076 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001077 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001078 changedInstallPermission = true;
1079 }
1080 } break;
1081
1082 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001083 boolean hardRestricted = bp.isHardRestricted();
1084 boolean softRestricted = bp.isSoftRestricted();
1085
Philip P. Moltmann48456672019-01-20 13:14:03 -08001086 for (int userId : currentUserIds) {
Svet Ganov0b41c892019-07-26 17:45:56 -07001087 // If permission policy is not ready we don't deal with restricted
1088 // permissions as the policy may whitelist some permissions. Once
1089 // the policy is initialized we would re-evaluate permissions.
1090 final boolean permissionPolicyInitialized =
1091 mPermissionPolicyInternal != null
1092 && mPermissionPolicyInternal.isInitialized(userId);
1093
Philip P. Moltmann48456672019-01-20 13:14:03 -08001094 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001095 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001096 int flags = permState != null ? permState.getFlags() : 0;
1097
1098 boolean wasChanged = false;
1099
Svet Ganov83a3a4a2019-05-03 18:50:43 -07001100 boolean restrictionExempt =
1101 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001102 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1103 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1104 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1105
Philip P. Moltmann48456672019-01-20 13:14:03 -08001106 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001107 // If hard restricted we don't allow holding it
Svet Ganov0b41c892019-07-26 17:45:56 -07001108 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001109 if (!restrictionExempt) {
1110 if (permState != null && permState.isGranted()
1111 && permissionsState.revokeRuntimePermission(
1112 bp, userId) != PERMISSION_OPERATION_FAILURE) {
1113 wasChanged = true;
1114 }
1115 if (!restrictionApplied) {
1116 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1117 wasChanged = true;
1118 }
1119 }
1120 // If soft restricted we allow holding in a restricted form
Svet Ganov0b41c892019-07-26 17:45:56 -07001121 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001122 // Regardless if granted set the restriction flag as it
1123 // may affect app treatment based on this permission.
1124 if (!restrictionExempt && !restrictionApplied) {
1125 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1126 wasChanged = true;
1127 }
1128 }
1129
Philip P. Moltmann48456672019-01-20 13:14:03 -08001130 // Remove review flag as it is not necessary anymore
1131 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1132 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1133 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001134 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001135
1136 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1137 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1138 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001139 // Hard restricted permissions cannot be held.
Svet Ganov0b41c892019-07-26 17:45:56 -07001140 } else if (!permissionPolicyInitialized
1141 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001142 if (permState != null && permState.isGranted()) {
1143 if (permissionsState.grantRuntimePermission(bp, userId)
1144 == PERMISSION_OPERATION_FAILURE) {
1145 wasChanged = true;
1146 }
1147 }
1148 }
1149 } else {
1150 if (permState == null) {
1151 // New permission
1152 if (PLATFORM_PACKAGE_NAME.equals(
1153 bp.getSourcePackageName())) {
1154 if (!bp.isRemoved()) {
1155 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
1156 | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1157 wasChanged = true;
1158 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001159 }
1160 }
1161
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001162 if (!permissionsState.hasRuntimePermission(bp.name, userId)
1163 && permissionsState.grantRuntimePermission(bp, userId)
1164 != PERMISSION_OPERATION_FAILURE) {
1165 wasChanged = true;
1166 }
1167
1168 // If legacy app always grant the permission but if restricted
1169 // and not exempt take a note a restriction should be applied.
Svet Ganov0b41c892019-07-26 17:45:56 -07001170 if (permissionPolicyInitialized
1171 && (hardRestricted || softRestricted)
1172 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001173 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1174 wasChanged = true;
1175 }
1176 }
1177
1178 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov0b41c892019-07-26 17:45:56 -07001179 if (permissionPolicyInitialized) {
1180 if (!(hardRestricted || softRestricted) || restrictionExempt) {
1181 if (restrictionApplied) {
1182 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1183 // Dropping restriction on a legacy app implies a review
1184 if (!appSupportsRuntimePermissions) {
1185 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1186 }
1187 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001188 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001189 }
1190 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001191
1192 if (wasChanged) {
1193 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1194 }
1195
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001196 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001197 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001198 }
1199 } break;
1200
1201 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001202 // Upgrade from Pre-Q to Q permission model. Make all permissions
1203 // runtime
1204 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001205 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001206 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001207
Zimuzoe6411402019-05-13 16:32:57 +01001208 BasePermission bpToRevoke =
1209 upgradedActivityRecognitionPermission == null
1210 ? bp : mSettings.getPermissionLocked(
1211 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001212 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01001213 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08001214 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01001215 origPermissions.updatePermissionFlags(bpToRevoke,
1216 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001217 (MASK_PERMISSION_FLAGS_ALL
1218 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001219 changedInstallPermission = true;
1220 }
1221
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001222 boolean hardRestricted = bp.isHardRestricted();
1223 boolean softRestricted = bp.isSoftRestricted();
1224
Philip P. Moltmann48456672019-01-20 13:14:03 -08001225 for (int userId : currentUserIds) {
Svet Ganov0b41c892019-07-26 17:45:56 -07001226 // If permission policy is not ready we don't deal with restricted
1227 // permissions as the policy may whitelist some permissions. Once
1228 // the policy is initialized we would re-evaluate permissions.
1229 final boolean permissionPolicyInitialized =
1230 mPermissionPolicyInternal != null
1231 && mPermissionPolicyInternal.isInitialized(userId);
1232
Philip P. Moltmann48456672019-01-20 13:14:03 -08001233 boolean wasChanged = false;
1234
Svet Ganov83a3a4a2019-05-03 18:50:43 -07001235 boolean restrictionExempt =
1236 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001237 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
1238 boolean restrictionApplied = (origPermissions.getPermissionFlags(
1239 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
1240
Philip P. Moltmann48456672019-01-20 13:14:03 -08001241 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001242 // If hard restricted we don't allow holding it
Svet Ganov0b41c892019-07-26 17:45:56 -07001243 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001244 if (!restrictionExempt) {
1245 if (permState != null && permState.isGranted()
1246 && permissionsState.revokeRuntimePermission(
1247 bp, userId) != PERMISSION_OPERATION_FAILURE) {
1248 wasChanged = true;
1249 }
1250 if (!restrictionApplied) {
1251 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1252 wasChanged = true;
1253 }
1254 }
1255 // If soft restricted we allow holding in a restricted form
Svet Ganov0b41c892019-07-26 17:45:56 -07001256 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001257 // Regardless if granted set the restriction flag as it
1258 // may affect app treatment based on this permission.
1259 if (!restrictionExempt && !restrictionApplied) {
1260 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1261 wasChanged = true;
1262 }
1263 }
1264
Philip P. Moltmann48456672019-01-20 13:14:03 -08001265 // Remove review flag as it is not necessary anymore
1266 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
1267 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
1268 wasChanged = true;
1269 }
1270
1271 if ((flags & FLAG_PERMISSION_REVOKE_ON_UPGRADE) != 0) {
1272 flags &= ~FLAG_PERMISSION_REVOKE_ON_UPGRADE;
1273 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001274 // Hard restricted permissions cannot be held.
Svet Ganov0b41c892019-07-26 17:45:56 -07001275 } else if (!permissionPolicyInitialized ||
1276 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001277 if (permissionsState.grantRuntimePermission(bp, userId) !=
1278 PERMISSION_OPERATION_FAILURE) {
1279 wasChanged = true;
1280 }
1281 }
1282 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001283 if (!permissionsState.hasRuntimePermission(bp.name, userId)
1284 && permissionsState.grantRuntimePermission(bp,
1285 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08001286 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1287 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001288 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001289
1290 // If legacy app always grant the permission but if restricted
1291 // and not exempt take a note a restriction should be applied.
Svet Ganov0b41c892019-07-26 17:45:56 -07001292 if (permissionPolicyInitialized
1293 && (hardRestricted || softRestricted)
1294 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001295 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
1296 wasChanged = true;
1297 }
1298 }
1299
1300 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov0b41c892019-07-26 17:45:56 -07001301 if (permissionPolicyInitialized) {
1302 if (!(hardRestricted || softRestricted) || restrictionExempt) {
1303 if (restrictionApplied) {
1304 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
1305 // Dropping restriction on a legacy app implies a review
1306 if (!appSupportsRuntimePermissions) {
1307 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
1308 }
1309 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001310 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001311 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001312 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08001313
1314 if (wasChanged) {
1315 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1316 }
1317
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08001318 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001319 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001320 }
1321 } break;
1322
1323 default: {
1324 if (packageOfInterest == null
1325 || packageOfInterest.equals(pkg.packageName)) {
1326 if (DEBUG_PERMISSIONS) {
1327 Slog.i(TAG, "Not granting permission " + perm
1328 + " to package " + pkg.packageName
1329 + " because it was previously installed without");
1330 }
1331 }
1332 } break;
1333 }
1334 } else {
1335 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08001336 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001337 // Also drop the permission flags.
1338 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08001339 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001340 changedInstallPermission = true;
1341 Slog.i(TAG, "Un-granting permission " + perm
1342 + " from package " + pkg.packageName
1343 + " (protectionLevel=" + bp.getProtectionLevel()
1344 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1345 + ")");
1346 } else if (bp.isAppOp()) {
1347 // Don't print warning for app op permissions, since it is fine for them
1348 // not to be granted, there is a UI for the user to decide.
1349 if (DEBUG_PERMISSIONS
1350 && (packageOfInterest == null
1351 || packageOfInterest.equals(pkg.packageName))) {
1352 Slog.i(TAG, "Not granting permission " + perm
1353 + " to package " + pkg.packageName
1354 + " (protectionLevel=" + bp.getProtectionLevel()
1355 + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
1356 + ")");
1357 }
1358 }
1359 }
1360 }
1361
1362 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
1363 !ps.isSystem() || ps.isUpdatedSystem()) {
1364 // This is the first that we have heard about this package, so the
1365 // permissions we have now selected are fixed until explicitly
1366 // changed.
1367 ps.setInstallPermissionsFixed(true);
1368 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001369
1370 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
1371 updatedUserIds);
1372 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07001373 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07001374 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001375 }
1376
1377 // Persist the runtime permissions state for users with changes. If permissions
1378 // were revoked because no app in the shared user declares them we have to
1379 // write synchronously to avoid losing runtime permissions state.
1380 if (callback != null) {
1381 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
1382 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001383
1384 for (int userId : updatedUserIds) {
1385 notifyRuntimePermissionStateChanged(pkg.packageName, userId);
1386 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001387 }
1388
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001389 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001390 * Revoke permissions that are not implicit anymore and that have
1391 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
1392 *
1393 * @param ps The state of the permissions of the package
1394 * @param pkg The package that is currently looked at
1395 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
1396 * for a user is changed.
1397 *
1398 * @return The updated value of the {@code updatedUserIds} parameter
1399 */
1400 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
1401 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1402 @NonNull int[] updatedUserIds) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001403 String pkgName = pkg.packageName;
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08001404 boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
1405 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001406
1407 int[] users = UserManagerService.getInstance().getUserIds();
1408 int numUsers = users.length;
1409 for (int i = 0; i < numUsers; i++) {
1410 int userId = users[i];
1411
1412 for (String permission : ps.getPermissions(userId)) {
1413 if (!pkg.implicitPermissions.contains(permission)) {
1414 if (!ps.hasInstallPermission(permission)) {
1415 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
1416
1417 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
1418 BasePermission bp = mSettings.getPermissionLocked(permission);
1419
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001420 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001421
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08001422 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
1423 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001424 int revokeResult = ps.revokeRuntimePermission(bp, userId);
1425 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
1426 if (DEBUG_PERMISSIONS) {
1427 Slog.i(TAG, "Revoking runtime permission "
1428 + permission + " for " + pkgName
1429 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001430 }
1431 }
1432
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08001433 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001434 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08001435
1436 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
1437 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001438 }
1439 }
1440 }
1441 }
1442 }
1443
1444 return updatedUserIds;
1445 }
1446
1447 /**
1448 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
1449 *
1450 * <p>A single new permission can be split off from several source permissions. In this case
1451 * the most leniant state is inherited.
1452 *
1453 * <p>Warning: This does not handle foreground / background permissions
1454 *
1455 * @param sourcePerms The permissions to inherit from
1456 * @param newPerm The permission to inherit to
1457 * @param ps The permission state of the package
1458 * @param pkg The package requesting the permissions
1459 * @param userId The user the permission belongs to
1460 */
1461 private void inheritPermissionStateToNewImplicitPermissionLocked(
1462 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
1463 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
1464 @UserIdInt int userId) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001465 String pkgName = pkg.packageName;
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001466 boolean isGranted = false;
1467 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001468
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001469 int numSourcePerm = sourcePerms.size();
1470 for (int i = 0; i < numSourcePerm; i++) {
1471 String sourcePerm = sourcePerms.valueAt(i);
1472 if ((ps.hasRuntimePermission(sourcePerm, userId))
1473 || ps.hasInstallPermission(sourcePerm)) {
1474 if (!isGranted) {
1475 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001476 }
1477
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001478 isGranted = true;
1479 flags |= ps.getPermissionFlags(sourcePerm, userId);
1480 } else {
1481 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08001482 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001483 }
1484 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001485 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07001486
1487 if (isGranted) {
1488 if (DEBUG_PERMISSIONS) {
1489 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
1490 + " for " + pkgName);
1491 }
1492
1493 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
1494 }
1495
1496 // Add permission flags
1497 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001498 }
1499
1500 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07001501 * When the app has requested legacy storage we might need to update
1502 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
1503 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
1504 *
1505 * @param pkg The package for which the permissions are updated
1506 * @param replace If the app is being replaced
1507 * @param updatedUserIds The ids of the users that already changed.
1508 *
1509 * @return The ids of the users that are changed
1510 */
1511 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
1512 @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
1513 if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
1514 pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
1515 || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
1516 return UserManagerService.getInstance().getUserIds();
1517 }
1518
1519 return updatedUserIds;
1520 }
1521
1522 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001523 * Set the state of a implicit permission that is seen for the first time.
1524 *
1525 * @param origPs The permission state of the package before the split
1526 * @param ps The new permission state
1527 * @param pkg The package the permission belongs to
1528 * @param updatedUserIds List of users for which the permission state has already been changed
1529 *
1530 * @return List of users for which the permission state has been changed
1531 */
1532 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
1533 @NonNull PermissionsState origPs,
1534 @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07001535 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001536 @NonNull int[] updatedUserIds) {
1537 String pkgName = pkg.packageName;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001538 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
1539
1540 int numSplitPerms = PermissionManager.SPLIT_PERMISSIONS.size();
1541 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
1542 PermissionManager.SplitPermissionInfo spi =
1543 PermissionManager.SPLIT_PERMISSIONS.get(splitPermNum);
1544
1545 List<String> newPerms = spi.getNewPermissions();
1546 int numNewPerms = newPerms.size();
1547 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
1548 String newPerm = newPerms.get(newPermNum);
1549
1550 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
1551 if (splitPerms == null) {
1552 splitPerms = new ArraySet<>();
1553 newToSplitPerms.put(newPerm, splitPerms);
1554 }
1555
1556 splitPerms.add(spi.getSplitPermission());
1557 }
1558 }
1559
1560 int numNewImplicitPerms = newImplicitPermissions.size();
1561 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
1562 newImplicitPermNum++) {
1563 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
1564 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
1565
1566 if (sourcePerms != null) {
1567 if (!ps.hasInstallPermission(newPerm)) {
1568 BasePermission bp = mSettings.getPermissionLocked(newPerm);
1569
1570 int[] users = UserManagerService.getInstance().getUserIds();
1571 int numUsers = users.length;
1572 for (int userNum = 0; userNum < numUsers; userNum++) {
1573 int userId = users[userNum];
1574
Zimuzoe6411402019-05-13 16:32:57 +01001575 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
1576 ps.updatePermissionFlags(bp, userId,
1577 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
1578 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
1579 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001580 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
1581
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001582 boolean inheritsFromInstallPerm = false;
1583 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
1584 sourcePermNum++) {
1585 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
1586 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001587 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07001588 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001589 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08001590
1591 if (!origPs.hasRequestedPermission(sourcePerms)
1592 && !inheritsFromInstallPerm) {
1593 // Both permissions are new so nothing to inherit.
1594 if (DEBUG_PERMISSIONS) {
1595 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
1596 + " for " + pkgName + " as split permission is also new");
1597 }
1598
1599 break;
1600 } else {
1601 // Inherit from new install or existing runtime permissions
1602 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
1603 newPerm, ps, pkg, userId);
1604 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07001605 }
1606 }
1607 }
1608 }
1609
1610 return updatedUserIds;
1611 }
1612
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001613 private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
1614 boolean allowed = false;
1615 final int NP = PackageParser.NEW_PERMISSIONS.length;
1616 for (int ip=0; ip<NP; ip++) {
1617 final PackageParser.NewPermissionInfo npi
1618 = PackageParser.NEW_PERMISSIONS[ip];
1619 if (npi.name.equals(perm)
1620 && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
1621 allowed = true;
1622 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
1623 + pkg.packageName);
1624 break;
1625 }
1626 }
1627 return allowed;
1628 }
1629
1630 /**
1631 * Determines whether a package is whitelisted for a particular privapp permission.
1632 *
1633 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
1634 *
1635 * <p>This handles parent/child apps.
1636 */
1637 private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001638 ArraySet<String> wlPermissions = null;
1639 if (pkg.isVendor()) {
1640 wlPermissions =
1641 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
1642 } else if (pkg.isProduct()) {
1643 wlPermissions =
1644 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
Jeongik Chaf6629832019-07-04 21:12:06 +09001645 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01001646 wlPermissions =
Jeongik Chaf6629832019-07-04 21:12:06 +09001647 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Dario Freni2bef1762018-06-01 14:02:08 +01001648 pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001649 } else {
1650 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
1651 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001652 // Let's check if this package is whitelisted...
1653 boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
1654 // If it's not, we'll also tail-recurse to the parent.
1655 return whitelisted ||
1656 pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
1657 }
1658
1659 private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
1660 BasePermission bp, PermissionsState origPermissions) {
1661 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09001662 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
1663 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001664 boolean privappPermissionsDisable =
1665 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
1666 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
1667 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
1668 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
1669 && !platformPackage && platformPermission) {
1670 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001671 // Only report violations for apps on system image
1672 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
1673 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001674 ArraySet<String> deniedPermissions = null;
1675 if (pkg.isVendor()) {
1676 deniedPermissions = SystemConfig.getInstance()
1677 .getVendorPrivAppDenyPermissions(pkg.packageName);
1678 } else if (pkg.isProduct()) {
1679 deniedPermissions = SystemConfig.getInstance()
1680 .getProductPrivAppDenyPermissions(pkg.packageName);
Jeongik Chaf6629832019-07-04 21:12:06 +09001681 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01001682 deniedPermissions = SystemConfig.getInstance()
Jeongik Chaf6629832019-07-04 21:12:06 +09001683 .getSystemExtPrivAppDenyPermissions(pkg.packageName);
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09001684 } else {
1685 deniedPermissions = SystemConfig.getInstance()
1686 .getPrivAppDenyPermissions(pkg.packageName);
1687 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001688 final boolean permissionViolation =
1689 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07001690 if (permissionViolation) {
1691 Slog.w(TAG, "Privileged permission " + perm + " for package "
1692 + pkg.packageName + " - not in privapp-permissions whitelist");
1693
1694 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1695 if (mPrivappPermissionsViolations == null) {
1696 mPrivappPermissionsViolations = new ArraySet<>();
1697 }
1698 mPrivappPermissionsViolations.add(pkg.packageName + ": " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001699 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001700 } else {
1701 return false;
1702 }
1703 }
1704 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
1705 return false;
1706 }
1707 }
1708 }
Chen Xuda02e072019-10-07 00:24:41 -07001709 // expect single system package
1710 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
1711 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001712 final PackageParser.Package systemPackage =
1713 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08001714
1715 // check if the package is allow to use this signature permission. A package is allowed to
1716 // use a signature permission if:
1717 // - it has the same set of signing certificates as the source package
1718 // - or its signing certificate was rotated from the source package's certificate
1719 // - or its signing certificate is a previous signing certificate of the defining
1720 // package, and the defining package still trusts the old certificate for permissions
1721 // - or it shares the above relationships with the system package
1722 boolean allowed =
1723 pkg.mSigningDetails.hasAncestorOrSelf(
1724 bp.getSourcePackageSetting().getSigningDetails())
1725 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
1726 pkg.mSigningDetails,
1727 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
1728 || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
1729 || systemPackage.mSigningDetails.checkCapability(
1730 pkg.mSigningDetails,
1731 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001732 if (!allowed && (privilegedPermission || oemPermission)) {
1733 if (pkg.isSystem()) {
1734 // For updated system applications, a privileged/oem permission
1735 // is granted only if it had been defined by the original application.
1736 if (pkg.isUpdatedSystemApp()) {
1737 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001738 mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001739 final PackageSetting disabledPs =
1740 (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
1741 if (disabledPs != null
1742 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
1743 // If the original was granted this permission, we take
1744 // that grant decision as read and propagate it to the
1745 // update.
1746 if ((privilegedPermission && disabledPs.isPrivileged())
1747 || (oemPermission && disabledPs.isOem()
1748 && canGrantOemPermission(disabledPs, perm))) {
1749 allowed = true;
1750 }
1751 } else {
1752 // The system apk may have been updated with an older
1753 // version of the one on the data partition, but which
1754 // granted a new system permission that it didn't have
1755 // before. In this case we do want to allow the app to
1756 // now get the new permission if the ancestral apk is
1757 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07001758 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001759 && isPackageRequestingPermission(disabledPkg, perm)
1760 && ((privilegedPermission && disabledPs.isPrivileged())
1761 || (oemPermission && disabledPs.isOem()
1762 && canGrantOemPermission(disabledPs, perm)))) {
1763 allowed = true;
1764 }
1765 // Also if a privileged parent package on the system image or any of
1766 // its children requested a privileged/oem permission, the updated child
1767 // packages can also get the permission.
1768 if (pkg.parentPackage != null) {
1769 final PackageParser.Package disabledParentPkg = mPackageManagerInt
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001770 .getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001771 final PackageSetting disabledParentPs = (disabledParentPkg != null)
1772 ? (PackageSetting) disabledParentPkg.mExtras : null;
1773 if (disabledParentPkg != null
1774 && ((privilegedPermission && disabledParentPs.isPrivileged())
1775 || (oemPermission && disabledParentPs.isOem()))) {
1776 if (isPackageRequestingPermission(disabledParentPkg, perm)
1777 && canGrantOemPermission(disabledParentPs, perm)) {
1778 allowed = true;
1779 } else if (disabledParentPkg.childPackages != null) {
1780 for (PackageParser.Package disabledChildPkg
1781 : disabledParentPkg.childPackages) {
1782 final PackageSetting disabledChildPs =
1783 (disabledChildPkg != null)
1784 ? (PackageSetting) disabledChildPkg.mExtras
1785 : null;
1786 if (isPackageRequestingPermission(disabledChildPkg, perm)
1787 && canGrantOemPermission(
1788 disabledChildPs, perm)) {
1789 allowed = true;
1790 break;
1791 }
1792 }
1793 }
1794 }
1795 }
1796 }
1797 } else {
1798 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1799 allowed = (privilegedPermission && pkg.isPrivileged())
1800 || (oemPermission && pkg.isOem()
1801 && canGrantOemPermission(ps, perm));
1802 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09001803 // In any case, don't grant a privileged permission to privileged vendor apps, if
1804 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
1805 // flag.
1806 if (allowed && privilegedPermission &&
1807 !vendorPrivilegedPermission && pkg.isVendor()) {
1808 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
1809 + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
1810 allowed = false;
1811 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001812 }
1813 }
1814 if (!allowed) {
1815 if (!allowed
1816 && bp.isPre23()
1817 && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
1818 // If this was a previously normal/dangerous permission that got moved
1819 // to a system permission as part of the runtime permission redesign, then
1820 // we still want to blindly grant it to old apps.
1821 allowed = true;
1822 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001823 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
1824 // need a separate flag anymore. Hence we need to check which
1825 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001826 if (!allowed && bp.isInstaller()
Chen Xuda02e072019-10-07 00:24:41 -07001827 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1828 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
1829 pkg.packageName) || ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07001830 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
Chen Xuda02e072019-10-07 00:24:41 -07001831 UserHandle.USER_SYSTEM), pkg.packageName)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001832 // If this permission is to be granted to the system installer and
1833 // this app is an installer, then it gets the permission.
1834 allowed = true;
1835 }
1836 if (!allowed && bp.isVerifier()
Chen Xuda02e072019-10-07 00:24:41 -07001837 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1838 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
1839 pkg.packageName)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001840 // If this permission is to be granted to the system verifier and
1841 // this app is a verifier, then it gets the permission.
1842 allowed = true;
1843 }
1844 if (!allowed && bp.isPreInstalled()
1845 && pkg.isSystem()) {
1846 // Any pre-installed system app is allowed to get this permission.
1847 allowed = true;
1848 }
1849 if (!allowed && bp.isDevelopment()) {
1850 // For development permissions, a development permission
1851 // is granted only if it was already granted.
1852 allowed = origPermissions.hasInstallPermission(perm);
1853 }
1854 if (!allowed && bp.isSetup()
Chen Xuda02e072019-10-07 00:24:41 -07001855 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1856 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
1857 pkg.packageName)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001858 // If this permission is to be granted to the system setup wizard and
1859 // this app is a setup wizard, then it gets the permission.
1860 allowed = true;
1861 }
Makoto Onuki700feef2018-02-15 10:59:41 -08001862 if (!allowed && bp.isSystemTextClassifier()
Chen Xuda02e072019-10-07 00:24:41 -07001863 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Makoto Onuki700feef2018-02-15 10:59:41 -08001864 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
Chen Xuda02e072019-10-07 00:24:41 -07001865 UserHandle.USER_SYSTEM), pkg.packageName)) {
Makoto Onuki700feef2018-02-15 10:59:41 -08001866 // Special permissions for the system default text classifier.
1867 allowed = true;
1868 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001869 if (!allowed && bp.isConfigurator()
Chen Xuda02e072019-10-07 00:24:41 -07001870 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1871 PackageManagerInternal.PACKAGE_CONFIGURATOR,
1872 UserHandle.USER_SYSTEM), pkg.packageName)) {
Stanislav Zholnin596437f2018-12-28 15:34:23 +00001873 // Special permissions for the device configurator.
1874 allowed = true;
1875 }
Varun Shah5f303652018-11-16 18:11:19 -08001876 if (!allowed && bp.isWellbeing()
Chen Xuda02e072019-10-07 00:24:41 -07001877 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1878 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
1879 pkg.packageName)) {
Varun Shah5f303652018-11-16 18:11:19 -08001880 // Special permission granted only to the OEM specified wellbeing app
1881 allowed = true;
1882 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07001883 if (!allowed && bp.isDocumenter()
Chen Xuda02e072019-10-07 00:24:41 -07001884 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1885 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
1886 pkg.packageName)) {
Jeff Sharkey15707b32018-12-10 12:08:41 -07001887 // If this permission is to be granted to the documenter and
1888 // this app is the documenter, then it gets the permission.
1889 allowed = true;
1890 }
Joe Onorato5a15b552018-12-18 10:40:04 -08001891 if (!allowed && bp.isIncidentReportApprover()
Chen Xuda02e072019-10-07 00:24:41 -07001892 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Joe Onorato5a15b552018-12-18 10:40:04 -08001893 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
Chen Xuda02e072019-10-07 00:24:41 -07001894 UserHandle.USER_SYSTEM), pkg.packageName)) {
Joe Onorato5a15b552018-12-18 10:40:04 -08001895 // If this permission is to be granted to the incident report approver and
1896 // this app is the incident report approver, then it gets the permission.
1897 allowed = true;
1898 }
George Hodulikcd7695d2019-01-29 18:17:05 -08001899 if (!allowed && bp.isAppPredictor()
Chen Xuda02e072019-10-07 00:24:41 -07001900 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1901 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
1902 pkg.packageName)) {
George Hodulikcd7695d2019-01-29 18:17:05 -08001903 // Special permissions for the system app predictor.
1904 allowed = true;
1905 }
Chen Xuda02e072019-10-07 00:24:41 -07001906 if (!allowed && bp.isTelephony()
1907 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
1908 PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM),
1909 pkg.packageName)) {
1910 // Special permissions for the system telephony apps.
1911 allowed = true;
1912 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001913 }
1914 return allowed;
1915 }
1916
1917 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
1918 if (!ps.isOem()) {
1919 return false;
1920 }
1921 // all oem permissions must explicitly be granted or denied
1922 final Boolean granted =
1923 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
1924 if (granted == null) {
1925 throw new IllegalStateException("OEM permission" + permission + " requested by package "
1926 + ps.name + " must be explicitly declared granted or not");
1927 }
1928 return Boolean.TRUE == granted;
1929 }
1930
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07001931 private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
1932 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001933 // Permission review applies only to apps not supporting the new permission model.
1934 if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
1935 return false;
1936 }
1937
1938 // Legacy apps have the permission and get user consent on launch.
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07001939 if (pkg.mExtras == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07001940 return false;
1941 }
1942 final PackageSetting ps = (PackageSetting) pkg.mExtras;
1943 final PermissionsState permissionsState = ps.getPermissionsState();
1944 return permissionsState.isPermissionReviewRequired(userId);
1945 }
1946
1947 private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
1948 final int permCount = pkg.requestedPermissions.size();
1949 for (int j = 0; j < permCount; j++) {
1950 String requestedPermission = pkg.requestedPermissions.get(j);
1951 if (permission.equals(requestedPermission)) {
1952 return true;
1953 }
1954 }
1955 return false;
1956 }
1957
Andreas Gampea36dc622018-02-05 17:19:22 -08001958 @GuardedBy("mLock")
Todd Kennedy0eb97382017-10-03 16:57:22 -07001959 private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
1960 PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
1961 if (pkg.parentPackage == null) {
1962 return;
1963 }
1964 if (pkg.requestedPermissions == null) {
1965 return;
1966 }
1967 final PackageParser.Package disabledPkg =
Philip P. Moltmannb0be05c2018-09-19 02:46:56 +00001968 mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07001969 if (disabledPkg == null || disabledPkg.mExtras == null) {
1970 return;
1971 }
1972 final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
1973 if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
1974 return;
1975 }
1976 final int permCount = pkg.requestedPermissions.size();
1977 for (int i = 0; i < permCount; i++) {
1978 String permission = pkg.requestedPermissions.get(i);
1979 BasePermission bp = mSettings.getPermissionLocked(permission);
1980 if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
1981 continue;
1982 }
1983 for (int userId : mUserManagerInt.getUserIds()) {
1984 if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
1985 grantRuntimePermission(
1986 permission, pkg.packageName, false, callingUid, userId, callback);
1987 }
1988 }
1989 }
1990 }
1991
1992 private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
1993 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
1994 for (int userId : userIds) {
1995 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
1996 callback);
1997 }
1998 }
1999
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002000 private @Nullable List<String> getWhitelistedRestrictedPermissions(
2001 @NonNull PackageParser.Package pkg, @PermissionWhitelistFlags int whitelistFlags,
2002 @UserIdInt int userId) {
2003 final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
2004 if (packageSetting == null) {
2005 return null;
2006 }
2007
2008 final PermissionsState permissionsState = packageSetting.getPermissionsState();
2009
2010 int queryFlags = 0;
2011 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
2012 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2013 }
2014 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
2015 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2016 }
2017 if ((whitelistFlags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
2018 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2019 }
2020
2021 ArrayList<String> whitelistedPermissions = null;
2022
2023 final int permissionCount = pkg.requestedPermissions.size();
2024 for (int i = 0; i < permissionCount; i++) {
2025 final String permissionName = pkg.requestedPermissions.get(i);
2026 final int currentFlags = permissionsState.getPermissionFlags(permissionName, userId);
2027 if ((currentFlags & queryFlags) != 0) {
2028 if (whitelistedPermissions == null) {
2029 whitelistedPermissions = new ArrayList<>();
2030 }
2031 whitelistedPermissions.add(permissionName);
2032 }
2033 }
2034
2035 return whitelistedPermissions;
2036 }
2037
2038 private void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
2039 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
2040 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
2041 @NonNull PermissionCallback callback) {
2042 for (int userId : userIds) {
2043 setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
2044 callingUid, whitelistFlags, callback);
2045 }
2046 }
2047
Todd Kennedy0eb97382017-10-03 16:57:22 -07002048 private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
2049 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
2050 PackageSetting ps = (PackageSetting) pkg.mExtras;
2051 if (ps == null) {
2052 return;
2053 }
2054
2055 PermissionsState permissionsState = ps.getPermissionsState();
2056
2057 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2058 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2059
2060 final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
2061 >= Build.VERSION_CODES.M;
2062
2063 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
2064
2065 for (String permission : pkg.requestedPermissions) {
2066 final BasePermission bp;
2067 synchronized (mLock) {
2068 bp = mSettings.getPermissionLocked(permission);
2069 }
2070 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
2071 && (!instantApp || bp.isInstant())
2072 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
2073 && (grantedPermissions == null
2074 || ArrayUtils.contains(grantedPermissions, permission))) {
2075 final int flags = permissionsState.getPermissionFlags(permission, userId);
2076 if (supportsRuntimePermissions) {
2077 // Installer cannot change immutable permissions.
2078 if ((flags & immutableFlags) == 0) {
2079 grantRuntimePermission(permission, pkg.packageName, false, callingUid,
2080 userId, callback);
2081 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002082 } else {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002083 // In permission review mode we clear the review flag when we
2084 // are asked to install the app with all permissions granted.
2085 if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2086 updatePermissionFlags(permission, pkg.packageName,
2087 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002088 userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002089 }
2090 }
2091 }
2092 }
2093 }
2094
2095 private void grantRuntimePermission(String permName, String packageName, boolean overridePolicy,
2096 int callingUid, final int userId, PermissionCallback callback) {
2097 if (!mUserManagerInt.exists(userId)) {
2098 Log.e(TAG, "No such user:" + userId);
2099 return;
2100 }
2101
2102 mContext.enforceCallingOrSelfPermission(
2103 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
2104 "grantRuntimePermission");
2105
2106 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002107 true, // requireFullPermission
2108 true, // checkShell
2109 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002110 "grantRuntimePermission");
2111
2112 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2113 if (pkg == null || pkg.mExtras == null) {
Hai Zhang03bb8ee2019-07-31 14:07:17 -07002114 Log.e(TAG, "Unknown package: " + packageName);
2115 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002116 }
2117 final BasePermission bp;
2118 synchronized(mLock) {
2119 bp = mSettings.getPermissionLocked(permName);
2120 }
2121 if (bp == null) {
2122 throw new IllegalArgumentException("Unknown permission: " + permName);
2123 }
2124 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2125 throw new IllegalArgumentException("Unknown package: " + packageName);
2126 }
2127
2128 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2129
2130 // If a permission review is required for legacy apps we represent
2131 // their permissions as always granted runtime ones since we need
2132 // to keep the review required permission flag per user while an
2133 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002134 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002135 && bp.isRuntime()) {
2136 return;
2137 }
2138
2139 final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
2140
2141 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2142 final PermissionsState permissionsState = ps.getPermissionsState();
2143
2144 final int flags = permissionsState.getPermissionFlags(permName, userId);
2145 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002146 Log.e(TAG, "Cannot grant system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002147 + permName + " for package " + packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002148 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002149 }
2150 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002151 Log.e(TAG, "Cannot grant policy fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002152 + permName + " for package " + packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002153 return;
2154 }
2155
Philip P. Moltmannd6b849c2019-05-15 16:36:32 -07002156 if (bp.isHardRestricted()
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002157 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002158 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002159 + permName + " for package " + packageName);
2160 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002161 }
2162
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002163 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Philip P. Moltmann69b645f2019-06-17 14:28:11 -07002164 pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -07002165 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
2166 + packageName);
2167 return;
2168 }
2169
Todd Kennedy0eb97382017-10-03 16:57:22 -07002170 if (bp.isDevelopment()) {
2171 // Development permissions must be handled specially, since they are not
2172 // normal runtime permissions. For now they apply to all users.
2173 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002174 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002175 if (callback != null) {
2176 callback.onInstallPermissionGranted();
2177 }
2178 }
2179 return;
2180 }
2181
2182 if (ps.getInstantApp(userId) && !bp.isInstant()) {
2183 throw new SecurityException("Cannot grant non-ephemeral permission"
2184 + permName + " for package " + packageName);
2185 }
2186
2187 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
2188 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
2189 return;
2190 }
2191
2192 final int result = permissionsState.grantRuntimePermission(bp, userId);
2193 switch (result) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002194 case PERMISSION_OPERATION_FAILURE: {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002195 return;
2196 }
2197
2198 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
2199 if (callback != null) {
2200 callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
2201 }
2202 }
2203 break;
2204 }
2205
2206 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002207 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002208 }
2209
2210 if (callback != null) {
2211 callback.onPermissionGranted(uid, userId);
2212 }
2213
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002214 if (bp.isRuntime()) {
2215 notifyRuntimePermissionStateChanged(packageName, userId);
2216 }
2217
Todd Kennedy0eb97382017-10-03 16:57:22 -07002218 // Only need to do this if user is initialized. Otherwise it's a new user
2219 // and there are no processes running as the user yet and there's no need
2220 // to make an expensive call to remount processes for the changed permissions.
2221 if (READ_EXTERNAL_STORAGE.equals(permName)
2222 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
2223 final long token = Binder.clearCallingIdentity();
2224 try {
2225 if (mUserManagerInt.isUserInitialized(userId)) {
2226 StorageManagerInternal storageManagerInternal = LocalServices.getService(
2227 StorageManagerInternal.class);
2228 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
2229 }
2230 } finally {
2231 Binder.restoreCallingIdentity(token);
2232 }
2233 }
2234
2235 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002236
2237 private void revokeRuntimePermission(String permName, String packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002238 boolean overridePolicy, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002239 if (!mUserManagerInt.exists(userId)) {
2240 Log.e(TAG, "No such user:" + userId);
2241 return;
2242 }
2243
2244 mContext.enforceCallingOrSelfPermission(
2245 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
2246 "revokeRuntimePermission");
2247
2248 enforceCrossUserPermission(Binder.getCallingUid(), userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002249 true, // requireFullPermission
2250 true, // checkShell
2251 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002252 "revokeRuntimePermission");
2253
Todd Kennedy0eb97382017-10-03 16:57:22 -07002254 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2255 if (pkg == null || pkg.mExtras == null) {
Hai Zhang03bb8ee2019-07-31 14:07:17 -07002256 Log.e(TAG, "Unknown package: " + packageName);
2257 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002258 }
2259 if (mPackageManagerInt.filterAppAccess(pkg, Binder.getCallingUid(), userId)) {
2260 throw new IllegalArgumentException("Unknown package: " + packageName);
2261 }
Hongming Jinae750fb2018-09-27 23:00:20 +00002262 final BasePermission bp = mSettings.getPermissionLocked(permName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002263 if (bp == null) {
2264 throw new IllegalArgumentException("Unknown permission: " + permName);
2265 }
2266
2267 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
2268
2269 // If a permission review is required for legacy apps we represent
2270 // their permissions as always granted runtime ones since we need
2271 // to keep the review required permission flag per user while an
2272 // install permission's state is shared across all users.
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07002273 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
Todd Kennedy0eb97382017-10-03 16:57:22 -07002274 && bp.isRuntime()) {
2275 return;
2276 }
2277
2278 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2279 final PermissionsState permissionsState = ps.getPermissionsState();
2280
2281 final int flags = permissionsState.getPermissionFlags(permName, userId);
Nathan Haroldd66b9f32018-03-14 19:55:38 -07002282 // Only the system may revoke SYSTEM_FIXED permissions.
2283 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
2284 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
2285 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
Todd Kennedy0eb97382017-10-03 16:57:22 -07002286 + permName + " for package " + packageName);
2287 }
2288 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
2289 throw new SecurityException("Cannot revoke policy fixed permission "
2290 + permName + " for package " + packageName);
2291 }
2292
2293 if (bp.isDevelopment()) {
2294 // Development permissions must be handled specially, since they are not
2295 // normal runtime permissions. For now they apply to all users.
2296 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002297 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002298 if (callback != null) {
2299 callback.onInstallPermissionRevoked();
2300 }
2301 }
2302 return;
2303 }
2304
Philip P. Moltmannf50316c2019-07-03 15:44:00 -07002305 // Permission is already revoked, no need to do anything.
2306 if (!permissionsState.hasRuntimePermission(permName, userId)) {
2307 return;
2308 }
2309
Todd Kennedy0eb97382017-10-03 16:57:22 -07002310 if (permissionsState.revokeRuntimePermission(bp, userId) ==
Philip P. Moltmann48456672019-01-20 13:14:03 -08002311 PERMISSION_OPERATION_FAILURE) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002312 return;
2313 }
2314
2315 if (bp.isRuntime()) {
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002316 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002317 }
2318
2319 if (callback != null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002320 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2321 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002322
2323 if (bp.isRuntime()) {
2324 notifyRuntimePermissionStateChanged(packageName, userId);
2325 }
2326 }
2327
2328 private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
2329 @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
2330 @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
2331 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2332 if (ps == null) {
2333 return;
2334 }
2335
2336 final PermissionsState permissionsState = ps.getPermissionsState();
2337
2338 ArraySet<String> oldGrantedRestrictedPermissions = null;
2339 boolean updatePermissions = false;
2340
2341 final int permissionCount = pkg.requestedPermissions.size();
2342 for (int i = 0; i < permissionCount; i++) {
2343 final String permissionName = pkg.requestedPermissions.get(i);
2344
2345 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
2346 if (bp == null) {
2347 Slog.w(TAG, "Cannot whitelist unknown permission: " + permissionName);
2348 continue;
2349 }
2350
Svet Ganovd563e932019-04-14 13:07:41 -07002351 if (!bp.isHardOrSoftRestricted()) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002352 continue;
2353 }
2354
2355 if (permissionsState.hasPermission(permissionName, userId)) {
2356 if (oldGrantedRestrictedPermissions == null) {
2357 oldGrantedRestrictedPermissions = new ArraySet<>();
2358 }
2359 oldGrantedRestrictedPermissions.add(permissionName);
2360 }
2361
2362 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
2363
2364 int newFlags = oldFlags;
2365 int mask = 0;
2366 int whitelistFlagsCopy = whitelistFlags;
2367 while (whitelistFlagsCopy != 0) {
2368 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
2369 whitelistFlagsCopy &= ~flag;
2370 switch (flag) {
2371 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
2372 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2373 if (permissions != null && permissions.contains(permissionName)) {
2374 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2375 } else {
2376 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2377 }
2378 } break;
2379 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
2380 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2381 if (permissions != null && permissions.contains(permissionName)) {
2382 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2383 } else {
2384 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2385 }
2386 } break;
2387 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
2388 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2389 if (permissions != null && permissions.contains(permissionName)) {
2390 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2391 } else {
2392 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2393 }
2394 } break;
2395 }
2396 }
2397
2398 if (oldFlags == newFlags) {
2399 continue;
2400 }
2401
2402 updatePermissions = true;
2403
Svet Ganovd563e932019-04-14 13:07:41 -07002404 final boolean wasWhitelisted = (oldFlags
2405 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2406 final boolean isWhitelisted = (newFlags
2407 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
2408
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002409 // If the permission is policy fixed as granted but it is no longer
2410 // on any of the whitelists we need to clear the policy fixed flag
2411 // as whitelisting trumps policy i.e. policy cannot grant a non
2412 // grantable permission.
2413 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002414 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
2415 if (!isWhitelisted && isGranted) {
2416 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2417 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
2418 }
2419 }
2420
Svet Ganovd563e932019-04-14 13:07:41 -07002421 // If we are whitelisting an app that does not support runtime permissions
2422 // we need to make sure it goes through the permission review UI at launch.
2423 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
2424 && !wasWhitelisted && isWhitelisted) {
2425 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2426 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
2427 }
2428
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002429 updatePermissionFlags(permissionName, pkg.packageName, mask, newFlags,
2430 callingUid, userId, false, null /*callback*/);
2431 }
2432
2433 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07002434 // Update permission of this app to take into account the new whitelist state.
2435 restorePermissionState(pkg, false, pkg.packageName, callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002436
2437 // If this resulted in losing a permission we need to kill the app.
2438 if (oldGrantedRestrictedPermissions != null) {
2439 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
2440 for (int i = 0; i < oldGrantedCount; i++) {
2441 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
2442 // Sometimes we create a new permission state instance during update.
2443 if (!ps.getPermissionsState().hasPermission(permission, userId)) {
2444 callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
2445 break;
2446 }
2447 }
2448 }
2449 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002450 }
2451
Andreas Gampea36dc622018-02-05 17:19:22 -08002452 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002453 private int[] revokeUnusedSharedUserPermissionsLocked(
2454 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002455 // Collect all used permissions in the UID
2456 final ArraySet<String> usedPermissions = new ArraySet<>();
2457 final List<PackageParser.Package> pkgList = suSetting.getPackages();
2458 if (pkgList == null || pkgList.size() == 0) {
2459 return EmptyArray.INT;
2460 }
2461 for (PackageParser.Package pkg : pkgList) {
Svet Ganovd8308072018-03-24 00:04:38 -07002462 if (pkg.requestedPermissions == null) {
2463 continue;
2464 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002465 final int requestedPermCount = pkg.requestedPermissions.size();
2466 for (int j = 0; j < requestedPermCount; j++) {
2467 String permission = pkg.requestedPermissions.get(j);
2468 BasePermission bp = mSettings.getPermissionLocked(permission);
2469 if (bp != null) {
2470 usedPermissions.add(permission);
2471 }
2472 }
2473 }
2474
2475 PermissionsState permissionsState = suSetting.getPermissionsState();
2476 // Prune install permissions
2477 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
2478 final int installPermCount = installPermStates.size();
2479 for (int i = installPermCount - 1; i >= 0; i--) {
2480 PermissionState permissionState = installPermStates.get(i);
2481 if (!usedPermissions.contains(permissionState.getName())) {
2482 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2483 if (bp != null) {
2484 permissionsState.revokeInstallPermission(bp);
2485 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002486 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002487 }
2488 }
2489 }
2490
2491 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
2492
2493 // Prune runtime permissions
2494 for (int userId : allUserIds) {
2495 List<PermissionState> runtimePermStates = permissionsState
2496 .getRuntimePermissionStates(userId);
2497 final int runtimePermCount = runtimePermStates.size();
2498 for (int i = runtimePermCount - 1; i >= 0; i--) {
2499 PermissionState permissionState = runtimePermStates.get(i);
2500 if (!usedPermissions.contains(permissionState.getName())) {
2501 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
2502 if (bp != null) {
2503 permissionsState.revokeRuntimePermission(bp, userId);
2504 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002505 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002506 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
2507 runtimePermissionChangedUserIds, userId);
2508 }
2509 }
2510 }
2511 }
2512
2513 return runtimePermissionChangedUserIds;
2514 }
2515
Todd Kennedyc8423932017-10-05 08:58:36 -07002516 private String[] getAppOpPermissionPackages(String permName) {
2517 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
2518 return null;
2519 }
2520 synchronized (mLock) {
2521 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
2522 if (pkgs == null) {
2523 return null;
2524 }
2525 return pkgs.toArray(new String[pkgs.size()]);
2526 }
2527 }
2528
2529 private int getPermissionFlags(
2530 String permName, String packageName, int callingUid, int userId) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002531 if (!mUserManagerInt.exists(userId)) {
2532 return 0;
2533 }
2534
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002535 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
Todd Kennedy0eb97382017-10-03 16:57:22 -07002536
2537 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002538 true, // requireFullPermission
2539 false, // checkShell
2540 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002541 "getPermissionFlags");
2542
2543 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2544 if (pkg == null || pkg.mExtras == null) {
2545 return 0;
2546 }
2547 synchronized (mLock) {
2548 if (mSettings.getPermissionLocked(permName) == null) {
2549 return 0;
2550 }
2551 }
2552 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2553 return 0;
2554 }
2555 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2556 PermissionsState permissionsState = ps.getPermissionsState();
2557 return permissionsState.getPermissionFlags(permName, userId);
2558 }
2559
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002560 private static final int UPDATE_PERMISSIONS_ALL = 1<<0;
2561 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
2562 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
2563
2564 private void updatePermissions(String packageName, PackageParser.Package pkg,
2565 boolean replaceGrant, Collection<PackageParser.Package> allPackages,
2566 PermissionCallback callback) {
2567 final int flags = (pkg != null ? UPDATE_PERMISSIONS_ALL : 0) |
2568 (replaceGrant ? UPDATE_PERMISSIONS_REPLACE_PKG : 0);
2569 updatePermissions(
2570 packageName, pkg, getVolumeUuidForPackage(pkg), flags, allPackages, callback);
2571 if (pkg != null && pkg.childPackages != null) {
2572 for (PackageParser.Package childPkg : pkg.childPackages) {
2573 updatePermissions(childPkg.packageName, childPkg,
2574 getVolumeUuidForPackage(childPkg), flags, allPackages, callback);
2575 }
2576 }
2577 }
2578
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08002579 private void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07002580 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002581 final int flags = UPDATE_PERMISSIONS_ALL |
2582 (sdkUpdated
2583 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
2584 : 0);
2585 updatePermissions(null, null, volumeUuid, flags, allPackages, callback);
2586 }
2587
2588 private void updatePermissions(String changingPkgName, PackageParser.Package changingPkg,
2589 String replaceVolumeUuid, int flags, Collection<PackageParser.Package> allPackages,
2590 PermissionCallback callback) {
2591 // TODO: Most of the methods exposing BasePermission internals [source package name,
2592 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
2593 // have package settings, we should make note of it elsewhere [map between
2594 // source package name and BasePermission] and cycle through that here. Then we
2595 // define a single method on BasePermission that takes a PackageSetting, changing
2596 // package name and a package.
2597 // NOTE: With this approach, we also don't need to tree trees differently than
2598 // normal permissions. Today, we need two separate loops because these BasePermission
2599 // objects are stored separately.
2600 // Make sure there are no dangling permission trees.
2601 flags = updatePermissionTrees(changingPkgName, changingPkg, flags);
2602
2603 // Make sure all dynamic permissions have been assigned to a package,
2604 // and make sure there are no dangling permissions.
2605 flags = updatePermissions(changingPkgName, changingPkg, flags);
2606
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002607 synchronized (mLock) {
2608 if (mBackgroundPermissions == null) {
2609 // Cache background -> foreground permission mapping.
2610 // Only system declares background permissions, hence mapping does never change.
2611 mBackgroundPermissions = new ArrayMap<>();
2612 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Philip P. Moltmann798bf9a2018-11-08 17:07:19 -08002613 if (bp.perm != null && bp.perm.info != null
2614 && bp.perm.info.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002615 String fgPerm = bp.name;
2616 String bgPerm = bp.perm.info.backgroundPermission;
2617
2618 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
2619 if (fgPerms == null) {
2620 fgPerms = new ArrayList<>();
2621 mBackgroundPermissions.put(bgPerm, fgPerms);
2622 }
2623
2624 fgPerms.add(fgPerm);
2625 }
2626 }
2627 }
2628 }
2629
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002630 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002631 // Now update the permissions for all packages, in particular
2632 // replace the granted permissions of the system packages.
2633 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
2634 for (PackageParser.Package pkg : allPackages) {
2635 if (pkg != changingPkg) {
2636 // Only replace for packages on requested volume
2637 final String volumeUuid = getVolumeUuidForPackage(pkg);
2638 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0)
2639 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002640 restorePermissionState(pkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002641 }
2642 }
2643 }
2644
2645 if (changingPkg != null) {
2646 // Only replace for packages on requested volume
2647 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
2648 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
2649 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002650 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002651 }
2652 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
2653 }
2654
2655 private int updatePermissions(String packageName, PackageParser.Package pkg, int flags) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002656 Set<BasePermission> needsUpdate = null;
2657 synchronized (mLock) {
2658 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
2659 while (it.hasNext()) {
2660 final BasePermission bp = it.next();
2661 if (bp.isDynamic()) {
2662 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
2663 }
2664 if (bp.getSourcePackageSetting() != null) {
2665 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002666 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002667 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2668 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002669 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002670 it.remove();
2671 }
2672 continue;
2673 }
2674 if (needsUpdate == null) {
2675 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
2676 }
2677 needsUpdate.add(bp);
2678 }
2679 }
2680 if (needsUpdate != null) {
2681 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002682 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002683 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2684 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002685 if (sourcePkg != null && sourcePkg.mExtras != null) {
2686 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002687 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002688 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002689 }
2690 continue;
2691 }
2692 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
2693 + " from package " + bp.getSourcePackageName());
2694 mSettings.removePermissionLocked(bp.getName());
2695 }
2696 }
2697 }
2698 return flags;
2699 }
2700
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002701 private int updatePermissionTrees(String packageName, PackageParser.Package pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002702 int flags) {
2703 Set<BasePermission> needsUpdate = null;
2704 synchronized (mLock) {
2705 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
2706 while (it.hasNext()) {
2707 final BasePermission bp = it.next();
2708 if (bp.getSourcePackageSetting() != null) {
2709 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002710 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002711 Slog.i(TAG, "Removing old permission tree: " + bp.getName()
2712 + " from package " + bp.getSourcePackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002713 flags |= UPDATE_PERMISSIONS_ALL;
Todd Kennedyc8423932017-10-05 08:58:36 -07002714 it.remove();
2715 }
2716 continue;
2717 }
2718 if (needsUpdate == null) {
2719 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
2720 }
2721 needsUpdate.add(bp);
2722 }
2723 }
2724 if (needsUpdate != null) {
2725 for (final BasePermission bp : needsUpdate) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002726 final PackageParser.Package sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07002727 mPackageManagerInt.getPackage(bp.getSourcePackageName());
2728 synchronized (mLock) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002729 if (sourcePkg != null && sourcePkg.mExtras != null) {
2730 final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
Todd Kennedyc8423932017-10-05 08:58:36 -07002731 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002732 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07002733 }
2734 continue;
2735 }
2736 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
2737 + " from package " + bp.getSourcePackageName());
2738 mSettings.removePermissionLocked(bp.getName());
2739 }
2740 }
2741 }
2742 return flags;
2743 }
2744
Todd Kennedy0eb97382017-10-03 16:57:22 -07002745 private void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002746 int flagValues, int callingUid, int userId, boolean overridePolicy,
2747 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002748 if (!mUserManagerInt.exists(userId)) {
2749 return;
2750 }
2751
2752 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
2753
2754 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002755 true, // requireFullPermission
2756 true, // checkShell
2757 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002758 "updatePermissionFlags");
2759
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08002760 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
2761 throw new SecurityException("updatePermissionFlags requires "
2762 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
2763 }
2764
Todd Kennedy0eb97382017-10-03 16:57:22 -07002765 // Only the system can change these flags and nothing else.
2766 if (callingUid != Process.SYSTEM_UID) {
2767 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2768 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2769 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2770 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
2771 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002772 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
2773 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
2774 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
2775 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002776 }
2777
2778 final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
2779 if (pkg == null || pkg.mExtras == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002780 Log.e(TAG, "Unknown package: " + packageName);
2781 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07002782 }
2783 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
2784 throw new IllegalArgumentException("Unknown package: " + packageName);
2785 }
2786
2787 final BasePermission bp;
2788 synchronized (mLock) {
2789 bp = mSettings.getPermissionLocked(permName);
2790 }
2791 if (bp == null) {
2792 throw new IllegalArgumentException("Unknown permission: " + permName);
2793 }
2794
2795 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2796 final PermissionsState permissionsState = ps.getPermissionsState();
2797 final boolean hadState =
2798 permissionsState.getRuntimePermissionState(permName, userId) != null;
2799 final boolean permissionUpdated =
2800 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002801 if (permissionUpdated && bp.isRuntime()) {
2802 notifyRuntimePermissionStateChanged(packageName, userId);
2803 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07002804 if (permissionUpdated && callback != null) {
2805 // Install and runtime permissions are stored in different places,
2806 // so figure out what permission changed and persist the change.
2807 if (permissionsState.getInstallPermissionState(permName) != null) {
2808 callback.onInstallPermissionUpdated();
2809 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
2810 || hadState) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002811 callback.onPermissionUpdated(new int[] { userId }, false);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002812 }
2813 }
2814 }
2815
2816 private boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
2817 int userId, Collection<Package> packages, PermissionCallback callback) {
2818 if (!mUserManagerInt.exists(userId)) {
2819 return false;
2820 }
2821
2822 enforceGrantRevokeRuntimePermissionPermissions(
2823 "updatePermissionFlagsForAllApps");
2824 enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002825 true, // requireFullPermission
2826 true, // checkShell
2827 false, // requirePermissionWhenSameUser
Todd Kennedy0eb97382017-10-03 16:57:22 -07002828 "updatePermissionFlagsForAllApps");
2829
2830 // Only the system can change system fixed flags.
2831 if (callingUid != Process.SYSTEM_UID) {
2832 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2833 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
2834 }
2835
2836 boolean changed = false;
2837 for (PackageParser.Package pkg : packages) {
2838 final PackageSetting ps = (PackageSetting) pkg.mExtras;
2839 if (ps == null) {
2840 continue;
2841 }
2842 PermissionsState permissionsState = ps.getPermissionsState();
2843 changed |= permissionsState.updatePermissionFlagsForAllPermissions(
2844 userId, flagMask, flagValues);
2845 }
2846 return changed;
2847 }
2848
2849 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
2850 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2851 != PackageManager.PERMISSION_GRANTED
2852 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2853 != PackageManager.PERMISSION_GRANTED) {
2854 throw new SecurityException(message + " requires "
2855 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2856 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
2857 }
2858 }
2859
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08002860 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
2861 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
2862 != PackageManager.PERMISSION_GRANTED
2863 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
2864 != PackageManager.PERMISSION_GRANTED
2865 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
2866 != PackageManager.PERMISSION_GRANTED) {
2867 throw new SecurityException(message + " requires "
2868 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
2869 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
2870 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
2871 }
2872 }
2873
Todd Kennedy0eb97382017-10-03 16:57:22 -07002874 /**
2875 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
2876 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
2877 * @param checkShell whether to prevent shell from access if there's a debugging restriction
2878 * @param message the message to log on security exception
2879 */
2880 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07002881 boolean requireFullPermission, boolean checkShell,
2882 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002883 if (userId < 0) {
2884 throw new IllegalArgumentException("Invalid userId " + userId);
2885 }
2886 if (checkShell) {
2887 PackageManagerServiceUtils.enforceShellRestriction(
2888 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
2889 }
Todd Kennedyef9acb62018-05-29 15:18:06 -07002890 if (!requirePermissionWhenSameUser && userId == UserHandle.getUserId(callingUid)) return;
Suprabh Shukla151b21b2018-04-27 19:30:30 -07002891 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002892 if (requireFullPermission) {
2893 mContext.enforceCallingOrSelfPermission(
2894 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2895 } else {
2896 try {
2897 mContext.enforceCallingOrSelfPermission(
2898 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, message);
2899 } catch (SecurityException se) {
2900 mContext.enforceCallingOrSelfPermission(
2901 android.Manifest.permission.INTERACT_ACROSS_USERS, message);
2902 }
2903 }
2904 }
2905 }
2906
Andreas Gampea71bee82018-07-20 12:55:36 -07002907 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002908 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
2909 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07002910 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002911 size += tree.calculateFootprint(perm);
2912 }
2913 return size;
2914 }
2915
Andreas Gampea71bee82018-07-20 12:55:36 -07002916 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07002917 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
2918 // We calculate the max size of permissions defined by this uid and throw
2919 // if that plus the size of 'info' would exceed our stated maximum.
2920 if (tree.getUid() != Process.SYSTEM_UID) {
2921 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
2922 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
2923 throw new SecurityException("Permission tree size cap exceeded");
2924 }
2925 }
2926 }
2927
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002928 private void systemReady() {
2929 mSystemReady = true;
2930 if (mPrivappPermissionsViolations != null) {
2931 throw new IllegalStateException("Signature|privileged permissions not in "
2932 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
2933 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002934
2935 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov0b41c892019-07-26 17:45:56 -07002936 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002937 }
2938
2939 private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
2940 if (pkg == null) {
2941 return StorageManager.UUID_PRIVATE_INTERNAL;
2942 }
2943 if (pkg.isExternal()) {
2944 if (TextUtils.isEmpty(pkg.volumeUuid)) {
2945 return StorageManager.UUID_PRIMARY_PHYSICAL;
2946 } else {
2947 return pkg.volumeUuid;
2948 }
2949 } else {
2950 return StorageManager.UUID_PRIVATE_INTERNAL;
2951 }
2952 }
2953
Todd Kennedyc8423932017-10-05 08:58:36 -07002954 private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
2955 for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
2956 if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
2957 return true;
2958 }
2959 }
2960 return false;
2961 }
2962
Todd Kennedy0eb97382017-10-03 16:57:22 -07002963 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002964 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07002965 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002966 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07002967 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002968 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07002969 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002970 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
2971 final LogMaker log = new LogMaker(action);
2972 log.setPackageName(packageName);
2973 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002974
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07002975 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002976 }
2977
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07002978 /**
2979 * Get the mapping of background permissions to their foreground permissions.
2980 *
2981 * <p>Only initialized in the system server.
2982 *
2983 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
2984 */
2985 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
2986 return mBackgroundPermissions;
2987 }
2988
Philip P. Moltmann48456672019-01-20 13:14:03 -08002989 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002990 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002991 public void systemReady() {
2992 PermissionManagerService.this.systemReady();
2993 }
2994 @Override
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07002995 public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002996 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
2997 }
2998 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002999 public void revokeRuntimePermissionsIfGroupChanged(
3000 @NonNull PackageParser.Package newPackage,
3001 @NonNull PackageParser.Package oldPackage,
3002 @NonNull ArrayList<String> allPackageNames,
3003 @NonNull PermissionCallback permissionCallback) {
3004 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
3005 oldPackage, allPackageNames, permissionCallback);
3006 }
3007 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07003008 public void addAllPermissions(Package pkg, boolean chatty) {
3009 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003010 }
3011 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07003012 public void addAllPermissionGroups(Package pkg, boolean chatty) {
3013 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
3014 }
3015 @Override
Hongming Jinae750fb2018-09-27 23:00:20 +00003016 public void removeAllPermissions(Package pkg, boolean chatty) {
3017 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07003018 }
3019 @Override
3020 public boolean addDynamicPermission(PermissionInfo info, boolean async, int callingUid,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003021 PermissionCallback callback) {
Todd Kennedyc8423932017-10-05 08:58:36 -07003022 return PermissionManagerService.this.addDynamicPermission(info, callingUid, callback);
3023 }
3024 @Override
3025 public void removeDynamicPermission(String permName, int callingUid,
3026 PermissionCallback callback) {
3027 PermissionManagerService.this.removeDynamicPermission(permName, callingUid, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003028 }
3029 @Override
3030 public void grantRuntimePermission(String permName, String packageName,
3031 boolean overridePolicy, int callingUid, int userId,
3032 PermissionCallback callback) {
3033 PermissionManagerService.this.grantRuntimePermission(
3034 permName, packageName, overridePolicy, callingUid, userId, callback);
3035 }
3036 @Override
3037 public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
3038 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3039 PermissionManagerService.this.grantRequestedRuntimePermissions(
3040 pkg, userIds, grantedPermissions, callingUid, callback);
3041 }
3042 @Override
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003043 public List<String> getWhitelistedRestrictedPermissions(PackageParser.Package pkg,
3044 @PackageManager.PermissionWhitelistFlags int whitelistFlags, int userId) {
3045 return PermissionManagerService.this.getWhitelistedRestrictedPermissions(pkg,
3046 whitelistFlags, userId);
3047 }
3048 @Override
3049 public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
3050 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
3051 @PackageManager.PermissionWhitelistFlags int whitelistFlags,
3052 @NonNull PermissionCallback callback) {
3053 PermissionManagerService.this.setWhitelistedRestrictedPermissions(
3054 pkg, userIds, permissions, callingUid, whitelistFlags, callback);
3055 }
3056 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003057 public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
3058 int callingUid, PermissionCallback callback) {
3059 PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
3060 pkg, callingUid, callback);
3061 }
3062 @Override
3063 public void revokeRuntimePermission(String permName, String packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003064 boolean overridePolicy, int userId, PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003065 PermissionManagerService.this.revokeRuntimePermission(permName, packageName,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003066 overridePolicy, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003067 }
3068 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003069 public void updatePermissions(String packageName, Package pkg, boolean replaceGrant,
3070 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
3071 PermissionManagerService.this.updatePermissions(
3072 packageName, pkg, replaceGrant, allPackages, callback);
3073 }
3074 @Override
Philip P. Moltmanne5d998f2019-03-01 09:42:53 -08003075 public void updateAllPermissions(String volumeUuid, boolean sdkUpdated,
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07003076 Collection<PackageParser.Package> allPackages, PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003077 PermissionManagerService.this.updateAllPermissions(
Philip P. Moltmannd11400a2019-04-08 10:42:42 -07003078 volumeUuid, sdkUpdated, allPackages, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003079 }
3080 @Override
Todd Kennedyc8423932017-10-05 08:58:36 -07003081 public String[] getAppOpPermissionPackages(String permName) {
3082 return PermissionManagerService.this.getAppOpPermissionPackages(permName);
3083 }
3084 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003085 public int getPermissionFlags(String permName, String packageName, int callingUid,
3086 int userId) {
3087 return PermissionManagerService.this.getPermissionFlags(permName, packageName,
3088 callingUid, userId);
3089 }
3090 @Override
3091 public void updatePermissionFlags(String permName, String packageName, int flagMask,
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003092 int flagValues, int callingUid, int userId, boolean overridePolicy,
3093 PermissionCallback callback) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003094 PermissionManagerService.this.updatePermissionFlags(
Philip P. Moltmann2a537a62019-02-08 13:07:57 -08003095 permName, packageName, flagMask, flagValues, callingUid, userId,
3096 overridePolicy, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003097 }
3098 @Override
3099 public boolean updatePermissionFlagsForAllApps(int flagMask, int flagValues, int callingUid,
3100 int userId, Collection<Package> packages, PermissionCallback callback) {
3101 return PermissionManagerService.this.updatePermissionFlagsForAllApps(
3102 flagMask, flagValues, callingUid, userId, packages, callback);
3103 }
3104 @Override
3105 public void enforceCrossUserPermission(int callingUid, int userId,
3106 boolean requireFullPermission, boolean checkShell, String message) {
3107 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07003108 requireFullPermission, checkShell, false, message);
3109 }
3110 @Override
3111 public void enforceCrossUserPermission(int callingUid, int userId,
3112 boolean requireFullPermission, boolean checkShell,
3113 boolean requirePermissionWhenSameUser, String message) {
3114 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
3115 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003116 }
3117 @Override
3118 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3119 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
3120 }
3121 @Override
3122 public int checkPermission(String permName, String packageName, int callingUid,
3123 int userId) {
3124 return PermissionManagerService.this.checkPermission(
3125 permName, packageName, callingUid, userId);
3126 }
3127 @Override
Todd Kennedy3c714492017-10-27 09:12:50 -07003128 public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,
3129 int callingUid) {
3130 return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);
Todd Kennedy3bc94722017-10-10 09:55:53 -07003131 }
3132 @Override
Todd Kennedy460f28c2017-10-06 13:46:22 -07003133 public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags,
3134 int callingUid) {
3135 return PermissionManagerService.this.getPermissionGroupInfo(
3136 groupName, flags, callingUid);
3137 }
3138 @Override
3139 public List<PermissionGroupInfo> getAllPermissionGroups(int flags, int callingUid) {
3140 return PermissionManagerService.this.getAllPermissionGroups(flags, callingUid);
3141 }
3142 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003143 public PermissionInfo getPermissionInfo(String permName, String packageName, int flags,
3144 int callingUid) {
3145 return PermissionManagerService.this.getPermissionInfo(
3146 permName, packageName, flags, callingUid);
3147 }
3148 @Override
3149 public List<PermissionInfo> getPermissionInfoByGroup(String group, int flags,
3150 int callingUid) {
3151 return PermissionManagerService.this.getPermissionInfoByGroup(group, flags, callingUid);
3152 }
3153 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07003154 public PermissionSettings getPermissionSettings() {
3155 return mSettings;
3156 }
3157 @Override
3158 public DefaultPermissionGrantPolicy getDefaultPermissionGrantPolicy() {
3159 return mDefaultPermissionGrantPolicy;
3160 }
3161 @Override
3162 public BasePermission getPermissionTEMP(String permName) {
3163 synchronized (PermissionManagerService.this.mLock) {
3164 return mSettings.getPermissionLocked(permName);
3165 }
3166 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08003167
3168 @Override
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07003169 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
3170 @PermissionInfo.Protection int protectionLevel) {
3171 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
3172
3173 synchronized (PermissionManagerService.this.mLock) {
3174 int numTotalPermissions = mSettings.mPermissions.size();
3175
3176 for (int i = 0; i < numTotalPermissions; i++) {
3177 BasePermission bp = mSettings.mPermissions.valueAt(i);
3178
3179 if (bp.perm != null && bp.perm.info != null
3180 && bp.protectionLevel == protectionLevel) {
3181 matchingPermissions.add(bp.perm.info);
3182 }
3183 }
3184 }
3185
3186 return matchingPermissions;
3187 }
3188
3189 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08003190 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
3191 return PermissionManagerService.this.backupRuntimePermissions(user);
3192 }
3193
3194 @Override
3195 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
3196 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
3197 }
3198
3199 @Override
3200 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
3201 @NonNull UserHandle user) {
3202 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
3203 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003204
3205 @Override
3206 public void addOnRuntimePermissionStateChangedListener(
3207 OnRuntimePermissionStateChangedListener listener) {
3208 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
3209 listener);
3210 }
3211
3212 @Override
3213 public void removeOnRuntimePermissionStateChangedListener(
3214 OnRuntimePermissionStateChangedListener listener) {
3215 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
3216 listener);
3217 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003218 }
3219}