blob: 0411e29f68a14fb374b04267916a170955199879 [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
Todd Kennedyc971a452019-07-08 16:04:52 -070019import static android.Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY;
Todd Kennedy0eb97382017-10-03 16:57:22 -070020import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
21import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070022import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
23import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070024import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
25import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070026import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Hai Zhang50a5a9b2019-09-19 13:57:45 -070027import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070028import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
29import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
30import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
31import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070032import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
33import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
34import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070035import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Todd Kennedyc5b0e862019-07-16 09:47:58 -070036import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
Hongwei Wangf391b552018-04-06 13:52:46 -070037import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedyc971a452019-07-08 16:04:52 -070038import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070039import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
Hongwei Wangf391b552018-04-06 13:52:46 -070040
Todd Kennedyc29b11a2017-10-23 15:55:59 -070041import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
42import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
43import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
44import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
45import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080046import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
47
48import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070049
50import android.Manifest;
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -070051import android.annotation.IntDef;
Todd Kennedy0eb97382017-10-03 16:57:22 -070052import android.annotation.NonNull;
53import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070054import android.annotation.UserIdInt;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070055import android.app.ActivityManager;
Eugene Suslad516bee2019-05-01 09:48:43 -070056import android.app.ApplicationPackageManager;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070057import android.app.IActivityManager;
Evan Severson50a77742020-01-06 10:38:19 -080058import android.compat.annotation.ChangeId;
59import android.compat.annotation.EnabledAfter;
Todd Kennedy0eb97382017-10-03 16:57:22 -070060import android.content.Context;
Hongming Jinbc4d0102019-08-16 14:28:30 -070061import android.content.pm.ApplicationInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070062import android.content.pm.PackageManager;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070063import android.content.pm.PackageManager.PermissionGroupInfoFlags;
64import android.content.pm.PackageManager.PermissionInfoFlags;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070065import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070066import android.content.pm.PackageManagerInternal;
67import android.content.pm.PackageParser;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070068import android.content.pm.ParceledListSlice;
Todd Kennedy460f28c2017-10-06 13:46:22 -070069import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070070import android.content.pm.PermissionInfo;
Winson14ff7172019-10-23 10:42:27 -070071import android.content.pm.parsing.AndroidPackage;
72import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
73import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
74import android.content.pm.parsing.PackageInfoUtils;
Anthony Hughde787d42019-08-22 15:35:48 -070075import android.content.pm.permission.SplitPermissionInfoParcelable;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070076import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070077import android.os.Binder;
78import android.os.Build;
79import android.os.Handler;
80import android.os.HandlerThread;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070081import android.os.Looper;
82import android.os.Message;
Todd Kennedy0eb97382017-10-03 16:57:22 -070083import android.os.Process;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070084import android.os.RemoteCallbackList;
85import android.os.RemoteException;
Todd Kennedy8f135982019-07-02 07:35:15 -070086import android.os.ServiceManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070087import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070088import android.os.UserHandle;
89import android.os.UserManager;
90import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070091import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -070092import android.os.storage.StorageManagerInternal;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070093import android.permission.IOnPermissionsChangeListener;
Todd Kennedy8f135982019-07-02 07:35:15 -070094import android.permission.IPermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080095import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070096import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -080097import android.permission.PermissionManagerInternal;
Todd Kennedyca1ea172019-07-03 15:02:28 -070098import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070099import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700100import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700101import android.util.ArrayMap;
102import android.util.ArraySet;
Eugene Suslad516bee2019-05-01 09:48:43 -0700103import android.util.DebugUtils;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700104import android.util.EventLog;
Todd Kennedyc971a452019-07-08 16:04:52 -0700105import android.util.IntArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700106import android.util.Log;
107import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700108import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800109import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700110
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700111import com.android.internal.annotations.GuardedBy;
Evan Severson50a77742020-01-06 10:38:19 -0800112import com.android.internal.compat.IPlatformCompat;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700113import com.android.internal.logging.MetricsLogger;
114import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700115import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700116import com.android.internal.util.ArrayUtils;
Todd Kennedyc971a452019-07-08 16:04:52 -0700117import com.android.internal.util.IntPair;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700118import com.android.internal.util.Preconditions;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700119import com.android.internal.util.function.pooled.PooledLambda;
120import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700121import com.android.server.LocalServices;
122import com.android.server.ServiceThread;
123import com.android.server.SystemConfig;
124import com.android.server.Watchdog;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700125import com.android.server.pm.PackageManagerServiceUtils;
126import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700127import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700128import com.android.server.pm.UserManagerService;
Todd Kennedy583378d2019-07-12 06:50:30 -0700129import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
130import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
131import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800132import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700133import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov3c499ea2019-07-26 17:45:56 -0700134import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700135import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700136
137import libcore.util.EmptyArray;
138
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -0700139import java.lang.annotation.Retention;
140import java.lang.annotation.RetentionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700141import java.util.ArrayList;
Hongwei Wangf391b552018-04-06 13:52:46 -0700142import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700143import java.util.Iterator;
144import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700145import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700146import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700147import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800148import java.util.concurrent.CompletableFuture;
149import java.util.concurrent.ExecutionException;
150import java.util.concurrent.TimeUnit;
151import java.util.concurrent.TimeoutException;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700152import java.util.function.Consumer;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700153
154/**
155 * Manages all permissions and handles permissions related tasks.
156 */
Todd Kennedy8f135982019-07-02 07:35:15 -0700157public class PermissionManagerService extends IPermissionManager.Stub {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700158 private static final String TAG = "PackageManager";
159
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700160 /** Permission grant: not grant the permission. */
161 private static final int GRANT_DENIED = 1;
162 /** Permission grant: grant the permission as an install permission. */
163 private static final int GRANT_INSTALL = 2;
164 /** Permission grant: grant the permission as a runtime one. */
165 private static final int GRANT_RUNTIME = 3;
166 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
167 private static final int GRANT_UPGRADE = 4;
168
Philip P. Moltmann48456672019-01-20 13:14:03 -0800169 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
170
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700171 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
172 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
173 /** Empty array to avoid allocations */
174 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700175
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800176 /**
177 * When these flags are set, the system should not automatically modify the permission grant
178 * state.
179 */
180 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
181 | FLAG_PERMISSION_POLICY_FIXED
182 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
183
184 /** Permission flags set by the user */
185 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
186 | FLAG_PERMISSION_USER_FIXED;
187
Hongwei Wangf391b552018-04-06 13:52:46 -0700188 /** If the permission of the value is granted, so is the key */
189 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
190
191 static {
192 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
193 Manifest.permission.ACCESS_FINE_LOCATION);
194 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
195 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
196 }
197
Todd Kennedy0eb97382017-10-03 16:57:22 -0700198 /** Lock to protect internal data access */
199 private final Object mLock;
200
201 /** Internal connection to the package manager */
202 private final PackageManagerInternal mPackageManagerInt;
203
204 /** Internal connection to the user manager */
205 private final UserManagerInternal mUserManagerInt;
206
Philip P. Moltmann48456672019-01-20 13:14:03 -0800207 /** Permission controller: User space permission management */
208 private PermissionControllerManager mPermissionControllerManager;
209
Evan Seversonb252d8b2019-11-20 08:41:33 -0800210 /** Map of OneTimePermissionUserManagers keyed by userId */
211 private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
212 new SparseArray<>();
213
Todd Kennedy0eb97382017-10-03 16:57:22 -0700214 /** Default permission policy to provide proper behaviour out-of-the-box */
215 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
216
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700217 /**
218 * Built-in permissions. Read from system configuration files. Mapping is from
219 * UID to permission name.
220 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700221 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700222
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700223 /** Built-in group IDs given to all packages. Read from system configuration files. */
224 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700225
226 private final HandlerThread mHandlerThread;
227 private final Handler mHandler;
228 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700229 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Evan Severson50a77742020-01-06 10:38:19 -0800230 private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
231 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
Todd Kennedy0eb97382017-10-03 16:57:22 -0700232
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700233 /** Internal storage for permissions and related settings */
234 @GuardedBy("mLock")
235 private final PermissionSettings mSettings;
236
237 @GuardedBy("mLock")
238 private ArraySet<String> mPrivappPermissionsViolations;
239
240 @GuardedBy("mLock")
241 private boolean mSystemReady;
242
Svet Ganov3c499ea2019-07-26 17:45:56 -0700243 @GuardedBy("mLock")
244 private PermissionPolicyInternal mPermissionPolicyInternal;
245
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700246 /**
247 * For each foreground/background permission the mapping:
248 * Background permission -> foreground permissions
249 */
250 @GuardedBy("mLock")
251 private ArrayMap<String, List<String>> mBackgroundPermissions;
252
Philip P. Moltmann48456672019-01-20 13:14:03 -0800253 /**
254 * A permission backup might contain apps that are not installed. In this case we delay the
255 * restoration until the app is installed.
256 *
257 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
258 * there is <u>no more</u> delayed backup left.
259 */
260 @GuardedBy("mLock")
261 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
262
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700263 /** Listeners for permission state (granting and flags) changes */
264 @GuardedBy("mLock")
265 final private ArrayList<OnRuntimePermissionStateChangedListener>
266 mRuntimePermissionStateChangedListeners = new ArrayList<>();
267
Todd Kennedyca1ea172019-07-03 15:02:28 -0700268 @GuardedBy("mLock")
269 private CheckPermissionDelegate mCheckPermissionDelegate;
270
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700271 @GuardedBy("mLock")
272 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
273
Todd Kennedy583378d2019-07-12 06:50:30 -0700274 @GuardedBy("mLock")
275 private DefaultBrowserProvider mDefaultBrowserProvider;
276
277 @GuardedBy("mLock")
278 private DefaultDialerProvider mDefaultDialerProvider;
279
280 @GuardedBy("mLock")
281 private DefaultHomeProvider mDefaultHomeProvider;
282
Todd Kennedy230c0a72019-07-03 13:06:35 -0700283 // TODO: Take a look at the methods defined in the callback.
284 // The callback was initially created to support the split between permission
285 // manager and the package manager. However, it's started to be used for other
286 // purposes. It may make sense to keep as an abstraction, but, the methods
287 // necessary to be overridden may be different than what was initially needed
288 // for the split.
289 private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
290 @Override
291 public void onGidsChanged(int appId, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -0700292 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700293 }
294 @Override
295 public void onPermissionGranted(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700296 mOnPermissionChangeListeners.onPermissionsChanged(uid);
297
298 // Not critical; if this is lost, the application has to request again.
299 mPackageManagerInt.writeSettings(true);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700300 }
301 @Override
302 public void onInstallPermissionGranted() {
303 mPackageManagerInt.writeSettings(true);
304 }
305 @Override
306 public void onPermissionRevoked(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700307 mOnPermissionChangeListeners.onPermissionsChanged(uid);
308
309 // Critical; after this call the application should never have the permission
310 mPackageManagerInt.writeSettings(false);
311 final int appId = UserHandle.getAppId(uid);
Philip P. Moltmannd3c37422019-10-11 14:59:33 -0700312 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700313 }
314 @Override
315 public void onInstallPermissionRevoked() {
316 mPackageManagerInt.writeSettings(true);
317 }
318 @Override
319 public void onPermissionUpdated(int[] userIds, boolean sync) {
320 mPackageManagerInt.writePermissionSettings(userIds, !sync);
321 }
322 @Override
323 public void onInstallPermissionUpdated() {
324 mPackageManagerInt.writeSettings(true);
325 }
326 @Override
327 public void onPermissionRemoved() {
328 mPackageManagerInt.writeSettings(false);
329 }
330 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
331 int uid) {
332 onPermissionUpdated(updatedUserIds, sync);
Nate Myren3fb13a12019-12-11 12:30:39 -0800333 for (int i = 0; i < updatedUserIds.length; i++) {
334 int userUid = UserHandle.getUid(updatedUserIds[i], UserHandle.getAppId(uid));
335 mOnPermissionChangeListeners.onPermissionsChanged(userUid);
336 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700337 }
338 public void onInstallPermissionUpdatedNotifyListener(int uid) {
339 onInstallPermissionUpdated();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700340 mOnPermissionChangeListeners.onPermissionsChanged(uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700341 }
342 };
343
Todd Kennedy0eb97382017-10-03 16:57:22 -0700344 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700345 @NonNull Object externalLock) {
346 mContext = context;
347 mLock = externalLock;
348 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
349 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700350 mSettings = new PermissionSettings(mLock);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700351
352 mHandlerThread = new ServiceThread(TAG,
353 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
354 mHandlerThread.start();
355 mHandler = new Handler(mHandlerThread.getLooper());
356 Watchdog.getInstance().addThread(mHandler);
357
358 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700359 context, mHandlerThread.getLooper(), this);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700360 SystemConfig systemConfig = SystemConfig.getInstance();
361 mSystemPermissions = systemConfig.getSystemPermissions();
362 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700363 mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
Todd Kennedy0eb97382017-10-03 16:57:22 -0700364
365 // propagate permission configuration
366 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
367 SystemConfig.getInstance().getPermissions();
368 synchronized (mLock) {
369 for (int i=0; i<permConfig.size(); i++) {
370 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
371 BasePermission bp = mSettings.getPermissionLocked(perm.name);
372 if (bp == null) {
373 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
374 mSettings.putPermissionLocked(perm.name, bp);
375 }
376 if (perm.gids != null) {
377 bp.setGids(perm.gids, perm.perUser);
378 }
379 }
380 }
381
Philip P. Moltmann48456672019-01-20 13:14:03 -0800382 PermissionManagerServiceInternalImpl localService =
383 new PermissionManagerServiceInternalImpl();
384 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
385 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700386 }
387
388 /**
389 * Creates and returns an initialized, internal service for use by other components.
390 * <p>
391 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800392 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700393 * <p>
394 * NOTE: The external lock is temporary and should be removed. This needs to be a
395 * lock created by the permission manager itself.
396 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800397 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700398 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800399 final PermissionManagerServiceInternal permMgrInt =
400 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700401 if (permMgrInt != null) {
402 return permMgrInt;
403 }
Todd Kennedy8f135982019-07-02 07:35:15 -0700404 PermissionManagerService permissionService =
405 (PermissionManagerService) ServiceManager.getService("permissionmgr");
406 if (permissionService == null) {
407 permissionService =
408 new PermissionManagerService(context, externalLock);
409 ServiceManager.addService("permissionmgr", permissionService);
410 }
Philip P. Moltmann48456672019-01-20 13:14:03 -0800411 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700412 }
413
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700414 /**
415 * This method should typically only be used when granting or revoking
416 * permissions, since the app may immediately restart after this call.
417 * <p>
418 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
419 * guard your work against the app being relaunched.
420 */
421 public static void killUid(int appId, int userId, String reason) {
422 final long identity = Binder.clearCallingIdentity();
423 try {
424 IActivityManager am = ActivityManager.getService();
425 if (am != null) {
426 try {
427 am.killUid(appId, userId, reason);
428 } catch (RemoteException e) {
429 /* ignore - same process */
430 }
431 }
432 } finally {
433 Binder.restoreCallingIdentity(identity);
434 }
435 }
436
Winson14ff7172019-10-23 10:42:27 -0700437 @Nullable
438 BasePermission getPermission(String permName) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700439 synchronized (mLock) {
440 return mSettings.getPermissionLocked(permName);
441 }
442 }
443
Todd Kennedy8f135982019-07-02 07:35:15 -0700444 @Override
445 public String[] getAppOpPermissionPackages(String permName) {
446 return getAppOpPermissionPackagesInternal(permName, getCallingUid());
447 }
448
449 private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
450 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
451 return null;
452 }
453 synchronized (mLock) {
454 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
455 if (pkgs == null) {
456 return null;
457 }
458 return pkgs.toArray(new String[pkgs.size()]);
459 }
460 }
461
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700462 @Override
463 @NonNull
464 public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
465 @PermissionGroupInfoFlags int flags) {
466 final int callingUid = getCallingUid();
467 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
468 return ParceledListSlice.emptyList();
469 }
470 synchronized (mLock) {
471 final int n = mSettings.mPermissionGroups.size();
Winson14ff7172019-10-23 10:42:27 -0700472 final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n);
473 for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) {
474 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700475 }
476 return new ParceledListSlice<>(out);
477 }
478 }
479
480
481 @Override
482 @Nullable
483 public PermissionGroupInfo getPermissionGroupInfo(String groupName,
484 @PermissionGroupInfoFlags int flags) {
485 final int callingUid = getCallingUid();
486 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
487 return null;
488 }
489 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -0700490 return PackageInfoUtils.generatePermissionGroupInfo(
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700491 mSettings.mPermissionGroups.get(groupName), flags);
492 }
493 }
494
495
496 @Override
497 @Nullable
498 public PermissionInfo getPermissionInfo(String permName, String packageName,
499 @PermissionInfoFlags int flags) {
500 final int callingUid = getCallingUid();
501 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
502 return null;
503 }
504 synchronized (mLock) {
505 final BasePermission bp = mSettings.getPermissionLocked(permName);
506 if (bp == null) {
507 return null;
508 }
509 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
510 bp.getProtectionLevel(), packageName, callingUid);
511 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
512 }
513 }
514
515 @Override
516 @Nullable
517 public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
518 @PermissionInfoFlags int flags) {
519 final int callingUid = getCallingUid();
520 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
521 return null;
522 }
523 synchronized (mLock) {
524 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
525 return null;
526 }
527 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
528 for (BasePermission bp : mSettings.mPermissions.values()) {
529 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
530 if (pi != null) {
531 out.add(pi);
532 }
533 }
534 return new ParceledListSlice<>(out);
535 }
536 }
537
Todd Kennedy6ffc5a62019-07-03 09:35:31 -0700538 @Override
539 public boolean addPermission(PermissionInfo info, boolean async) {
540 final int callingUid = getCallingUid();
541 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
542 throw new SecurityException("Instant apps can't add permissions");
543 }
544 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
545 throw new SecurityException("Label must be specified in permission");
546 }
547 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
548 final boolean added;
549 final boolean changed;
550 synchronized (mLock) {
551 BasePermission bp = mSettings.getPermissionLocked(info.name);
552 added = bp == null;
553 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
554 if (added) {
555 enforcePermissionCapLocked(info, tree);
556 bp = new BasePermission(info.name, tree.getSourcePackageName(),
557 BasePermission.TYPE_DYNAMIC);
558 } else if (!bp.isDynamic()) {
559 throw new SecurityException("Not allowed to modify non-dynamic permission "
560 + info.name);
561 }
562 changed = bp.addToTree(fixedLevel, info, tree);
563 if (added) {
564 mSettings.putPermissionLocked(info.name, bp);
565 }
566 }
567 if (changed) {
568 mPackageManagerInt.writeSettings(async);
569 }
570 return added;
571 }
572
573 @Override
574 public void removePermission(String permName) {
575 final int callingUid = getCallingUid();
576 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
577 throw new SecurityException("Instant applications don't have access to this method");
578 }
579 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
580 synchronized (mLock) {
581 final BasePermission bp = mSettings.getPermissionLocked(permName);
582 if (bp == null) {
583 return;
584 }
585 if (bp.isDynamic()) {
586 // TODO: switch this back to SecurityException
587 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
588 + permName);
589 }
590 mSettings.removePermissionLocked(permName);
591 mPackageManagerInt.writeSettings(false);
592 }
593 }
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700594
Todd Kennedy230c0a72019-07-03 13:06:35 -0700595 @Override
596 public int getPermissionFlags(String permName, String packageName, int userId) {
597 final int callingUid = getCallingUid();
598 return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
599 }
600
601 private int getPermissionFlagsInternal(
602 String permName, String packageName, int callingUid, int userId) {
603 if (!mUserManagerInt.exists(userId)) {
604 return 0;
605 }
606
607 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
608 enforceCrossUserPermission(callingUid, userId,
609 true, // requireFullPermission
610 false, // checkShell
611 false, // requirePermissionWhenSameUser
612 "getPermissionFlags");
613
Winson14ff7172019-10-23 10:42:27 -0700614 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
615 if (pkg == null) {
616 return 0;
617 }
618 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
619 pkg.getPackageName());
620 if (ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700621 return 0;
622 }
623 synchronized (mLock) {
624 if (mSettings.getPermissionLocked(permName) == null) {
625 return 0;
626 }
627 }
628 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
629 return 0;
630 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700631 PermissionsState permissionsState = ps.getPermissionsState();
632 return permissionsState.getPermissionFlags(permName, userId);
633 }
634
635 @Override
636 public void updatePermissionFlags(String permName, String packageName, int flagMask,
637 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
638 final int callingUid = getCallingUid();
639 boolean overridePolicy = false;
640
641 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
642 long callingIdentity = Binder.clearCallingIdentity();
643 try {
644 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
645 if (checkAdjustPolicyFlagPermission) {
646 mContext.enforceCallingOrSelfPermission(
647 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
648 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
649 + " to change policy flags");
Hai Zhang053c3a22019-08-23 15:08:03 -0700650 } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid)
Todd Kennedy230c0a72019-07-03 13:06:35 -0700651 >= Build.VERSION_CODES.Q) {
652 throw new IllegalArgumentException(
653 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
654 + " to be checked for packages targeting "
655 + Build.VERSION_CODES.Q + " or later when changing policy "
656 + "flags");
657 }
658 overridePolicy = true;
659 }
660 } finally {
661 Binder.restoreCallingIdentity(callingIdentity);
662 }
663 }
664
665 updatePermissionFlagsInternal(
666 permName, packageName, flagMask, flagValues, callingUid, userId,
667 overridePolicy, mDefaultPermissionCallback);
668 }
669
670 private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
671 int flagValues, int callingUid, int userId, boolean overridePolicy,
672 PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700673 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedy230c0a72019-07-03 13:06:35 -0700674 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700675 Log.i(TAG, "System is updating flags for " + packageName + " "
Todd Kennedy230c0a72019-07-03 13:06:35 -0700676 + permName + " for user " + userId + " "
677 + DebugUtils.flagsToString(
678 PackageManager.class, "FLAG_PERMISSION_", flagMask)
679 + " := "
680 + DebugUtils.flagsToString(
681 PackageManager.class, "FLAG_PERMISSION_", flagValues)
682 + " on behalf of uid " + callingUid
683 + " " + mPackageManagerInt.getNameForUid(callingUid),
684 new RuntimeException());
685 }
686
687 if (!mUserManagerInt.exists(userId)) {
688 return;
689 }
690
691 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
692
693 enforceCrossUserPermission(callingUid, userId,
694 true, // requireFullPermission
695 true, // checkShell
696 false, // requirePermissionWhenSameUser
697 "updatePermissionFlags");
698
699 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
700 throw new SecurityException("updatePermissionFlags requires "
701 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
702 }
703
704 // Only the system can change these flags and nothing else.
705 if (callingUid != Process.SYSTEM_UID) {
706 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
707 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
708 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
709 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
710 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
711 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
712 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
713 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
714 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
715 }
716
Winson14ff7172019-10-23 10:42:27 -0700717 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
718 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
719 packageName);
720 if (pkg == null || ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700721 Log.e(TAG, "Unknown package: " + packageName);
722 return;
723 }
724 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
725 throw new IllegalArgumentException("Unknown package: " + packageName);
726 }
727
728 final BasePermission bp;
729 synchronized (mLock) {
730 bp = mSettings.getPermissionLocked(permName);
731 }
732 if (bp == null) {
733 throw new IllegalArgumentException("Unknown permission: " + permName);
734 }
735
Todd Kennedy230c0a72019-07-03 13:06:35 -0700736 final PermissionsState permissionsState = ps.getPermissionsState();
737 final boolean hadState =
738 permissionsState.getRuntimePermissionState(permName, userId) != null;
739 final boolean permissionUpdated =
740 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
741 if (permissionUpdated && bp.isRuntime()) {
742 notifyRuntimePermissionStateChanged(packageName, userId);
743 }
744 if (permissionUpdated && callback != null) {
745 // Install and runtime permissions are stored in different places,
746 // so figure out what permission changed and persist the change.
747 if (permissionsState.getInstallPermissionState(permName) != null) {
Nate Myren3fb13a12019-12-11 12:30:39 -0800748 int userUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
749 callback.onInstallPermissionUpdatedNotifyListener(userUid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700750 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
751 || hadState) {
Winson14ff7172019-10-23 10:42:27 -0700752 callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false,
753 pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700754 }
755 }
756 }
757
758 /**
759 * Update the permission flags for all packages and runtime permissions of a user in order
760 * to allow device or profile owner to remove POLICY_FIXED.
761 */
762 @Override
763 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
764 final int userId) {
765 final int callingUid = getCallingUid();
766 if (!mUserManagerInt.exists(userId)) {
767 return;
768 }
769
770 enforceGrantRevokeRuntimePermissionPermissions(
771 "updatePermissionFlagsForAllApps");
772 enforceCrossUserPermission(callingUid, userId,
773 true, // requireFullPermission
774 true, // checkShell
775 false, // requirePermissionWhenSameUser
776 "updatePermissionFlagsForAllApps");
777
778 // Only the system can change system fixed flags.
779 final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
780 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
781 final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
782 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
783
784 final boolean[] changed = new boolean[1];
Winson14ff7172019-10-23 10:42:27 -0700785 mPackageManagerInt.forEachPackage(pkg -> {
786 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
787 pkg.getPackageName());
788 if (ps == null) {
789 return;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700790 }
Winson14ff7172019-10-23 10:42:27 -0700791 final PermissionsState permissionsState = ps.getPermissionsState();
792 changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
793 userId, effectiveFlagMask, effectiveFlagValues);
794 mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700795 });
796
797 if (changed[0]) {
798 mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
799 }
800 }
801
Todd Kennedyca1ea172019-07-03 15:02:28 -0700802 @Override
803 public int checkPermission(String permName, String pkgName, int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000804 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700805 if (permName == null || pkgName == null) {
806 return PackageManager.PERMISSION_DENIED;
807 }
808 if (!mUserManagerInt.exists(userId)) {
809 return PackageManager.PERMISSION_DENIED;
810 }
811
Todd Kennedyca1ea172019-07-03 15:02:28 -0700812 final CheckPermissionDelegate checkPermissionDelegate;
813 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700814 checkPermissionDelegate = mCheckPermissionDelegate;
815 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700816 if (checkPermissionDelegate == null) {
817 return checkPermissionImpl(permName, pkgName, userId);
818 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700819 return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
Hai Zhang61b4d352019-10-07 13:45:26 -0700820 this::checkPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700821 }
822
Hai Zhang4fef76a2019-09-28 00:03:50 +0000823 private int checkPermissionImpl(String permName, String pkgName, int userId) {
Winson655a5b92019-10-23 10:49:32 -0700824 final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName);
Hai Zhang3b049a52019-08-16 15:37:46 -0700825 if (pkg == null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700826 return PackageManager.PERMISSION_DENIED;
827 }
Hai Zhang4fef76a2019-09-28 00:03:50 +0000828 return checkPermissionInternal(pkg, true, permName, userId);
Hai Zhang3b049a52019-08-16 15:37:46 -0700829 }
830
Winson655a5b92019-10-23 10:49:32 -0700831 private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000832 @NonNull String permissionName, @UserIdInt int userId) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700833 final int callingUid = getCallingUid();
Winson14ff7172019-10-23 10:42:27 -0700834 if (isPackageExplicit || pkg.getSharedUserId() == null) {
Patrick Baumann97b9b532018-04-11 14:51:30 +0000835 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000836 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700837 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700838 } else {
839 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000840 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700841 }
842 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700843
Winson14ff7172019-10-23 10:42:27 -0700844 final int uid = UserHandle.getUid(userId, pkg.getUid());
845 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
846 pkg.getPackageName());
Hai Zhang3b049a52019-08-16 15:37:46 -0700847 if (ps == null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000848 return PackageManager.PERMISSION_DENIED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700849 }
850 final PermissionsState permissionsState = ps.getPermissionsState();
851
Hai Zhang4fef76a2019-09-28 00:03:50 +0000852 if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) {
853 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700854 }
855
856 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000857 if (fullerPermissionName != null
858 && checkSinglePermissionInternal(uid, permissionsState, fullerPermissionName)) {
859 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700860 }
861
Hai Zhang4fef76a2019-09-28 00:03:50 +0000862 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700863 }
864
Hai Zhang3b049a52019-08-16 15:37:46 -0700865 private boolean checkSinglePermissionInternal(int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000866 @NonNull PermissionsState permissionsState, @NonNull String permissionName) {
Hai Zhang61b4d352019-10-07 13:45:26 -0700867 if (!permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid))) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700868 return false;
869 }
870
871 if (mPackageManagerInt.getInstantAppPackageName(uid) != null) {
872 return mSettings.isPermissionInstant(permissionName);
873 }
874
875 return true;
876 }
877
Todd Kennedyca1ea172019-07-03 15:02:28 -0700878 @Override
879 public int checkUidPermission(String permName, int uid) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000880 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700881 if (permName == null) {
882 return PackageManager.PERMISSION_DENIED;
883 }
884 final int userId = UserHandle.getUserId(uid);
885 if (!mUserManagerInt.exists(userId)) {
886 return PackageManager.PERMISSION_DENIED;
887 }
888
Todd Kennedyca1ea172019-07-03 15:02:28 -0700889 final CheckPermissionDelegate checkPermissionDelegate;
890 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700891 checkPermissionDelegate = mCheckPermissionDelegate;
892 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700893 if (checkPermissionDelegate == null) {
894 return checkUidPermissionImpl(permName, uid);
895 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700896 return checkPermissionDelegate.checkUidPermission(permName, uid,
Hai Zhang61b4d352019-10-07 13:45:26 -0700897 this::checkUidPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700898 }
899
Hai Zhang4fef76a2019-09-28 00:03:50 +0000900 private int checkUidPermissionImpl(String permName, int uid) {
Winson655a5b92019-10-23 10:49:32 -0700901 final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000902 return checkUidPermissionInternal(pkg, uid, permName);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700903 }
904
905 /**
906 * Checks whether or not the given package has been granted the specified
907 * permission. If the given package is {@code null}, we instead check the
908 * system permissions for the given UID.
909 *
910 * @see SystemConfig#getSystemPermissions()
911 */
Winson655a5b92019-10-23 10:49:32 -0700912 private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000913 @NonNull String permissionName) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700914 if (pkg != null) {
915 final int userId = UserHandle.getUserId(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000916 return checkPermissionInternal(pkg, false, permissionName, userId);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700917 }
918
Hai Zhang3b049a52019-08-16 15:37:46 -0700919 if (checkSingleUidPermissionInternal(uid, permissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000920 return PackageManager.PERMISSION_GRANTED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700921 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700922
923 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
924 if (fullerPermissionName != null
925 && checkSingleUidPermissionInternal(uid, fullerPermissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000926 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700927 }
928
Hai Zhang4fef76a2019-09-28 00:03:50 +0000929 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700930 }
931
Hai Zhang3b049a52019-08-16 15:37:46 -0700932 private boolean checkSingleUidPermissionInternal(int uid, @NonNull String permissionName) {
933 synchronized (mLock) {
934 ArraySet<String> permissions = mSystemPermissions.get(uid);
935 return permissions != null && permissions.contains(permissionName);
936 }
937 }
938
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700939 @Override
940 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
941 mContext.enforceCallingOrSelfPermission(
942 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
943 "addOnPermissionsChangeListener");
944
945 synchronized (mLock) {
946 mOnPermissionChangeListeners.addListenerLocked(listener);
947 }
948 }
949
950 @Override
951 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
952 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
953 throw new SecurityException("Instant applications don't have access to this method");
954 }
955 synchronized (mLock) {
956 mOnPermissionChangeListeners.removeListenerLocked(listener);
957 }
958 }
959
960 @Override
961 @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
962 @PermissionWhitelistFlags int flags, @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000963 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700964 Preconditions.checkFlagsArgument(flags,
965 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
966 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
967 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
968 Preconditions.checkArgumentNonNegative(userId, null);
969
970 if (UserHandle.getCallingUserId() != userId) {
971 mContext.enforceCallingOrSelfPermission(
972 android.Manifest.permission.INTERACT_ACROSS_USERS,
973 "getWhitelistedRestrictedPermissions for user " + userId);
974 }
975
Winson14ff7172019-10-23 10:42:27 -0700976 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700977 if (pkg == null) {
978 return null;
979 }
980
981 final int callingUid = Binder.getCallingUid();
982 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
983 return null;
984 }
985 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
986 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
987 == PackageManager.PERMISSION_GRANTED;
988 final boolean isCallerInstallerOnRecord =
989 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
990
991 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
992 && !isCallerPrivileged) {
993 throw new SecurityException("Querying system whitelist requires "
994 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
995 }
996
997 if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
998 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
999 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1000 throw new SecurityException("Querying upgrade or installer whitelist"
1001 + " requires being installer on record or "
1002 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1003 }
1004 }
1005
1006 final long identity = Binder.clearCallingIdentity();
1007 try {
1008 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07001009 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001010 if (permissionsState == null) {
1011 return null;
1012 }
1013
1014 int queryFlags = 0;
1015 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
1016 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
1017 }
1018 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1019 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
1020 }
1021 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1022 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
1023 }
1024
1025 ArrayList<String> whitelistedPermissions = null;
1026
Winson14ff7172019-10-23 10:42:27 -07001027 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001028 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001029 final String permissionName = pkg.getRequestedPermissions().get(i);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001030 final int currentFlags =
1031 permissionsState.getPermissionFlags(permissionName, userId);
1032 if ((currentFlags & queryFlags) != 0) {
1033 if (whitelistedPermissions == null) {
1034 whitelistedPermissions = new ArrayList<>();
1035 }
1036 whitelistedPermissions.add(permissionName);
1037 }
1038 }
1039
1040 return whitelistedPermissions;
1041 } finally {
1042 Binder.restoreCallingIdentity(identity);
1043 }
1044 }
1045
1046 @Override
1047 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
1048 @NonNull String permName, @PermissionWhitelistFlags int flags,
1049 @UserIdInt int userId) {
1050 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001051 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001052
1053 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1054 return false;
1055 }
1056
1057 List<String> permissions =
1058 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1059 if (permissions == null) {
1060 permissions = new ArrayList<>(1);
1061 }
1062 if (permissions.indexOf(permName) < 0) {
1063 permissions.add(permName);
1064 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1065 flags, userId);
1066 }
1067 return false;
1068 }
1069
1070 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
1071 @NonNull String permName) {
1072 synchronized (mLock) {
1073 final BasePermission bp = mSettings.getPermissionLocked(permName);
1074 if (bp == null) {
1075 Slog.w(TAG, "No such permissions: " + permName);
1076 return false;
1077 }
1078 if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
1079 && mContext.checkCallingOrSelfPermission(
1080 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1081 != PackageManager.PERMISSION_GRANTED) {
1082 throw new SecurityException("Cannot modify whitelisting of an immutably "
1083 + "restricted permission: " + permName);
1084 }
1085 return true;
1086 }
1087 }
1088
1089 @Override
1090 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
1091 @NonNull String permName, @PermissionWhitelistFlags int flags,
1092 @UserIdInt int userId) {
1093 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001094 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001095
1096 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1097 return false;
1098 }
1099
1100 final List<String> permissions =
1101 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1102 if (permissions != null && permissions.remove(permName)) {
1103 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1104 flags, userId);
1105 }
1106 return false;
1107 }
1108
1109 private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
1110 @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
1111 @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001112 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001113 Preconditions.checkFlagsArgument(flags,
1114 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1115 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1116 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1117 Preconditions.checkArgument(Integer.bitCount(flags) == 1);
1118 Preconditions.checkArgumentNonNegative(userId, null);
1119
1120 if (UserHandle.getCallingUserId() != userId) {
1121 mContext.enforceCallingOrSelfPermission(
1122 Manifest.permission.INTERACT_ACROSS_USERS,
1123 "setWhitelistedRestrictedPermissions for user " + userId);
1124 }
1125
Winson14ff7172019-10-23 10:42:27 -07001126 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001127 if (pkg == null) {
1128 return false;
1129 }
1130
1131 final int callingUid = Binder.getCallingUid();
1132 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1133 return false;
1134 }
1135
1136 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1137 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1138 == PackageManager.PERMISSION_GRANTED;
1139 final boolean isCallerInstallerOnRecord =
1140 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1141
1142 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1143 && !isCallerPrivileged) {
1144 throw new SecurityException("Modifying system whitelist requires "
1145 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1146 }
1147
1148 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1149 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1150 throw new SecurityException("Modifying upgrade whitelist requires"
1151 + " being installer on record or "
1152 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1153 }
1154 final List<String> whitelistedPermissions =
Winson14ff7172019-10-23 10:42:27 -07001155 getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001156 if (permissions == null || permissions.isEmpty()) {
1157 if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
1158 return true;
1159 }
1160 } else {
1161 // Only the system can add and remove while the installer can only remove.
1162 final int permissionCount = permissions.size();
1163 for (int i = 0; i < permissionCount; i++) {
1164 if ((whitelistedPermissions == null
1165 || !whitelistedPermissions.contains(permissions.get(i)))
1166 && !isCallerPrivileged) {
1167 throw new SecurityException("Adding to upgrade whitelist requires"
1168 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1169 }
1170 }
1171 }
1172
1173 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1174 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1175 throw new SecurityException("Modifying installer whitelist requires"
1176 + " being installer on record or "
1177 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1178 }
1179 }
1180 }
1181
1182 final long identity = Binder.clearCallingIdentity();
1183 try {
1184 setWhitelistedRestrictedPermissionsForUser(
1185 pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
1186 } finally {
1187 Binder.restoreCallingIdentity(identity);
1188 }
1189
1190 return true;
1191 }
1192
Todd Kennedyc971a452019-07-08 16:04:52 -07001193 @Override
1194 public void grantRuntimePermission(String packageName, String permName, final int userId) {
1195 final int callingUid = Binder.getCallingUid();
1196 final boolean overridePolicy =
1197 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1198 == PackageManager.PERMISSION_GRANTED;
1199
1200 grantRuntimePermissionInternal(permName, packageName, overridePolicy,
1201 callingUid, userId, mDefaultPermissionCallback);
1202 }
1203
1204 // TODO swap permission name and package name
1205 private void grantRuntimePermissionInternal(String permName, String packageName,
1206 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1207 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
1208 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001209 Log.i(TAG, "System is granting " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001210 + permName + " for user " + userId + " on behalf of uid " + callingUid
1211 + " " + mPackageManagerInt.getNameForUid(callingUid),
1212 new RuntimeException());
1213 }
1214 if (!mUserManagerInt.exists(userId)) {
1215 Log.e(TAG, "No such user:" + userId);
1216 return;
1217 }
1218
1219 mContext.enforceCallingOrSelfPermission(
1220 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1221 "grantRuntimePermission");
1222
1223 enforceCrossUserPermission(callingUid, userId,
1224 true, // requireFullPermission
1225 true, // checkShell
1226 false, // requirePermissionWhenSameUser
1227 "grantRuntimePermission");
1228
Winson14ff7172019-10-23 10:42:27 -07001229 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1230 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1231 packageName);
1232 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001233 Log.e(TAG, "Unknown package: " + packageName);
1234 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001235 }
1236 final BasePermission bp;
1237 synchronized (mLock) {
1238 bp = mSettings.getPermissionLocked(permName);
1239 }
1240 if (bp == null) {
1241 throw new IllegalArgumentException("Unknown permission: " + permName);
1242 }
1243 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1244 throw new IllegalArgumentException("Unknown package: " + packageName);
1245 }
1246
Winson14ff7172019-10-23 10:42:27 -07001247 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001248
1249 // If a permission review is required for legacy apps we represent
1250 // their permissions as always granted runtime ones since we need
1251 // to keep the review required permission flag per user while an
1252 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001253 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001254 && bp.isRuntime()) {
1255 return;
1256 }
1257
Winson14ff7172019-10-23 10:42:27 -07001258 final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
Todd Kennedyc971a452019-07-08 16:04:52 -07001259
Todd Kennedyc971a452019-07-08 16:04:52 -07001260 final PermissionsState permissionsState = ps.getPermissionsState();
1261
1262 final int flags = permissionsState.getPermissionFlags(permName, userId);
1263 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1264 Log.e(TAG, "Cannot grant system fixed permission "
1265 + permName + " for package " + packageName);
1266 return;
1267 }
1268 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1269 Log.e(TAG, "Cannot grant policy fixed permission "
1270 + permName + " for package " + packageName);
1271 return;
1272 }
1273
1274 if (bp.isHardRestricted()
1275 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1276 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
1277 + permName + " for package " + packageName);
1278 return;
1279 }
1280
1281 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Winson6571c8a2019-10-23 17:00:42 -07001282 pkg.toAppInfoWithoutState(), UserHandle.of(userId), permName)
1283 .mayGrantPermission()) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001284 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
1285 + packageName);
1286 return;
1287 }
1288
1289 if (bp.isDevelopment()) {
1290 // Development permissions must be handled specially, since they are not
1291 // normal runtime permissions. For now they apply to all users.
1292 if (permissionsState.grantInstallPermission(bp)
1293 != PERMISSION_OPERATION_FAILURE) {
1294 if (callback != null) {
1295 callback.onInstallPermissionGranted();
1296 }
1297 }
1298 return;
1299 }
1300
1301 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1302 throw new SecurityException("Cannot grant non-ephemeral permission"
1303 + permName + " for package " + packageName);
1304 }
1305
Winson14ff7172019-10-23 10:42:27 -07001306 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001307 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1308 return;
1309 }
1310
1311 final int result = permissionsState.grantRuntimePermission(bp, userId);
1312 switch (result) {
1313 case PERMISSION_OPERATION_FAILURE: {
1314 return;
1315 }
1316
1317 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1318 if (callback != null) {
Winson14ff7172019-10-23 10:42:27 -07001319 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001320 }
1321 }
1322 break;
1323 }
1324
1325 if (bp.isRuntime()) {
1326 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
1327 }
1328
1329 if (callback != null) {
1330 callback.onPermissionGranted(uid, userId);
1331 }
1332
1333 if (bp.isRuntime()) {
1334 notifyRuntimePermissionStateChanged(packageName, userId);
1335 }
1336
1337 // Only need to do this if user is initialized. Otherwise it's a new user
1338 // and there are no processes running as the user yet and there's no need
1339 // to make an expensive call to remount processes for the changed permissions.
1340 if (READ_EXTERNAL_STORAGE.equals(permName)
1341 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1342 final long token = Binder.clearCallingIdentity();
1343 try {
1344 if (mUserManagerInt.isUserInitialized(userId)) {
1345 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1346 StorageManagerInternal.class);
1347 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1348 }
1349 } finally {
1350 Binder.restoreCallingIdentity(token);
1351 }
1352 }
1353
1354 }
1355
1356 @Override
1357 public void revokeRuntimePermission(String packageName, String permName, int userId) {
1358 final int callingUid = Binder.getCallingUid();
1359 final boolean overridePolicy =
1360 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1361 == PackageManager.PERMISSION_GRANTED;
1362
1363 revokeRuntimePermissionInternal(permName, packageName, overridePolicy, callingUid, userId,
1364 mDefaultPermissionCallback);
1365 }
1366
1367 // TODO swap permission name and package name
1368 private void revokeRuntimePermissionInternal(String permName, String packageName,
1369 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001370 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedyc971a452019-07-08 16:04:52 -07001371 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001372 Log.i(TAG, "System is revoking " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001373 + permName + " for user " + userId + " on behalf of uid " + callingUid
1374 + " " + mPackageManagerInt.getNameForUid(callingUid),
1375 new RuntimeException());
1376 }
1377 if (!mUserManagerInt.exists(userId)) {
1378 Log.e(TAG, "No such user:" + userId);
1379 return;
1380 }
1381
1382 mContext.enforceCallingOrSelfPermission(
1383 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1384 "revokeRuntimePermission");
1385
1386 enforceCrossUserPermission(callingUid, userId,
1387 true, // requireFullPermission
1388 true, // checkShell
1389 false, // requirePermissionWhenSameUser
1390 "revokeRuntimePermission");
1391
Winson14ff7172019-10-23 10:42:27 -07001392 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1393 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1394 packageName);
1395 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001396 Log.e(TAG, "Unknown package: " + packageName);
1397 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001398 }
1399 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1400 throw new IllegalArgumentException("Unknown package: " + packageName);
1401 }
1402 final BasePermission bp = mSettings.getPermissionLocked(permName);
1403 if (bp == null) {
1404 throw new IllegalArgumentException("Unknown permission: " + permName);
1405 }
1406
Winson14ff7172019-10-23 10:42:27 -07001407 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001408
1409 // If a permission review is required for legacy apps we represent
1410 // their permissions as always granted runtime ones since we need
1411 // to keep the review required permission flag per user while an
1412 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001413 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001414 && bp.isRuntime()) {
1415 return;
1416 }
1417
Todd Kennedyc971a452019-07-08 16:04:52 -07001418 final PermissionsState permissionsState = ps.getPermissionsState();
1419
1420 final int flags = permissionsState.getPermissionFlags(permName, userId);
1421 // Only the system may revoke SYSTEM_FIXED permissions.
1422 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1423 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1424 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1425 + permName + " for package " + packageName);
1426 }
1427 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1428 throw new SecurityException("Cannot revoke policy fixed permission "
1429 + permName + " for package " + packageName);
1430 }
1431
1432 if (bp.isDevelopment()) {
1433 // Development permissions must be handled specially, since they are not
1434 // normal runtime permissions. For now they apply to all users.
1435 if (permissionsState.revokeInstallPermission(bp)
1436 != PERMISSION_OPERATION_FAILURE) {
1437 if (callback != null) {
1438 mDefaultPermissionCallback.onInstallPermissionRevoked();
1439 }
1440 }
1441 return;
1442 }
1443
1444 // Permission is already revoked, no need to do anything.
1445 if (!permissionsState.hasRuntimePermission(permName, userId)) {
1446 return;
1447 }
1448
1449 if (permissionsState.revokeRuntimePermission(bp, userId)
1450 == PERMISSION_OPERATION_FAILURE) {
1451 return;
1452 }
1453
1454 if (bp.isRuntime()) {
1455 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
1456 }
1457
1458 if (callback != null) {
Nate Myren8f6a9092019-08-27 15:50:03 -07001459 callback.onPermissionRevoked(UserHandle.getUid(userId,
Winson14ff7172019-10-23 10:42:27 -07001460 UserHandle.getAppId(pkg.getUid())), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001461 }
1462
1463 if (bp.isRuntime()) {
1464 notifyRuntimePermissionStateChanged(packageName, userId);
1465 }
1466 }
1467
1468 @Override
1469 public void resetRuntimePermissions() {
1470 mContext.enforceCallingOrSelfPermission(
1471 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1472 "revokeRuntimePermission");
1473
1474 final int callingUid = Binder.getCallingUid();
1475 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1476 mContext.enforceCallingOrSelfPermission(
1477 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1478 "resetRuntimePermissions");
1479 }
1480
1481 updateAllPermissions(
1482 StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
1483 for (final int userId : UserManagerService.getInstance().getUserIds()) {
1484 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07001485 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedyc971a452019-07-08 16:04:52 -07001486 }
1487 }
1488
1489 /**
1490 * Reverts user permission state changes (permissions and flags).
1491 *
Hai Zhang4ffebb72019-07-18 14:50:58 -07001492 * @param pkg The package for which to reset.
Todd Kennedyc971a452019-07-08 16:04:52 -07001493 * @param userId The device user for which to do a reset.
1494 */
Patrick Baumann865fd3a2019-07-26 14:53:02 -07001495 @GuardedBy("mLock")
Winson14ff7172019-10-23 10:42:27 -07001496 private void resetRuntimePermissionsInternal(final AndroidPackage pkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07001497 final int userId) {
Winson14ff7172019-10-23 10:42:27 -07001498 final String packageName = pkg.getPackageName();
Todd Kennedyc971a452019-07-08 16:04:52 -07001499
1500 // These are flags that can change base on user actions.
1501 final int userSettableMask = FLAG_PERMISSION_USER_SET
1502 | FLAG_PERMISSION_USER_FIXED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001503 | FLAG_PERMISSION_REVOKED_COMPAT
Todd Kennedyc971a452019-07-08 16:04:52 -07001504 | FLAG_PERMISSION_REVIEW_REQUIRED;
1505
1506 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
1507 | FLAG_PERMISSION_POLICY_FIXED;
1508
1509 // Delay and combine non-async permission callbacks
Winson14ff7172019-10-23 10:42:27 -07001510 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedyc971a452019-07-08 16:04:52 -07001511 final boolean[] permissionRemoved = new boolean[1];
1512 final ArraySet<Long> revokedPermissions = new ArraySet<>();
1513 final IntArray syncUpdatedUsers = new IntArray(permissionCount);
1514 final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
1515
1516 PermissionCallback delayingPermCallback = new PermissionCallback() {
1517 public void onGidsChanged(int appId, int userId) {
1518 mDefaultPermissionCallback.onGidsChanged(appId, userId);
1519 }
1520
1521 public void onPermissionChanged() {
1522 mDefaultPermissionCallback.onPermissionChanged();
1523 }
1524
1525 public void onPermissionGranted(int uid, int userId) {
1526 mDefaultPermissionCallback.onPermissionGranted(uid, userId);
1527 }
1528
1529 public void onInstallPermissionGranted() {
1530 mDefaultPermissionCallback.onInstallPermissionGranted();
1531 }
1532
1533 public void onPermissionRevoked(int uid, int userId) {
1534 revokedPermissions.add(IntPair.of(uid, userId));
1535
1536 syncUpdatedUsers.add(userId);
1537 }
1538
1539 public void onInstallPermissionRevoked() {
1540 mDefaultPermissionCallback.onInstallPermissionRevoked();
1541 }
1542
1543 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1544 for (int userId : updatedUserIds) {
1545 if (sync) {
1546 syncUpdatedUsers.add(userId);
1547 asyncUpdatedUsers.remove(userId);
1548 } else {
1549 // Don't override sync=true by sync=false
1550 if (syncUpdatedUsers.indexOf(userId) == -1) {
1551 asyncUpdatedUsers.add(userId);
1552 }
1553 }
1554 }
1555 }
1556
1557 public void onPermissionRemoved() {
1558 permissionRemoved[0] = true;
1559 }
1560
1561 public void onInstallPermissionUpdated() {
1562 mDefaultPermissionCallback.onInstallPermissionUpdated();
1563 }
Nate Myrencc9e2c72019-11-08 14:57:15 -08001564
1565 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds,
1566 boolean sync, int uid) {
1567 onPermissionUpdated(updatedUserIds, sync);
1568 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1569 }
1570
1571 public void onInstallPermissionUpdatedNotifyListener(int uid) {
1572 mDefaultPermissionCallback.onInstallPermissionUpdatedNotifyListener(uid);
1573 }
Todd Kennedyc971a452019-07-08 16:04:52 -07001574 };
1575
1576 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001577 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc971a452019-07-08 16:04:52 -07001578 final BasePermission bp;
1579 synchronized (mLock) {
1580 bp = mSettings.getPermissionLocked(permName);
1581 }
1582 if (bp == null) {
1583 continue;
1584 }
1585
1586 if (bp.isRemoved()) {
1587 continue;
1588 }
1589
1590 // If shared user we just reset the state to which only this app contributed.
Alan Stokes20fbef22019-12-17 15:33:12 +00001591 final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
1592 pkg.getPackageName(), userId);
1593 if (pkgNames.length > 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001594 boolean used = false;
Alan Stokes20fbef22019-12-17 15:33:12 +00001595 for (String sharedPkgName : pkgNames) {
Winson14ff7172019-10-23 10:42:27 -07001596 final AndroidPackage sharedPkg =
Todd Kennedyc971a452019-07-08 16:04:52 -07001597 mPackageManagerInt.getPackage(sharedPkgName);
Winson14ff7172019-10-23 10:42:27 -07001598 if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
1599 && sharedPkg.getRequestedPermissions().contains(permName)) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001600 used = true;
1601 break;
1602 }
1603 }
1604 if (used) {
1605 continue;
1606 }
1607 }
1608
1609 final int oldFlags =
1610 getPermissionFlagsInternal(permName, packageName, Process.SYSTEM_UID, userId);
1611
1612 // Always clear the user settable flags.
1613 // If permission review is enabled and this is a legacy app, mark the
1614 // permission as requiring a review as this is the initial state.
1615 final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
Hai Zhang053c3a22019-08-23 15:08:03 -07001616 final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
Todd Kennedyc971a452019-07-08 16:04:52 -07001617 final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001618 ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
Todd Kennedyc971a452019-07-08 16:04:52 -07001619 : 0;
1620
1621 updatePermissionFlagsInternal(
1622 permName, packageName, userSettableMask, flags, Process.SYSTEM_UID, userId,
1623 false, delayingPermCallback);
1624
1625 // Below is only runtime permission handling.
1626 if (!bp.isRuntime()) {
1627 continue;
1628 }
1629
1630 // Never clobber system or policy.
1631 if ((oldFlags & policyOrSystemFlags) != 0) {
1632 continue;
1633 }
1634
1635 // If this permission was granted by default, make sure it is.
1636 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
Hai Zhangab6a6822019-10-18 00:34:06 +00001637 // PermissionPolicyService will handle the app op for runtime permissions later.
Todd Kennedyc971a452019-07-08 16:04:52 -07001638 grantRuntimePermissionInternal(permName, packageName, false,
1639 Process.SYSTEM_UID, userId, delayingPermCallback);
1640 // If permission review is enabled the permissions for a legacy apps
1641 // are represented as constantly granted runtime ones, so don't revoke.
1642 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
1643 // Otherwise, reset the permission.
1644 revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
1645 userId, delayingPermCallback);
1646 }
1647 }
1648
1649 // Execute delayed callbacks
1650 if (permissionRemoved[0]) {
1651 mDefaultPermissionCallback.onPermissionRemoved();
1652 }
1653
1654 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
1655 // kill uid while holding mPackages-lock
1656 if (!revokedPermissions.isEmpty()) {
1657 int numRevokedPermissions = revokedPermissions.size();
1658 for (int i = 0; i < numRevokedPermissions; i++) {
1659 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
1660 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
1661
1662 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
1663
1664 // Kill app later as we are holding mPackages
1665 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
1666 KILL_APP_REASON_PERMISSIONS_REVOKED));
1667 }
1668 }
1669
1670 mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
1671 mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
1672 }
1673
Todd Kennedy583378d2019-07-12 06:50:30 -07001674 @Override
1675 public String getDefaultBrowser(int userId) {
1676 final int callingUid = Binder.getCallingUid();
1677 if (UserHandle.getUserId(callingUid) != userId) {
1678 mContext.enforceCallingOrSelfPermission(
1679 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1680 }
1681 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
1682 return null;
1683 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001684 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001685 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001686 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001687 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001688 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07001689 }
1690
1691 @Override
1692 public boolean setDefaultBrowser(String packageName, int userId) {
1693 mContext.enforceCallingOrSelfPermission(
1694 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
1695 if (UserHandle.getCallingUserId() != userId) {
1696 mContext.enforceCallingOrSelfPermission(
1697 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1698 }
1699 return setDefaultBrowserInternal(packageName, false, true, userId);
1700 }
1701
1702 private boolean setDefaultBrowserInternal(String packageName, boolean async,
1703 boolean doGrant, int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001704 if (userId == UserHandle.USER_ALL) {
1705 return false;
1706 }
1707 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001708 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001709 provider = mDefaultBrowserProvider;
1710 }
1711 if (provider == null) {
1712 return false;
1713 }
1714 if (async) {
1715 provider.setDefaultBrowserAsync(packageName, userId);
1716 } else {
1717 if (!provider.setDefaultBrowser(packageName, userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07001718 return false;
1719 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001720 }
1721 if (doGrant && packageName != null) {
1722 synchronized (mLock) {
1723 mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
1724 userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07001725 }
1726 }
1727 return true;
1728 }
1729
1730 @Override
1731 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
1732 final int callingUid = Binder.getCallingUid();
1733 PackageManagerServiceUtils
1734 .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
1735 synchronized (mLock) {
1736 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1737 .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
1738 }
1739 }
1740
1741 @Override
1742 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
1743 final int callingUid = Binder.getCallingUid();
1744 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1745 "grantDefaultPermissionsToEnabledImsServices", callingUid);
1746 synchronized (mLock) {
1747 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1748 .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
1749 }
1750 }
1751
1752 @Override
1753 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
1754 String[] packageNames, int userId) {
1755 final int callingUid = Binder.getCallingUid();
1756 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1757 "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
1758 synchronized (mLock) {
1759 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1760 .grantDefaultPermissionsToEnabledTelephonyDataServices(
1761 packageNames, userId));
1762 }
1763 }
1764
1765 @Override
1766 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1767 String[] packageNames, int userId) {
1768 final int callingUid = Binder.getCallingUid();
1769 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1770 "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
1771 synchronized (mLock) {
1772 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1773 .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1774 packageNames, userId));
1775 }
1776 }
1777
1778 @Override
1779 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
1780 final int callingUid = Binder.getCallingUid();
1781 PackageManagerServiceUtils
1782 .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
1783 synchronized (mLock) {
1784 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1785 .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
1786 }
1787 }
1788
1789 @Override
1790 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
1791 final int callingUid = Binder.getCallingUid();
1792 PackageManagerServiceUtils
1793 .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
1794 synchronized (mLock) {
1795 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1796 .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
1797 }
1798 }
1799
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001800 @Override
1801 public void setPermissionEnforced(String permName, boolean enforced) {
1802 // TODO: Now that we no longer change GID for storage, this should to away.
1803 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1804 "setPermissionEnforced");
1805 if (READ_EXTERNAL_STORAGE.equals(permName)) {
1806 mPackageManagerInt.setReadExternalStorageEnforced(enforced);
1807 // kill any non-foreground processes so we restart them and
1808 // grant/revoke the GID.
1809 final IActivityManager am = ActivityManager.getService();
1810 if (am != null) {
1811 final long token = Binder.clearCallingIdentity();
1812 try {
1813 am.killProcessesBelowForeground("setPermissionEnforcement");
1814 } catch (RemoteException e) {
1815 } finally {
1816 Binder.restoreCallingIdentity(token);
1817 }
1818 }
1819 } else {
1820 throw new IllegalArgumentException("No selective enforcement for " + permName);
1821 }
1822 }
1823
1824 /** @deprecated */
1825 @Override
1826 @Deprecated
1827 public boolean isPermissionEnforced(String permName) {
1828 // allow instant applications
1829 return true;
1830 }
1831
Evan Severson50a77742020-01-06 10:38:19 -08001832 /**
1833 * This change makes it so that apps are told to show rationale for asking for background
1834 * location access every time they request.
1835 */
1836 @ChangeId
1837 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
1838 private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L;
1839
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001840 @Override
1841 public boolean shouldShowRequestPermissionRationale(String permName,
1842 String packageName, int userId) {
1843 final int callingUid = Binder.getCallingUid();
1844 if (UserHandle.getCallingUserId() != userId) {
1845 mContext.enforceCallingPermission(
1846 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1847 "canShowRequestPermissionRationale for user " + userId);
1848 }
1849
1850 final int uid =
1851 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
1852 if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
1853 return false;
1854 }
1855
1856 if (checkPermission(permName, packageName, userId)
1857 == PackageManager.PERMISSION_GRANTED) {
1858 return false;
1859 }
1860
1861 final int flags;
1862
1863 final long identity = Binder.clearCallingIdentity();
1864 try {
1865 flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
1866 } finally {
1867 Binder.restoreCallingIdentity(identity);
1868 }
1869
1870 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
1871 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
1872 | PackageManager.FLAG_PERMISSION_USER_FIXED;
1873
1874 if ((flags & fixedFlags) != 0) {
1875 return false;
1876 }
1877
Evan Severson50a77742020-01-06 10:38:19 -08001878 try {
1879 if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
1880 && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID,
1881 packageName, userId)) {
1882 return true;
1883 }
1884 } catch (RemoteException e) {
1885 Log.e(TAG, "Unable to check if compatibility change is enabled.", e);
1886 }
1887
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001888 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
1889 }
1890
1891 @Override
1892 public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
1893 if (UserHandle.getCallingUserId() != userId) {
1894 mContext.enforceCallingPermission(
1895 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1896 "isPermissionRevokedByPolicy for user " + userId);
1897 }
1898
1899 if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
1900 return false;
1901 }
1902
1903 final int callingUid = Binder.getCallingUid();
1904 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
1905 return false;
1906 }
1907
1908 final long identity = Binder.clearCallingIdentity();
1909 try {
1910 final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
1911 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
1912 } finally {
1913 Binder.restoreCallingIdentity(identity);
1914 }
1915 }
1916
Hongwei Wangf391b552018-04-06 13:52:46 -07001917 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -08001918 * Get the state of the runtime permissions as xml file.
1919 *
1920 * <p>Can not be called on main thread.
1921 *
1922 * @param user The user the data should be extracted for
1923 *
1924 * @return The state as a xml file
1925 */
1926 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
1927 CompletableFuture<byte[]> backup = new CompletableFuture<>();
1928 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
1929 backup::complete);
1930
1931 try {
1932 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
1933 } catch (InterruptedException | ExecutionException | TimeoutException e) {
1934 Slog.e(TAG, "Cannot create permission backup for " + user, e);
1935 return null;
1936 }
1937 }
1938
1939 /**
1940 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
1941 *
1942 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
1943 * applied via {@link #restoreDelayedRuntimePermissions}.
1944 *
1945 * @param backup The state as an xml file
1946 * @param user The user the data should be restored for
1947 */
1948 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
1949 synchronized (mLock) {
1950 mHasNoDelayedPermBackup.delete(user.getIdentifier());
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07001951 mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
Philip P. Moltmann48456672019-01-20 13:14:03 -08001952 }
1953 }
1954
1955 /**
1956 * Try to apply permission backup that was previously not applied.
1957 *
1958 * <p>Can not be called on main thread.
1959 *
1960 * @param packageName The package that is newly installed
1961 * @param user The user the package is installed for
1962 *
1963 * @see #restoreRuntimePermissions
1964 */
1965 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
1966 @NonNull UserHandle user) {
1967 synchronized (mLock) {
1968 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
1969 return;
1970 }
1971
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07001972 mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
Philip P. Moltmann48456672019-01-20 13:14:03 -08001973 mContext.getMainExecutor(), (hasMoreBackup) -> {
1974 if (hasMoreBackup) {
1975 return;
1976 }
1977
1978 synchronized (mLock) {
1979 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
1980 }
1981 });
1982 }
1983 }
1984
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001985 private void addOnRuntimePermissionStateChangedListener(@NonNull
1986 OnRuntimePermissionStateChangedListener listener) {
1987 synchronized (mLock) {
1988 mRuntimePermissionStateChangedListeners.add(listener);
1989 }
1990 }
1991
1992 private void removeOnRuntimePermissionStateChangedListener(@NonNull
1993 OnRuntimePermissionStateChangedListener listener) {
1994 synchronized (mLock) {
1995 mRuntimePermissionStateChangedListeners.remove(listener);
1996 }
1997 }
1998
1999 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
2000 @UserIdInt int userId) {
2001 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
2002 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
2003 PermissionManagerService.this, packageName, userId));
2004 }
2005
2006 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
2007 @UserIdInt int userId) {
2008 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
2009 synchronized (mLock) {
2010 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
2011 return;
2012 }
2013 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
2014 }
2015 final int listenerCount = listeners.size();
2016 for (int i = 0; i < listenerCount; i++) {
2017 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
2018 }
2019 }
2020
Todd Kennedy0eb97382017-10-03 16:57:22 -07002021 private int adjustPermissionProtectionFlagsLocked(
2022 int protectionLevel, String packageName, int uid) {
2023 // Signature permission flags area always reported
2024 final int protectionLevelMasked = protectionLevel
2025 & (PermissionInfo.PROTECTION_NORMAL
2026 | PermissionInfo.PROTECTION_DANGEROUS
2027 | PermissionInfo.PROTECTION_SIGNATURE);
2028 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
2029 return protectionLevel;
2030 }
2031 // System sees all flags.
2032 final int appId = UserHandle.getAppId(uid);
2033 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
2034 || appId == Process.SHELL_UID) {
2035 return protectionLevel;
2036 }
2037 // Normalize package name to handle renamed packages and static libs
Winson14ff7172019-10-23 10:42:27 -07002038 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002039 if (pkg == null) {
2040 return protectionLevel;
2041 }
Winson14ff7172019-10-23 10:42:27 -07002042 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002043 return protectionLevelMasked;
2044 }
2045 // Apps that target O see flags for all protection levels.
Winson14ff7172019-10-23 10:42:27 -07002046 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2047 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07002048 if (ps == null) {
2049 return protectionLevel;
2050 }
2051 if (ps.getAppId() != appId) {
2052 return protectionLevel;
2053 }
2054 return protectionLevel;
2055 }
2056
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002057 /**
2058 * We might auto-grant permissions if any permission of the group is already granted. Hence if
2059 * the group of a granted permission changes we need to revoke it to avoid having permissions of
2060 * the new group auto-granted.
2061 *
2062 * @param newPackage The new package that was installed
2063 * @param oldPackage The old package that was updated
2064 * @param allPackageNames All package names
2065 * @param permissionCallback Callback for permission changed
2066 */
2067 private void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07002068 @NonNull AndroidPackage newPackage,
2069 @NonNull AndroidPackage oldPackage,
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002070 @NonNull ArrayList<String> allPackageNames,
2071 @NonNull PermissionCallback permissionCallback) {
Winson14ff7172019-10-23 10:42:27 -07002072 final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002073 final ArrayMap<String, String> oldPermissionNameToGroupName
2074 = new ArrayMap<>(numOldPackagePermissions);
2075
2076 for (int i = 0; i < numOldPackagePermissions; i++) {
Winson14ff7172019-10-23 10:42:27 -07002077 final ParsedPermission permission = oldPackage.getPermissions().get(i);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002078
Winson14ff7172019-10-23 10:42:27 -07002079 if (permission.parsedPermissionGroup != null) {
2080 oldPermissionNameToGroupName.put(permission.getName(),
2081 permission.parsedPermissionGroup.getName());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002082 }
2083 }
2084
Todd Kennedyc971a452019-07-08 16:04:52 -07002085 final int callingUid = Binder.getCallingUid();
Winson14ff7172019-10-23 10:42:27 -07002086 final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002087 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
2088 newPermissionNum++) {
Winson14ff7172019-10-23 10:42:27 -07002089 final ParsedPermission newPermission =
2090 newPackage.getPermissions().get(newPermissionNum);
2091 final int newProtection = newPermission.getProtection();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002092
2093 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
Winson14ff7172019-10-23 10:42:27 -07002094 final String permissionName = newPermission.getName();
2095 final String newPermissionGroupName = newPermission.parsedPermissionGroup == null
2096 ? null : newPermission.parsedPermissionGroup.getName();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002097 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
2098 permissionName);
2099
2100 if (newPermissionGroupName != null
2101 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
2102 final int[] userIds = mUserManagerInt.getUserIds();
2103 final int numUserIds = userIds.length;
2104 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2105 final int userId = userIds[userIdNum];
2106
2107 final int numPackages = allPackageNames.size();
2108 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
2109 final String packageName = allPackageNames.get(packageNum);
Hai Zhang3b049a52019-08-16 15:37:46 -07002110 final int permissionState = checkPermission(permissionName, packageName,
2111 userId);
Todd Kennedyca1ea172019-07-03 15:02:28 -07002112 if (permissionState == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002113 EventLog.writeEvent(0x534e4554, "72710897",
Winson14ff7172019-10-23 10:42:27 -07002114 newPackage.getUid(),
Koji Fukuiacae3ef2018-05-09 11:38:01 +09002115 "Revoking permission " + permissionName +
2116 " from package " + packageName +
2117 " as the group changed from " + oldPermissionGroupName +
2118 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002119
2120 try {
Todd Kennedyc971a452019-07-08 16:04:52 -07002121 revokeRuntimePermissionInternal(permissionName, packageName,
2122 false, callingUid, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002123 } catch (IllegalArgumentException e) {
2124 Slog.e(TAG, "Could not revoke " + permissionName + " from "
2125 + packageName, e);
2126 }
2127 }
2128 }
2129 }
2130 }
2131 }
2132 }
2133 }
2134
Winson14ff7172019-10-23 10:42:27 -07002135 private void addAllPermissions(AndroidPackage pkg, boolean chatty) {
2136 final int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002137 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002138 ParsedPermission p = pkg.getPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002139
2140 // Assume by default that we did not install this permission into the system.
Winson14ff7172019-10-23 10:42:27 -07002141 p.flags &= ~PermissionInfo.FLAG_INSTALLED;
Todd Kennedyc8423932017-10-05 08:58:36 -07002142
Todd Kennedyc8423932017-10-05 08:58:36 -07002143 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002144 // Now that permission groups have a special meaning, we ignore permission
2145 // groups for legacy apps to prevent unexpected behavior. In particular,
2146 // permissions for one app being granted to someone just because they happen
2147 // to be in a group defined by another app (before this had no implications).
Winson14ff7172019-10-23 10:42:27 -07002148 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
2149 p.parsedPermissionGroup = mSettings.mPermissionGroups.get(p.getGroup());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002150 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002151 if (DEBUG_PERMISSIONS
Winson14ff7172019-10-23 10:42:27 -07002152 && p.getGroup() != null && p.parsedPermissionGroup == null) {
2153 Slog.i(TAG, "Permission " + p.getName() + " from package "
2154 + p.getPackageName() + " in an unknown group " + p.getGroup());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002155 }
2156 }
2157
Todd Kennedyc8423932017-10-05 08:58:36 -07002158 if (p.tree) {
2159 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002160 mPackageManagerInt,
2161 mSettings.getPermissionTreeLocked(p.getName()), p, pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002162 mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002163 mSettings.putPermissionTreeLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002164 } else {
2165 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002166 mPackageManagerInt,
2167 mSettings.getPermissionLocked(p.getName()),
Todd Kennedyc8423932017-10-05 08:58:36 -07002168 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002169 mSettings.putPermissionLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002170 }
2171 }
2172 }
2173 }
2174
Winson14ff7172019-10-23 10:42:27 -07002175 private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
2176 final int N = ArrayUtils.size(pkg.getPermissionGroups());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002177 StringBuilder r = null;
2178 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002179 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
2180 final ParsedPermissionGroup cur = mSettings.mPermissionGroups.get(pg.getName());
2181 final String curPackageName = (cur == null) ? null : cur.getPackageName();
2182 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
Todd Kennedy460f28c2017-10-06 13:46:22 -07002183 if (cur == null || isPackageUpdate) {
Winson14ff7172019-10-23 10:42:27 -07002184 mSettings.mPermissionGroups.put(pg.getName(), pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002185 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002186 if (r == null) {
2187 r = new StringBuilder(256);
2188 } else {
2189 r.append(' ');
2190 }
2191 if (isPackageUpdate) {
2192 r.append("UPD:");
2193 }
Winson14ff7172019-10-23 10:42:27 -07002194 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002195 }
2196 } else {
Winson14ff7172019-10-23 10:42:27 -07002197 Slog.w(TAG, "Permission group " + pg.getName() + " from package "
2198 + pg.getPackageName() + " ignored: original from "
2199 + cur.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002200 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002201 if (r == null) {
2202 r = new StringBuilder(256);
2203 } else {
2204 r.append(' ');
2205 }
2206 r.append("DUP:");
Winson14ff7172019-10-23 10:42:27 -07002207 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002208 }
2209 }
2210 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002211 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002212 Log.d(TAG, " Permission Groups: " + r);
2213 }
2214
2215 }
2216
Winson14ff7172019-10-23 10:42:27 -07002217 private void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002218 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07002219 int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002220 StringBuilder r = null;
2221 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002222 ParsedPermission p = pkg.getPermissions().get(i);
2223 BasePermission bp = mSettings.mPermissions.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002224 if (bp == null) {
Winson14ff7172019-10-23 10:42:27 -07002225 bp = mSettings.mPermissionTrees.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002226 }
2227 if (bp != null && bp.isPermission(p)) {
2228 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002229 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002230 if (r == null) {
2231 r = new StringBuilder(256);
2232 } else {
2233 r.append(' ');
2234 }
Winson14ff7172019-10-23 10:42:27 -07002235 r.append(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002236 }
2237 }
2238 if (p.isAppOp()) {
2239 ArraySet<String> appOpPkgs =
Winson14ff7172019-10-23 10:42:27 -07002240 mSettings.mAppOpPermissionPackages.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002241 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002242 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002243 }
2244 }
2245 }
2246 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002247 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002248 }
2249
Winson14ff7172019-10-23 10:42:27 -07002250 N = pkg.getRequestedPermissions().size();
Todd Kennedyc8423932017-10-05 08:58:36 -07002251 r = null;
2252 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002253 String perm = pkg.getRequestedPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002254 if (mSettings.isPermissionAppOp(perm)) {
2255 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
2256 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002257 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002258 if (appOpPkgs.isEmpty()) {
2259 mSettings.mAppOpPermissionPackages.remove(perm);
2260 }
2261 }
2262 }
2263 }
2264 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002265 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002266 }
2267 }
2268 }
2269
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002270 /**
2271 * Restore the permission state for a package.
2272 *
2273 * <ul>
2274 * <li>During boot the state gets restored from the disk</li>
2275 * <li>During app update the state gets restored from the last version of the app</li>
2276 * </ul>
2277 *
2278 * <p>This restores the permission state for all users.
2279 *
2280 * @param pkg the package the permissions belong to
2281 * @param replace if the package is getting replaced (this might change the requested
2282 * permissions of this package)
2283 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
2284 * @param callback Result call back
2285 */
Winson14ff7172019-10-23 10:42:27 -07002286 private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002287 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002288 // IMPORTANT: There are two types of permissions: install and runtime.
2289 // Install time permissions are granted when the app is installed to
2290 // all device users and users added in the future. Runtime permissions
2291 // are granted at runtime explicitly to specific users. Normal and signature
2292 // protected permissions are install time permissions. Dangerous permissions
2293 // are install permissions if the app's target SDK is Lollipop MR1 or older,
2294 // otherwise they are runtime permissions. This function does not manage
2295 // runtime permissions except for the case an app targeting Lollipop MR1
2296 // being upgraded to target a newer SDK, in which case dangerous permissions
2297 // are transformed from install time to runtime ones.
2298
Winson14ff7172019-10-23 10:42:27 -07002299 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2300 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002301 if (ps == null) {
2302 return;
2303 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002304
2305 final PermissionsState permissionsState = ps.getPermissionsState();
2306 PermissionsState origPermissions = permissionsState;
2307
2308 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2309
2310 boolean runtimePermissionsRevoked = false;
2311 int[] updatedUserIds = EMPTY_INT_ARRAY;
2312
2313 boolean changedInstallPermission = false;
2314
2315 if (replace) {
2316 ps.setInstallPermissionsFixed(false);
2317 if (!ps.isSharedUser()) {
2318 origPermissions = new PermissionsState(permissionsState);
2319 permissionsState.reset();
2320 } else {
2321 // We need to know only about runtime permission changes since the
2322 // calling code always writes the install permissions state but
2323 // the runtime ones are written only if changed. The only cases of
2324 // changed runtime permissions here are promotion of an install to
2325 // runtime and revocation of a runtime from a shared user.
2326 synchronized (mLock) {
2327 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
2328 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
2329 if (!ArrayUtils.isEmpty(updatedUserIds)) {
2330 runtimePermissionsRevoked = true;
2331 }
2332 }
2333 }
2334 }
2335
2336 permissionsState.setGlobalGids(mGlobalGids);
2337
2338 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002339 ArraySet<String> newImplicitPermissions = new ArraySet<>();
2340
Winson14ff7172019-10-23 10:42:27 -07002341 final int N = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002342 for (int i = 0; i < N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002343 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002344 final BasePermission bp = mSettings.getPermissionLocked(permName);
2345 final boolean appSupportsRuntimePermissions =
Winson14ff7172019-10-23 10:42:27 -07002346 pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +01002347 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002348
2349 if (DEBUG_INSTALL) {
Winson14ff7172019-10-23 10:42:27 -07002350 Log.i(TAG, "Package " + pkg.getPackageName()
2351 + " checking " + permName + ": " + bp);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002352 }
2353
2354 if (bp == null || bp.getSourcePackageSetting() == null) {
Winson14ff7172019-10-23 10:42:27 -07002355 if (packageOfInterest == null || packageOfInterest.equals(
2356 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002357 if (DEBUG_PERMISSIONS) {
2358 Slog.i(TAG, "Unknown permission " + permName
Winson14ff7172019-10-23 10:42:27 -07002359 + " in package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002360 }
2361 }
2362 continue;
2363 }
2364
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002365 // Cache newImplicitPermissions before modifing permissionsState as for the shared
2366 // uids the original and new state are the same object
2367 if (!origPermissions.hasRequestedPermission(permName)
Winson14ff7172019-10-23 10:42:27 -07002368 && (pkg.getImplicitPermissions().contains(permName)
Zimuzoe6411402019-05-13 16:32:57 +01002369 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
Winson14ff7172019-10-23 10:42:27 -07002370 if (pkg.getImplicitPermissions().contains(permName)) {
Zimuzoe6411402019-05-13 16:32:57 +01002371 // If permName is an implicit permission, try to auto-grant
2372 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002373
Zimuzoe6411402019-05-13 16:32:57 +01002374 if (DEBUG_PERMISSIONS) {
Winson14ff7172019-10-23 10:42:27 -07002375 Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002376 }
2377 } else {
2378 // Special case for Activity Recognition permission. Even if AR permission
2379 // is not an implicit permission we want to add it to the list (try to
2380 // auto-grant it) if the app was installed on a device before AR permission
2381 // was split, regardless of if the app now requests the new AR permission
2382 // or has updated its target SDK and AR is no longer implicit to it.
2383 // This is a compatibility workaround for apps when AR permission was
2384 // split in Q.
Anthony Hughde787d42019-08-22 15:35:48 -07002385 final List<SplitPermissionInfoParcelable> permissionList =
2386 getSplitPermissions();
2387 int numSplitPerms = permissionList.size();
Zimuzoe6411402019-05-13 16:32:57 +01002388 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07002389 SplitPermissionInfoParcelable sp = permissionList.get(splitPermNum);
Zimuzoe6411402019-05-13 16:32:57 +01002390 String splitPermName = sp.getSplitPermission();
2391 if (sp.getNewPermissions().contains(permName)
2392 && origPermissions.hasInstallPermission(splitPermName)) {
2393 upgradedActivityRecognitionPermission = splitPermName;
2394 newImplicitPermissions.add(permName);
2395
2396 if (DEBUG_PERMISSIONS) {
2397 Slog.i(TAG, permName + " is newly added for "
Winson14ff7172019-10-23 10:42:27 -07002398 + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002399 }
2400 break;
2401 }
2402 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002403 }
2404 }
2405
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002406 // Limit ephemeral apps to ephemeral allowed permissions.
Winson14ff7172019-10-23 10:42:27 -07002407 if (pkg.isInstantApp() && !bp.isInstant()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002408 if (DEBUG_PERMISSIONS) {
2409 Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
Winson14ff7172019-10-23 10:42:27 -07002410 + " for package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002411 }
2412 continue;
2413 }
2414
2415 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
2416 if (DEBUG_PERMISSIONS) {
2417 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
Winson14ff7172019-10-23 10:42:27 -07002418 + " for package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002419 }
2420 continue;
2421 }
2422
2423 final String perm = bp.getName();
2424 boolean allowedSig = false;
2425 int grant = GRANT_DENIED;
2426
2427 // Keep track of app op permissions.
2428 if (bp.isAppOp()) {
Winson14ff7172019-10-23 10:42:27 -07002429 mSettings.addAppOpPackage(perm, pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002430 }
2431
2432 if (bp.isNormal()) {
2433 // For all apps normal permissions are install time ones.
2434 grant = GRANT_INSTALL;
2435 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01002436 if (origPermissions.hasInstallPermission(bp.getName())
2437 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002438 // Before Q we represented some runtime permissions as install permissions,
2439 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002440 grant = GRANT_UPGRADE;
2441 } else {
2442 // For modern apps keep runtime permissions unchanged.
2443 grant = GRANT_RUNTIME;
2444 }
2445 } else if (bp.isSignature()) {
2446 // For all apps signature permissions are install time ones.
2447 allowedSig = grantSignaturePermission(perm, pkg, bp, origPermissions);
2448 if (allowedSig) {
2449 grant = GRANT_INSTALL;
2450 }
2451 }
2452
2453 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002454 Slog.i(TAG, "Considering granting permission " + perm + " to package "
Winson14ff7172019-10-23 10:42:27 -07002455 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002456 }
2457
2458 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002459 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002460 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002461 // we can't add any new permissions to it. Runtime
2462 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002463 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
2464 // Except... if this is a permission that was added
2465 // to the platform (note: need to only do this when
2466 // updating the platform).
2467 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
2468 grant = GRANT_DENIED;
2469 }
2470 }
2471 }
2472
2473 switch (grant) {
2474 case GRANT_INSTALL: {
2475 // Revoke this as runtime permission to handle the case of
2476 // a runtime permission being downgraded to an install one.
2477 // Also in permission review mode we keep dangerous permissions
2478 // for legacy apps
2479 for (int userId : UserManagerService.getInstance().getUserIds()) {
2480 if (origPermissions.getRuntimePermissionState(
2481 perm, userId) != null) {
2482 // Revoke the runtime permission and clear the flags.
2483 origPermissions.revokeRuntimePermission(bp, userId);
2484 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002485 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002486 // If we revoked a permission permission, we have to write.
2487 updatedUserIds = ArrayUtils.appendInt(
2488 updatedUserIds, userId);
2489 }
2490 }
2491 // Grant an install permission.
2492 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002493 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002494 changedInstallPermission = true;
2495 }
2496 } break;
2497
2498 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002499 boolean hardRestricted = bp.isHardRestricted();
2500 boolean softRestricted = bp.isSoftRestricted();
2501
Philip P. Moltmann48456672019-01-20 13:14:03 -08002502 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002503 // If permission policy is not ready we don't deal with restricted
2504 // permissions as the policy may whitelist some permissions. Once
2505 // the policy is initialized we would re-evaluate permissions.
2506 final boolean permissionPolicyInitialized =
2507 mPermissionPolicyInternal != null
2508 && mPermissionPolicyInternal.isInitialized(userId);
2509
Philip P. Moltmann48456672019-01-20 13:14:03 -08002510 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002511 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002512 int flags = permState != null ? permState.getFlags() : 0;
2513
2514 boolean wasChanged = false;
2515
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002516 boolean restrictionExempt =
2517 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002518 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2519 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2520 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2521
Philip P. Moltmann48456672019-01-20 13:14:03 -08002522 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002523 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002524 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002525 if (!restrictionExempt) {
2526 if (permState != null && permState.isGranted()
2527 && permissionsState.revokeRuntimePermission(
2528 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2529 wasChanged = true;
2530 }
2531 if (!restrictionApplied) {
2532 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2533 wasChanged = true;
2534 }
2535 }
2536 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002537 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002538 // Regardless if granted set the restriction flag as it
2539 // may affect app treatment based on this permission.
2540 if (!restrictionExempt && !restrictionApplied) {
2541 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2542 wasChanged = true;
2543 }
2544 }
2545
Philip P. Moltmann48456672019-01-20 13:14:03 -08002546 // Remove review flag as it is not necessary anymore
2547 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2548 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2549 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002550 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002551
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002552 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2553 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002554 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002555 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002556 } else if (!permissionPolicyInitialized
2557 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002558 if (permState != null && permState.isGranted()) {
2559 if (permissionsState.grantRuntimePermission(bp, userId)
2560 == PERMISSION_OPERATION_FAILURE) {
2561 wasChanged = true;
2562 }
2563 }
2564 }
2565 } else {
2566 if (permState == null) {
2567 // New permission
2568 if (PLATFORM_PACKAGE_NAME.equals(
2569 bp.getSourcePackageName())) {
2570 if (!bp.isRemoved()) {
2571 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002572 | FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002573 wasChanged = true;
2574 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002575 }
2576 }
2577
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002578 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2579 && permissionsState.grantRuntimePermission(bp, userId)
2580 != PERMISSION_OPERATION_FAILURE) {
2581 wasChanged = true;
2582 }
2583
2584 // If legacy app always grant the permission but if restricted
2585 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002586 if (permissionPolicyInitialized
2587 && (hardRestricted || softRestricted)
2588 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002589 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2590 wasChanged = true;
2591 }
2592 }
2593
2594 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002595 if (permissionPolicyInitialized) {
2596 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2597 if (restrictionApplied) {
2598 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2599 // Dropping restriction on a legacy app implies a review
2600 if (!appSupportsRuntimePermissions) {
2601 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2602 }
2603 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002604 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002605 }
2606 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002607
2608 if (wasChanged) {
2609 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2610 }
2611
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002612 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002613 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002614 }
2615 } break;
2616
2617 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002618 // Upgrade from Pre-Q to Q permission model. Make all permissions
2619 // runtime
2620 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002621 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002622 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002623
Zimuzoe6411402019-05-13 16:32:57 +01002624 BasePermission bpToRevoke =
2625 upgradedActivityRecognitionPermission == null
2626 ? bp : mSettings.getPermissionLocked(
2627 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002628 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01002629 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08002630 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01002631 origPermissions.updatePermissionFlags(bpToRevoke,
2632 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002633 (MASK_PERMISSION_FLAGS_ALL
2634 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002635 changedInstallPermission = true;
2636 }
2637
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002638 boolean hardRestricted = bp.isHardRestricted();
2639 boolean softRestricted = bp.isSoftRestricted();
2640
Philip P. Moltmann48456672019-01-20 13:14:03 -08002641 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002642 // If permission policy is not ready we don't deal with restricted
2643 // permissions as the policy may whitelist some permissions. Once
2644 // the policy is initialized we would re-evaluate permissions.
2645 final boolean permissionPolicyInitialized =
2646 mPermissionPolicyInternal != null
2647 && mPermissionPolicyInternal.isInitialized(userId);
2648
Philip P. Moltmann48456672019-01-20 13:14:03 -08002649 boolean wasChanged = false;
2650
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002651 boolean restrictionExempt =
2652 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002653 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2654 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2655 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2656
Philip P. Moltmann48456672019-01-20 13:14:03 -08002657 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002658 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002659 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002660 if (!restrictionExempt) {
2661 if (permState != null && permState.isGranted()
2662 && permissionsState.revokeRuntimePermission(
2663 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2664 wasChanged = true;
2665 }
2666 if (!restrictionApplied) {
2667 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2668 wasChanged = true;
2669 }
2670 }
2671 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002672 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002673 // Regardless if granted set the restriction flag as it
2674 // may affect app treatment based on this permission.
2675 if (!restrictionExempt && !restrictionApplied) {
2676 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2677 wasChanged = true;
2678 }
2679 }
2680
Philip P. Moltmann48456672019-01-20 13:14:03 -08002681 // Remove review flag as it is not necessary anymore
2682 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2683 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2684 wasChanged = true;
2685 }
2686
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002687 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2688 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002689 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002690 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002691 } else if (!permissionPolicyInitialized ||
2692 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002693 if (permissionsState.grantRuntimePermission(bp, userId) !=
2694 PERMISSION_OPERATION_FAILURE) {
2695 wasChanged = true;
2696 }
2697 }
2698 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002699 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2700 && permissionsState.grantRuntimePermission(bp,
2701 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002702 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2703 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002704 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002705
2706 // If legacy app always grant the permission but if restricted
2707 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002708 if (permissionPolicyInitialized
2709 && (hardRestricted || softRestricted)
2710 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002711 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2712 wasChanged = true;
2713 }
2714 }
2715
2716 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002717 if (permissionPolicyInitialized) {
2718 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2719 if (restrictionApplied) {
2720 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2721 // Dropping restriction on a legacy app implies a review
2722 if (!appSupportsRuntimePermissions) {
2723 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2724 }
2725 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002726 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002727 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002728 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002729
2730 if (wasChanged) {
2731 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2732 }
2733
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002734 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002735 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002736 }
2737 } break;
2738
2739 default: {
2740 if (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002741 || packageOfInterest.equals(pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002742 if (DEBUG_PERMISSIONS) {
2743 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002744 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002745 + " because it was previously installed without");
2746 }
2747 }
2748 } break;
2749 }
2750 } else {
2751 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002752 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002753 // Also drop the permission flags.
2754 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002755 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002756 changedInstallPermission = true;
Nate Myrened67bdd2019-05-07 10:32:22 -07002757 if (DEBUG_PERMISSIONS) {
2758 Slog.i(TAG, "Un-granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002759 + " from package " + pkg.getPackageName()
Nate Myrened67bdd2019-05-07 10:32:22 -07002760 + " (protectionLevel=" + bp.getProtectionLevel()
Winson14ff7172019-10-23 10:42:27 -07002761 + " flags=0x" + Integer.toHexString(pkg.getFlags())
Nate Myrened67bdd2019-05-07 10:32:22 -07002762 + ")");
2763 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002764 } else if (bp.isAppOp()) {
2765 // Don't print warning for app op permissions, since it is fine for them
2766 // not to be granted, there is a UI for the user to decide.
2767 if (DEBUG_PERMISSIONS
2768 && (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002769 || packageOfInterest.equals(pkg.getPackageName()))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002770 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002771 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002772 + " (protectionLevel=" + bp.getProtectionLevel()
Winson14ff7172019-10-23 10:42:27 -07002773 + " flags=0x" + Integer.toHexString(pkg.getFlags())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002774 + ")");
2775 }
2776 }
2777 }
2778 }
2779
2780 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
2781 !ps.isSystem() || ps.isUpdatedSystem()) {
2782 // This is the first that we have heard about this package, so the
2783 // permissions we have now selected are fixed until explicitly
2784 // changed.
2785 ps.setInstallPermissionsFixed(true);
2786 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002787
2788 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
2789 updatedUserIds);
2790 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002791 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002792 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002793 }
2794
2795 // Persist the runtime permissions state for users with changes. If permissions
2796 // were revoked because no app in the shared user declares them we have to
2797 // write synchronously to avoid losing runtime permissions state.
2798 if (callback != null) {
2799 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
2800 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002801
2802 for (int userId : updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07002803 notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002804 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002805 }
2806
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002807 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002808 * Revoke permissions that are not implicit anymore and that have
2809 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
2810 *
2811 * @param ps The state of the permissions of the package
2812 * @param pkg The package that is currently looked at
2813 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
2814 * for a user is changed.
2815 *
2816 * @return The updated value of the {@code updatedUserIds} parameter
2817 */
2818 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
Winson14ff7172019-10-23 10:42:27 -07002819 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002820 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07002821 String pkgName = pkg.getPackageName();
2822 boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08002823 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002824
2825 int[] users = UserManagerService.getInstance().getUserIds();
2826 int numUsers = users.length;
2827 for (int i = 0; i < numUsers; i++) {
2828 int userId = users[i];
2829
2830 for (String permission : ps.getPermissions(userId)) {
Winson14ff7172019-10-23 10:42:27 -07002831 if (!pkg.getImplicitPermissions().contains(permission)) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002832 if (!ps.hasInstallPermission(permission)) {
2833 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
2834
2835 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
2836 BasePermission bp = mSettings.getPermissionLocked(permission);
2837
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08002838 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002839
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002840 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
2841 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08002842 int revokeResult = ps.revokeRuntimePermission(bp, userId);
2843 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
2844 if (DEBUG_PERMISSIONS) {
2845 Slog.i(TAG, "Revoking runtime permission "
2846 + permission + " for " + pkgName
2847 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002848 }
2849 }
2850
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08002851 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002852 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08002853
2854 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
2855 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002856 }
2857 }
2858 }
2859 }
2860 }
2861
2862 return updatedUserIds;
2863 }
2864
2865 /**
2866 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
2867 *
2868 * <p>A single new permission can be split off from several source permissions. In this case
2869 * the most leniant state is inherited.
2870 *
2871 * <p>Warning: This does not handle foreground / background permissions
2872 *
2873 * @param sourcePerms The permissions to inherit from
2874 * @param newPerm The permission to inherit to
2875 * @param ps The permission state of the package
2876 * @param pkg The package requesting the permissions
2877 * @param userId The user the permission belongs to
2878 */
2879 private void inheritPermissionStateToNewImplicitPermissionLocked(
2880 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
Winson14ff7172019-10-23 10:42:27 -07002881 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002882 @UserIdInt int userId) {
Winson14ff7172019-10-23 10:42:27 -07002883 String pkgName = pkg.getPackageName();
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002884 boolean isGranted = false;
2885 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002886
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002887 int numSourcePerm = sourcePerms.size();
2888 for (int i = 0; i < numSourcePerm; i++) {
2889 String sourcePerm = sourcePerms.valueAt(i);
2890 if ((ps.hasRuntimePermission(sourcePerm, userId))
2891 || ps.hasInstallPermission(sourcePerm)) {
2892 if (!isGranted) {
2893 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002894 }
2895
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002896 isGranted = true;
2897 flags |= ps.getPermissionFlags(sourcePerm, userId);
2898 } else {
2899 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08002900 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002901 }
2902 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002903 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07002904
2905 if (isGranted) {
2906 if (DEBUG_PERMISSIONS) {
2907 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
2908 + " for " + pkgName);
2909 }
2910
2911 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
2912 }
2913
2914 // Add permission flags
2915 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002916 }
2917
2918 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002919 * When the app has requested legacy storage we might need to update
2920 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
2921 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
2922 *
2923 * @param pkg The package for which the permissions are updated
2924 * @param replace If the app is being replaced
2925 * @param updatedUserIds The ids of the users that already changed.
2926 *
2927 * @return The ids of the users that are changed
2928 */
2929 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
Winson14ff7172019-10-23 10:42:27 -07002930 @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) {
2931 if (replace && pkg.hasRequestedLegacyExternalStorage() && (
2932 pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
2933 || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
Philip P. Moltmann74065c82019-05-15 10:46:32 -07002934 return UserManagerService.getInstance().getUserIds();
2935 }
2936
2937 return updatedUserIds;
2938 }
2939
2940 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002941 * Set the state of a implicit permission that is seen for the first time.
2942 *
2943 * @param origPs The permission state of the package before the split
2944 * @param ps The new permission state
2945 * @param pkg The package the permission belongs to
2946 * @param updatedUserIds List of users for which the permission state has already been changed
2947 *
2948 * @return List of users for which the permission state has been changed
2949 */
2950 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
2951 @NonNull PermissionsState origPs,
Winson14ff7172019-10-23 10:42:27 -07002952 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002953 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002954 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07002955 String pkgName = pkg.getPackageName();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002956 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
2957
Anthony Hughde787d42019-08-22 15:35:48 -07002958 final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions();
2959 int numSplitPerms = permissionList.size();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002960 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07002961 SplitPermissionInfoParcelable spi = permissionList.get(splitPermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002962
2963 List<String> newPerms = spi.getNewPermissions();
2964 int numNewPerms = newPerms.size();
2965 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
2966 String newPerm = newPerms.get(newPermNum);
2967
2968 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
2969 if (splitPerms == null) {
2970 splitPerms = new ArraySet<>();
2971 newToSplitPerms.put(newPerm, splitPerms);
2972 }
2973
2974 splitPerms.add(spi.getSplitPermission());
2975 }
2976 }
2977
2978 int numNewImplicitPerms = newImplicitPermissions.size();
2979 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
2980 newImplicitPermNum++) {
2981 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
2982 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
2983
2984 if (sourcePerms != null) {
2985 if (!ps.hasInstallPermission(newPerm)) {
2986 BasePermission bp = mSettings.getPermissionLocked(newPerm);
2987
2988 int[] users = UserManagerService.getInstance().getUserIds();
2989 int numUsers = users.length;
2990 for (int userNum = 0; userNum < numUsers; userNum++) {
2991 int userId = users[userNum];
2992
Zimuzoe6411402019-05-13 16:32:57 +01002993 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
2994 ps.updatePermissionFlags(bp, userId,
2995 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
2996 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
2997 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002998 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2999
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003000 boolean inheritsFromInstallPerm = false;
3001 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
3002 sourcePermNum++) {
3003 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
3004 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003005 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003006 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003007 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003008
3009 if (!origPs.hasRequestedPermission(sourcePerms)
3010 && !inheritsFromInstallPerm) {
3011 // Both permissions are new so nothing to inherit.
3012 if (DEBUG_PERMISSIONS) {
3013 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
3014 + " for " + pkgName + " as split permission is also new");
3015 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003016 } else {
3017 // Inherit from new install or existing runtime permissions
3018 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
3019 newPerm, ps, pkg, userId);
3020 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003021 }
3022 }
3023 }
3024 }
3025
3026 return updatedUserIds;
3027 }
3028
Anthony Hughde787d42019-08-22 15:35:48 -07003029 @Override
3030 public List<SplitPermissionInfoParcelable> getSplitPermissions() {
3031 return PermissionManager.splitPermissionInfoListToParcelableList(
3032 SystemConfig.getInstance().getSplitPermissions());
3033 }
3034
Evan Seversonb252d8b2019-11-20 08:41:33 -08003035 private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
3036 synchronized (mLock) {
3037 OneTimePermissionUserManager oneTimePermissionUserManager =
3038 mOneTimePermissionUserManagers.get(userId);
3039 if (oneTimePermissionUserManager == null) {
3040 oneTimePermissionUserManager = new OneTimePermissionUserManager(
3041 mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0));
3042 mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager);
3043 }
3044 return oneTimePermissionUserManager;
3045 }
3046 }
3047
3048 @Override
3049 public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
3050 long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) {
Evan Severson43e17e02020-01-03 10:04:38 -08003051 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3052 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3053 + " to register permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003054 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003055
3056 long token = Binder.clearCallingIdentity();
3057 try {
3058 getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
3059 timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
3060 } finally {
3061 Binder.restoreCallingIdentity(token);
3062 }
3063 }
3064
3065 @Override
3066 public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
Evan Severson43e17e02020-01-03 10:04:38 -08003067 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3068 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3069 + " to remove permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003070 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003071
3072 long token = Binder.clearCallingIdentity();
3073 try {
3074 getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName);
3075 } finally {
3076 Binder.restoreCallingIdentity(token);
3077 }
3078 }
3079
Winson14ff7172019-10-23 10:42:27 -07003080 private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003081 boolean allowed = false;
3082 final int NP = PackageParser.NEW_PERMISSIONS.length;
3083 for (int ip=0; ip<NP; ip++) {
3084 final PackageParser.NewPermissionInfo npi
3085 = PackageParser.NEW_PERMISSIONS[ip];
3086 if (npi.name.equals(perm)
Winson14ff7172019-10-23 10:42:27 -07003087 && pkg.getTargetSdkVersion() < npi.sdkVersion) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003088 allowed = true;
3089 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
Winson14ff7172019-10-23 10:42:27 -07003090 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003091 break;
3092 }
3093 }
3094 return allowed;
3095 }
3096
3097 /**
3098 * Determines whether a package is whitelisted for a particular privapp permission.
3099 *
3100 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
3101 *
3102 * <p>This handles parent/child apps.
3103 */
Winson14ff7172019-10-23 10:42:27 -07003104 private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) {
3105 ArraySet<String> wlPermissions;
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003106 if (pkg.isVendor()) {
3107 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003108 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003109 } else if (pkg.isProduct()) {
3110 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003111 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName());
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003112 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003113 wlPermissions =
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003114 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Winson14ff7172019-10-23 10:42:27 -07003115 pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003116 } else {
Winson14ff7172019-10-23 10:42:27 -07003117 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003118 }
Winson14ff7172019-10-23 10:42:27 -07003119
3120 return wlPermissions != null && wlPermissions.contains(perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003121 }
3122
Winson14ff7172019-10-23 10:42:27 -07003123 private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003124 BasePermission bp, PermissionsState origPermissions) {
3125 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09003126 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
3127 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003128 boolean privappPermissionsDisable =
3129 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
3130 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07003131 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003132 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
3133 && !platformPackage && platformPermission) {
3134 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003135 // Only report violations for apps on system image
3136 if (!mSystemReady && !pkg.isUpdatedSystemApp()) {
3137 // it's only a reportable violation if the permission isn't explicitly denied
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003138 ArraySet<String> deniedPermissions = null;
3139 if (pkg.isVendor()) {
3140 deniedPermissions = SystemConfig.getInstance()
Winson14ff7172019-10-23 10:42:27 -07003141 .getVendorPrivAppDenyPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003142 } else if (pkg.isProduct()) {
3143 deniedPermissions = SystemConfig.getInstance()
Winson14ff7172019-10-23 10:42:27 -07003144 .getProductPrivAppDenyPermissions(pkg.getPackageName());
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003145 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003146 deniedPermissions = SystemConfig.getInstance()
Winson14ff7172019-10-23 10:42:27 -07003147 .getSystemExtPrivAppDenyPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003148 } else {
3149 deniedPermissions = SystemConfig.getInstance()
Winson14ff7172019-10-23 10:42:27 -07003150 .getPrivAppDenyPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003151 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003152 final boolean permissionViolation =
3153 deniedPermissions == null || !deniedPermissions.contains(perm);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003154 if (permissionViolation) {
3155 Slog.w(TAG, "Privileged permission " + perm + " for package "
Winson14ff7172019-10-23 10:42:27 -07003156 + pkg.getPackageName() + " (" + pkg.getCodePath()
Philip P. Moltmann384db3f2019-07-12 09:00:05 -07003157 + ") not in privapp-permissions whitelist");
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003158
3159 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3160 if (mPrivappPermissionsViolations == null) {
3161 mPrivappPermissionsViolations = new ArraySet<>();
3162 }
Philip P. Moltmann384db3f2019-07-12 09:00:05 -07003163 mPrivappPermissionsViolations.add(
Winson14ff7172019-10-23 10:42:27 -07003164 pkg.getPackageName() + " (" + pkg.getCodePath() + "): " + perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003165 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003166 } else {
3167 return false;
3168 }
3169 }
3170 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3171 return false;
3172 }
3173 }
3174 }
Chen Xu45c183d2019-10-07 00:24:41 -07003175 // expect single system package
3176 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
3177 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
Winson655a5b92019-10-23 10:49:32 -07003178 final AndroidPackage systemPackage =
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003179 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003180
3181 // check if the package is allow to use this signature permission. A package is allowed to
3182 // use a signature permission if:
3183 // - it has the same set of signing certificates as the source package
3184 // - or its signing certificate was rotated from the source package's certificate
3185 // - or its signing certificate is a previous signing certificate of the defining
3186 // package, and the defining package still trusts the old certificate for permissions
3187 // - or it shares the above relationships with the system package
3188 boolean allowed =
Winson14ff7172019-10-23 10:42:27 -07003189 pkg.getSigningDetails().hasAncestorOrSelf(
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003190 bp.getSourcePackageSetting().getSigningDetails())
3191 || bp.getSourcePackageSetting().getSigningDetails().checkCapability(
Winson14ff7172019-10-23 10:42:27 -07003192 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003193 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
Winson14ff7172019-10-23 10:42:27 -07003194 || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
3195 || systemPackage.getSigningDetails().checkCapability(
3196 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003197 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003198 if (!allowed && (privilegedPermission || oemPermission)) {
3199 if (pkg.isSystem()) {
3200 // For updated system applications, a privileged/oem permission
3201 // is granted only if it had been defined by the original application.
3202 if (pkg.isUpdatedSystemApp()) {
Winson14ff7172019-10-23 10:42:27 -07003203 final PackageSetting disabledPs = (PackageSetting) mPackageManagerInt
3204 .getDisabledSystemPackage(pkg.getPackageName());
3205 final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003206 if (disabledPs != null
3207 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
3208 // If the original was granted this permission, we take
3209 // that grant decision as read and propagate it to the
3210 // update.
3211 if ((privilegedPermission && disabledPs.isPrivileged())
3212 || (oemPermission && disabledPs.isOem()
3213 && canGrantOemPermission(disabledPs, perm))) {
3214 allowed = true;
3215 }
3216 } else {
3217 // The system apk may have been updated with an older
3218 // version of the one on the data partition, but which
3219 // granted a new system permission that it didn't have
3220 // before. In this case we do want to allow the app to
3221 // now get the new permission if the ancestral apk is
3222 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07003223 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003224 && isPackageRequestingPermission(disabledPkg, perm)
3225 && ((privilegedPermission && disabledPs.isPrivileged())
3226 || (oemPermission && disabledPs.isOem()
3227 && canGrantOemPermission(disabledPs, perm)))) {
3228 allowed = true;
3229 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003230 }
3231 } else {
Winson14ff7172019-10-23 10:42:27 -07003232 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3233 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003234 allowed = (privilegedPermission && pkg.isPrivileged())
3235 || (oemPermission && pkg.isOem()
3236 && canGrantOemPermission(ps, perm));
3237 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09003238 // In any case, don't grant a privileged permission to privileged vendor apps, if
3239 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
3240 // flag.
3241 if (allowed && privilegedPermission &&
3242 !vendorPrivilegedPermission && pkg.isVendor()) {
3243 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
Winson14ff7172019-10-23 10:42:27 -07003244 + pkg.getPackageName()
3245 + " because it isn't a 'vendorPrivileged' permission.");
Jiyong Park002fdbd2017-02-13 20:50:31 +09003246 allowed = false;
3247 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003248 }
3249 }
3250 if (!allowed) {
3251 if (!allowed
3252 && bp.isPre23()
Winson14ff7172019-10-23 10:42:27 -07003253 && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003254 // If this was a previously normal/dangerous permission that got moved
3255 // to a system permission as part of the runtime permission redesign, then
3256 // we still want to blindly grant it to old apps.
3257 allowed = true;
3258 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07003259 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
3260 // need a separate flag anymore. Hence we need to check which
3261 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003262 if (!allowed && bp.isInstaller()
Chen Xu45c183d2019-10-07 00:24:41 -07003263 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3264 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003265 pkg.getPackageName()) || ArrayUtils.contains(
3266 mPackageManagerInt.getKnownPackageNames(
3267 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
3268 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003269 // If this permission is to be granted to the system installer and
3270 // this app is an installer, then it gets the permission.
3271 allowed = true;
3272 }
3273 if (!allowed && bp.isVerifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003274 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3275 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003276 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003277 // If this permission is to be granted to the system verifier and
3278 // this app is a verifier, then it gets the permission.
3279 allowed = true;
3280 }
3281 if (!allowed && bp.isPreInstalled()
3282 && pkg.isSystem()) {
3283 // Any pre-installed system app is allowed to get this permission.
3284 allowed = true;
3285 }
3286 if (!allowed && bp.isDevelopment()) {
3287 // For development permissions, a development permission
3288 // is granted only if it was already granted.
3289 allowed = origPermissions.hasInstallPermission(perm);
3290 }
3291 if (!allowed && bp.isSetup()
Chen Xu45c183d2019-10-07 00:24:41 -07003292 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3293 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003294 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003295 // If this permission is to be granted to the system setup wizard and
3296 // this app is a setup wizard, then it gets the permission.
3297 allowed = true;
3298 }
Makoto Onuki700feef2018-02-15 10:59:41 -08003299 if (!allowed && bp.isSystemTextClassifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003300 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Makoto Onuki700feef2018-02-15 10:59:41 -08003301 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
Winson655a5b92019-10-23 10:49:32 -07003302 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Makoto Onuki700feef2018-02-15 10:59:41 -08003303 // Special permissions for the system default text classifier.
3304 allowed = true;
3305 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003306 if (!allowed && bp.isConfigurator()
Chen Xu45c183d2019-10-07 00:24:41 -07003307 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3308 PackageManagerInternal.PACKAGE_CONFIGURATOR,
Winson655a5b92019-10-23 10:49:32 -07003309 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003310 // Special permissions for the device configurator.
3311 allowed = true;
3312 }
Varun Shah5f303652018-11-16 18:11:19 -08003313 if (!allowed && bp.isWellbeing()
Chen Xu45c183d2019-10-07 00:24:41 -07003314 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3315 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003316 pkg.getPackageName())) {
Varun Shah5f303652018-11-16 18:11:19 -08003317 // Special permission granted only to the OEM specified wellbeing app
3318 allowed = true;
3319 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07003320 if (!allowed && bp.isDocumenter()
Chen Xu45c183d2019-10-07 00:24:41 -07003321 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3322 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003323 pkg.getPackageName())) {
Jeff Sharkey15707b32018-12-10 12:08:41 -07003324 // If this permission is to be granted to the documenter and
3325 // this app is the documenter, then it gets the permission.
3326 allowed = true;
3327 }
Joe Onorato5a15b552018-12-18 10:40:04 -08003328 if (!allowed && bp.isIncidentReportApprover()
Chen Xu45c183d2019-10-07 00:24:41 -07003329 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Joe Onorato5a15b552018-12-18 10:40:04 -08003330 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
Winson655a5b92019-10-23 10:49:32 -07003331 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Joe Onorato5a15b552018-12-18 10:40:04 -08003332 // If this permission is to be granted to the incident report approver and
3333 // this app is the incident report approver, then it gets the permission.
3334 allowed = true;
3335 }
George Hodulikcd7695d2019-01-29 18:17:05 -08003336 if (!allowed && bp.isAppPredictor()
Chen Xu45c183d2019-10-07 00:24:41 -07003337 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3338 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003339 pkg.getPackageName())) {
George Hodulikcd7695d2019-01-29 18:17:05 -08003340 // Special permissions for the system app predictor.
3341 allowed = true;
3342 }
Chen Xu45c183d2019-10-07 00:24:41 -07003343 if (!allowed && bp.isTelephony()
3344 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3345 PackageManagerInternal.PACKAGE_TELEPHONY, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003346 pkg.getPackageName())) {
Chen Xu45c183d2019-10-07 00:24:41 -07003347 // Special permissions for the system telephony apps.
3348 allowed = true;
3349 }
Eugene Susla1fa23ed02019-07-24 16:30:16 -07003350 if (!allowed && bp.isCompanion()
3351 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3352 PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
3353 pkg.getPackageName())) {
3354 // Special permissions for the system companion device manager.
3355 allowed = true;
3356 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003357 }
3358 return allowed;
3359 }
3360
3361 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
3362 if (!ps.isOem()) {
3363 return false;
3364 }
3365 // all oem permissions must explicitly be granted or denied
3366 final Boolean granted =
3367 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
3368 if (granted == null) {
3369 throw new IllegalStateException("OEM permission" + permission + " requested by package "
3370 + ps.name + " must be explicitly declared granted or not");
3371 }
3372 return Boolean.TRUE == granted;
3373 }
3374
Winson14ff7172019-10-23 10:42:27 -07003375 private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003376 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003377 // Permission review applies only to apps not supporting the new permission model.
Winson14ff7172019-10-23 10:42:27 -07003378 if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003379 return false;
3380 }
3381
3382 // Legacy apps have the permission and get user consent on launch.
Winson14ff7172019-10-23 10:42:27 -07003383 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3384 pkg.getPackageName());
3385 if (ps == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003386 return false;
3387 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003388 final PermissionsState permissionsState = ps.getPermissionsState();
3389 return permissionsState.isPermissionReviewRequired(userId);
3390 }
3391
Winson14ff7172019-10-23 10:42:27 -07003392 private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) {
3393 final int permCount = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003394 for (int j = 0; j < permCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003395 String requestedPermission = pkg.getRequestedPermissions().get(j);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003396 if (permission.equals(requestedPermission)) {
3397 return true;
3398 }
3399 }
3400 return false;
3401 }
3402
Winson14ff7172019-10-23 10:42:27 -07003403 private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003404 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3405 for (int userId : userIds) {
3406 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
3407 callback);
3408 }
3409 }
3410
Winson14ff7172019-10-23 10:42:27 -07003411 private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003412 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
Winson14ff7172019-10-23 10:42:27 -07003413 PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3414 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07003415 if (ps == null) {
3416 return;
3417 }
3418
3419 PermissionsState permissionsState = ps.getPermissionsState();
3420
3421 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3422 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3423
Hai Zhangfa291702019-09-19 16:35:44 -07003424 final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
3425 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
3426
Winson14ff7172019-10-23 10:42:27 -07003427 final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Todd Kennedy0eb97382017-10-03 16:57:22 -07003428 >= Build.VERSION_CODES.M;
3429
Winson14ff7172019-10-23 10:42:27 -07003430 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003431
Winson14ff7172019-10-23 10:42:27 -07003432 for (String permission : pkg.getRequestedPermissions()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003433 final BasePermission bp;
3434 synchronized (mLock) {
3435 bp = mSettings.getPermissionLocked(permission);
3436 }
3437 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
3438 && (!instantApp || bp.isInstant())
3439 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
3440 && (grantedPermissions == null
3441 || ArrayUtils.contains(grantedPermissions, permission))) {
3442 final int flags = permissionsState.getPermissionFlags(permission, userId);
3443 if (supportsRuntimePermissions) {
3444 // Installer cannot change immutable permissions.
3445 if ((flags & immutableFlags) == 0) {
Winson14ff7172019-10-23 10:42:27 -07003446 grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
Todd Kennedyc971a452019-07-08 16:04:52 -07003447 callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003448 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07003449 } else {
Hai Zhangfa291702019-09-19 16:35:44 -07003450 // In permission review mode we clear the review flag and the revoked compat
3451 // flag when we are asked to install the app with all permissions granted.
3452 if ((flags & compatFlags) != 0) {
Winson14ff7172019-10-23 10:42:27 -07003453 updatePermissionFlagsInternal(permission, pkg.getPackageName(), compatFlags,
Hai Zhangfa291702019-09-19 16:35:44 -07003454 0, callingUid, userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003455 }
3456 }
3457 }
3458 }
3459 }
3460
Winson14ff7172019-10-23 10:42:27 -07003461 private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003462 @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
3463 @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003464 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07003465 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003466 if (permissionsState == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003467 return;
3468 }
3469
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003470 ArraySet<String> oldGrantedRestrictedPermissions = null;
3471 boolean updatePermissions = false;
3472
Winson14ff7172019-10-23 10:42:27 -07003473 final int permissionCount = pkg.getRequestedPermissions().size();
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003474 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07003475 final String permissionName = pkg.getRequestedPermissions().get(i);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003476
3477 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003478
Evan Seversoncdcaaaa2019-07-02 10:29:25 -07003479 if (bp == null || !bp.isHardOrSoftRestricted()) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003480 continue;
3481 }
3482
3483 if (permissionsState.hasPermission(permissionName, userId)) {
3484 if (oldGrantedRestrictedPermissions == null) {
3485 oldGrantedRestrictedPermissions = new ArraySet<>();
3486 }
3487 oldGrantedRestrictedPermissions.add(permissionName);
3488 }
3489
3490 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
3491
3492 int newFlags = oldFlags;
3493 int mask = 0;
3494 int whitelistFlagsCopy = whitelistFlags;
3495 while (whitelistFlagsCopy != 0) {
3496 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
3497 whitelistFlagsCopy &= ~flag;
3498 switch (flag) {
3499 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
3500 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3501 if (permissions != null && permissions.contains(permissionName)) {
3502 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3503 } else {
3504 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3505 }
3506 } break;
3507 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
3508 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3509 if (permissions != null && permissions.contains(permissionName)) {
3510 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3511 } else {
3512 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3513 }
3514 } break;
3515 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
3516 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3517 if (permissions != null && permissions.contains(permissionName)) {
3518 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3519 } else {
3520 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3521 }
3522 } break;
3523 }
3524 }
3525
3526 if (oldFlags == newFlags) {
3527 continue;
3528 }
3529
3530 updatePermissions = true;
3531
Svet Ganovd563e932019-04-14 13:07:41 -07003532 final boolean wasWhitelisted = (oldFlags
3533 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3534 final boolean isWhitelisted = (newFlags
3535 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3536
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003537 // If the permission is policy fixed as granted but it is no longer
3538 // on any of the whitelists we need to clear the policy fixed flag
3539 // as whitelisting trumps policy i.e. policy cannot grant a non
3540 // grantable permission.
3541 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003542 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
3543 if (!isWhitelisted && isGranted) {
3544 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3545 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3546 }
3547 }
3548
Svet Ganovd563e932019-04-14 13:07:41 -07003549 // If we are whitelisting an app that does not support runtime permissions
3550 // we need to make sure it goes through the permission review UI at launch.
Winson14ff7172019-10-23 10:42:27 -07003551 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Svet Ganovd563e932019-04-14 13:07:41 -07003552 && !wasWhitelisted && isWhitelisted) {
3553 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3554 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3555 }
3556
Winson14ff7172019-10-23 10:42:27 -07003557 updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003558 callingUid, userId, false, null /*callback*/);
3559 }
3560
3561 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07003562 // Update permission of this app to take into account the new whitelist state.
Winson14ff7172019-10-23 10:42:27 -07003563 restorePermissionState(pkg, false, pkg.getPackageName(), callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003564
3565 // If this resulted in losing a permission we need to kill the app.
3566 if (oldGrantedRestrictedPermissions != null) {
3567 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
3568 for (int i = 0; i < oldGrantedCount; i++) {
3569 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
3570 // Sometimes we create a new permission state instance during update.
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003571 final PermissionsState newPermissionsState =
Winson14ff7172019-10-23 10:42:27 -07003572 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003573 if (!newPermissionsState.hasPermission(permission, userId)) {
Winson14ff7172019-10-23 10:42:27 -07003574 callback.onPermissionRevoked(pkg.getUid(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003575 break;
3576 }
3577 }
3578 }
3579 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003580 }
3581
Andreas Gampea36dc622018-02-05 17:19:22 -08003582 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003583 private int[] revokeUnusedSharedUserPermissionsLocked(
3584 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003585 // Collect all used permissions in the UID
3586 final ArraySet<String> usedPermissions = new ArraySet<>();
Winson14ff7172019-10-23 10:42:27 -07003587 final List<AndroidPackage> pkgList = suSetting.getPackages();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003588 if (pkgList == null || pkgList.size() == 0) {
3589 return EmptyArray.INT;
3590 }
Winson14ff7172019-10-23 10:42:27 -07003591 for (AndroidPackage pkg : pkgList) {
3592 if (pkg.getRequestedPermissions() == null) {
Svet Ganovd8308072018-03-24 00:04:38 -07003593 continue;
3594 }
Winson14ff7172019-10-23 10:42:27 -07003595 final int requestedPermCount = pkg.getRequestedPermissions().size();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003596 for (int j = 0; j < requestedPermCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003597 String permission = pkg.getRequestedPermissions().get(j);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003598 BasePermission bp = mSettings.getPermissionLocked(permission);
3599 if (bp != null) {
3600 usedPermissions.add(permission);
3601 }
3602 }
3603 }
3604
3605 PermissionsState permissionsState = suSetting.getPermissionsState();
3606 // Prune install permissions
3607 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
3608 final int installPermCount = installPermStates.size();
3609 for (int i = installPermCount - 1; i >= 0; i--) {
3610 PermissionState permissionState = installPermStates.get(i);
3611 if (!usedPermissions.contains(permissionState.getName())) {
3612 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3613 if (bp != null) {
3614 permissionsState.revokeInstallPermission(bp);
3615 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003616 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003617 }
3618 }
3619 }
3620
3621 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
3622
3623 // Prune runtime permissions
3624 for (int userId : allUserIds) {
3625 List<PermissionState> runtimePermStates = permissionsState
3626 .getRuntimePermissionStates(userId);
3627 final int runtimePermCount = runtimePermStates.size();
3628 for (int i = runtimePermCount - 1; i >= 0; i--) {
3629 PermissionState permissionState = runtimePermStates.get(i);
3630 if (!usedPermissions.contains(permissionState.getName())) {
3631 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3632 if (bp != null) {
3633 permissionsState.revokeRuntimePermission(bp, userId);
3634 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003635 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003636 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
3637 runtimePermissionChangedUserIds, userId);
3638 }
3639 }
3640 }
3641 }
3642
3643 return runtimePermissionChangedUserIds;
3644 }
3645
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003646 /**
3647 * Update permissions when a package changed.
3648 *
3649 * <p><ol>
3650 * <li>Reconsider the ownership of permission</li>
3651 * <li>Update the state (grant, flags) of the permissions</li>
3652 * </ol>
3653 *
3654 * @param packageName The package that is updated
3655 * @param pkg The package that is updated, or {@code null} if package is deleted
3656 * @param allPackages All currently known packages
3657 * @param callback Callback to call after permission changes
3658 */
Winson14ff7172019-10-23 10:42:27 -07003659 private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003660 @NonNull PermissionCallback callback) {
3661 final int flags =
3662 (pkg != null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG : 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003663 updatePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07003664 packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003665 }
3666
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003667 /**
3668 * Update all permissions for all apps.
3669 *
3670 * <p><ol>
3671 * <li>Reconsider the ownership of permission</li>
3672 * <li>Update the state (grant, flags) of the permissions</li>
3673 * </ol>
3674 *
3675 * @param volumeUuid The volume of the packages to be updated, {@code null} for all volumes
3676 * @param allPackages All currently known packages
3677 * @param callback Callback to call after permission changes
3678 */
3679 private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003680 @NonNull PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003681 final int flags = UPDATE_PERMISSIONS_ALL |
3682 (sdkUpdated
3683 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
3684 : 0);
Todd Kennedyc971a452019-07-08 16:04:52 -07003685 updatePermissions(null, null, volumeUuid, flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003686 }
3687
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003688 /**
3689 * Cache background->foreground permission mapping.
3690 *
3691 * <p>This is only run once.
3692 */
3693 private void cacheBackgroundToForegoundPermissionMapping() {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003694 synchronized (mLock) {
3695 if (mBackgroundPermissions == null) {
3696 // Cache background -> foreground permission mapping.
3697 // Only system declares background permissions, hence mapping does never change.
3698 mBackgroundPermissions = new ArrayMap<>();
3699 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Winson14ff7172019-10-23 10:42:27 -07003700 if (bp.perm != null && bp.perm.backgroundPermission != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003701 String fgPerm = bp.name;
Winson14ff7172019-10-23 10:42:27 -07003702 String bgPerm = bp.perm.backgroundPermission;
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003703
3704 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
3705 if (fgPerms == null) {
3706 fgPerms = new ArrayList<>();
3707 mBackgroundPermissions.put(bgPerm, fgPerms);
3708 }
3709
3710 fgPerms.add(fgPerm);
3711 }
3712 }
3713 }
3714 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003715 }
3716
3717 /**
3718 * Update all packages on the volume, <u>beside</u> the changing package. If the changing
3719 * package is set too, all packages are updated.
3720 */
3721 private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
3722 /** The changing package is replaced. Requires the changing package to be set */
3723 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
3724 /**
3725 * Schedule all packages <u>beside</u> the changing package for replacement. Requires
3726 * UPDATE_PERMISSIONS_ALL to be set
3727 */
3728 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;
3729
3730 @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
3731 UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
3732 UPDATE_PERMISSIONS_REPLACE_ALL })
3733 @Retention(RetentionPolicy.SOURCE)
3734 private @interface UpdatePermissionFlags {}
3735
3736 /**
3737 * Update permissions when packages changed.
3738 *
3739 * <p><ol>
3740 * <li>Reconsider the ownership of permission</li>
3741 * <li>Update the state (grant, flags) of the permissions</li>
3742 * </ol>
3743 *
3744 * <p>Meaning of combination of package parameters:
3745 * <table>
3746 * <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
3747 * <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
3748 * <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
3749 * updated</td></tr>
3750 * </table>
3751 *
3752 * @param changingPkgName The package that is updated, or {@code null} if all packages should be
3753 * updated
3754 * @param changingPkg The package that is updated, or {@code null} if all packages should be
3755 * updated or package is deleted
3756 * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
3757 * all volumes
3758 * @param flags Control permission for which apps should be updated
3759 * @param allPackages All currently known packages
3760 * @param callback Callback to call after permission changes
3761 */
Todd Kennedyc971a452019-07-08 16:04:52 -07003762 private void updatePermissions(final @Nullable String changingPkgName,
Winson14ff7172019-10-23 10:42:27 -07003763 final @Nullable AndroidPackage changingPkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07003764 final @Nullable String replaceVolumeUuid,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003765 @UpdatePermissionFlags int flags,
Todd Kennedyc971a452019-07-08 16:04:52 -07003766 final @Nullable PermissionCallback callback) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003767 // TODO: Most of the methods exposing BasePermission internals [source package name,
3768 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
3769 // have package settings, we should make note of it elsewhere [map between
3770 // source package name and BasePermission] and cycle through that here. Then we
3771 // define a single method on BasePermission that takes a PackageSetting, changing
3772 // package name and a package.
3773 // NOTE: With this approach, we also don't need to tree trees differently than
3774 // normal permissions. Today, we need two separate loops because these BasePermission
3775 // objects are stored separately.
3776 // Make sure there are no dangling permission trees.
3777 boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
3778 changingPkgName, changingPkg);
3779 // Make sure all dynamic permissions have been assigned to a package,
3780 // and make sure there are no dangling permissions.
3781 boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
Hongming Jinbc4d0102019-08-16 14:28:30 -07003782 changingPkg, callback);
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003783
3784 if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
3785 // Permission ownership has changed. This e.g. changes which packages can get signature
3786 // permissions
3787 flags |= UPDATE_PERMISSIONS_ALL;
3788 }
3789
3790 cacheBackgroundToForegoundPermissionMapping();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003791
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07003792 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003793 // Now update the permissions for all packages.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003794 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07003795 final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
Winson14ff7172019-10-23 10:42:27 -07003796 mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
Todd Kennedyc971a452019-07-08 16:04:52 -07003797 if (pkg == changingPkg) {
3798 return;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003799 }
Todd Kennedyc971a452019-07-08 16:04:52 -07003800 // Only replace for packages on requested volume
3801 final String volumeUuid = getVolumeUuidForPackage(pkg);
3802 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
3803 restorePermissionState(pkg, replace, changingPkgName, callback);
3804 });
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003805 }
3806
3807 if (changingPkg != null) {
3808 // Only replace for packages on requested volume
3809 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
3810 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
3811 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07003812 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003813 }
3814 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
3815 }
3816
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003817 /**
3818 * Update which app declares a permission.
3819 *
3820 * <p>Possible parameter combinations
3821 * <table>
3822 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
3823 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
3824 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
3825 * </table>
3826 *
3827 * @param packageName The package that is updated, or {@code null} if all packages should be
3828 * updated
3829 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
3830 * package is deleted
3831 *
3832 * @return {@code true} if a permission source package might have changed
3833 */
3834 private boolean updatePermissionSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07003835 @Nullable AndroidPackage pkg,
Hongming Jinbc4d0102019-08-16 14:28:30 -07003836 final @Nullable PermissionCallback callback) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003837 boolean changed = false;
3838
Todd Kennedyc8423932017-10-05 08:58:36 -07003839 Set<BasePermission> needsUpdate = null;
3840 synchronized (mLock) {
3841 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
3842 while (it.hasNext()) {
3843 final BasePermission bp = it.next();
3844 if (bp.isDynamic()) {
3845 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
3846 }
3847 if (bp.getSourcePackageSetting() != null) {
3848 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003849 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003850 Slog.i(TAG, "Removing permission " + bp.getName()
3851 + " that used to be declared by " + bp.getSourcePackageName());
Hongming Jinbc4d0102019-08-16 14:28:30 -07003852 if (bp.isRuntime()) {
3853 final int[] userIds = mUserManagerInt.getUserIds();
3854 final int numUserIds = userIds.length;
3855 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
3856 final int userId = userIds[userIdNum];
3857
Winson14ff7172019-10-23 10:42:27 -07003858 mPackageManagerInt.forEachPackage((AndroidPackage p) -> {
3859 final String pName = p.getPackageName();
Hongming Jinbc4d0102019-08-16 14:28:30 -07003860 final ApplicationInfo appInfo =
3861 mPackageManagerInt.getApplicationInfo(pName, 0,
3862 Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
3863 if (appInfo != null
3864 && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
3865 return;
3866 }
3867
3868 final String permissionName = bp.getName();
3869 if (checkPermissionImpl(permissionName, pName, userId)
3870 == PackageManager.PERMISSION_GRANTED) {
3871 try {
3872 revokeRuntimePermissionInternal(
3873 permissionName,
3874 pName,
3875 false,
3876 Process.SYSTEM_UID,
3877 userId,
3878 callback);
3879 } catch (IllegalArgumentException e) {
3880 Slog.e(TAG,
3881 "Failed to revoke "
3882 + permissionName
3883 + " from "
3884 + pName,
3885 e);
3886 }
3887 }
3888 });
3889 }
3890 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003891 changed = true;
Todd Kennedyc8423932017-10-05 08:58:36 -07003892 it.remove();
3893 }
3894 continue;
3895 }
3896 if (needsUpdate == null) {
3897 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
3898 }
3899 needsUpdate.add(bp);
3900 }
3901 }
3902 if (needsUpdate != null) {
3903 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07003904 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07003905 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07003906 final PackageSetting sourcePs =
3907 (PackageSetting) mPackageManagerInt.getPackageSetting(
3908 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07003909 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07003910 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07003911 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003912 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07003913 }
3914 continue;
3915 }
3916 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
3917 + " from package " + bp.getSourcePackageName());
3918 mSettings.removePermissionLocked(bp.getName());
3919 }
3920 }
3921 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003922 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07003923 }
3924
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003925 /**
3926 * Update which app owns a permission trees.
3927 *
3928 * <p>Possible parameter combinations
3929 * <table>
3930 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
3931 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
3932 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
3933 * </table>
3934 *
3935 * @param packageName The package that is updated, or {@code null} if all packages should be
3936 * updated
3937 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
3938 * package is deleted
3939 *
3940 * @return {@code true} if a permission tree ownership might have changed
3941 */
3942 private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07003943 @Nullable AndroidPackage pkg) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003944 boolean changed = false;
3945
Todd Kennedyc8423932017-10-05 08:58:36 -07003946 Set<BasePermission> needsUpdate = null;
3947 synchronized (mLock) {
3948 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
3949 while (it.hasNext()) {
3950 final BasePermission bp = it.next();
3951 if (bp.getSourcePackageSetting() != null) {
3952 if (packageName != null && packageName.equals(bp.getSourcePackageName())
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003953 && (pkg == null || !hasPermission(pkg, bp.getName()))) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003954 Slog.i(TAG, "Removing permission tree " + bp.getName()
3955 + " that used to be declared by " + bp.getSourcePackageName());
3956 changed = true;
Todd Kennedyc8423932017-10-05 08:58:36 -07003957 it.remove();
3958 }
3959 continue;
3960 }
3961 if (needsUpdate == null) {
3962 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
3963 }
3964 needsUpdate.add(bp);
3965 }
3966 }
3967 if (needsUpdate != null) {
3968 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07003969 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07003970 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07003971 final PackageSetting sourcePs =
3972 (PackageSetting) mPackageManagerInt.getPackageSetting(
3973 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07003974 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07003975 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07003976 if (bp.getSourcePackageSetting() == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003977 bp.setSourcePackageSetting(sourcePs);
Todd Kennedyc8423932017-10-05 08:58:36 -07003978 }
3979 continue;
3980 }
3981 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
3982 + " from package " + bp.getSourcePackageName());
3983 mSettings.removePermissionLocked(bp.getName());
3984 }
3985 }
3986 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003987 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07003988 }
3989
Todd Kennedy0eb97382017-10-03 16:57:22 -07003990 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
3991 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
3992 != PackageManager.PERMISSION_GRANTED
3993 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
3994 != PackageManager.PERMISSION_GRANTED) {
3995 throw new SecurityException(message + " requires "
3996 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
3997 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
3998 }
3999 }
4000
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08004001 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
4002 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
4003 != PackageManager.PERMISSION_GRANTED
4004 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4005 != PackageManager.PERMISSION_GRANTED
4006 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4007 != PackageManager.PERMISSION_GRANTED) {
4008 throw new SecurityException(message + " requires "
4009 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4010 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
4011 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
4012 }
4013 }
4014
Todd Kennedy0eb97382017-10-03 16:57:22 -07004015 /**
4016 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4017 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4018 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4019 * @param message the message to log on security exception
4020 */
4021 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004022 boolean requireFullPermission, boolean checkShell,
4023 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004024 if (userId < 0) {
4025 throw new IllegalArgumentException("Invalid userId " + userId);
4026 }
4027 if (checkShell) {
Patrick Baumann2f2fd712019-07-31 15:18:53 -07004028 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
Todd Kennedy0eb97382017-10-03 16:57:22 -07004029 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4030 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004031 final int callingUserId = UserHandle.getUserId(callingUid);
4032 if (hasCrossUserPermission(
4033 callingUid, callingUserId, userId, requireFullPermission,
4034 requirePermissionWhenSameUser)) {
4035 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07004036 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004037 String errorMessage = buildInvalidCrossUserPermissionMessage(
4038 message, requireFullPermission);
4039 Slog.w(TAG, errorMessage);
4040 throw new SecurityException(errorMessage);
4041 }
4042
4043 /**
4044 * Checks if the request is from the system or an app that has the appropriate cross-user
4045 * permissions defined as follows:
4046 * <ul>
4047 * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
4048 * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group
4049 * to the caller.</li>
4050 * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group
4051 * as the caller.</li>
4052 * </ul>
4053 *
4054 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4055 * @param message the message to log on security exception
4056 */
4057 private void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4058 boolean requireFullPermission, boolean checkShell,
4059 String message) {
4060 if (userId < 0) {
4061 throw new IllegalArgumentException("Invalid userId " + userId);
4062 }
4063 if (checkShell) {
4064 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
4065 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4066 }
4067 final int callingUserId = UserHandle.getUserId(callingUid);
4068 if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
4069 /*requirePermissionWhenSameUser= */ false)) {
4070 return;
4071 }
4072 final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
4073 if (isSameProfileGroup
4074 && hasPermission(android.Manifest.permission.INTERACT_ACROSS_PROFILES)) {
4075 return;
4076 }
4077 String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
4078 message, requireFullPermission, isSameProfileGroup);
4079 Slog.w(TAG, errorMessage);
4080 throw new SecurityException(errorMessage);
4081 }
4082
4083 private boolean hasCrossUserPermission(
4084 int callingUid, int callingUserId, int userId, boolean requireFullPermission,
4085 boolean requirePermissionWhenSameUser) {
4086 if (!requirePermissionWhenSameUser && userId == callingUserId) {
4087 return true;
4088 }
4089 if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4090 return true;
4091 }
4092 if (requireFullPermission) {
4093 return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4094 }
4095 return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4096 || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
4097 }
4098
4099 private boolean hasPermission(String permission) {
4100 return mContext.checkCallingOrSelfPermission(permission)
4101 == PackageManager.PERMISSION_GRANTED;
4102 }
4103
4104 private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
4105 final long identity = Binder.clearCallingIdentity();
4106 try {
4107 return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
4108 } finally {
4109 Binder.restoreCallingIdentity(identity);
4110 }
4111 }
4112
4113 private static String buildInvalidCrossUserPermissionMessage(
4114 String message, boolean requireFullPermission) {
4115 StringBuilder builder = new StringBuilder();
4116 if (message != null) {
4117 builder.append(message);
4118 builder.append(": ");
4119 }
4120 builder.append("Requires ");
4121 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4122 if (requireFullPermission) {
4123 builder.append(".");
4124 return builder.toString();
4125 }
4126 builder.append(" or ");
4127 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4128 builder.append(".");
4129 return builder.toString();
4130 }
4131
4132 private static String buildInvalidCrossUserOrProfilePermissionMessage(
4133 String message, boolean requireFullPermission, boolean isSameProfileGroup) {
4134 StringBuilder builder = new StringBuilder();
4135 if (message != null) {
4136 builder.append(message);
4137 builder.append(": ");
4138 }
4139 builder.append("Requires ");
4140 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4141 if (requireFullPermission) {
4142 builder.append(".");
4143 return builder.toString();
4144 }
4145 builder.append(" or ");
4146 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4147 if (isSameProfileGroup) {
4148 builder.append(" or ");
4149 builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
4150 }
4151 builder.append(".");
4152 return builder.toString();
Todd Kennedy0eb97382017-10-03 16:57:22 -07004153 }
4154
Andreas Gampea71bee82018-07-20 12:55:36 -07004155 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004156 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4157 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07004158 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004159 size += tree.calculateFootprint(perm);
4160 }
4161 return size;
4162 }
4163
Andreas Gampea71bee82018-07-20 12:55:36 -07004164 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004165 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4166 // We calculate the max size of permissions defined by this uid and throw
4167 // if that plus the size of 'info' would exceed our stated maximum.
4168 if (tree.getUid() != Process.SYSTEM_UID) {
4169 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4170 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
4171 throw new SecurityException("Permission tree size cap exceeded");
4172 }
4173 }
4174 }
4175
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004176 private void systemReady() {
4177 mSystemReady = true;
4178 if (mPrivappPermissionsViolations != null) {
4179 throw new IllegalStateException("Signature|privileged permissions not in "
4180 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
4181 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004182
4183 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov3c499ea2019-07-26 17:45:56 -07004184 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedy583378d2019-07-12 06:50:30 -07004185
4186 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
4187 for (int userId : UserManagerService.getInstance().getUserIds()) {
4188 if (!mPackageManagerInt.areDefaultRuntimePermissionsGranted(userId)) {
4189 grantPermissionsUserIds = ArrayUtils.appendInt(
4190 grantPermissionsUserIds, userId);
4191 }
4192 }
4193 // If we upgraded grant all default permissions before kicking off.
4194 for (int userId : grantPermissionsUserIds) {
4195 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
4196 }
4197 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
4198 // If we did not grant default permissions, we preload from this the
4199 // default permission exceptions lazily to ensure we don't hit the
4200 // disk on a new user creation.
4201 mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
4202 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004203 }
4204
Winson14ff7172019-10-23 10:42:27 -07004205 private static String getVolumeUuidForPackage(AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004206 if (pkg == null) {
4207 return StorageManager.UUID_PRIVATE_INTERNAL;
4208 }
4209 if (pkg.isExternal()) {
Winson14ff7172019-10-23 10:42:27 -07004210 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004211 return StorageManager.UUID_PRIMARY_PHYSICAL;
4212 } else {
Winson14ff7172019-10-23 10:42:27 -07004213 return pkg.getVolumeUuid();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004214 }
4215 } else {
4216 return StorageManager.UUID_PRIVATE_INTERNAL;
4217 }
4218 }
4219
Winson14ff7172019-10-23 10:42:27 -07004220 private static boolean hasPermission(AndroidPackage pkg, String permName) {
4221 if (pkg.getPermissions() == null) {
4222 return false;
4223 }
4224
4225 for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
4226 if (pkg.getPermissions().get(i).getName().equals(permName)) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004227 return true;
4228 }
4229 }
4230 return false;
4231 }
4232
Todd Kennedy0eb97382017-10-03 16:57:22 -07004233 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004234 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07004235 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004236 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07004237 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004238 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07004239 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004240 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
4241 final LogMaker log = new LogMaker(action);
4242 log.setPackageName(packageName);
4243 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004244
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004245 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004246 }
4247
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004248 /**
4249 * Get the mapping of background permissions to their foreground permissions.
4250 *
4251 * <p>Only initialized in the system server.
4252 *
4253 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
4254 */
4255 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
4256 return mBackgroundPermissions;
4257 }
4258
Philip P. Moltmann48456672019-01-20 13:14:03 -08004259 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004260 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004261 public void systemReady() {
4262 PermissionManagerService.this.systemReady();
4263 }
4264 @Override
Winson14ff7172019-10-23 10:42:27 -07004265 public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
4266 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004267 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
4268 }
Winson14ff7172019-10-23 10:42:27 -07004269
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004270 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004271 public void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07004272 @NonNull AndroidPackage newPackage,
4273 @NonNull AndroidPackage oldPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004274 @NonNull ArrayList<String> allPackageNames) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004275 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004276 oldPackage, allPackageNames, mDefaultPermissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004277 }
4278 @Override
Winson14ff7172019-10-23 10:42:27 -07004279 public void addAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004280 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004281 }
4282 @Override
Winson14ff7172019-10-23 10:42:27 -07004283 public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07004284 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
4285 }
4286 @Override
Winson14ff7172019-10-23 10:42:27 -07004287 public void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Hongming Jinae750fb2018-09-27 23:00:20 +00004288 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07004289 }
4290 @Override
Winson14ff7172019-10-23 10:42:27 -07004291 public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedyc971a452019-07-08 16:04:52 -07004292 String[] grantedPermissions, int callingUid) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004293 PermissionManagerService.this.grantRequestedRuntimePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07004294 pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004295 }
4296 @Override
Winson14ff7172019-10-23 10:42:27 -07004297 public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004298 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
Todd Kennedyc971a452019-07-08 16:04:52 -07004299 @PackageManager.PermissionWhitelistFlags int flags) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004300 for (int userId : userIds) {
4301 setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
Todd Kennedyc971a452019-07-08 16:04:52 -07004302 callingUid, flags, mDefaultPermissionCallback);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004303 }
4304 }
4305 @Override
4306 public void setWhitelistedRestrictedPermissions(String packageName,
4307 List<String> permissions, int flags, int userId) {
4308 PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
4309 packageName, permissions, flags, userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004310 }
4311 @Override
Winson14ff7172019-10-23 10:42:27 -07004312 public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004313 PermissionManagerService.this
4314 .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004315 }
4316 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004317 public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
4318 PermissionManagerService.this
4319 .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004320 }
4321 @Override
Winson14ff7172019-10-23 10:42:27 -07004322 public void resetRuntimePermissions(AndroidPackage pkg, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004323 PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
4324 }
4325 @Override
4326 public void resetAllRuntimePermissions(final int userId) {
4327 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07004328 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedy0eb97382017-10-03 16:57:22 -07004329 }
4330 @Override
Todd Kennedy8f135982019-07-02 07:35:15 -07004331 public String[] getAppOpPermissionPackages(String permName, int callingUid) {
4332 return PermissionManagerService.this
4333 .getAppOpPermissionPackagesInternal(permName, callingUid);
Todd Kennedyc8423932017-10-05 08:58:36 -07004334 }
4335 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004336 public void enforceCrossUserPermission(int callingUid, int userId,
4337 boolean requireFullPermission, boolean checkShell, String message) {
4338 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004339 requireFullPermission, checkShell, false, message);
4340 }
4341 @Override
4342 public void enforceCrossUserPermission(int callingUid, int userId,
4343 boolean requireFullPermission, boolean checkShell,
4344 boolean requirePermissionWhenSameUser, String message) {
4345 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
4346 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004347 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004348
4349 @Override
4350 public void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4351 boolean requireFullPermission, boolean checkShell, String message) {
4352 PermissionManagerService.this.enforceCrossUserOrProfilePermission(callingUid,
4353 userId,
4354 requireFullPermission,
4355 checkShell,
4356 message);
4357 }
4358
Todd Kennedy0eb97382017-10-03 16:57:22 -07004359 @Override
4360 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4361 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
4362 }
4363 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004364 public PermissionSettings getPermissionSettings() {
4365 return mSettings;
4366 }
4367 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004368 public BasePermission getPermissionTEMP(String permName) {
4369 synchronized (PermissionManagerService.this.mLock) {
4370 return mSettings.getPermissionLocked(permName);
4371 }
4372 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004373
4374 @Override
Hai Zhang57bc3122019-10-21 16:04:15 -07004375 public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtection(
4376 @PermissionInfo.Protection int protection) {
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004377 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
4378
4379 synchronized (PermissionManagerService.this.mLock) {
4380 int numTotalPermissions = mSettings.mPermissions.size();
4381
4382 for (int i = 0; i < numTotalPermissions; i++) {
4383 BasePermission bp = mSettings.mPermissions.valueAt(i);
4384
Winson655a5b92019-10-23 10:49:32 -07004385 if (bp.perm != null && bp.perm.getProtection() == protection) {
4386 matchingPermissions.add(
4387 PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004388 }
4389 }
4390 }
4391
4392 return matchingPermissions;
4393 }
4394
4395 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08004396 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
4397 return PermissionManagerService.this.backupRuntimePermissions(user);
4398 }
4399
4400 @Override
4401 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
4402 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
4403 }
4404
4405 @Override
4406 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
4407 @NonNull UserHandle user) {
4408 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
4409 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004410
4411 @Override
4412 public void addOnRuntimePermissionStateChangedListener(
4413 OnRuntimePermissionStateChangedListener listener) {
4414 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
4415 listener);
4416 }
4417
4418 @Override
4419 public void removeOnRuntimePermissionStateChangedListener(
4420 OnRuntimePermissionStateChangedListener listener) {
4421 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
4422 listener);
4423 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004424
4425 @Override
4426 public CheckPermissionDelegate getCheckPermissionDelegate() {
4427 synchronized (mLock) {
4428 return mCheckPermissionDelegate;
4429 }
4430 }
4431
4432 @Override
4433 public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
4434 synchronized (mLock) {
4435 mCheckPermissionDelegate = delegate;
4436 }
4437 }
Todd Kennedy583378d2019-07-12 06:50:30 -07004438
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004439 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004440 public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
4441 synchronized (mLock) {
4442 mDefaultBrowserProvider = provider;
4443 }
4444 }
4445
4446 @Override
4447 public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
4448 int userId) {
4449 setDefaultBrowserInternal(packageName, async, doGrant, userId);
4450 }
4451
4452 @Override
4453 public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
4454 synchronized (mLock) {
4455 mDefaultDialerProvider = provider;
4456 }
4457 }
4458
4459 @Override
4460 public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
4461 synchronized (mLock) {
4462 mDefaultHomeProvider = provider;
4463 }
4464 }
4465
4466 @Override
4467 public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004468 if (userId == UserHandle.USER_ALL) {
4469 return;
Todd Kennedy583378d2019-07-12 06:50:30 -07004470 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004471 DefaultHomeProvider provider;
4472 synchronized (mLock) {
4473 provider = mDefaultHomeProvider;
4474 }
4475 if (provider == null) {
4476 return;
4477 }
4478 provider.setDefaultHomeAsync(packageName, userId, callback);
Todd Kennedy583378d2019-07-12 06:50:30 -07004479 }
4480
4481 @Override
4482 public void setDialerAppPackagesProvider(PackagesProvider provider) {
4483 synchronized (mLock) {
4484 mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
4485 }
4486 }
4487
4488 @Override
4489 public void setLocationExtraPackagesProvider(PackagesProvider provider) {
4490 synchronized (mLock) {
4491 mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
4492 }
4493 }
4494
4495 @Override
4496 public void setLocationPackagesProvider(PackagesProvider provider) {
4497 synchronized (mLock) {
4498 mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
4499 }
4500 }
4501
4502 @Override
4503 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
4504 synchronized (mLock) {
4505 mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
4506 }
4507 }
4508
4509 @Override
4510 public void setSmsAppPackagesProvider(PackagesProvider provider) {
4511 synchronized (mLock) {
4512 mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
4513 }
4514 }
4515
4516 @Override
4517 public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
4518 synchronized (mLock) {
4519 mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
4520 }
4521 }
4522
4523 @Override
4524 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
4525 synchronized (mLock) {
4526 mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
4527 }
4528 }
4529
4530 @Override
4531 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
4532 synchronized (mLock) {
4533 mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
4534 }
4535 }
4536
4537 @Override
4538 public String getDefaultBrowser(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004539 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004540 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004541 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004542 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004543 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004544 }
4545
4546 @Override
4547 public String getDefaultDialer(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004548 DefaultDialerProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004549 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004550 provider = mDefaultDialerProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004551 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004552 return provider != null ? provider.getDefaultDialer(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004553 }
4554
4555 @Override
4556 public String getDefaultHome(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004557 DefaultHomeProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004558 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004559 provider = mDefaultHomeProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004560 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004561 return provider != null ? provider.getDefaultHome(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004562 }
4563
4564 @Override
4565 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
4566 synchronized (mLock) {
4567 mDefaultPermissionGrantPolicy
4568 .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
4569 }
4570 }
4571
4572 @Override
4573 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
4574 synchronized (mLock) {
4575 mDefaultPermissionGrantPolicy
4576 .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
4577 }
4578 }
4579
4580 @Override
4581 public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
4582 synchronized (mLock) {
4583 mDefaultPermissionGrantPolicy
4584 .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
4585 }
4586 }
4587
4588 @Override
4589 public boolean wereDefaultPermissionsGrantedSinceBoot(int userId) {
4590 synchronized (mLock) {
4591 return mDefaultPermissionGrantPolicy.wereDefaultPermissionsGrantedSinceBoot(userId);
4592 }
4593 }
4594
4595 @Override
4596 public void onNewUserCreated(int userId) {
Hai Zhang93236822020-01-09 13:15:17 -08004597 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07004598 synchronized (mLock) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004599 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
4600 PermissionManagerService.this.updateAllPermissions(
4601 StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
4602 }
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004603 }
4604 }
4605
4606 private static final class OnPermissionChangeListeners extends Handler {
4607 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
4608
4609 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
4610 new RemoteCallbackList<>();
4611
4612 OnPermissionChangeListeners(Looper looper) {
4613 super(looper);
4614 }
4615
4616 @Override
4617 public void handleMessage(Message msg) {
4618 switch (msg.what) {
4619 case MSG_ON_PERMISSIONS_CHANGED: {
4620 final int uid = msg.arg1;
4621 handleOnPermissionsChanged(uid);
4622 } break;
4623 }
4624 }
4625
4626 public void addListenerLocked(IOnPermissionsChangeListener listener) {
4627 mPermissionListeners.register(listener);
4628
4629 }
4630
4631 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
4632 mPermissionListeners.unregister(listener);
4633 }
4634
4635 public void onPermissionsChanged(int uid) {
4636 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
4637 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
4638 }
4639 }
4640
4641 private void handleOnPermissionsChanged(int uid) {
4642 final int count = mPermissionListeners.beginBroadcast();
4643 try {
4644 for (int i = 0; i < count; i++) {
4645 IOnPermissionsChangeListener callback = mPermissionListeners
4646 .getBroadcastItem(i);
4647 try {
4648 callback.onPermissionsChanged(uid);
4649 } catch (RemoteException e) {
4650 Log.e(TAG, "Permission listener is dead", e);
4651 }
4652 }
4653 } finally {
4654 mPermissionListeners.finishBroadcast();
4655 }
4656 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07004657 }
4658}