blob: 1b11e2d0860d793b4cbd19d1c8af1576ac447255 [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;
Eugene Susla922cd082020-03-11 12:38:17 -070022import static android.app.AppOpsManager.MODE_ALLOWED;
23import static android.app.AppOpsManager.MODE_IGNORED;
Eugene Susla49b84c32020-03-23 15:19:29 -070024import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISALLOWED;
25import static android.content.pm.ApplicationInfo.AUTO_REVOKE_DISCOURAGED;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070026import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT;
27import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070028import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
Hai Zhang253fa2b2020-06-02 14:07:23 -070029import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
Evan Seversonf21a09a2020-03-19 10:54:51 -070030import static android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070031import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
Todd Kennedy3bc94722017-10-10 09:55:53 -070032import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Hai Zhang50a5a9b2019-09-19 13:57:45 -070033import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070034import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
35import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
36import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
37import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070038import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
39import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM;
40import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE;
Philip P. Moltmannba742062019-04-08 13:22:44 -070041import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL;
Todd Kennedyc5b0e862019-07-16 09:47:58 -070042import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
Hongwei Wangf391b552018-04-06 13:52:46 -070043import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
Todd Kennedyc971a452019-07-08 16:04:52 -070044import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070045import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
Hongwei Wangf391b552018-04-06 13:52:46 -070046
Philip P. Moltmannbd278012020-03-10 14:46:27 -070047import static com.android.server.pm.ApexManager.MATCH_ACTIVE_PACKAGE;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070048import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL;
49import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
50import static com.android.server.pm.PackageManagerService.DEBUG_PERMISSIONS;
51import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
52import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
Philip P. Moltmann48456672019-01-20 13:14:03 -080053import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
54
55import static java.util.concurrent.TimeUnit.SECONDS;
Todd Kennedy0eb97382017-10-03 16:57:22 -070056
57import android.Manifest;
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -070058import android.annotation.IntDef;
Todd Kennedy0eb97382017-10-03 16:57:22 -070059import android.annotation.NonNull;
60import android.annotation.Nullable;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -070061import android.annotation.UserIdInt;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070062import android.app.ActivityManager;
Eugene Susla922cd082020-03-11 12:38:17 -070063import android.app.AppOpsManager;
Eugene Suslad516bee2019-05-01 09:48:43 -070064import android.app.ApplicationPackageManager;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070065import android.app.IActivityManager;
wayneyang8126b1f2020-01-09 14:10:31 +080066import android.app.admin.DeviceAdminInfo;
Michael Groover56a84b22020-03-04 20:41:36 -080067import android.app.admin.DevicePolicyManager;
wayneyang8126b1f2020-01-09 14:10:31 +080068import android.app.admin.DevicePolicyManagerInternal;
Evan Severson50a77742020-01-06 10:38:19 -080069import android.compat.annotation.ChangeId;
70import android.compat.annotation.EnabledAfter;
Todd Kennedy0eb97382017-10-03 16:57:22 -070071import android.content.Context;
kholoud mohamed79a89f02020-01-15 15:30:07 +000072import android.content.PermissionChecker;
Hongming Jinbc4d0102019-08-16 14:28:30 -070073import android.content.pm.ApplicationInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070074import android.content.pm.PackageManager;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070075import android.content.pm.PackageManager.PermissionGroupInfoFlags;
76import android.content.pm.PackageManager.PermissionInfoFlags;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070077import android.content.pm.PackageManager.PermissionWhitelistFlags;
Todd Kennedy0eb97382017-10-03 16:57:22 -070078import android.content.pm.PackageManagerInternal;
79import android.content.pm.PackageParser;
Todd Kennedy1d29b4a2019-07-02 14:49:28 -070080import android.content.pm.ParceledListSlice;
Todd Kennedy460f28c2017-10-06 13:46:22 -070081import android.content.pm.PermissionGroupInfo;
Todd Kennedy0eb97382017-10-03 16:57:22 -070082import android.content.pm.PermissionInfo;
Winsonf00c7552020-01-28 12:52:01 -080083import android.content.pm.parsing.component.ParsedPermission;
84import android.content.pm.parsing.component.ParsedPermissionGroup;
Anthony Hughde787d42019-08-22 15:35:48 -070085import android.content.pm.permission.SplitPermissionInfoParcelable;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -070086import android.metrics.LogMaker;
Todd Kennedy0eb97382017-10-03 16:57:22 -070087import android.os.Binder;
88import android.os.Build;
89import android.os.Handler;
90import android.os.HandlerThread;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070091import android.os.Looper;
92import android.os.Message;
Todd Kennedy0eb97382017-10-03 16:57:22 -070093import android.os.Process;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -070094import android.os.RemoteCallbackList;
95import android.os.RemoteException;
Todd Kennedy8f135982019-07-02 07:35:15 -070096import android.os.ServiceManager;
Todd Kennedyc29b11a2017-10-23 15:55:59 -070097import android.os.Trace;
Todd Kennedy0eb97382017-10-03 16:57:22 -070098import android.os.UserHandle;
99import android.os.UserManager;
100import android.os.UserManagerInternal;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700101import android.os.storage.StorageManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700102import android.os.storage.StorageManagerInternal;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700103import android.permission.IOnPermissionsChangeListener;
Todd Kennedy8f135982019-07-02 07:35:15 -0700104import android.permission.IPermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800105import android.permission.PermissionControllerManager;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -0700106import android.permission.PermissionManager;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800107import android.permission.PermissionManagerInternal;
Todd Kennedyca1ea172019-07-03 15:02:28 -0700108import android.permission.PermissionManagerInternal.CheckPermissionDelegate;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700109import android.permission.PermissionManagerInternal.OnRuntimePermissionStateChangedListener;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700110import android.text.TextUtils;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700111import android.util.ArrayMap;
112import android.util.ArraySet;
Eugene Suslad516bee2019-05-01 09:48:43 -0700113import android.util.DebugUtils;
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -0700114import android.util.EventLog;
Todd Kennedyc971a452019-07-08 16:04:52 -0700115import android.util.IntArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700116import android.util.Log;
117import android.util.Slog;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700118import android.util.SparseArray;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800119import android.util.SparseBooleanArray;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700120
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700121import com.android.internal.annotations.GuardedBy;
Michael Groover56a84b22020-03-04 20:41:36 -0800122import com.android.internal.annotations.VisibleForTesting;
Evan Severson50a77742020-01-06 10:38:19 -0800123import com.android.internal.compat.IPlatformCompat;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700124import com.android.internal.logging.MetricsLogger;
125import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700126import com.android.internal.os.RoSystemProperties;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700127import com.android.internal.util.ArrayUtils;
Philip P. Moltmann58c52d42020-05-18 12:06:13 -0700128import com.android.internal.util.DumpUtils;
Todd Kennedyc971a452019-07-08 16:04:52 -0700129import com.android.internal.util.IntPair;
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700130import com.android.internal.util.Preconditions;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700131import com.android.internal.util.function.pooled.PooledLambda;
132import com.android.server.FgThread;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700133import com.android.server.LocalServices;
134import com.android.server.ServiceThread;
135import com.android.server.SystemConfig;
136import com.android.server.Watchdog;
Philip P. Moltmannbd278012020-03-10 14:46:27 -0700137import com.android.server.pm.ApexManager;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700138import com.android.server.pm.PackageManagerServiceUtils;
139import com.android.server.pm.PackageSetting;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700140import com.android.server.pm.SharedUserSetting;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700141import com.android.server.pm.UserManagerService;
Winson5e0a1d52020-01-24 12:00:33 -0800142import com.android.server.pm.parsing.PackageInfoUtils;
Winsonf00c7552020-01-28 12:52:01 -0800143import com.android.server.pm.parsing.pkg.AndroidPackage;
Todd Kennedy583378d2019-07-12 06:50:30 -0700144import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultBrowserProvider;
145import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultDialerProvider;
146import com.android.server.pm.permission.PermissionManagerServiceInternal.DefaultHomeProvider;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800147import com.android.server.pm.permission.PermissionManagerServiceInternal.PermissionCallback;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700148import com.android.server.pm.permission.PermissionsState.PermissionState;
Svet Ganov3c499ea2019-07-26 17:45:56 -0700149import com.android.server.policy.PermissionPolicyInternal;
Philip P. Moltmann8625cdd2019-05-30 08:27:19 -0700150import com.android.server.policy.SoftRestrictedPermissionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700151
152import libcore.util.EmptyArray;
153
Philip P. Moltmann5ab27fc2020-05-06 17:10:59 -0700154import java.io.FileDescriptor;
155import java.io.PrintWriter;
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -0700156import java.lang.annotation.Retention;
157import java.lang.annotation.RetentionPolicy;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700158import java.util.ArrayList;
Hai Zhang4c0d15b2020-05-18 16:06:58 -0700159import java.util.Collection;
Hongwei Wangf391b552018-04-06 13:52:46 -0700160import java.util.HashMap;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700161import java.util.Iterator;
162import java.util.List;
Hongwei Wangf391b552018-04-06 13:52:46 -0700163import java.util.Map;
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700164import java.util.Objects;
Todd Kennedyc8423932017-10-05 08:58:36 -0700165import java.util.Set;
Philip P. Moltmann48456672019-01-20 13:14:03 -0800166import java.util.concurrent.CompletableFuture;
167import java.util.concurrent.ExecutionException;
168import java.util.concurrent.TimeUnit;
169import java.util.concurrent.TimeoutException;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700170import java.util.function.Consumer;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700171
172/**
173 * Manages all permissions and handles permissions related tasks.
174 */
Todd Kennedy8f135982019-07-02 07:35:15 -0700175public class PermissionManagerService extends IPermissionManager.Stub {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700176 private static final String TAG = "PackageManager";
177
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700178 /** Permission grant: not grant the permission. */
179 private static final int GRANT_DENIED = 1;
180 /** Permission grant: grant the permission as an install permission. */
181 private static final int GRANT_INSTALL = 2;
182 /** Permission grant: grant the permission as a runtime one. */
183 private static final int GRANT_RUNTIME = 3;
184 /** Permission grant: grant as runtime a permission that was granted as an install time one. */
185 private static final int GRANT_UPGRADE = 4;
186
Philip P. Moltmann48456672019-01-20 13:14:03 -0800187 private static final long BACKUP_TIMEOUT_MILLIS = SECONDS.toMillis(60);
188
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700189 /** Cap the size of permission trees that 3rd party apps can define; in characters of text */
190 private static final int MAX_PERMISSION_TREE_FOOTPRINT = 32768;
191 /** Empty array to avoid allocations */
192 private static final int[] EMPTY_INT_ARRAY = new int[0];
Todd Kennedy0eb97382017-10-03 16:57:22 -0700193
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -0800194 /**
195 * When these flags are set, the system should not automatically modify the permission grant
196 * state.
197 */
198 private static final int BLOCKING_PERMISSION_FLAGS = FLAG_PERMISSION_SYSTEM_FIXED
199 | FLAG_PERMISSION_POLICY_FIXED
200 | FLAG_PERMISSION_GRANTED_BY_DEFAULT;
201
202 /** Permission flags set by the user */
203 private static final int USER_PERMISSION_FLAGS = FLAG_PERMISSION_USER_SET
204 | FLAG_PERMISSION_USER_FIXED;
205
Hongwei Wangf391b552018-04-06 13:52:46 -0700206 /** If the permission of the value is granted, so is the key */
207 private static final Map<String, String> FULLER_PERMISSION_MAP = new HashMap<>();
208
209 static {
210 FULLER_PERMISSION_MAP.put(Manifest.permission.ACCESS_COARSE_LOCATION,
211 Manifest.permission.ACCESS_FINE_LOCATION);
212 FULLER_PERMISSION_MAP.put(Manifest.permission.INTERACT_ACROSS_USERS,
213 Manifest.permission.INTERACT_ACROSS_USERS_FULL);
214 }
215
Todd Kennedy0eb97382017-10-03 16:57:22 -0700216 /** Lock to protect internal data access */
217 private final Object mLock;
218
219 /** Internal connection to the package manager */
220 private final PackageManagerInternal mPackageManagerInt;
221
222 /** Internal connection to the user manager */
223 private final UserManagerInternal mUserManagerInt;
224
Philip P. Moltmann48456672019-01-20 13:14:03 -0800225 /** Permission controller: User space permission management */
226 private PermissionControllerManager mPermissionControllerManager;
227
Evan Seversonb252d8b2019-11-20 08:41:33 -0800228 /** Map of OneTimePermissionUserManagers keyed by userId */
229 private final SparseArray<OneTimePermissionUserManager> mOneTimePermissionUserManagers =
230 new SparseArray<>();
231
Todd Kennedy0eb97382017-10-03 16:57:22 -0700232 /** Default permission policy to provide proper behaviour out-of-the-box */
233 private final DefaultPermissionGrantPolicy mDefaultPermissionGrantPolicy;
234
Eugene Susla922cd082020-03-11 12:38:17 -0700235 /** App ops manager */
236 private final AppOpsManager mAppOpsManager;
237
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700238 /**
239 * Built-in permissions. Read from system configuration files. Mapping is from
240 * UID to permission name.
241 */
Todd Kennedy3bc94722017-10-10 09:55:53 -0700242 private final SparseArray<ArraySet<String>> mSystemPermissions;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700243
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700244 /** Built-in group IDs given to all packages. Read from system configuration files. */
245 private final int[] mGlobalGids;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700246
247 private final HandlerThread mHandlerThread;
248 private final Handler mHandler;
249 private final Context mContext;
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -0700250 private final MetricsLogger mMetricsLogger = new MetricsLogger();
Evan Severson50a77742020-01-06 10:38:19 -0800251 private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
252 ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
Todd Kennedy0eb97382017-10-03 16:57:22 -0700253
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700254 /** Internal storage for permissions and related settings */
255 @GuardedBy("mLock")
256 private final PermissionSettings mSettings;
257
Michael Groover56a84b22020-03-04 20:41:36 -0800258 /** Injector that can be used to facilitate testing. */
259 private final Injector mInjector;
260
Todd Kennedyc29b11a2017-10-23 15:55:59 -0700261 @GuardedBy("mLock")
262 private ArraySet<String> mPrivappPermissionsViolations;
263
264 @GuardedBy("mLock")
265 private boolean mSystemReady;
266
Svet Ganov3c499ea2019-07-26 17:45:56 -0700267 @GuardedBy("mLock")
268 private PermissionPolicyInternal mPermissionPolicyInternal;
269
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -0700270 /**
271 * For each foreground/background permission the mapping:
272 * Background permission -> foreground permissions
273 */
274 @GuardedBy("mLock")
275 private ArrayMap<String, List<String>> mBackgroundPermissions;
276
Philip P. Moltmann48456672019-01-20 13:14:03 -0800277 /**
278 * A permission backup might contain apps that are not installed. In this case we delay the
279 * restoration until the app is installed.
280 *
281 * <p>This array ({@code userId -> noDelayedBackupLeft}) is {@code true} for all the users where
282 * there is <u>no more</u> delayed backup left.
283 */
284 @GuardedBy("mLock")
285 private final SparseBooleanArray mHasNoDelayedPermBackup = new SparseBooleanArray();
286
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700287 /** Listeners for permission state (granting and flags) changes */
288 @GuardedBy("mLock")
289 final private ArrayList<OnRuntimePermissionStateChangedListener>
290 mRuntimePermissionStateChangedListeners = new ArrayList<>();
291
Todd Kennedyca1ea172019-07-03 15:02:28 -0700292 @GuardedBy("mLock")
293 private CheckPermissionDelegate mCheckPermissionDelegate;
294
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700295 @GuardedBy("mLock")
296 private final OnPermissionChangeListeners mOnPermissionChangeListeners;
297
Todd Kennedy583378d2019-07-12 06:50:30 -0700298 @GuardedBy("mLock")
299 private DefaultBrowserProvider mDefaultBrowserProvider;
300
301 @GuardedBy("mLock")
302 private DefaultDialerProvider mDefaultDialerProvider;
303
304 @GuardedBy("mLock")
305 private DefaultHomeProvider mDefaultHomeProvider;
306
Todd Kennedy230c0a72019-07-03 13:06:35 -0700307 // TODO: Take a look at the methods defined in the callback.
308 // The callback was initially created to support the split between permission
309 // manager and the package manager. However, it's started to be used for other
310 // purposes. It may make sense to keep as an abstraction, but, the methods
311 // necessary to be overridden may be different than what was initially needed
312 // for the split.
313 private PermissionCallback mDefaultPermissionCallback = new PermissionCallback() {
314 @Override
315 public void onGidsChanged(int appId, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -0700316 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700317 }
318 @Override
319 public void onPermissionGranted(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700320 mOnPermissionChangeListeners.onPermissionsChanged(uid);
321
322 // Not critical; if this is lost, the application has to request again.
323 mPackageManagerInt.writeSettings(true);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700324 }
325 @Override
326 public void onInstallPermissionGranted() {
327 mPackageManagerInt.writeSettings(true);
328 }
329 @Override
330 public void onPermissionRevoked(int uid, int userId) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700331 mOnPermissionChangeListeners.onPermissionsChanged(uid);
332
333 // Critical; after this call the application should never have the permission
334 mPackageManagerInt.writeSettings(false);
335 final int appId = UserHandle.getAppId(uid);
Philip P. Moltmannd3c37422019-10-11 14:59:33 -0700336 mHandler.post(() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
Todd Kennedy230c0a72019-07-03 13:06:35 -0700337 }
338 @Override
339 public void onInstallPermissionRevoked() {
340 mPackageManagerInt.writeSettings(true);
341 }
342 @Override
343 public void onPermissionUpdated(int[] userIds, boolean sync) {
344 mPackageManagerInt.writePermissionSettings(userIds, !sync);
345 }
346 @Override
347 public void onInstallPermissionUpdated() {
348 mPackageManagerInt.writeSettings(true);
349 }
350 @Override
351 public void onPermissionRemoved() {
352 mPackageManagerInt.writeSettings(false);
353 }
354 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds, boolean sync,
355 int uid) {
356 onPermissionUpdated(updatedUserIds, sync);
Nate Myren3fb13a12019-12-11 12:30:39 -0800357 for (int i = 0; i < updatedUserIds.length; i++) {
358 int userUid = UserHandle.getUid(updatedUserIds[i], UserHandle.getAppId(uid));
359 mOnPermissionChangeListeners.onPermissionsChanged(userUid);
360 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700361 }
362 public void onInstallPermissionUpdatedNotifyListener(int uid) {
363 onInstallPermissionUpdated();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700364 mOnPermissionChangeListeners.onPermissionsChanged(uid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700365 }
366 };
367
Todd Kennedy0eb97382017-10-03 16:57:22 -0700368 PermissionManagerService(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700369 @NonNull Object externalLock) {
Michael Groover56a84b22020-03-04 20:41:36 -0800370 this(context, externalLock, new Injector(context));
371 }
372
373 @VisibleForTesting
374 PermissionManagerService(Context context, @NonNull Object externalLock,
375 @NonNull Injector injector) {
376 mInjector = injector;
Daniel Colascionea46b7b32020-01-24 13:30:25 -0800377 // The package info cache is the cache for package and permission information.
Michael Groover56a84b22020-03-04 20:41:36 -0800378 mInjector.invalidatePackageInfoCache();
379 mInjector.disablePermissionCache();
380 mInjector.disablePackageNamePermissionCache();
Daniel Colascionea46b7b32020-01-24 13:30:25 -0800381
Todd Kennedy0eb97382017-10-03 16:57:22 -0700382 mContext = context;
383 mLock = externalLock;
384 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
385 mUserManagerInt = LocalServices.getService(UserManagerInternal.class);
Philip P. Moltmann6c644e62018-07-18 15:41:24 -0700386 mSettings = new PermissionSettings(mLock);
Eugene Susla922cd082020-03-11 12:38:17 -0700387 mAppOpsManager = context.getSystemService(AppOpsManager.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700388
389 mHandlerThread = new ServiceThread(TAG,
390 Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
391 mHandlerThread.start();
392 mHandler = new Handler(mHandlerThread.getLooper());
393 Watchdog.getInstance().addThread(mHandler);
394
395 mDefaultPermissionGrantPolicy = new DefaultPermissionGrantPolicy(
Philip P. Moltmannbe11ab62020-05-01 00:11:09 -0700396 context, mHandlerThread.getLooper());
Todd Kennedy3bc94722017-10-10 09:55:53 -0700397 SystemConfig systemConfig = SystemConfig.getInstance();
398 mSystemPermissions = systemConfig.getSystemPermissions();
399 mGlobalGids = systemConfig.getGlobalGids();
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700400 mOnPermissionChangeListeners = new OnPermissionChangeListeners(FgThread.get().getLooper());
Todd Kennedy0eb97382017-10-03 16:57:22 -0700401
402 // propagate permission configuration
403 final ArrayMap<String, SystemConfig.PermissionEntry> permConfig =
404 SystemConfig.getInstance().getPermissions();
405 synchronized (mLock) {
406 for (int i=0; i<permConfig.size(); i++) {
407 final SystemConfig.PermissionEntry perm = permConfig.valueAt(i);
408 BasePermission bp = mSettings.getPermissionLocked(perm.name);
409 if (bp == null) {
410 bp = new BasePermission(perm.name, "android", BasePermission.TYPE_BUILTIN);
411 mSettings.putPermissionLocked(perm.name, bp);
412 }
413 if (perm.gids != null) {
414 bp.setGids(perm.gids, perm.perUser);
415 }
416 }
417 }
418
Philip P. Moltmann48456672019-01-20 13:14:03 -0800419 PermissionManagerServiceInternalImpl localService =
420 new PermissionManagerServiceInternalImpl();
421 LocalServices.addService(PermissionManagerServiceInternal.class, localService);
422 LocalServices.addService(PermissionManagerInternal.class, localService);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700423 }
424
Philip P. Moltmann5ab27fc2020-05-06 17:10:59 -0700425 @Override
426 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Philip P. Moltmann58c52d42020-05-18 12:06:13 -0700427 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) {
428 return;
429 }
430
Philip P. Moltmann1a446782020-05-07 22:51:38 -0700431 mContext.getSystemService(PermissionControllerManager.class).dump(fd, args);
Philip P. Moltmann5ab27fc2020-05-06 17:10:59 -0700432 }
433
Todd Kennedy0eb97382017-10-03 16:57:22 -0700434 /**
435 * Creates and returns an initialized, internal service for use by other components.
436 * <p>
437 * The object returned is identical to the one returned by the LocalServices class using:
Philip P. Moltmann48456672019-01-20 13:14:03 -0800438 * {@code LocalServices.getService(PermissionManagerServiceInternal.class);}
Todd Kennedy0eb97382017-10-03 16:57:22 -0700439 * <p>
440 * NOTE: The external lock is temporary and should be removed. This needs to be a
441 * lock created by the permission manager itself.
442 */
Philip P. Moltmann48456672019-01-20 13:14:03 -0800443 public static PermissionManagerServiceInternal create(Context context,
Todd Kennedy0eb97382017-10-03 16:57:22 -0700444 @NonNull Object externalLock) {
Philip P. Moltmann48456672019-01-20 13:14:03 -0800445 final PermissionManagerServiceInternal permMgrInt =
446 LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700447 if (permMgrInt != null) {
448 return permMgrInt;
449 }
Todd Kennedy8f135982019-07-02 07:35:15 -0700450 PermissionManagerService permissionService =
451 (PermissionManagerService) ServiceManager.getService("permissionmgr");
452 if (permissionService == null) {
453 permissionService =
454 new PermissionManagerService(context, externalLock);
455 ServiceManager.addService("permissionmgr", permissionService);
456 }
Philip P. Moltmann48456672019-01-20 13:14:03 -0800457 return LocalServices.getService(PermissionManagerServiceInternal.class);
Todd Kennedy0eb97382017-10-03 16:57:22 -0700458 }
459
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700460 /**
461 * This method should typically only be used when granting or revoking
462 * permissions, since the app may immediately restart after this call.
463 * <p>
464 * If you're doing surgery on app code/data, use {@link PackageFreezer} to
465 * guard your work against the app being relaunched.
466 */
467 public static void killUid(int appId, int userId, String reason) {
468 final long identity = Binder.clearCallingIdentity();
469 try {
470 IActivityManager am = ActivityManager.getService();
471 if (am != null) {
472 try {
473 am.killUid(appId, userId, reason);
474 } catch (RemoteException e) {
475 /* ignore - same process */
476 }
477 }
478 } finally {
479 Binder.restoreCallingIdentity(identity);
480 }
481 }
482
Winson14ff7172019-10-23 10:42:27 -0700483 @Nullable
484 BasePermission getPermission(String permName) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700485 synchronized (mLock) {
486 return mSettings.getPermissionLocked(permName);
487 }
488 }
489
Todd Kennedy8f135982019-07-02 07:35:15 -0700490 @Override
491 public String[] getAppOpPermissionPackages(String permName) {
492 return getAppOpPermissionPackagesInternal(permName, getCallingUid());
493 }
494
495 private String[] getAppOpPermissionPackagesInternal(String permName, int callingUid) {
496 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
497 return null;
498 }
499 synchronized (mLock) {
500 final ArraySet<String> pkgs = mSettings.mAppOpPermissionPackages.get(permName);
501 if (pkgs == null) {
502 return null;
503 }
504 return pkgs.toArray(new String[pkgs.size()]);
505 }
506 }
507
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700508 @Override
509 @NonNull
510 public ParceledListSlice<PermissionGroupInfo> getAllPermissionGroups(
511 @PermissionGroupInfoFlags int flags) {
512 final int callingUid = getCallingUid();
513 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
514 return ParceledListSlice.emptyList();
515 }
516 synchronized (mLock) {
517 final int n = mSettings.mPermissionGroups.size();
Winson14ff7172019-10-23 10:42:27 -0700518 final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n);
519 for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) {
520 out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700521 }
522 return new ParceledListSlice<>(out);
523 }
524 }
525
526
527 @Override
528 @Nullable
529 public PermissionGroupInfo getPermissionGroupInfo(String groupName,
530 @PermissionGroupInfoFlags int flags) {
531 final int callingUid = getCallingUid();
532 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
533 return null;
534 }
535 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -0700536 return PackageInfoUtils.generatePermissionGroupInfo(
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700537 mSettings.mPermissionGroups.get(groupName), flags);
538 }
539 }
540
541
542 @Override
543 @Nullable
544 public PermissionInfo getPermissionInfo(String permName, String packageName,
545 @PermissionInfoFlags int flags) {
546 final int callingUid = getCallingUid();
547 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
548 return null;
549 }
550 synchronized (mLock) {
551 final BasePermission bp = mSettings.getPermissionLocked(permName);
552 if (bp == null) {
553 return null;
554 }
555 final int adjustedProtectionLevel = adjustPermissionProtectionFlagsLocked(
556 bp.getProtectionLevel(), packageName, callingUid);
557 return bp.generatePermissionInfo(adjustedProtectionLevel, flags);
558 }
559 }
560
561 @Override
562 @Nullable
563 public ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String groupName,
564 @PermissionInfoFlags int flags) {
565 final int callingUid = getCallingUid();
566 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
567 return null;
568 }
569 synchronized (mLock) {
570 if (groupName != null && !mSettings.mPermissionGroups.containsKey(groupName)) {
571 return null;
572 }
573 final ArrayList<PermissionInfo> out = new ArrayList<PermissionInfo>(10);
574 for (BasePermission bp : mSettings.mPermissions.values()) {
575 final PermissionInfo pi = bp.generatePermissionInfo(groupName, flags);
576 if (pi != null) {
577 out.add(pi);
578 }
579 }
580 return new ParceledListSlice<>(out);
581 }
582 }
583
Todd Kennedy6ffc5a62019-07-03 09:35:31 -0700584 @Override
585 public boolean addPermission(PermissionInfo info, boolean async) {
586 final int callingUid = getCallingUid();
587 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
588 throw new SecurityException("Instant apps can't add permissions");
589 }
590 if (info.labelRes == 0 && info.nonLocalizedLabel == null) {
591 throw new SecurityException("Label must be specified in permission");
592 }
593 final BasePermission tree = mSettings.enforcePermissionTree(info.name, callingUid);
594 final boolean added;
595 final boolean changed;
596 synchronized (mLock) {
597 BasePermission bp = mSettings.getPermissionLocked(info.name);
598 added = bp == null;
599 int fixedLevel = PermissionInfo.fixProtectionLevel(info.protectionLevel);
600 if (added) {
601 enforcePermissionCapLocked(info, tree);
602 bp = new BasePermission(info.name, tree.getSourcePackageName(),
603 BasePermission.TYPE_DYNAMIC);
604 } else if (!bp.isDynamic()) {
605 throw new SecurityException("Not allowed to modify non-dynamic permission "
606 + info.name);
607 }
608 changed = bp.addToTree(fixedLevel, info, tree);
609 if (added) {
610 mSettings.putPermissionLocked(info.name, bp);
611 }
612 }
613 if (changed) {
614 mPackageManagerInt.writeSettings(async);
615 }
616 return added;
617 }
618
619 @Override
620 public void removePermission(String permName) {
621 final int callingUid = getCallingUid();
622 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
623 throw new SecurityException("Instant applications don't have access to this method");
624 }
625 final BasePermission tree = mSettings.enforcePermissionTree(permName, callingUid);
626 synchronized (mLock) {
627 final BasePermission bp = mSettings.getPermissionLocked(permName);
628 if (bp == null) {
629 return;
630 }
631 if (bp.isDynamic()) {
632 // TODO: switch this back to SecurityException
633 Slog.wtf(TAG, "Not allowed to modify non-dynamic permission "
634 + permName);
635 }
636 mSettings.removePermissionLocked(permName);
637 mPackageManagerInt.writeSettings(false);
638 }
639 }
Todd Kennedy1d29b4a2019-07-02 14:49:28 -0700640
Todd Kennedy230c0a72019-07-03 13:06:35 -0700641 @Override
642 public int getPermissionFlags(String permName, String packageName, int userId) {
643 final int callingUid = getCallingUid();
644 return getPermissionFlagsInternal(permName, packageName, callingUid, userId);
645 }
646
647 private int getPermissionFlagsInternal(
648 String permName, String packageName, int callingUid, int userId) {
649 if (!mUserManagerInt.exists(userId)) {
650 return 0;
651 }
652
653 enforceGrantRevokeGetRuntimePermissionPermissions("getPermissionFlags");
654 enforceCrossUserPermission(callingUid, userId,
655 true, // requireFullPermission
656 false, // checkShell
657 false, // requirePermissionWhenSameUser
658 "getPermissionFlags");
659
Winson14ff7172019-10-23 10:42:27 -0700660 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
661 if (pkg == null) {
662 return 0;
663 }
664 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
665 pkg.getPackageName());
666 if (ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700667 return 0;
668 }
669 synchronized (mLock) {
670 if (mSettings.getPermissionLocked(permName) == null) {
671 return 0;
672 }
673 }
674 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
675 return 0;
676 }
Todd Kennedy230c0a72019-07-03 13:06:35 -0700677 PermissionsState permissionsState = ps.getPermissionsState();
678 return permissionsState.getPermissionFlags(permName, userId);
679 }
680
681 @Override
682 public void updatePermissionFlags(String permName, String packageName, int flagMask,
683 int flagValues, boolean checkAdjustPolicyFlagPermission, int userId) {
684 final int callingUid = getCallingUid();
685 boolean overridePolicy = false;
686
687 if (callingUid != Process.SYSTEM_UID && callingUid != Process.ROOT_UID) {
688 long callingIdentity = Binder.clearCallingIdentity();
689 try {
690 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0) {
691 if (checkAdjustPolicyFlagPermission) {
692 mContext.enforceCallingOrSelfPermission(
693 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
694 "Need " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY
695 + " to change policy flags");
Hai Zhang053c3a22019-08-23 15:08:03 -0700696 } else if (mPackageManagerInt.getUidTargetSdkVersion(callingUid)
Todd Kennedy230c0a72019-07-03 13:06:35 -0700697 >= Build.VERSION_CODES.Q) {
698 throw new IllegalArgumentException(
699 Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " needs "
700 + " to be checked for packages targeting "
701 + Build.VERSION_CODES.Q + " or later when changing policy "
702 + "flags");
703 }
704 overridePolicy = true;
705 }
706 } finally {
707 Binder.restoreCallingIdentity(callingIdentity);
708 }
709 }
710
711 updatePermissionFlagsInternal(
712 permName, packageName, flagMask, flagValues, callingUid, userId,
713 overridePolicy, mDefaultPermissionCallback);
714 }
715
716 private void updatePermissionFlagsInternal(String permName, String packageName, int flagMask,
717 int flagValues, int callingUid, int userId, boolean overridePolicy,
718 PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700719 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedy230c0a72019-07-03 13:06:35 -0700720 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -0700721 Log.i(TAG, "System is updating flags for " + packageName + " "
Todd Kennedy230c0a72019-07-03 13:06:35 -0700722 + permName + " for user " + userId + " "
723 + DebugUtils.flagsToString(
724 PackageManager.class, "FLAG_PERMISSION_", flagMask)
725 + " := "
726 + DebugUtils.flagsToString(
727 PackageManager.class, "FLAG_PERMISSION_", flagValues)
728 + " on behalf of uid " + callingUid
729 + " " + mPackageManagerInt.getNameForUid(callingUid),
730 new RuntimeException());
731 }
732
733 if (!mUserManagerInt.exists(userId)) {
734 return;
735 }
736
737 enforceGrantRevokeRuntimePermissionPermissions("updatePermissionFlags");
738
739 enforceCrossUserPermission(callingUid, userId,
740 true, // requireFullPermission
741 true, // checkShell
742 false, // requirePermissionWhenSameUser
743 "updatePermissionFlags");
744
745 if ((flagMask & FLAG_PERMISSION_POLICY_FIXED) != 0 && !overridePolicy) {
746 throw new SecurityException("updatePermissionFlags requires "
747 + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
748 }
749
750 // Only the system can change these flags and nothing else.
751 if (callingUid != Process.SYSTEM_UID) {
752 flagMask &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
753 flagValues &= ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
754 flagMask &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
755 flagValues &= ~PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
756 flagValues &= ~PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
757 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
758 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
759 flagValues &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
760 flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
761 }
762
Winson14ff7172019-10-23 10:42:27 -0700763 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
764 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
765 packageName);
766 if (pkg == null || ps == null) {
Todd Kennedy230c0a72019-07-03 13:06:35 -0700767 Log.e(TAG, "Unknown package: " + packageName);
768 return;
769 }
770 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
771 throw new IllegalArgumentException("Unknown package: " + packageName);
772 }
773
774 final BasePermission bp;
775 synchronized (mLock) {
776 bp = mSettings.getPermissionLocked(permName);
777 }
778 if (bp == null) {
779 throw new IllegalArgumentException("Unknown permission: " + permName);
780 }
781
Todd Kennedy230c0a72019-07-03 13:06:35 -0700782 final PermissionsState permissionsState = ps.getPermissionsState();
783 final boolean hadState =
784 permissionsState.getRuntimePermissionState(permName, userId) != null;
785 final boolean permissionUpdated =
786 permissionsState.updatePermissionFlags(bp, userId, flagMask, flagValues);
787 if (permissionUpdated && bp.isRuntime()) {
788 notifyRuntimePermissionStateChanged(packageName, userId);
789 }
790 if (permissionUpdated && callback != null) {
791 // Install and runtime permissions are stored in different places,
792 // so figure out what permission changed and persist the change.
793 if (permissionsState.getInstallPermissionState(permName) != null) {
Nate Myren3fb13a12019-12-11 12:30:39 -0800794 int userUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
795 callback.onInstallPermissionUpdatedNotifyListener(userUid);
Todd Kennedy230c0a72019-07-03 13:06:35 -0700796 } else if (permissionsState.getRuntimePermissionState(permName, userId) != null
797 || hadState) {
Winson14ff7172019-10-23 10:42:27 -0700798 callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false,
799 pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700800 }
801 }
802 }
803
804 /**
805 * Update the permission flags for all packages and runtime permissions of a user in order
806 * to allow device or profile owner to remove POLICY_FIXED.
807 */
808 @Override
809 public void updatePermissionFlagsForAllApps(int flagMask, int flagValues,
810 final int userId) {
811 final int callingUid = getCallingUid();
812 if (!mUserManagerInt.exists(userId)) {
813 return;
814 }
815
816 enforceGrantRevokeRuntimePermissionPermissions(
817 "updatePermissionFlagsForAllApps");
818 enforceCrossUserPermission(callingUid, userId,
819 true, // requireFullPermission
820 true, // checkShell
821 false, // requirePermissionWhenSameUser
822 "updatePermissionFlagsForAllApps");
823
824 // Only the system can change system fixed flags.
825 final int effectiveFlagMask = (callingUid != Process.SYSTEM_UID)
826 ? flagMask : flagMask & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
827 final int effectiveFlagValues = (callingUid != Process.SYSTEM_UID)
828 ? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
829
830 final boolean[] changed = new boolean[1];
Winson14ff7172019-10-23 10:42:27 -0700831 mPackageManagerInt.forEachPackage(pkg -> {
832 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
833 pkg.getPackageName());
834 if (ps == null) {
835 return;
Todd Kennedy230c0a72019-07-03 13:06:35 -0700836 }
Winson14ff7172019-10-23 10:42:27 -0700837 final PermissionsState permissionsState = ps.getPermissionsState();
838 changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
839 userId, effectiveFlagMask, effectiveFlagValues);
840 mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
Todd Kennedy230c0a72019-07-03 13:06:35 -0700841 });
842
843 if (changed[0]) {
844 mPackageManagerInt.writePermissionSettings(new int[] { userId }, true);
845 }
846 }
847
Todd Kennedyca1ea172019-07-03 15:02:28 -0700848 @Override
849 public int checkPermission(String permName, String pkgName, int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000850 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700851 if (permName == null || pkgName == null) {
852 return PackageManager.PERMISSION_DENIED;
853 }
854 if (!mUserManagerInt.exists(userId)) {
855 return PackageManager.PERMISSION_DENIED;
856 }
857
Todd Kennedyca1ea172019-07-03 15:02:28 -0700858 final CheckPermissionDelegate checkPermissionDelegate;
859 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700860 checkPermissionDelegate = mCheckPermissionDelegate;
861 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700862 if (checkPermissionDelegate == null) {
863 return checkPermissionImpl(permName, pkgName, userId);
864 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700865 return checkPermissionDelegate.checkPermission(permName, pkgName, userId,
Hai Zhang61b4d352019-10-07 13:45:26 -0700866 this::checkPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700867 }
868
Hai Zhang4fef76a2019-09-28 00:03:50 +0000869 private int checkPermissionImpl(String permName, String pkgName, int userId) {
Winson655a5b92019-10-23 10:49:32 -0700870 final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName);
Hai Zhang3b049a52019-08-16 15:37:46 -0700871 if (pkg == null) {
Todd Kennedy0eb97382017-10-03 16:57:22 -0700872 return PackageManager.PERMISSION_DENIED;
873 }
Hai Zhang4fef76a2019-09-28 00:03:50 +0000874 return checkPermissionInternal(pkg, true, permName, userId);
Hai Zhang3b049a52019-08-16 15:37:46 -0700875 }
876
Winson655a5b92019-10-23 10:49:32 -0700877 private int checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000878 @NonNull String permissionName, @UserIdInt int userId) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700879 final int callingUid = getCallingUid();
Winson14ff7172019-10-23 10:42:27 -0700880 if (isPackageExplicit || pkg.getSharedUserId() == null) {
Patrick Baumann97b9b532018-04-11 14:51:30 +0000881 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000882 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700883 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700884 } else {
885 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000886 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700887 }
888 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700889
Winson14ff7172019-10-23 10:42:27 -0700890 final int uid = UserHandle.getUid(userId, pkg.getUid());
891 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
892 pkg.getPackageName());
Hai Zhang3b049a52019-08-16 15:37:46 -0700893 if (ps == null) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000894 return PackageManager.PERMISSION_DENIED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700895 }
896 final PermissionsState permissionsState = ps.getPermissionsState();
897
Hai Zhang4fef76a2019-09-28 00:03:50 +0000898 if (checkSinglePermissionInternal(uid, permissionsState, permissionName)) {
899 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700900 }
901
902 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000903 if (fullerPermissionName != null
904 && checkSinglePermissionInternal(uid, permissionsState, fullerPermissionName)) {
905 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700906 }
907
Hai Zhang4fef76a2019-09-28 00:03:50 +0000908 return PackageManager.PERMISSION_DENIED;
Todd Kennedy0eb97382017-10-03 16:57:22 -0700909 }
910
Hai Zhang3b049a52019-08-16 15:37:46 -0700911 private boolean checkSinglePermissionInternal(int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000912 @NonNull PermissionsState permissionsState, @NonNull String permissionName) {
Hai Zhang61b4d352019-10-07 13:45:26 -0700913 if (!permissionsState.hasPermission(permissionName, UserHandle.getUserId(uid))) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700914 return false;
915 }
916
917 if (mPackageManagerInt.getInstantAppPackageName(uid) != null) {
918 return mSettings.isPermissionInstant(permissionName);
919 }
920
921 return true;
922 }
923
Todd Kennedyca1ea172019-07-03 15:02:28 -0700924 @Override
925 public int checkUidPermission(String permName, int uid) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +0000926 // Not using Objects.requireNonNull() here for compatibility reasons.
Hai Zhang3b049a52019-08-16 15:37:46 -0700927 if (permName == null) {
928 return PackageManager.PERMISSION_DENIED;
929 }
930 final int userId = UserHandle.getUserId(uid);
931 if (!mUserManagerInt.exists(userId)) {
932 return PackageManager.PERMISSION_DENIED;
933 }
934
Todd Kennedyca1ea172019-07-03 15:02:28 -0700935 final CheckPermissionDelegate checkPermissionDelegate;
936 synchronized (mLock) {
Todd Kennedyca1ea172019-07-03 15:02:28 -0700937 checkPermissionDelegate = mCheckPermissionDelegate;
938 }
Hai Zhang61b4d352019-10-07 13:45:26 -0700939 if (checkPermissionDelegate == null) {
940 return checkUidPermissionImpl(permName, uid);
941 }
Todd Kennedyca1ea172019-07-03 15:02:28 -0700942 return checkPermissionDelegate.checkUidPermission(permName, uid,
Hai Zhang61b4d352019-10-07 13:45:26 -0700943 this::checkUidPermissionImpl);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700944 }
945
Hai Zhang4fef76a2019-09-28 00:03:50 +0000946 private int checkUidPermissionImpl(String permName, int uid) {
Winson655a5b92019-10-23 10:49:32 -0700947 final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000948 return checkUidPermissionInternal(pkg, uid, permName);
Todd Kennedyca1ea172019-07-03 15:02:28 -0700949 }
950
951 /**
952 * Checks whether or not the given package has been granted the specified
953 * permission. If the given package is {@code null}, we instead check the
954 * system permissions for the given UID.
955 *
956 * @see SystemConfig#getSystemPermissions()
957 */
Winson655a5b92019-10-23 10:49:32 -0700958 private int checkUidPermissionInternal(@Nullable AndroidPackage pkg, int uid,
Hai Zhang4fef76a2019-09-28 00:03:50 +0000959 @NonNull String permissionName) {
Hai Zhang3b049a52019-08-16 15:37:46 -0700960 if (pkg != null) {
961 final int userId = UserHandle.getUserId(uid);
Hai Zhang4fef76a2019-09-28 00:03:50 +0000962 return checkPermissionInternal(pkg, false, permissionName, userId);
Todd Kennedy3bc94722017-10-10 09:55:53 -0700963 }
964
Hai Zhang3b049a52019-08-16 15:37:46 -0700965 if (checkSingleUidPermissionInternal(uid, permissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000966 return PackageManager.PERMISSION_GRANTED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700967 }
Hai Zhang3b049a52019-08-16 15:37:46 -0700968
969 final String fullerPermissionName = FULLER_PERMISSION_MAP.get(permissionName);
970 if (fullerPermissionName != null
971 && checkSingleUidPermissionInternal(uid, fullerPermissionName)) {
Hai Zhang4fef76a2019-09-28 00:03:50 +0000972 return PackageManager.PERMISSION_GRANTED;
Hai Zhang3b049a52019-08-16 15:37:46 -0700973 }
974
Hai Zhang4fef76a2019-09-28 00:03:50 +0000975 return PackageManager.PERMISSION_DENIED;
Todd Kennedy3bc94722017-10-10 09:55:53 -0700976 }
977
Hai Zhang3b049a52019-08-16 15:37:46 -0700978 private boolean checkSingleUidPermissionInternal(int uid, @NonNull String permissionName) {
979 synchronized (mLock) {
980 ArraySet<String> permissions = mSystemPermissions.get(uid);
981 return permissions != null && permissions.contains(permissionName);
982 }
983 }
984
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -0700985 @Override
Michael Groover56a84b22020-03-04 20:41:36 -0800986 public int checkDeviceIdentifierAccess(@Nullable String packageName, @Nullable String message,
987 @Nullable String callingFeatureId, int pid, int uid) {
988 // If the check is being requested by an app then only allow the app to query its own
989 // access status.
990 int callingUid = mInjector.getCallingUid();
991 int callingPid = mInjector.getCallingPid();
992 if (UserHandle.getAppId(callingUid) >= Process.FIRST_APPLICATION_UID && (callingUid != uid
993 || callingPid != pid)) {
994 String response = String.format(
995 "Calling uid %d, pid %d cannot check device identifier access for package %s "
996 + "(uid=%d, pid=%d)",
997 callingUid, callingPid, packageName, uid, pid);
998 Log.w(TAG, response);
999 throw new SecurityException(response);
1000 }
1001 // Allow system and root access to the device identifiers.
1002 final int appId = UserHandle.getAppId(uid);
1003 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID) {
1004 return PackageManager.PERMISSION_GRANTED;
1005 }
1006 // Allow access to packages that have the READ_PRIVILEGED_PHONE_STATE permission.
1007 if (mInjector.checkPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, pid,
1008 uid) == PackageManager.PERMISSION_GRANTED) {
1009 return PackageManager.PERMISSION_GRANTED;
1010 }
1011 // If the calling package is not null then perform the appop and device / profile owner
1012 // check.
1013 if (packageName != null) {
1014 // Allow access to a package that has been granted the READ_DEVICE_IDENTIFIERS appop.
1015 long token = mInjector.clearCallingIdentity();
1016 AppOpsManager appOpsManager = (AppOpsManager) mInjector.getSystemService(
1017 Context.APP_OPS_SERVICE);
1018 try {
1019 if (appOpsManager.noteOpNoThrow(AppOpsManager.OPSTR_READ_DEVICE_IDENTIFIERS, uid,
1020 packageName, callingFeatureId, message) == AppOpsManager.MODE_ALLOWED) {
1021 return PackageManager.PERMISSION_GRANTED;
1022 }
1023 } finally {
1024 mInjector.restoreCallingIdentity(token);
1025 }
1026 // Check if the calling packages meets the device / profile owner requirements for
1027 // identifier access.
1028 DevicePolicyManager devicePolicyManager =
1029 (DevicePolicyManager) mInjector.getSystemService(Context.DEVICE_POLICY_SERVICE);
1030 if (devicePolicyManager != null && devicePolicyManager.hasDeviceIdentifierAccess(
1031 packageName, pid, uid)) {
1032 return PackageManager.PERMISSION_GRANTED;
1033 }
1034 }
1035 return PackageManager.PERMISSION_DENIED;
1036 }
1037
1038 @Override
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001039 public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1040 mContext.enforceCallingOrSelfPermission(
1041 Manifest.permission.OBSERVE_GRANT_REVOKE_PERMISSIONS,
1042 "addOnPermissionsChangeListener");
1043
1044 synchronized (mLock) {
1045 mOnPermissionChangeListeners.addListenerLocked(listener);
1046 }
1047 }
1048
1049 @Override
1050 public void removeOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
1051 if (mPackageManagerInt.getInstantAppPackageName(Binder.getCallingUid()) != null) {
1052 throw new SecurityException("Instant applications don't have access to this method");
1053 }
1054 synchronized (mLock) {
1055 mOnPermissionChangeListeners.removeListenerLocked(listener);
1056 }
1057 }
1058
1059 @Override
1060 @Nullable public List<String> getWhitelistedRestrictedPermissions(@NonNull String packageName,
1061 @PermissionWhitelistFlags int flags, @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001062 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001063 Preconditions.checkFlagsArgument(flags,
1064 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1065 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1066 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1067 Preconditions.checkArgumentNonNegative(userId, null);
1068
1069 if (UserHandle.getCallingUserId() != userId) {
1070 mContext.enforceCallingOrSelfPermission(
1071 android.Manifest.permission.INTERACT_ACROSS_USERS,
1072 "getWhitelistedRestrictedPermissions for user " + userId);
1073 }
1074
Winson14ff7172019-10-23 10:42:27 -07001075 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001076 if (pkg == null) {
1077 return null;
1078 }
1079
1080 final int callingUid = Binder.getCallingUid();
1081 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1082 return null;
1083 }
1084 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1085 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1086 == PackageManager.PERMISSION_GRANTED;
1087 final boolean isCallerInstallerOnRecord =
1088 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1089
1090 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1091 && !isCallerPrivileged) {
1092 throw new SecurityException("Querying system whitelist requires "
1093 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1094 }
1095
1096 if ((flags & (PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1097 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER)) != 0) {
1098 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1099 throw new SecurityException("Querying upgrade or installer whitelist"
1100 + " requires being installer on record or "
1101 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1102 }
1103 }
1104
1105 final long identity = Binder.clearCallingIdentity();
1106 try {
1107 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07001108 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001109 if (permissionsState == null) {
1110 return null;
1111 }
1112
1113 int queryFlags = 0;
1114 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0) {
1115 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
1116 }
1117 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1118 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
1119 }
1120 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1121 queryFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
1122 }
1123
1124 ArrayList<String> whitelistedPermissions = null;
1125
Winson14ff7172019-10-23 10:42:27 -07001126 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001127 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001128 final String permissionName = pkg.getRequestedPermissions().get(i);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001129 final int currentFlags =
1130 permissionsState.getPermissionFlags(permissionName, userId);
1131 if ((currentFlags & queryFlags) != 0) {
1132 if (whitelistedPermissions == null) {
1133 whitelistedPermissions = new ArrayList<>();
1134 }
1135 whitelistedPermissions.add(permissionName);
1136 }
1137 }
1138
1139 return whitelistedPermissions;
1140 } finally {
1141 Binder.restoreCallingIdentity(identity);
1142 }
1143 }
1144
1145 @Override
1146 public boolean addWhitelistedRestrictedPermission(@NonNull String packageName,
1147 @NonNull String permName, @PermissionWhitelistFlags int flags,
1148 @UserIdInt int userId) {
1149 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001150 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001151
1152 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1153 return false;
1154 }
1155
1156 List<String> permissions =
1157 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1158 if (permissions == null) {
1159 permissions = new ArrayList<>(1);
1160 }
1161 if (permissions.indexOf(permName) < 0) {
1162 permissions.add(permName);
1163 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1164 flags, userId);
1165 }
1166 return false;
1167 }
1168
1169 private boolean checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(
1170 @NonNull String permName) {
1171 synchronized (mLock) {
1172 final BasePermission bp = mSettings.getPermissionLocked(permName);
1173 if (bp == null) {
1174 Slog.w(TAG, "No such permissions: " + permName);
1175 return false;
1176 }
1177 if (bp.isHardOrSoftRestricted() && bp.isImmutablyRestricted()
1178 && mContext.checkCallingOrSelfPermission(
1179 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1180 != PackageManager.PERMISSION_GRANTED) {
1181 throw new SecurityException("Cannot modify whitelisting of an immutably "
1182 + "restricted permission: " + permName);
1183 }
1184 return true;
1185 }
1186 }
1187
1188 @Override
1189 public boolean removeWhitelistedRestrictedPermission(@NonNull String packageName,
1190 @NonNull String permName, @PermissionWhitelistFlags int flags,
1191 @UserIdInt int userId) {
1192 // Other argument checks are done in get/setWhitelistedRestrictedPermissions
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001193 Objects.requireNonNull(permName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001194
1195 if (!checkExistsAndEnforceCannotModifyImmutablyRestrictedPermission(permName)) {
1196 return false;
1197 }
1198
1199 final List<String> permissions =
1200 getWhitelistedRestrictedPermissions(packageName, flags, userId);
1201 if (permissions != null && permissions.remove(permName)) {
1202 return setWhitelistedRestrictedPermissionsInternal(packageName, permissions,
1203 flags, userId);
1204 }
1205 return false;
1206 }
1207
1208 private boolean setWhitelistedRestrictedPermissionsInternal(@NonNull String packageName,
1209 @Nullable List<String> permissions, @PermissionWhitelistFlags int flags,
1210 @UserIdInt int userId) {
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00001211 Objects.requireNonNull(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001212 Preconditions.checkFlagsArgument(flags,
1213 PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE
1214 | PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM
1215 | PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER);
1216 Preconditions.checkArgument(Integer.bitCount(flags) == 1);
1217 Preconditions.checkArgumentNonNegative(userId, null);
1218
1219 if (UserHandle.getCallingUserId() != userId) {
1220 mContext.enforceCallingOrSelfPermission(
1221 Manifest.permission.INTERACT_ACROSS_USERS,
1222 "setWhitelistedRestrictedPermissions for user " + userId);
1223 }
1224
Winson14ff7172019-10-23 10:42:27 -07001225 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001226 if (pkg == null) {
1227 return false;
1228 }
1229
1230 final int callingUid = Binder.getCallingUid();
1231 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, UserHandle.getCallingUserId())) {
1232 return false;
1233 }
1234
1235 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1236 Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS)
1237 == PackageManager.PERMISSION_GRANTED;
1238 final boolean isCallerInstallerOnRecord =
1239 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1240
1241 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_SYSTEM) != 0
1242 && !isCallerPrivileged) {
1243 throw new SecurityException("Modifying system whitelist requires "
1244 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1245 }
1246
1247 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_UPGRADE) != 0) {
1248 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1249 throw new SecurityException("Modifying upgrade whitelist requires"
1250 + " being installer on record or "
1251 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1252 }
1253 final List<String> whitelistedPermissions =
Winson14ff7172019-10-23 10:42:27 -07001254 getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07001255 if (permissions == null || permissions.isEmpty()) {
1256 if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
1257 return true;
1258 }
1259 } else {
1260 // Only the system can add and remove while the installer can only remove.
1261 final int permissionCount = permissions.size();
1262 for (int i = 0; i < permissionCount; i++) {
1263 if ((whitelistedPermissions == null
1264 || !whitelistedPermissions.contains(permissions.get(i)))
1265 && !isCallerPrivileged) {
1266 throw new SecurityException("Adding to upgrade whitelist requires"
1267 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1268 }
1269 }
1270 }
1271
1272 if ((flags & PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER) != 0) {
1273 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1274 throw new SecurityException("Modifying installer whitelist requires"
1275 + " being installer on record or "
1276 + Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
1277 }
1278 }
1279 }
1280
1281 final long identity = Binder.clearCallingIdentity();
1282 try {
1283 setWhitelistedRestrictedPermissionsForUser(
1284 pkg, userId, permissions, Process.myUid(), flags, mDefaultPermissionCallback);
1285 } finally {
1286 Binder.restoreCallingIdentity(identity);
1287 }
1288
1289 return true;
1290 }
1291
Todd Kennedyc971a452019-07-08 16:04:52 -07001292 @Override
Eugene Susla922cd082020-03-11 12:38:17 -07001293 public boolean setAutoRevokeWhitelisted(
1294 @NonNull String packageName, boolean whitelisted, int userId) {
1295 Objects.requireNonNull(packageName);
1296
1297 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1298 final int callingUid = Binder.getCallingUid();
Eugene Susla64c88c02020-05-07 15:31:23 -07001299 final int packageUid = UserHandle.getUid(userId, pkg.getUid());
Eugene Susla922cd082020-03-11 12:38:17 -07001300
1301 if (!checkAutoRevokeAccess(pkg, callingUid)) {
1302 return false;
1303 }
1304
1305 if (mAppOpsManager
1306 .checkOpNoThrow(AppOpsManager.OP_AUTO_REVOKE_MANAGED_BY_INSTALLER,
Eugene Susla64c88c02020-05-07 15:31:23 -07001307 packageUid, packageName)
Eugene Susla922cd082020-03-11 12:38:17 -07001308 != MODE_ALLOWED) {
1309 // Whitelist user set - don't override
1310 return false;
1311 }
1312
1313 final long identity = Binder.clearCallingIdentity();
1314 try {
1315 mAppOpsManager.setMode(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
Eugene Susla64c88c02020-05-07 15:31:23 -07001316 packageUid, packageName,
Eugene Susla922cd082020-03-11 12:38:17 -07001317 whitelisted ? MODE_IGNORED : MODE_ALLOWED);
1318 } finally {
1319 Binder.restoreCallingIdentity(identity);
1320 }
1321 return true;
1322 }
1323
1324 private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
1325 if (pkg == null) {
1326 return false;
1327 }
1328
1329 final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
1330 Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
1331 == PackageManager.PERMISSION_GRANTED;
1332 final boolean isCallerInstallerOnRecord =
1333 mPackageManagerInt.isCallerInstallerOfRecord(pkg, callingUid);
1334
1335 if (!isCallerPrivileged && !isCallerInstallerOnRecord) {
1336 throw new SecurityException("Caller must either hold "
1337 + Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
1338 + " or be the installer on record");
1339 }
1340 return true;
1341 }
1342
1343 @Override
1344 public boolean isAutoRevokeWhitelisted(@NonNull String packageName, int userId) {
1345 Objects.requireNonNull(packageName);
1346
1347 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1348 final int callingUid = Binder.getCallingUid();
Eugene Susla64c88c02020-05-07 15:31:23 -07001349 final int packageUid = UserHandle.getUid(userId, pkg.getUid());
Eugene Susla922cd082020-03-11 12:38:17 -07001350
1351 if (!checkAutoRevokeAccess(pkg, callingUid)) {
1352 return false;
1353 }
1354
1355 final long identity = Binder.clearCallingIdentity();
1356 try {
1357 return mAppOpsManager.checkOpNoThrow(
Eugene Susla64c88c02020-05-07 15:31:23 -07001358 AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, packageUid, packageName)
Eugene Susla922cd082020-03-11 12:38:17 -07001359 == MODE_IGNORED;
1360 } finally {
1361 Binder.restoreCallingIdentity(identity);
1362 }
1363 }
1364
1365 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07001366 public void grantRuntimePermission(String packageName, String permName, final int userId) {
1367 final int callingUid = Binder.getCallingUid();
1368 final boolean overridePolicy =
1369 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1370 == PackageManager.PERMISSION_GRANTED;
1371
1372 grantRuntimePermissionInternal(permName, packageName, overridePolicy,
1373 callingUid, userId, mDefaultPermissionCallback);
1374 }
1375
1376 // TODO swap permission name and package name
1377 private void grantRuntimePermissionInternal(String permName, String packageName,
1378 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
1379 if (ApplicationPackageManager.DEBUG_TRACE_GRANTS
1380 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001381 Log.i(TAG, "System is granting " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001382 + permName + " for user " + userId + " on behalf of uid " + callingUid
1383 + " " + mPackageManagerInt.getNameForUid(callingUid),
1384 new RuntimeException());
1385 }
1386 if (!mUserManagerInt.exists(userId)) {
1387 Log.e(TAG, "No such user:" + userId);
1388 return;
1389 }
1390
1391 mContext.enforceCallingOrSelfPermission(
1392 android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1393 "grantRuntimePermission");
1394
1395 enforceCrossUserPermission(callingUid, userId,
1396 true, // requireFullPermission
1397 true, // checkShell
1398 false, // requirePermissionWhenSameUser
1399 "grantRuntimePermission");
1400
Winson14ff7172019-10-23 10:42:27 -07001401 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1402 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1403 packageName);
1404 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001405 Log.e(TAG, "Unknown package: " + packageName);
1406 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001407 }
1408 final BasePermission bp;
1409 synchronized (mLock) {
1410 bp = mSettings.getPermissionLocked(permName);
1411 }
1412 if (bp == null) {
1413 throw new IllegalArgumentException("Unknown permission: " + permName);
1414 }
1415 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1416 throw new IllegalArgumentException("Unknown package: " + packageName);
1417 }
1418
Winson14ff7172019-10-23 10:42:27 -07001419 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001420
1421 // If a permission review is required for legacy apps we represent
1422 // their permissions as always granted runtime ones since we need
1423 // to keep the review required permission flag per user while an
1424 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001425 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001426 && bp.isRuntime()) {
1427 return;
1428 }
1429
Winson14ff7172019-10-23 10:42:27 -07001430 final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
Todd Kennedyc971a452019-07-08 16:04:52 -07001431
Todd Kennedyc971a452019-07-08 16:04:52 -07001432 final PermissionsState permissionsState = ps.getPermissionsState();
1433
1434 final int flags = permissionsState.getPermissionFlags(permName, userId);
1435 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0) {
1436 Log.e(TAG, "Cannot grant system fixed permission "
1437 + permName + " for package " + packageName);
1438 return;
1439 }
1440 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1441 Log.e(TAG, "Cannot grant policy fixed permission "
1442 + permName + " for package " + packageName);
1443 return;
1444 }
1445
1446 if (bp.isHardRestricted()
1447 && (flags & PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) == 0) {
1448 Log.e(TAG, "Cannot grant hard restricted non-exempt permission "
1449 + permName + " for package " + packageName);
1450 return;
1451 }
1452
1453 if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
Winson33eacc62020-01-24 12:02:58 -08001454 pkg.toAppInfoWithoutState(), pkg, UserHandle.of(userId), permName)
Winson6571c8a2019-10-23 17:00:42 -07001455 .mayGrantPermission()) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001456 Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
1457 + packageName);
1458 return;
1459 }
1460
1461 if (bp.isDevelopment()) {
1462 // Development permissions must be handled specially, since they are not
1463 // normal runtime permissions. For now they apply to all users.
1464 if (permissionsState.grantInstallPermission(bp)
1465 != PERMISSION_OPERATION_FAILURE) {
1466 if (callback != null) {
1467 callback.onInstallPermissionGranted();
1468 }
1469 }
1470 return;
1471 }
1472
1473 if (ps.getInstantApp(userId) && !bp.isInstant()) {
1474 throw new SecurityException("Cannot grant non-ephemeral permission"
1475 + permName + " for package " + packageName);
1476 }
1477
Winson14ff7172019-10-23 10:42:27 -07001478 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001479 Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
1480 return;
1481 }
1482
1483 final int result = permissionsState.grantRuntimePermission(bp, userId);
1484 switch (result) {
1485 case PERMISSION_OPERATION_FAILURE: {
1486 return;
1487 }
1488
1489 case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
1490 if (callback != null) {
Winson14ff7172019-10-23 10:42:27 -07001491 callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001492 }
1493 }
1494 break;
1495 }
1496
1497 if (bp.isRuntime()) {
1498 logPermission(MetricsEvent.ACTION_PERMISSION_GRANTED, permName, packageName);
1499 }
1500
1501 if (callback != null) {
1502 callback.onPermissionGranted(uid, userId);
1503 }
1504
1505 if (bp.isRuntime()) {
1506 notifyRuntimePermissionStateChanged(packageName, userId);
1507 }
1508
1509 // Only need to do this if user is initialized. Otherwise it's a new user
1510 // and there are no processes running as the user yet and there's no need
1511 // to make an expensive call to remount processes for the changed permissions.
1512 if (READ_EXTERNAL_STORAGE.equals(permName)
1513 || WRITE_EXTERNAL_STORAGE.equals(permName)) {
1514 final long token = Binder.clearCallingIdentity();
1515 try {
1516 if (mUserManagerInt.isUserInitialized(userId)) {
1517 StorageManagerInternal storageManagerInternal = LocalServices.getService(
1518 StorageManagerInternal.class);
1519 storageManagerInternal.onExternalStoragePolicyChanged(uid, packageName);
1520 }
1521 } finally {
1522 Binder.restoreCallingIdentity(token);
1523 }
1524 }
1525
1526 }
1527
1528 @Override
1529 public void revokeRuntimePermission(String packageName, String permName, int userId) {
1530 final int callingUid = Binder.getCallingUid();
1531 final boolean overridePolicy =
1532 checkUidPermission(ADJUST_RUNTIME_PERMISSIONS_POLICY, callingUid)
1533 == PackageManager.PERMISSION_GRANTED;
1534
1535 revokeRuntimePermissionInternal(permName, packageName, overridePolicy, callingUid, userId,
1536 mDefaultPermissionCallback);
1537 }
1538
1539 // TODO swap permission name and package name
1540 private void revokeRuntimePermissionInternal(String permName, String packageName,
1541 boolean overridePolicy, int callingUid, final int userId, PermissionCallback callback) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001542 if (ApplicationPackageManager.DEBUG_TRACE_PERMISSION_UPDATES
Todd Kennedyc971a452019-07-08 16:04:52 -07001543 && ApplicationPackageManager.shouldTraceGrant(packageName, permName, userId)) {
Eugene Suslacb923e32019-08-20 16:48:55 -07001544 Log.i(TAG, "System is revoking " + packageName + " "
Todd Kennedyc971a452019-07-08 16:04:52 -07001545 + permName + " for user " + userId + " on behalf of uid " + callingUid
1546 + " " + mPackageManagerInt.getNameForUid(callingUid),
1547 new RuntimeException());
1548 }
1549 if (!mUserManagerInt.exists(userId)) {
1550 Log.e(TAG, "No such user:" + userId);
1551 return;
1552 }
1553
1554 mContext.enforceCallingOrSelfPermission(
1555 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1556 "revokeRuntimePermission");
1557
1558 enforceCrossUserPermission(callingUid, userId,
1559 true, // requireFullPermission
1560 true, // checkShell
1561 false, // requirePermissionWhenSameUser
1562 "revokeRuntimePermission");
1563
Winson14ff7172019-10-23 10:42:27 -07001564 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
1565 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
1566 packageName);
1567 if (pkg == null || ps == null) {
Hai Zhangb94491c2019-07-31 14:07:17 -07001568 Log.e(TAG, "Unknown package: " + packageName);
1569 return;
Todd Kennedyc971a452019-07-08 16:04:52 -07001570 }
1571 if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
1572 throw new IllegalArgumentException("Unknown package: " + packageName);
1573 }
1574 final BasePermission bp = mSettings.getPermissionLocked(permName);
1575 if (bp == null) {
1576 throw new IllegalArgumentException("Unknown permission: " + permName);
1577 }
1578
Winson14ff7172019-10-23 10:42:27 -07001579 bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
Todd Kennedyc971a452019-07-08 16:04:52 -07001580
1581 // If a permission review is required for legacy apps we represent
1582 // their permissions as always granted runtime ones since we need
1583 // to keep the review required permission flag per user while an
1584 // install permission's state is shared across all users.
Winson14ff7172019-10-23 10:42:27 -07001585 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Todd Kennedyc971a452019-07-08 16:04:52 -07001586 && bp.isRuntime()) {
1587 return;
1588 }
1589
Todd Kennedyc971a452019-07-08 16:04:52 -07001590 final PermissionsState permissionsState = ps.getPermissionsState();
1591
1592 final int flags = permissionsState.getPermissionFlags(permName, userId);
1593 // Only the system may revoke SYSTEM_FIXED permissions.
1594 if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0
1595 && UserHandle.getCallingAppId() != Process.SYSTEM_UID) {
1596 throw new SecurityException("Non-System UID cannot revoke system fixed permission "
1597 + permName + " for package " + packageName);
1598 }
1599 if (!overridePolicy && (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
1600 throw new SecurityException("Cannot revoke policy fixed permission "
1601 + permName + " for package " + packageName);
1602 }
1603
1604 if (bp.isDevelopment()) {
1605 // Development permissions must be handled specially, since they are not
1606 // normal runtime permissions. For now they apply to all users.
1607 if (permissionsState.revokeInstallPermission(bp)
1608 != PERMISSION_OPERATION_FAILURE) {
1609 if (callback != null) {
1610 mDefaultPermissionCallback.onInstallPermissionRevoked();
1611 }
1612 }
1613 return;
1614 }
1615
1616 // Permission is already revoked, no need to do anything.
1617 if (!permissionsState.hasRuntimePermission(permName, userId)) {
1618 return;
1619 }
1620
1621 if (permissionsState.revokeRuntimePermission(bp, userId)
1622 == PERMISSION_OPERATION_FAILURE) {
1623 return;
1624 }
1625
1626 if (bp.isRuntime()) {
1627 logPermission(MetricsEvent.ACTION_PERMISSION_REVOKED, permName, packageName);
1628 }
1629
1630 if (callback != null) {
Nate Myren8f6a9092019-08-27 15:50:03 -07001631 callback.onPermissionRevoked(UserHandle.getUid(userId,
Winson14ff7172019-10-23 10:42:27 -07001632 UserHandle.getAppId(pkg.getUid())), userId);
Todd Kennedyc971a452019-07-08 16:04:52 -07001633 }
1634
1635 if (bp.isRuntime()) {
1636 notifyRuntimePermissionStateChanged(packageName, userId);
1637 }
1638 }
1639
1640 @Override
1641 public void resetRuntimePermissions() {
1642 mContext.enforceCallingOrSelfPermission(
1643 android.Manifest.permission.REVOKE_RUNTIME_PERMISSIONS,
1644 "revokeRuntimePermission");
1645
1646 final int callingUid = Binder.getCallingUid();
1647 if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
1648 mContext.enforceCallingOrSelfPermission(
1649 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
1650 "resetRuntimePermissions");
1651 }
1652
1653 updateAllPermissions(
1654 StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
1655 for (final int userId : UserManagerService.getInstance().getUserIds()) {
1656 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07001657 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedyc971a452019-07-08 16:04:52 -07001658 }
1659 }
1660
1661 /**
1662 * Reverts user permission state changes (permissions and flags).
1663 *
Hai Zhang4ffebb72019-07-18 14:50:58 -07001664 * @param pkg The package for which to reset.
Todd Kennedyc971a452019-07-08 16:04:52 -07001665 * @param userId The device user for which to do a reset.
1666 */
Patrick Baumann865fd3a2019-07-26 14:53:02 -07001667 @GuardedBy("mLock")
Winson14ff7172019-10-23 10:42:27 -07001668 private void resetRuntimePermissionsInternal(final AndroidPackage pkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07001669 final int userId) {
Winson14ff7172019-10-23 10:42:27 -07001670 final String packageName = pkg.getPackageName();
Todd Kennedyc971a452019-07-08 16:04:52 -07001671
1672 // These are flags that can change base on user actions.
1673 final int userSettableMask = FLAG_PERMISSION_USER_SET
1674 | FLAG_PERMISSION_USER_FIXED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001675 | FLAG_PERMISSION_REVOKED_COMPAT
Evan Seversonf21a09a2020-03-19 10:54:51 -07001676 | FLAG_PERMISSION_REVIEW_REQUIRED
1677 | FLAG_PERMISSION_ONE_TIME;
Todd Kennedyc971a452019-07-08 16:04:52 -07001678
1679 final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
1680 | FLAG_PERMISSION_POLICY_FIXED;
1681
1682 // Delay and combine non-async permission callbacks
Winson14ff7172019-10-23 10:42:27 -07001683 final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
Todd Kennedyc971a452019-07-08 16:04:52 -07001684 final boolean[] permissionRemoved = new boolean[1];
1685 final ArraySet<Long> revokedPermissions = new ArraySet<>();
1686 final IntArray syncUpdatedUsers = new IntArray(permissionCount);
1687 final IntArray asyncUpdatedUsers = new IntArray(permissionCount);
1688
1689 PermissionCallback delayingPermCallback = new PermissionCallback() {
1690 public void onGidsChanged(int appId, int userId) {
1691 mDefaultPermissionCallback.onGidsChanged(appId, userId);
1692 }
1693
1694 public void onPermissionChanged() {
1695 mDefaultPermissionCallback.onPermissionChanged();
1696 }
1697
1698 public void onPermissionGranted(int uid, int userId) {
1699 mDefaultPermissionCallback.onPermissionGranted(uid, userId);
1700 }
1701
1702 public void onInstallPermissionGranted() {
1703 mDefaultPermissionCallback.onInstallPermissionGranted();
1704 }
1705
1706 public void onPermissionRevoked(int uid, int userId) {
1707 revokedPermissions.add(IntPair.of(uid, userId));
1708
1709 syncUpdatedUsers.add(userId);
1710 }
1711
1712 public void onInstallPermissionRevoked() {
1713 mDefaultPermissionCallback.onInstallPermissionRevoked();
1714 }
1715
1716 public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
1717 for (int userId : updatedUserIds) {
1718 if (sync) {
1719 syncUpdatedUsers.add(userId);
1720 asyncUpdatedUsers.remove(userId);
1721 } else {
1722 // Don't override sync=true by sync=false
1723 if (syncUpdatedUsers.indexOf(userId) == -1) {
1724 asyncUpdatedUsers.add(userId);
1725 }
1726 }
1727 }
1728 }
1729
1730 public void onPermissionRemoved() {
1731 permissionRemoved[0] = true;
1732 }
1733
1734 public void onInstallPermissionUpdated() {
1735 mDefaultPermissionCallback.onInstallPermissionUpdated();
1736 }
Nate Myrencc9e2c72019-11-08 14:57:15 -08001737
1738 public void onPermissionUpdatedNotifyListener(@UserIdInt int[] updatedUserIds,
1739 boolean sync, int uid) {
1740 onPermissionUpdated(updatedUserIds, sync);
1741 mOnPermissionChangeListeners.onPermissionsChanged(uid);
1742 }
1743
1744 public void onInstallPermissionUpdatedNotifyListener(int uid) {
1745 mDefaultPermissionCallback.onInstallPermissionUpdatedNotifyListener(uid);
1746 }
Todd Kennedyc971a452019-07-08 16:04:52 -07001747 };
1748
1749 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07001750 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc971a452019-07-08 16:04:52 -07001751 final BasePermission bp;
1752 synchronized (mLock) {
1753 bp = mSettings.getPermissionLocked(permName);
1754 }
1755 if (bp == null) {
1756 continue;
1757 }
1758
1759 if (bp.isRemoved()) {
1760 continue;
1761 }
1762
1763 // If shared user we just reset the state to which only this app contributed.
Alan Stokes20fbef22019-12-17 15:33:12 +00001764 final String[] pkgNames = mPackageManagerInt.getSharedUserPackagesForPackage(
1765 pkg.getPackageName(), userId);
1766 if (pkgNames.length > 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001767 boolean used = false;
Alan Stokes20fbef22019-12-17 15:33:12 +00001768 for (String sharedPkgName : pkgNames) {
Winson14ff7172019-10-23 10:42:27 -07001769 final AndroidPackage sharedPkg =
Todd Kennedyc971a452019-07-08 16:04:52 -07001770 mPackageManagerInt.getPackage(sharedPkgName);
Winson14ff7172019-10-23 10:42:27 -07001771 if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
1772 && sharedPkg.getRequestedPermissions().contains(permName)) {
Todd Kennedyc971a452019-07-08 16:04:52 -07001773 used = true;
1774 break;
1775 }
1776 }
1777 if (used) {
1778 continue;
1779 }
1780 }
1781
1782 final int oldFlags =
1783 getPermissionFlagsInternal(permName, packageName, Process.SYSTEM_UID, userId);
1784
1785 // Always clear the user settable flags.
1786 // If permission review is enabled and this is a legacy app, mark the
1787 // permission as requiring a review as this is the initial state.
1788 final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId);
Hai Zhang053c3a22019-08-23 15:08:03 -07001789 final int targetSdk = mPackageManagerInt.getUidTargetSdkVersion(uid);
Todd Kennedyc971a452019-07-08 16:04:52 -07001790 final int flags = (targetSdk < Build.VERSION_CODES.M && bp.isRuntime())
Hai Zhang50a5a9b2019-09-19 13:57:45 -07001791 ? FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKED_COMPAT
Todd Kennedyc971a452019-07-08 16:04:52 -07001792 : 0;
1793
1794 updatePermissionFlagsInternal(
1795 permName, packageName, userSettableMask, flags, Process.SYSTEM_UID, userId,
1796 false, delayingPermCallback);
1797
1798 // Below is only runtime permission handling.
1799 if (!bp.isRuntime()) {
1800 continue;
1801 }
1802
1803 // Never clobber system or policy.
1804 if ((oldFlags & policyOrSystemFlags) != 0) {
1805 continue;
1806 }
1807
Hai Zhang253fa2b2020-06-02 14:07:23 -07001808 // If this permission was granted by default or role, make sure it is.
1809 if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0
1810 || (oldFlags & FLAG_PERMISSION_GRANTED_BY_ROLE) != 0) {
Hai Zhangab6a6822019-10-18 00:34:06 +00001811 // PermissionPolicyService will handle the app op for runtime permissions later.
Todd Kennedyc971a452019-07-08 16:04:52 -07001812 grantRuntimePermissionInternal(permName, packageName, false,
1813 Process.SYSTEM_UID, userId, delayingPermCallback);
1814 // If permission review is enabled the permissions for a legacy apps
1815 // are represented as constantly granted runtime ones, so don't revoke.
1816 } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
1817 // Otherwise, reset the permission.
1818 revokeRuntimePermissionInternal(permName, packageName, false, Process.SYSTEM_UID,
1819 userId, delayingPermCallback);
1820 }
1821 }
1822
1823 // Execute delayed callbacks
1824 if (permissionRemoved[0]) {
1825 mDefaultPermissionCallback.onPermissionRemoved();
1826 }
1827
1828 // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
1829 // kill uid while holding mPackages-lock
1830 if (!revokedPermissions.isEmpty()) {
1831 int numRevokedPermissions = revokedPermissions.size();
1832 for (int i = 0; i < numRevokedPermissions; i++) {
1833 int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
1834 int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
1835
1836 mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
1837
1838 // Kill app later as we are holding mPackages
1839 mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
1840 KILL_APP_REASON_PERMISSIONS_REVOKED));
1841 }
1842 }
1843
1844 mPackageManagerInt.writePermissionSettings(syncUpdatedUsers.toArray(), false);
1845 mPackageManagerInt.writePermissionSettings(asyncUpdatedUsers.toArray(), true);
1846 }
1847
Todd Kennedy583378d2019-07-12 06:50:30 -07001848 @Override
1849 public String getDefaultBrowser(int userId) {
1850 final int callingUid = Binder.getCallingUid();
1851 if (UserHandle.getUserId(callingUid) != userId) {
1852 mContext.enforceCallingOrSelfPermission(
1853 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1854 }
1855 if (mPackageManagerInt.getInstantAppPackageName(callingUid) != null) {
1856 return null;
1857 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001858 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001859 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001860 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001861 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001862 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07001863 }
1864
1865 @Override
1866 public boolean setDefaultBrowser(String packageName, int userId) {
1867 mContext.enforceCallingOrSelfPermission(
1868 android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
1869 if (UserHandle.getCallingUserId() != userId) {
1870 mContext.enforceCallingOrSelfPermission(
1871 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
1872 }
1873 return setDefaultBrowserInternal(packageName, false, true, userId);
1874 }
1875
1876 private boolean setDefaultBrowserInternal(String packageName, boolean async,
1877 boolean doGrant, int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001878 if (userId == UserHandle.USER_ALL) {
1879 return false;
1880 }
1881 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07001882 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07001883 provider = mDefaultBrowserProvider;
1884 }
1885 if (provider == null) {
1886 return false;
1887 }
1888 if (async) {
1889 provider.setDefaultBrowserAsync(packageName, userId);
1890 } else {
1891 if (!provider.setDefaultBrowser(packageName, userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07001892 return false;
1893 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07001894 }
1895 if (doGrant && packageName != null) {
1896 synchronized (mLock) {
1897 mDefaultPermissionGrantPolicy.grantDefaultPermissionsToDefaultBrowser(packageName,
1898 userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07001899 }
1900 }
1901 return true;
1902 }
1903
1904 @Override
1905 public void grantDefaultPermissionsToEnabledCarrierApps(String[] packageNames, int userId) {
1906 final int callingUid = Binder.getCallingUid();
1907 PackageManagerServiceUtils
1908 .enforceSystemOrPhoneCaller("grantPermissionsToEnabledCarrierApps", callingUid);
1909 synchronized (mLock) {
1910 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1911 .grantDefaultPermissionsToEnabledCarrierApps(packageNames, userId));
1912 }
1913 }
1914
1915 @Override
1916 public void grantDefaultPermissionsToEnabledImsServices(String[] packageNames, int userId) {
1917 final int callingUid = Binder.getCallingUid();
1918 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1919 "grantDefaultPermissionsToEnabledImsServices", callingUid);
1920 synchronized (mLock) {
1921 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1922 .grantDefaultPermissionsToEnabledImsServices(packageNames, userId));
1923 }
1924 }
1925
1926 @Override
1927 public void grantDefaultPermissionsToEnabledTelephonyDataServices(
1928 String[] packageNames, int userId) {
1929 final int callingUid = Binder.getCallingUid();
1930 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1931 "grantDefaultPermissionsToEnabledTelephonyDataServices", callingUid);
1932 synchronized (mLock) {
1933 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1934 .grantDefaultPermissionsToEnabledTelephonyDataServices(
1935 packageNames, userId));
1936 }
1937 }
1938
1939 @Override
1940 public void revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1941 String[] packageNames, int userId) {
1942 final int callingUid = Binder.getCallingUid();
1943 PackageManagerServiceUtils.enforceSystemOrPhoneCaller(
1944 "revokeDefaultPermissionsFromDisabledTelephonyDataServices", callingUid);
1945 synchronized (mLock) {
1946 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1947 .revokeDefaultPermissionsFromDisabledTelephonyDataServices(
1948 packageNames, userId));
1949 }
1950 }
1951
1952 @Override
1953 public void grantDefaultPermissionsToActiveLuiApp(String packageName, int userId) {
1954 final int callingUid = Binder.getCallingUid();
1955 PackageManagerServiceUtils
1956 .enforceSystemOrPhoneCaller("grantDefaultPermissionsToActiveLuiApp", callingUid);
1957 synchronized (mLock) {
1958 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1959 .grantDefaultPermissionsToActiveLuiApp(packageName, userId));
1960 }
1961 }
1962
1963 @Override
1964 public void revokeDefaultPermissionsFromLuiApps(String[] packageNames, int userId) {
1965 final int callingUid = Binder.getCallingUid();
1966 PackageManagerServiceUtils
1967 .enforceSystemOrPhoneCaller("revokeDefaultPermissionsFromLuiApps", callingUid);
1968 synchronized (mLock) {
1969 Binder.withCleanCallingIdentity(() -> mDefaultPermissionGrantPolicy
1970 .revokeDefaultPermissionsFromLuiApps(packageNames, userId));
1971 }
1972 }
1973
Todd Kennedyc5b0e862019-07-16 09:47:58 -07001974 @Override
1975 public void setPermissionEnforced(String permName, boolean enforced) {
1976 // TODO: Now that we no longer change GID for storage, this should to away.
1977 mContext.enforceCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS,
1978 "setPermissionEnforced");
1979 if (READ_EXTERNAL_STORAGE.equals(permName)) {
1980 mPackageManagerInt.setReadExternalStorageEnforced(enforced);
1981 // kill any non-foreground processes so we restart them and
1982 // grant/revoke the GID.
1983 final IActivityManager am = ActivityManager.getService();
1984 if (am != null) {
1985 final long token = Binder.clearCallingIdentity();
1986 try {
1987 am.killProcessesBelowForeground("setPermissionEnforcement");
1988 } catch (RemoteException e) {
1989 } finally {
1990 Binder.restoreCallingIdentity(token);
1991 }
1992 }
1993 } else {
1994 throw new IllegalArgumentException("No selective enforcement for " + permName);
1995 }
1996 }
1997
1998 /** @deprecated */
1999 @Override
2000 @Deprecated
2001 public boolean isPermissionEnforced(String permName) {
2002 // allow instant applications
2003 return true;
2004 }
2005
Evan Severson50a77742020-01-06 10:38:19 -08002006 /**
2007 * This change makes it so that apps are told to show rationale for asking for background
2008 * location access every time they request.
2009 */
2010 @ChangeId
2011 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q)
2012 private static final long BACKGROUND_RATIONALE_CHANGE_ID = 147316723L;
2013
Todd Kennedyc5b0e862019-07-16 09:47:58 -07002014 @Override
2015 public boolean shouldShowRequestPermissionRationale(String permName,
2016 String packageName, int userId) {
2017 final int callingUid = Binder.getCallingUid();
2018 if (UserHandle.getCallingUserId() != userId) {
2019 mContext.enforceCallingPermission(
2020 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2021 "canShowRequestPermissionRationale for user " + userId);
2022 }
2023
2024 final int uid =
2025 mPackageManagerInt.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
2026 if (UserHandle.getAppId(callingUid) != UserHandle.getAppId(uid)) {
2027 return false;
2028 }
2029
2030 if (checkPermission(permName, packageName, userId)
2031 == PackageManager.PERMISSION_GRANTED) {
2032 return false;
2033 }
2034
2035 final int flags;
2036
2037 final long identity = Binder.clearCallingIdentity();
2038 try {
2039 flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
2040 } finally {
2041 Binder.restoreCallingIdentity(identity);
2042 }
2043
2044 final int fixedFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
2045 | PackageManager.FLAG_PERMISSION_POLICY_FIXED
2046 | PackageManager.FLAG_PERMISSION_USER_FIXED;
2047
2048 if ((flags & fixedFlags) != 0) {
2049 return false;
2050 }
2051
atrost24274272020-02-17 19:26:41 +00002052 final long token = Binder.clearCallingIdentity();
Evan Severson50a77742020-01-06 10:38:19 -08002053 try {
2054 if (permName.equals(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
2055 && mPlatformCompat.isChangeEnabledByPackageName(BACKGROUND_RATIONALE_CHANGE_ID,
2056 packageName, userId)) {
2057 return true;
2058 }
2059 } catch (RemoteException e) {
2060 Log.e(TAG, "Unable to check if compatibility change is enabled.", e);
atrost24274272020-02-17 19:26:41 +00002061 } finally {
2062 Binder.restoreCallingIdentity(token);
Evan Severson50a77742020-01-06 10:38:19 -08002063 }
2064
Todd Kennedyc5b0e862019-07-16 09:47:58 -07002065 return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
2066 }
2067
2068 @Override
2069 public boolean isPermissionRevokedByPolicy(String permName, String packageName, int userId) {
2070 if (UserHandle.getCallingUserId() != userId) {
2071 mContext.enforceCallingPermission(
2072 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2073 "isPermissionRevokedByPolicy for user " + userId);
2074 }
2075
2076 if (checkPermission(permName, packageName, userId) == PackageManager.PERMISSION_GRANTED) {
2077 return false;
2078 }
2079
2080 final int callingUid = Binder.getCallingUid();
2081 if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
2082 return false;
2083 }
2084
2085 final long identity = Binder.clearCallingIdentity();
2086 try {
2087 final int flags = getPermissionFlagsInternal(permName, packageName, callingUid, userId);
2088 return (flags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0;
2089 } finally {
2090 Binder.restoreCallingIdentity(identity);
2091 }
2092 }
2093
Hongwei Wangf391b552018-04-06 13:52:46 -07002094 /**
Philip P. Moltmann48456672019-01-20 13:14:03 -08002095 * Get the state of the runtime permissions as xml file.
2096 *
2097 * <p>Can not be called on main thread.
2098 *
2099 * @param user The user the data should be extracted for
2100 *
2101 * @return The state as a xml file
2102 */
2103 private @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
2104 CompletableFuture<byte[]> backup = new CompletableFuture<>();
2105 mPermissionControllerManager.getRuntimePermissionBackup(user, mContext.getMainExecutor(),
2106 backup::complete);
2107
2108 try {
2109 return backup.get(BACKUP_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
2110 } catch (InterruptedException | ExecutionException | TimeoutException e) {
2111 Slog.e(TAG, "Cannot create permission backup for " + user, e);
2112 return null;
2113 }
2114 }
2115
2116 /**
2117 * Restore a permission state previously backed up via {@link #backupRuntimePermissions}.
2118 *
2119 * <p>If not all state can be restored, the un-appliable state will be delayed and can be
2120 * applied via {@link #restoreDelayedRuntimePermissions}.
2121 *
2122 * @param backup The state as an xml file
2123 * @param user The user the data should be restored for
2124 */
2125 private void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
2126 synchronized (mLock) {
2127 mHasNoDelayedPermBackup.delete(user.getIdentifier());
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07002128 mPermissionControllerManager.stageAndApplyRuntimePermissionsBackup(backup, user);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002129 }
2130 }
2131
2132 /**
2133 * Try to apply permission backup that was previously not applied.
2134 *
2135 * <p>Can not be called on main thread.
2136 *
2137 * @param packageName The package that is newly installed
2138 * @param user The user the package is installed for
2139 *
2140 * @see #restoreRuntimePermissions
2141 */
2142 private void restoreDelayedRuntimePermissions(@NonNull String packageName,
2143 @NonNull UserHandle user) {
2144 synchronized (mLock) {
2145 if (mHasNoDelayedPermBackup.get(user.getIdentifier(), false)) {
2146 return;
2147 }
2148
Philip P. Moltmann4a6c5de2019-09-13 11:15:44 -07002149 mPermissionControllerManager.applyStagedRuntimePermissionBackup(packageName, user,
Philip P. Moltmann48456672019-01-20 13:14:03 -08002150 mContext.getMainExecutor(), (hasMoreBackup) -> {
2151 if (hasMoreBackup) {
2152 return;
2153 }
2154
2155 synchronized (mLock) {
2156 mHasNoDelayedPermBackup.put(user.getIdentifier(), true);
2157 }
2158 });
2159 }
2160 }
2161
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002162 private void addOnRuntimePermissionStateChangedListener(@NonNull
2163 OnRuntimePermissionStateChangedListener listener) {
2164 synchronized (mLock) {
2165 mRuntimePermissionStateChangedListeners.add(listener);
2166 }
2167 }
2168
2169 private void removeOnRuntimePermissionStateChangedListener(@NonNull
2170 OnRuntimePermissionStateChangedListener listener) {
2171 synchronized (mLock) {
2172 mRuntimePermissionStateChangedListeners.remove(listener);
2173 }
2174 }
2175
2176 private void notifyRuntimePermissionStateChanged(@NonNull String packageName,
2177 @UserIdInt int userId) {
2178 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage
2179 (PermissionManagerService::doNotifyRuntimePermissionStateChanged,
2180 PermissionManagerService.this, packageName, userId));
2181 }
2182
2183 private void doNotifyRuntimePermissionStateChanged(@NonNull String packageName,
2184 @UserIdInt int userId) {
2185 final ArrayList<OnRuntimePermissionStateChangedListener> listeners;
2186 synchronized (mLock) {
2187 if (mRuntimePermissionStateChangedListeners.isEmpty()) {
2188 return;
2189 }
2190 listeners = new ArrayList<>(mRuntimePermissionStateChangedListeners);
2191 }
2192 final int listenerCount = listeners.size();
2193 for (int i = 0; i < listenerCount; i++) {
2194 listeners.get(i).onRuntimePermissionStateChanged(packageName, userId);
2195 }
2196 }
2197
Todd Kennedy0eb97382017-10-03 16:57:22 -07002198 private int adjustPermissionProtectionFlagsLocked(
2199 int protectionLevel, String packageName, int uid) {
2200 // Signature permission flags area always reported
2201 final int protectionLevelMasked = protectionLevel
2202 & (PermissionInfo.PROTECTION_NORMAL
2203 | PermissionInfo.PROTECTION_DANGEROUS
2204 | PermissionInfo.PROTECTION_SIGNATURE);
2205 if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
2206 return protectionLevel;
2207 }
2208 // System sees all flags.
2209 final int appId = UserHandle.getAppId(uid);
2210 if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
2211 || appId == Process.SHELL_UID) {
2212 return protectionLevel;
2213 }
2214 // Normalize package name to handle renamed packages and static libs
Winson14ff7172019-10-23 10:42:27 -07002215 final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
Todd Kennedy0eb97382017-10-03 16:57:22 -07002216 if (pkg == null) {
2217 return protectionLevel;
2218 }
Winson14ff7172019-10-23 10:42:27 -07002219 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07002220 return protectionLevelMasked;
2221 }
2222 // Apps that target O see flags for all protection levels.
Winson14ff7172019-10-23 10:42:27 -07002223 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2224 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07002225 if (ps == null) {
2226 return protectionLevel;
2227 }
2228 if (ps.getAppId() != appId) {
2229 return protectionLevel;
2230 }
2231 return protectionLevel;
2232 }
2233
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002234 /**
2235 * We might auto-grant permissions if any permission of the group is already granted. Hence if
2236 * the group of a granted permission changes we need to revoke it to avoid having permissions of
2237 * the new group auto-granted.
2238 *
2239 * @param newPackage The new package that was installed
2240 * @param oldPackage The old package that was updated
2241 * @param allPackageNames All package names
2242 * @param permissionCallback Callback for permission changed
2243 */
2244 private void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07002245 @NonNull AndroidPackage newPackage,
2246 @NonNull AndroidPackage oldPackage,
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002247 @NonNull ArrayList<String> allPackageNames,
2248 @NonNull PermissionCallback permissionCallback) {
Winson14ff7172019-10-23 10:42:27 -07002249 final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002250 final ArrayMap<String, String> oldPermissionNameToGroupName
2251 = new ArrayMap<>(numOldPackagePermissions);
2252
2253 for (int i = 0; i < numOldPackagePermissions; i++) {
Winson14ff7172019-10-23 10:42:27 -07002254 final ParsedPermission permission = oldPackage.getPermissions().get(i);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002255
Winsonf00c7552020-01-28 12:52:01 -08002256 if (permission.getParsedPermissionGroup() != null) {
Winson14ff7172019-10-23 10:42:27 -07002257 oldPermissionNameToGroupName.put(permission.getName(),
Winsonf00c7552020-01-28 12:52:01 -08002258 permission.getParsedPermissionGroup().getName());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002259 }
2260 }
2261
Todd Kennedyc971a452019-07-08 16:04:52 -07002262 final int callingUid = Binder.getCallingUid();
Winson14ff7172019-10-23 10:42:27 -07002263 final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002264 for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
2265 newPermissionNum++) {
Winson14ff7172019-10-23 10:42:27 -07002266 final ParsedPermission newPermission =
2267 newPackage.getPermissions().get(newPermissionNum);
2268 final int newProtection = newPermission.getProtection();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002269
2270 if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
Winson14ff7172019-10-23 10:42:27 -07002271 final String permissionName = newPermission.getName();
Winsonf00c7552020-01-28 12:52:01 -08002272 final String newPermissionGroupName =
2273 newPermission.getParsedPermissionGroup() == null
2274 ? null : newPermission.getParsedPermissionGroup().getName();
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002275 final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
2276 permissionName);
2277
2278 if (newPermissionGroupName != null
2279 && !newPermissionGroupName.equals(oldPermissionGroupName)) {
2280 final int[] userIds = mUserManagerInt.getUserIds();
2281 final int numUserIds = userIds.length;
2282 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
2283 final int userId = userIds[userIdNum];
2284
2285 final int numPackages = allPackageNames.size();
2286 for (int packageNum = 0; packageNum < numPackages; packageNum++) {
2287 final String packageName = allPackageNames.get(packageNum);
Hai Zhang3b049a52019-08-16 15:37:46 -07002288 final int permissionState = checkPermission(permissionName, packageName,
2289 userId);
Todd Kennedyca1ea172019-07-03 15:02:28 -07002290 if (permissionState == PackageManager.PERMISSION_GRANTED) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002291 EventLog.writeEvent(0x534e4554, "72710897",
Winson14ff7172019-10-23 10:42:27 -07002292 newPackage.getUid(),
Koji Fukuiacae3ef2018-05-09 11:38:01 +09002293 "Revoking permission " + permissionName +
2294 " from package " + packageName +
2295 " as the group changed from " + oldPermissionGroupName +
2296 " to " + newPermissionGroupName);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002297
2298 try {
Todd Kennedyc971a452019-07-08 16:04:52 -07002299 revokeRuntimePermissionInternal(permissionName, packageName,
2300 false, callingUid, userId, permissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07002301 } catch (IllegalArgumentException e) {
2302 Slog.e(TAG, "Could not revoke " + permissionName + " from "
2303 + packageName, e);
2304 }
2305 }
2306 }
2307 }
2308 }
2309 }
2310 }
2311 }
2312
Winson14ff7172019-10-23 10:42:27 -07002313 private void addAllPermissions(AndroidPackage pkg, boolean chatty) {
2314 final int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002315 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002316 ParsedPermission p = pkg.getPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002317
2318 // Assume by default that we did not install this permission into the system.
Winsonf00c7552020-01-28 12:52:01 -08002319 p.setFlags(p.getFlags() & ~PermissionInfo.FLAG_INSTALLED);
Todd Kennedyc8423932017-10-05 08:58:36 -07002320
Todd Kennedyc8423932017-10-05 08:58:36 -07002321 synchronized (PermissionManagerService.this.mLock) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002322 // Now that permission groups have a special meaning, we ignore permission
2323 // groups for legacy apps to prevent unexpected behavior. In particular,
2324 // permissions for one app being granted to someone just because they happen
2325 // to be in a group defined by another app (before this had no implications).
Winson14ff7172019-10-23 10:42:27 -07002326 if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
Winsonf00c7552020-01-28 12:52:01 -08002327 p.setParsedPermissionGroup(mSettings.mPermissionGroups.get(p.getGroup()));
Todd Kennedy460f28c2017-10-06 13:46:22 -07002328 // Warn for a permission in an unknown group.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002329 if (DEBUG_PERMISSIONS
Winsonf00c7552020-01-28 12:52:01 -08002330 && p.getGroup() != null && p.getParsedPermissionGroup() == null) {
Winson14ff7172019-10-23 10:42:27 -07002331 Slog.i(TAG, "Permission " + p.getName() + " from package "
2332 + p.getPackageName() + " in an unknown group " + p.getGroup());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002333 }
2334 }
2335
Winsonf00c7552020-01-28 12:52:01 -08002336 if (p.isTree()) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002337 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002338 mPackageManagerInt,
2339 mSettings.getPermissionTreeLocked(p.getName()), p, pkg,
Todd Kennedyc8423932017-10-05 08:58:36 -07002340 mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002341 mSettings.putPermissionTreeLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002342 } else {
2343 final BasePermission bp = BasePermission.createOrUpdate(
Winson14ff7172019-10-23 10:42:27 -07002344 mPackageManagerInt,
2345 mSettings.getPermissionLocked(p.getName()),
Todd Kennedyc8423932017-10-05 08:58:36 -07002346 p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
Winson14ff7172019-10-23 10:42:27 -07002347 mSettings.putPermissionLocked(p.getName(), bp);
Todd Kennedyc8423932017-10-05 08:58:36 -07002348 }
2349 }
2350 }
2351 }
2352
Winson14ff7172019-10-23 10:42:27 -07002353 private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
2354 final int N = ArrayUtils.size(pkg.getPermissionGroups());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002355 StringBuilder r = null;
2356 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002357 final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
2358 final ParsedPermissionGroup cur = mSettings.mPermissionGroups.get(pg.getName());
2359 final String curPackageName = (cur == null) ? null : cur.getPackageName();
2360 final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
Todd Kennedy460f28c2017-10-06 13:46:22 -07002361 if (cur == null || isPackageUpdate) {
Winson14ff7172019-10-23 10:42:27 -07002362 mSettings.mPermissionGroups.put(pg.getName(), pg);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002363 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002364 if (r == null) {
2365 r = new StringBuilder(256);
2366 } else {
2367 r.append(' ');
2368 }
2369 if (isPackageUpdate) {
2370 r.append("UPD:");
2371 }
Winson14ff7172019-10-23 10:42:27 -07002372 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002373 }
2374 } else {
Winson14ff7172019-10-23 10:42:27 -07002375 Slog.w(TAG, "Permission group " + pg.getName() + " from package "
2376 + pg.getPackageName() + " ignored: original from "
2377 + cur.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002378 if (chatty && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002379 if (r == null) {
2380 r = new StringBuilder(256);
2381 } else {
2382 r.append(' ');
2383 }
2384 r.append("DUP:");
Winson14ff7172019-10-23 10:42:27 -07002385 r.append(pg.getName());
Todd Kennedy460f28c2017-10-06 13:46:22 -07002386 }
2387 }
2388 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002389 if (r != null && DEBUG_PACKAGE_SCANNING) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07002390 Log.d(TAG, " Permission Groups: " + r);
2391 }
2392
2393 }
2394
Winson14ff7172019-10-23 10:42:27 -07002395 private void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002396 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07002397 int N = ArrayUtils.size(pkg.getPermissions());
Todd Kennedyc8423932017-10-05 08:58:36 -07002398 StringBuilder r = null;
2399 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002400 ParsedPermission p = pkg.getPermissions().get(i);
2401 BasePermission bp = mSettings.mPermissions.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002402 if (bp == null) {
Winson14ff7172019-10-23 10:42:27 -07002403 bp = mSettings.mPermissionTrees.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002404 }
2405 if (bp != null && bp.isPermission(p)) {
2406 bp.setPermission(null);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002407 if (DEBUG_REMOVE && chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07002408 if (r == null) {
2409 r = new StringBuilder(256);
2410 } else {
2411 r.append(' ');
2412 }
Winson14ff7172019-10-23 10:42:27 -07002413 r.append(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002414 }
2415 }
2416 if (p.isAppOp()) {
2417 ArraySet<String> appOpPkgs =
Winson14ff7172019-10-23 10:42:27 -07002418 mSettings.mAppOpPermissionPackages.get(p.getName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002419 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002420 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002421 }
2422 }
2423 }
2424 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002425 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002426 }
2427
Winson14ff7172019-10-23 10:42:27 -07002428 N = pkg.getRequestedPermissions().size();
Todd Kennedyc8423932017-10-05 08:58:36 -07002429 r = null;
2430 for (int i=0; i<N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002431 String perm = pkg.getRequestedPermissions().get(i);
Todd Kennedyc8423932017-10-05 08:58:36 -07002432 if (mSettings.isPermissionAppOp(perm)) {
2433 ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
2434 if (appOpPkgs != null) {
Winson14ff7172019-10-23 10:42:27 -07002435 appOpPkgs.remove(pkg.getPackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07002436 if (appOpPkgs.isEmpty()) {
2437 mSettings.mAppOpPermissionPackages.remove(perm);
2438 }
2439 }
2440 }
2441 }
2442 if (r != null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002443 if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
Todd Kennedyc8423932017-10-05 08:58:36 -07002444 }
2445 }
2446 }
2447
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002448 /**
2449 * Restore the permission state for a package.
2450 *
2451 * <ul>
2452 * <li>During boot the state gets restored from the disk</li>
2453 * <li>During app update the state gets restored from the last version of the app</li>
2454 * </ul>
2455 *
2456 * <p>This restores the permission state for all users.
2457 *
2458 * @param pkg the package the permissions belong to
2459 * @param replace if the package is getting replaced (this might change the requested
2460 * permissions of this package)
2461 * @param packageOfInterest If this is the name of {@code pkg} add extra logging
2462 * @param callback Result call back
2463 */
Winson14ff7172019-10-23 10:42:27 -07002464 private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07002465 @Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002466 // IMPORTANT: There are two types of permissions: install and runtime.
2467 // Install time permissions are granted when the app is installed to
2468 // all device users and users added in the future. Runtime permissions
2469 // are granted at runtime explicitly to specific users. Normal and signature
2470 // protected permissions are install time permissions. Dangerous permissions
2471 // are install permissions if the app's target SDK is Lollipop MR1 or older,
2472 // otherwise they are runtime permissions. This function does not manage
2473 // runtime permissions except for the case an app targeting Lollipop MR1
2474 // being upgraded to target a newer SDK, in which case dangerous permissions
2475 // are transformed from install time to runtime ones.
2476
Winson14ff7172019-10-23 10:42:27 -07002477 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
2478 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002479 if (ps == null) {
2480 return;
2481 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002482
2483 final PermissionsState permissionsState = ps.getPermissionsState();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002484
2485 final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
2486
2487 boolean runtimePermissionsRevoked = false;
2488 int[] updatedUserIds = EMPTY_INT_ARRAY;
2489
Hai Zhang4c0d15b2020-05-18 16:06:58 -07002490 for (int userId : currentUserIds) {
2491 if (permissionsState.isMissing(userId)) {
2492 Collection<String> requestedPermissions;
2493 int targetSdkVersion;
2494 if (!ps.isSharedUser()) {
2495 requestedPermissions = pkg.getRequestedPermissions();
2496 targetSdkVersion = pkg.getTargetSdkVersion();
2497 } else {
2498 requestedPermissions = new ArraySet<>();
2499 targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
2500 List<AndroidPackage> packages = ps.getSharedUser().getPackages();
2501 int packagesSize = packages.size();
2502 for (int i = 0; i < packagesSize; i++) {
2503 AndroidPackage sharedUserPackage = packages.get(i);
2504 requestedPermissions.addAll(sharedUserPackage.getRequestedPermissions());
2505 targetSdkVersion = Math.min(targetSdkVersion,
2506 sharedUserPackage.getTargetSdkVersion());
2507 }
2508 }
2509
2510 for (String permissionName : requestedPermissions) {
2511 BasePermission permission = mSettings.getPermission(permissionName);
Hai Zhangd8ba6852020-06-16 13:28:48 -07002512 if (permission == null) {
2513 continue;
2514 }
Hai Zhang4c0d15b2020-05-18 16:06:58 -07002515 if (Objects.equals(permission.getSourcePackageName(), PLATFORM_PACKAGE_NAME)
2516 && permission.isRuntime() && !permission.isRemoved()) {
2517 if (permission.isHardOrSoftRestricted()
2518 || permission.isImmutablyRestricted()) {
2519 permissionsState.updatePermissionFlags(permission, userId,
2520 PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
2521 PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
2522 }
2523 if (targetSdkVersion < Build.VERSION_CODES.M) {
2524 permissionsState.updatePermissionFlags(permission, userId,
2525 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
2526 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
2527 PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
2528 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT);
2529 permissionsState.grantRuntimePermission(permission, userId);
2530 }
2531 }
2532 }
2533
2534 permissionsState.setMissing(false, userId);
2535 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2536 }
2537 }
2538
2539 PermissionsState origPermissions = permissionsState;
2540
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002541 boolean changedInstallPermission = false;
2542
2543 if (replace) {
2544 ps.setInstallPermissionsFixed(false);
2545 if (!ps.isSharedUser()) {
2546 origPermissions = new PermissionsState(permissionsState);
2547 permissionsState.reset();
2548 } else {
2549 // We need to know only about runtime permission changes since the
2550 // calling code always writes the install permissions state but
2551 // the runtime ones are written only if changed. The only cases of
2552 // changed runtime permissions here are promotion of an install to
2553 // runtime and revocation of a runtime from a shared user.
2554 synchronized (mLock) {
2555 updatedUserIds = revokeUnusedSharedUserPermissionsLocked(
2556 ps.getSharedUser(), UserManagerService.getInstance().getUserIds());
2557 if (!ArrayUtils.isEmpty(updatedUserIds)) {
2558 runtimePermissionsRevoked = true;
2559 }
2560 }
2561 }
2562 }
2563
2564 permissionsState.setGlobalGids(mGlobalGids);
2565
2566 synchronized (mLock) {
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002567 ArraySet<String> newImplicitPermissions = new ArraySet<>();
2568
Winson14ff7172019-10-23 10:42:27 -07002569 final int N = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002570 for (int i = 0; i < N; i++) {
Winson14ff7172019-10-23 10:42:27 -07002571 final String permName = pkg.getRequestedPermissions().get(i);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002572 final BasePermission bp = mSettings.getPermissionLocked(permName);
2573 final boolean appSupportsRuntimePermissions =
Winson14ff7172019-10-23 10:42:27 -07002574 pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
Zimuzoe6411402019-05-13 16:32:57 +01002575 String upgradedActivityRecognitionPermission = null;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002576
Songchun Fanbcc899e2020-04-06 16:51:45 -07002577 if (DEBUG_INSTALL && bp != null) {
Winson14ff7172019-10-23 10:42:27 -07002578 Log.i(TAG, "Package " + pkg.getPackageName()
2579 + " checking " + permName + ": " + bp);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002580 }
2581
Songchun Fane5c0afe2020-04-22 12:22:52 -07002582 if (bp == null || getSourcePackageSetting(bp) == null) {
Winson14ff7172019-10-23 10:42:27 -07002583 if (packageOfInterest == null || packageOfInterest.equals(
2584 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002585 if (DEBUG_PERMISSIONS) {
2586 Slog.i(TAG, "Unknown permission " + permName
Winson14ff7172019-10-23 10:42:27 -07002587 + " in package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002588 }
2589 }
2590 continue;
2591 }
2592
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002593 // Cache newImplicitPermissions before modifing permissionsState as for the shared
2594 // uids the original and new state are the same object
2595 if (!origPermissions.hasRequestedPermission(permName)
Winson14ff7172019-10-23 10:42:27 -07002596 && (pkg.getImplicitPermissions().contains(permName)
Zimuzoe6411402019-05-13 16:32:57 +01002597 || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
Winson14ff7172019-10-23 10:42:27 -07002598 if (pkg.getImplicitPermissions().contains(permName)) {
Zimuzoe6411402019-05-13 16:32:57 +01002599 // If permName is an implicit permission, try to auto-grant
2600 newImplicitPermissions.add(permName);
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002601
Zimuzoe6411402019-05-13 16:32:57 +01002602 if (DEBUG_PERMISSIONS) {
Winson14ff7172019-10-23 10:42:27 -07002603 Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002604 }
2605 } else {
2606 // Special case for Activity Recognition permission. Even if AR permission
2607 // is not an implicit permission we want to add it to the list (try to
2608 // auto-grant it) if the app was installed on a device before AR permission
2609 // was split, regardless of if the app now requests the new AR permission
2610 // or has updated its target SDK and AR is no longer implicit to it.
2611 // This is a compatibility workaround for apps when AR permission was
2612 // split in Q.
Anthony Hughde787d42019-08-22 15:35:48 -07002613 final List<SplitPermissionInfoParcelable> permissionList =
2614 getSplitPermissions();
2615 int numSplitPerms = permissionList.size();
Zimuzoe6411402019-05-13 16:32:57 +01002616 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07002617 SplitPermissionInfoParcelable sp = permissionList.get(splitPermNum);
Zimuzoe6411402019-05-13 16:32:57 +01002618 String splitPermName = sp.getSplitPermission();
2619 if (sp.getNewPermissions().contains(permName)
2620 && origPermissions.hasInstallPermission(splitPermName)) {
2621 upgradedActivityRecognitionPermission = splitPermName;
2622 newImplicitPermissions.add(permName);
2623
2624 if (DEBUG_PERMISSIONS) {
2625 Slog.i(TAG, permName + " is newly added for "
Winson14ff7172019-10-23 10:42:27 -07002626 + pkg.getPackageName());
Zimuzoe6411402019-05-13 16:32:57 +01002627 }
2628 break;
2629 }
2630 }
Philip P. Moltmanne1233192019-04-18 08:45:55 -07002631 }
2632 }
2633
Winson5e0a1d52020-01-24 12:00:33 -08002634 // TODO(b/140256621): The package instant app method has been removed
2635 // as part of work in b/135203078, so this has been commented out in the meantime
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002636 // Limit ephemeral apps to ephemeral allowed permissions.
Winson5e0a1d52020-01-24 12:00:33 -08002637// if (/*pkg.isInstantApp()*/ false && !bp.isInstant()) {
2638// if (DEBUG_PERMISSIONS) {
2639// Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
2640// + " for package " + pkg.getPackageName());
2641// }
2642// continue;
2643// }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002644
2645 if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
2646 if (DEBUG_PERMISSIONS) {
2647 Log.i(TAG, "Denying runtime-only permission " + bp.getName()
Winson14ff7172019-10-23 10:42:27 -07002648 + " for package " + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002649 }
2650 continue;
2651 }
2652
2653 final String perm = bp.getName();
2654 boolean allowedSig = false;
2655 int grant = GRANT_DENIED;
2656
2657 // Keep track of app op permissions.
2658 if (bp.isAppOp()) {
Winson14ff7172019-10-23 10:42:27 -07002659 mSettings.addAppOpPackage(perm, pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002660 }
2661
2662 if (bp.isNormal()) {
2663 // For all apps normal permissions are install time ones.
2664 grant = GRANT_INSTALL;
2665 } else if (bp.isRuntime()) {
Zimuzoe6411402019-05-13 16:32:57 +01002666 if (origPermissions.hasInstallPermission(bp.getName())
2667 || upgradedActivityRecognitionPermission != null) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002668 // Before Q we represented some runtime permissions as install permissions,
2669 // in Q we cannot do this anymore. Hence upgrade them all.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002670 grant = GRANT_UPGRADE;
2671 } else {
2672 // For modern apps keep runtime permissions unchanged.
2673 grant = GRANT_RUNTIME;
2674 }
2675 } else if (bp.isSignature()) {
2676 // For all apps signature permissions are install time ones.
Winsone0756292020-01-31 12:21:54 -08002677 allowedSig = grantSignaturePermission(perm, pkg, ps, bp, origPermissions);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002678 if (allowedSig) {
2679 grant = GRANT_INSTALL;
2680 }
2681 }
2682
2683 if (DEBUG_PERMISSIONS) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07002684 Slog.i(TAG, "Considering granting permission " + perm + " to package "
Winson14ff7172019-10-23 10:42:27 -07002685 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002686 }
2687
2688 if (grant != GRANT_DENIED) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002689 if (!ps.isSystem() && ps.areInstallPermissionsFixed() && !bp.isRuntime()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002690 // If this is an existing, non-system package, then
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002691 // we can't add any new permissions to it. Runtime
2692 // permissions can be added any time - they ad dynamic.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002693 if (!allowedSig && !origPermissions.hasInstallPermission(perm)) {
2694 // Except... if this is a permission that was added
2695 // to the platform (note: need to only do this when
2696 // updating the platform).
2697 if (!isNewPlatformPermissionForPackage(perm, pkg)) {
2698 grant = GRANT_DENIED;
2699 }
2700 }
2701 }
2702
2703 switch (grant) {
2704 case GRANT_INSTALL: {
2705 // Revoke this as runtime permission to handle the case of
2706 // a runtime permission being downgraded to an install one.
2707 // Also in permission review mode we keep dangerous permissions
2708 // for legacy apps
2709 for (int userId : UserManagerService.getInstance().getUserIds()) {
2710 if (origPermissions.getRuntimePermissionState(
2711 perm, userId) != null) {
2712 // Revoke the runtime permission and clear the flags.
2713 origPermissions.revokeRuntimePermission(bp, userId);
2714 origPermissions.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002715 PackageManager.MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002716 // If we revoked a permission permission, we have to write.
2717 updatedUserIds = ArrayUtils.appendInt(
2718 updatedUserIds, userId);
2719 }
2720 }
2721 // Grant an install permission.
2722 if (permissionsState.grantInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002723 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002724 changedInstallPermission = true;
2725 }
2726 } break;
2727
2728 case GRANT_RUNTIME: {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002729 boolean hardRestricted = bp.isHardRestricted();
2730 boolean softRestricted = bp.isSoftRestricted();
2731
Philip P. Moltmann48456672019-01-20 13:14:03 -08002732 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002733 // If permission policy is not ready we don't deal with restricted
2734 // permissions as the policy may whitelist some permissions. Once
2735 // the policy is initialized we would re-evaluate permissions.
2736 final boolean permissionPolicyInitialized =
2737 mPermissionPolicyInternal != null
2738 && mPermissionPolicyInternal.isInitialized(userId);
2739
Philip P. Moltmann48456672019-01-20 13:14:03 -08002740 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002741 .getRuntimePermissionState(perm, userId);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002742 int flags = permState != null ? permState.getFlags() : 0;
2743
2744 boolean wasChanged = false;
2745
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002746 boolean restrictionExempt =
2747 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002748 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2749 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2750 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2751
Philip P. Moltmann48456672019-01-20 13:14:03 -08002752 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002753 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002754 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002755 if (!restrictionExempt) {
2756 if (permState != null && permState.isGranted()
2757 && permissionsState.revokeRuntimePermission(
2758 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2759 wasChanged = true;
2760 }
2761 if (!restrictionApplied) {
2762 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2763 wasChanged = true;
2764 }
2765 }
2766 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002767 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002768 // Regardless if granted set the restriction flag as it
2769 // may affect app treatment based on this permission.
2770 if (!restrictionExempt && !restrictionApplied) {
2771 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2772 wasChanged = true;
2773 }
2774 }
2775
Philip P. Moltmann48456672019-01-20 13:14:03 -08002776 // Remove review flag as it is not necessary anymore
2777 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2778 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2779 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002780 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002781
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002782 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2783 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002784 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002785 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002786 } else if (!permissionPolicyInitialized
2787 || (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002788 if (permState != null && permState.isGranted()) {
2789 if (permissionsState.grantRuntimePermission(bp, userId)
2790 == PERMISSION_OPERATION_FAILURE) {
2791 wasChanged = true;
2792 }
2793 }
2794 }
2795 } else {
2796 if (permState == null) {
2797 // New permission
2798 if (PLATFORM_PACKAGE_NAME.equals(
2799 bp.getSourcePackageName())) {
2800 if (!bp.isRemoved()) {
2801 flags |= FLAG_PERMISSION_REVIEW_REQUIRED
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002802 | FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002803 wasChanged = true;
2804 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002805 }
2806 }
2807
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002808 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2809 && permissionsState.grantRuntimePermission(bp, userId)
2810 != PERMISSION_OPERATION_FAILURE) {
2811 wasChanged = true;
2812 }
2813
2814 // If legacy app always grant the permission but if restricted
2815 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002816 if (permissionPolicyInitialized
2817 && (hardRestricted || softRestricted)
2818 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002819 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2820 wasChanged = true;
2821 }
2822 }
2823
2824 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002825 if (permissionPolicyInitialized) {
2826 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2827 if (restrictionApplied) {
2828 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2829 // Dropping restriction on a legacy app implies a review
2830 if (!appSupportsRuntimePermissions) {
2831 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2832 }
2833 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002834 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002835 }
2836 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002837
2838 if (wasChanged) {
2839 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2840 }
2841
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002842 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002843 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002844 }
2845 } break;
2846
2847 case GRANT_UPGRADE: {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002848 // Upgrade from Pre-Q to Q permission model. Make all permissions
2849 // runtime
2850 PermissionState permState = origPermissions
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002851 .getInstallPermissionState(perm);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002852 int flags = (permState != null) ? permState.getFlags() : 0;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002853
Zimuzoe6411402019-05-13 16:32:57 +01002854 BasePermission bpToRevoke =
2855 upgradedActivityRecognitionPermission == null
2856 ? bp : mSettings.getPermissionLocked(
2857 upgradedActivityRecognitionPermission);
Philip P. Moltmann48456672019-01-20 13:14:03 -08002858 // Remove install permission
Zimuzoe6411402019-05-13 16:32:57 +01002859 if (origPermissions.revokeInstallPermission(bpToRevoke)
Philip P. Moltmann48456672019-01-20 13:14:03 -08002860 != PERMISSION_OPERATION_FAILURE) {
Zimuzoe6411402019-05-13 16:32:57 +01002861 origPermissions.updatePermissionFlags(bpToRevoke,
2862 UserHandle.USER_ALL,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002863 (MASK_PERMISSION_FLAGS_ALL
2864 & ~FLAG_PERMISSION_APPLY_RESTRICTION), 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002865 changedInstallPermission = true;
2866 }
2867
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002868 boolean hardRestricted = bp.isHardRestricted();
2869 boolean softRestricted = bp.isSoftRestricted();
2870
Philip P. Moltmann48456672019-01-20 13:14:03 -08002871 for (int userId : currentUserIds) {
Svet Ganov3c499ea2019-07-26 17:45:56 -07002872 // If permission policy is not ready we don't deal with restricted
2873 // permissions as the policy may whitelist some permissions. Once
2874 // the policy is initialized we would re-evaluate permissions.
2875 final boolean permissionPolicyInitialized =
2876 mPermissionPolicyInternal != null
2877 && mPermissionPolicyInternal.isInitialized(userId);
2878
Philip P. Moltmann48456672019-01-20 13:14:03 -08002879 boolean wasChanged = false;
2880
Svet Ganov83a3a4a2019-05-03 18:50:43 -07002881 boolean restrictionExempt =
2882 (origPermissions.getPermissionFlags(bp.name, userId)
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002883 & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
2884 boolean restrictionApplied = (origPermissions.getPermissionFlags(
2885 bp.name, userId) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
2886
Philip P. Moltmann48456672019-01-20 13:14:03 -08002887 if (appSupportsRuntimePermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002888 // If hard restricted we don't allow holding it
Svet Ganov3c499ea2019-07-26 17:45:56 -07002889 if (permissionPolicyInitialized && hardRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002890 if (!restrictionExempt) {
2891 if (permState != null && permState.isGranted()
2892 && permissionsState.revokeRuntimePermission(
2893 bp, userId) != PERMISSION_OPERATION_FAILURE) {
2894 wasChanged = true;
2895 }
2896 if (!restrictionApplied) {
2897 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2898 wasChanged = true;
2899 }
2900 }
2901 // If soft restricted we allow holding in a restricted form
Svet Ganov3c499ea2019-07-26 17:45:56 -07002902 } else if (permissionPolicyInitialized && softRestricted) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002903 // Regardless if granted set the restriction flag as it
2904 // may affect app treatment based on this permission.
2905 if (!restrictionExempt && !restrictionApplied) {
2906 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2907 wasChanged = true;
2908 }
2909 }
2910
Philip P. Moltmann48456672019-01-20 13:14:03 -08002911 // Remove review flag as it is not necessary anymore
2912 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
2913 flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
2914 wasChanged = true;
2915 }
2916
Hai Zhang50a5a9b2019-09-19 13:57:45 -07002917 if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0) {
2918 flags &= ~FLAG_PERMISSION_REVOKED_COMPAT;
Philip P. Moltmann48456672019-01-20 13:14:03 -08002919 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002920 // Hard restricted permissions cannot be held.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002921 } else if (!permissionPolicyInitialized ||
2922 (!hardRestricted || restrictionExempt)) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002923 if (permissionsState.grantRuntimePermission(bp, userId) !=
2924 PERMISSION_OPERATION_FAILURE) {
2925 wasChanged = true;
2926 }
2927 }
2928 } else {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002929 if (!permissionsState.hasRuntimePermission(bp.name, userId)
2930 && permissionsState.grantRuntimePermission(bp,
2931 userId) != PERMISSION_OPERATION_FAILURE) {
Philip P. Moltmann48456672019-01-20 13:14:03 -08002932 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2933 wasChanged = true;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002934 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002935
2936 // If legacy app always grant the permission but if restricted
2937 // and not exempt take a note a restriction should be applied.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002938 if (permissionPolicyInitialized
2939 && (hardRestricted || softRestricted)
2940 && !restrictionExempt && !restrictionApplied) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002941 flags |= FLAG_PERMISSION_APPLY_RESTRICTION;
2942 wasChanged = true;
2943 }
2944 }
2945
2946 // If unrestricted or restriction exempt, don't apply restriction.
Svet Ganov3c499ea2019-07-26 17:45:56 -07002947 if (permissionPolicyInitialized) {
2948 if (!(hardRestricted || softRestricted) || restrictionExempt) {
2949 if (restrictionApplied) {
2950 flags &= ~FLAG_PERMISSION_APPLY_RESTRICTION;
2951 // Dropping restriction on a legacy app implies a review
2952 if (!appSupportsRuntimePermissions) {
2953 flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
2954 }
2955 wasChanged = true;
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002956 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07002957 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002958 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08002959
2960 if (wasChanged) {
2961 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
2962 }
2963
Philip P. Moltmannc6e3a8e2019-02-21 13:57:31 -08002964 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002965 MASK_PERMISSION_FLAGS_ALL, flags);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002966 }
2967 } break;
2968
2969 default: {
2970 if (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07002971 || packageOfInterest.equals(pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002972 if (DEBUG_PERMISSIONS) {
2973 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002974 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002975 + " because it was previously installed without");
2976 }
2977 }
2978 } break;
2979 }
2980 } else {
2981 if (permissionsState.revokeInstallPermission(bp) !=
Philip P. Moltmann48456672019-01-20 13:14:03 -08002982 PERMISSION_OPERATION_FAILURE) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002983 // Also drop the permission flags.
2984 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08002985 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002986 changedInstallPermission = true;
Nate Myrened67bdd2019-05-07 10:32:22 -07002987 if (DEBUG_PERMISSIONS) {
2988 Slog.i(TAG, "Un-granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07002989 + " from package " + pkg.getPackageName()
Nate Myrened67bdd2019-05-07 10:32:22 -07002990 + " (protectionLevel=" + bp.getProtectionLevel()
Winsonf00c7552020-01-28 12:52:01 -08002991 + " flags=0x"
2992 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
Nate Myrened67bdd2019-05-07 10:32:22 -07002993 + ")");
2994 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07002995 } else if (bp.isAppOp()) {
2996 // Don't print warning for app op permissions, since it is fine for them
2997 // not to be granted, there is a UI for the user to decide.
2998 if (DEBUG_PERMISSIONS
2999 && (packageOfInterest == null
Winson14ff7172019-10-23 10:42:27 -07003000 || packageOfInterest.equals(pkg.getPackageName()))) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003001 Slog.i(TAG, "Not granting permission " + perm
Winson14ff7172019-10-23 10:42:27 -07003002 + " to package " + pkg.getPackageName()
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003003 + " (protectionLevel=" + bp.getProtectionLevel()
Winsonf00c7552020-01-28 12:52:01 -08003004 + " flags=0x"
3005 + Integer.toHexString(PackageInfoUtils.appInfoFlags(pkg, ps))
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003006 + ")");
3007 }
3008 }
3009 }
3010 }
3011
3012 if ((changedInstallPermission || replace) && !ps.areInstallPermissionsFixed() &&
Winson8359e402020-02-21 17:32:14 -08003013 !ps.isSystem() || ps.getPkgState().isUpdatedSystemApp()) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003014 // This is the first that we have heard about this package, so the
3015 // permissions we have now selected are fixed until explicitly
3016 // changed.
3017 ps.setInstallPermissionsFixed(true);
3018 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003019
3020 updatedUserIds = revokePermissionsNoLongerImplicitLocked(permissionsState, pkg,
3021 updatedUserIds);
3022 updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07003023 permissionsState, pkg, newImplicitPermissions, updatedUserIds);
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003024 updatedUserIds = checkIfLegacyStorageOpsNeedToBeUpdated(pkg, replace, updatedUserIds);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003025 }
3026
3027 // Persist the runtime permissions state for users with changes. If permissions
3028 // were revoked because no app in the shared user declares them we have to
3029 // write synchronously to avoid losing runtime permissions state.
3030 if (callback != null) {
3031 callback.onPermissionUpdated(updatedUserIds, runtimePermissionsRevoked);
3032 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003033
3034 for (int userId : updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07003035 notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003036 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003037 }
3038
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003039 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003040 * Revoke permissions that are not implicit anymore and that have
3041 * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
3042 *
3043 * @param ps The state of the permissions of the package
3044 * @param pkg The package that is currently looked at
3045 * @param updatedUserIds a list of user ids that needs to be amended if the permission state
3046 * for a user is changed.
3047 *
3048 * @return The updated value of the {@code updatedUserIds} parameter
3049 */
3050 private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
Winson14ff7172019-10-23 10:42:27 -07003051 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003052 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07003053 String pkgName = pkg.getPackageName();
3054 boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Philip P. Moltmannd030ce22019-02-18 21:05:48 -08003055 >= Build.VERSION_CODES.M;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003056
3057 int[] users = UserManagerService.getInstance().getUserIds();
3058 int numUsers = users.length;
3059 for (int i = 0; i < numUsers; i++) {
3060 int userId = users[i];
3061
3062 for (String permission : ps.getPermissions(userId)) {
Winson14ff7172019-10-23 10:42:27 -07003063 if (!pkg.getImplicitPermissions().contains(permission)) {
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003064 if (!ps.hasInstallPermission(permission)) {
3065 int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
3066
3067 if ((flags & FLAG_PERMISSION_REVOKE_WHEN_REQUESTED) != 0) {
3068 BasePermission bp = mSettings.getPermissionLocked(permission);
3069
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003070 int flagsToRemove = FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003071
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08003072 if ((flags & BLOCKING_PERMISSION_FLAGS) == 0
3073 && supportsRuntimePermissions) {
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003074 int revokeResult = ps.revokeRuntimePermission(bp, userId);
3075 if (revokeResult != PERMISSION_OPERATION_FAILURE) {
3076 if (DEBUG_PERMISSIONS) {
3077 Slog.i(TAG, "Revoking runtime permission "
3078 + permission + " for " + pkgName
3079 + " as it is now requested");
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003080 }
3081 }
3082
Philip P. Moltmann319c4ee2019-02-25 09:21:23 -08003083 flagsToRemove |= USER_PERMISSION_FLAGS;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003084 }
Philip P. Moltmann8277ab62019-02-21 14:08:30 -08003085
3086 ps.updatePermissionFlags(bp, userId, flagsToRemove, 0);
3087 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003088 }
3089 }
3090 }
3091 }
3092 }
3093
3094 return updatedUserIds;
3095 }
3096
3097 /**
3098 * {@code newPerm} is newly added; Inherit the state from {@code sourcePerms}.
3099 *
3100 * <p>A single new permission can be split off from several source permissions. In this case
3101 * the most leniant state is inherited.
3102 *
3103 * <p>Warning: This does not handle foreground / background permissions
3104 *
3105 * @param sourcePerms The permissions to inherit from
3106 * @param newPerm The permission to inherit to
3107 * @param ps The permission state of the package
3108 * @param pkg The package requesting the permissions
3109 * @param userId The user the permission belongs to
3110 */
3111 private void inheritPermissionStateToNewImplicitPermissionLocked(
3112 @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
Winson14ff7172019-10-23 10:42:27 -07003113 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003114 @UserIdInt int userId) {
Winson14ff7172019-10-23 10:42:27 -07003115 String pkgName = pkg.getPackageName();
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003116 boolean isGranted = false;
3117 int flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003118
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003119 int numSourcePerm = sourcePerms.size();
3120 for (int i = 0; i < numSourcePerm; i++) {
3121 String sourcePerm = sourcePerms.valueAt(i);
3122 if ((ps.hasRuntimePermission(sourcePerm, userId))
3123 || ps.hasInstallPermission(sourcePerm)) {
3124 if (!isGranted) {
3125 flags = 0;
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003126 }
3127
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003128 isGranted = true;
3129 flags |= ps.getPermissionFlags(sourcePerm, userId);
3130 } else {
3131 if (!isGranted) {
Philip P. Moltmanndddadd72019-02-25 09:21:23 -08003132 flags |= ps.getPermissionFlags(sourcePerm, userId);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003133 }
3134 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003135 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -07003136
3137 if (isGranted) {
3138 if (DEBUG_PERMISSIONS) {
3139 Slog.i(TAG, newPerm + " inherits runtime perm grant from " + sourcePerms
3140 + " for " + pkgName);
3141 }
3142
3143 ps.grantRuntimePermission(mSettings.getPermissionLocked(newPerm), userId);
3144 }
3145
3146 // Add permission flags
3147 ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003148 }
3149
3150 /**
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003151 * When the app has requested legacy storage we might need to update
3152 * {@link android.app.AppOpsManager#OP_LEGACY_STORAGE}. Hence force an update in
3153 * {@link com.android.server.policy.PermissionPolicyService#synchronizePackagePermissionsAndAppOpsForUser(Context, String, int)}
3154 *
3155 * @param pkg The package for which the permissions are updated
3156 * @param replace If the app is being replaced
3157 * @param updatedUserIds The ids of the users that already changed.
3158 *
3159 * @return The ids of the users that are changed
3160 */
3161 private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
Winson14ff7172019-10-23 10:42:27 -07003162 @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) {
Winson5e0a1d52020-01-24 12:00:33 -08003163 if (replace && pkg.isRequestLegacyExternalStorage() && (
Winson14ff7172019-10-23 10:42:27 -07003164 pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
3165 || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
Philip P. Moltmann74065c82019-05-15 10:46:32 -07003166 return UserManagerService.getInstance().getUserIds();
3167 }
3168
3169 return updatedUserIds;
3170 }
3171
3172 /**
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003173 * Set the state of a implicit permission that is seen for the first time.
3174 *
3175 * @param origPs The permission state of the package before the split
3176 * @param ps The new permission state
3177 * @param pkg The package the permission belongs to
3178 * @param updatedUserIds List of users for which the permission state has already been changed
3179 *
3180 * @return List of users for which the permission state has been changed
3181 */
3182 private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
3183 @NonNull PermissionsState origPs,
Winson14ff7172019-10-23 10:42:27 -07003184 @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
Philip P. Moltmanne1233192019-04-18 08:45:55 -07003185 @NonNull ArraySet<String> newImplicitPermissions,
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003186 @NonNull int[] updatedUserIds) {
Winson14ff7172019-10-23 10:42:27 -07003187 String pkgName = pkg.getPackageName();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003188 ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
3189
Anthony Hughde787d42019-08-22 15:35:48 -07003190 final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions();
3191 int numSplitPerms = permissionList.size();
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003192 for (int splitPermNum = 0; splitPermNum < numSplitPerms; splitPermNum++) {
Anthony Hughde787d42019-08-22 15:35:48 -07003193 SplitPermissionInfoParcelable spi = permissionList.get(splitPermNum);
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003194
3195 List<String> newPerms = spi.getNewPermissions();
3196 int numNewPerms = newPerms.size();
3197 for (int newPermNum = 0; newPermNum < numNewPerms; newPermNum++) {
3198 String newPerm = newPerms.get(newPermNum);
3199
3200 ArraySet<String> splitPerms = newToSplitPerms.get(newPerm);
3201 if (splitPerms == null) {
3202 splitPerms = new ArraySet<>();
3203 newToSplitPerms.put(newPerm, splitPerms);
3204 }
3205
3206 splitPerms.add(spi.getSplitPermission());
3207 }
3208 }
3209
3210 int numNewImplicitPerms = newImplicitPermissions.size();
3211 for (int newImplicitPermNum = 0; newImplicitPermNum < numNewImplicitPerms;
3212 newImplicitPermNum++) {
3213 String newPerm = newImplicitPermissions.valueAt(newImplicitPermNum);
3214 ArraySet<String> sourcePerms = newToSplitPerms.get(newPerm);
3215
3216 if (sourcePerms != null) {
3217 if (!ps.hasInstallPermission(newPerm)) {
3218 BasePermission bp = mSettings.getPermissionLocked(newPerm);
3219
3220 int[] users = UserManagerService.getInstance().getUserIds();
3221 int numUsers = users.length;
3222 for (int userNum = 0; userNum < numUsers; userNum++) {
3223 int userId = users[userNum];
3224
Zimuzoe6411402019-05-13 16:32:57 +01003225 if (!newPerm.equals(Manifest.permission.ACTIVITY_RECOGNITION)) {
3226 ps.updatePermissionFlags(bp, userId,
3227 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
3228 FLAG_PERMISSION_REVOKE_WHEN_REQUESTED);
3229 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003230 updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
3231
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003232 boolean inheritsFromInstallPerm = false;
3233 for (int sourcePermNum = 0; sourcePermNum < sourcePerms.size();
3234 sourcePermNum++) {
3235 if (ps.hasInstallPermission(sourcePerms.valueAt(sourcePermNum))) {
3236 inheritsFromInstallPerm = true;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003237 break;
Philip P. Moltmannd82bdaf2018-10-30 12:46:40 -07003238 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003239 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003240
3241 if (!origPs.hasRequestedPermission(sourcePerms)
3242 && !inheritsFromInstallPerm) {
3243 // Both permissions are new so nothing to inherit.
3244 if (DEBUG_PERMISSIONS) {
3245 Slog.i(TAG, newPerm + " does not inherit from " + sourcePerms
3246 + " for " + pkgName + " as split permission is also new");
3247 }
Philip P. Moltmannd3e64162019-02-22 16:24:01 -08003248 } else {
3249 // Inherit from new install or existing runtime permissions
3250 inheritPermissionStateToNewImplicitPermissionLocked(sourcePerms,
3251 newPerm, ps, pkg, userId);
3252 }
Philip P. Moltmann17f65af2018-10-18 15:32:29 -07003253 }
3254 }
3255 }
3256 }
3257
3258 return updatedUserIds;
3259 }
3260
Anthony Hughde787d42019-08-22 15:35:48 -07003261 @Override
3262 public List<SplitPermissionInfoParcelable> getSplitPermissions() {
3263 return PermissionManager.splitPermissionInfoListToParcelableList(
3264 SystemConfig.getInstance().getSplitPermissions());
3265 }
3266
Evan Seversonb252d8b2019-11-20 08:41:33 -08003267 private OneTimePermissionUserManager getOneTimePermissionUserManager(@UserIdInt int userId) {
Evan Severson2cbceb92020-04-14 18:27:10 +00003268 OneTimePermissionUserManager oneTimePermissionUserManager;
Evan Seversonb252d8b2019-11-20 08:41:33 -08003269 synchronized (mLock) {
Evan Severson2cbceb92020-04-14 18:27:10 +00003270 oneTimePermissionUserManager =
Evan Seversonb252d8b2019-11-20 08:41:33 -08003271 mOneTimePermissionUserManagers.get(userId);
Evan Severson2cbceb92020-04-14 18:27:10 +00003272 if (oneTimePermissionUserManager != null) {
3273 return oneTimePermissionUserManager;
Evan Seversonb252d8b2019-11-20 08:41:33 -08003274 }
Evan Severson2cbceb92020-04-14 18:27:10 +00003275 oneTimePermissionUserManager = new OneTimePermissionUserManager(
3276 mContext.createContextAsUser(UserHandle.of(userId), /*flags*/ 0));
3277 mOneTimePermissionUserManagers.put(userId, oneTimePermissionUserManager);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003278 }
Evan Severson2cbceb92020-04-14 18:27:10 +00003279 oneTimePermissionUserManager.registerUninstallListener();
3280 return oneTimePermissionUserManager;
Evan Seversonb252d8b2019-11-20 08:41:33 -08003281 }
3282
3283 @Override
3284 public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
3285 long timeoutMillis, int importanceToResetTimer, int importanceToKeepSessionAlive) {
Evan Severson43e17e02020-01-03 10:04:38 -08003286 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3287 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3288 + " to register permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003289 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003290
3291 long token = Binder.clearCallingIdentity();
3292 try {
3293 getOneTimePermissionUserManager(userId).startPackageOneTimeSession(packageName,
3294 timeoutMillis, importanceToResetTimer, importanceToKeepSessionAlive);
3295 } finally {
3296 Binder.restoreCallingIdentity(token);
3297 }
3298 }
3299
3300 @Override
3301 public void stopOneTimePermissionSession(String packageName, @UserIdInt int userId) {
Evan Severson43e17e02020-01-03 10:04:38 -08003302 mContext.enforceCallingPermission(Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
3303 "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
3304 + " to remove permissions as one time.");
Daulet Zhanguzin82adfcb2020-01-02 17:31:40 +00003305 Objects.requireNonNull(packageName);
Evan Seversonb252d8b2019-11-20 08:41:33 -08003306
3307 long token = Binder.clearCallingIdentity();
3308 try {
3309 getOneTimePermissionUserManager(userId).stopPackageOneTimeSession(packageName);
3310 } finally {
3311 Binder.restoreCallingIdentity(token);
3312 }
3313 }
3314
Eugene Susladb77bc12020-03-03 12:09:00 -08003315 @Override
3316 public List<String> getAutoRevokeExemptionRequestedPackages(int userId) {
Eugene Susla49b84c32020-03-23 15:19:29 -07003317 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISCOURAGED, userId);
Eugene Susladb77bc12020-03-03 12:09:00 -08003318 }
3319
3320 @Override
3321 public List<String> getAutoRevokeExemptionGrantedPackages(int userId) {
Eugene Susla49b84c32020-03-23 15:19:29 -07003322 return getPackagesWithAutoRevokePolicy(AUTO_REVOKE_DISALLOWED, userId);
3323 }
3324
3325 @NonNull
3326 private List<String> getPackagesWithAutoRevokePolicy(int autoRevokePolicy, int userId) {
Eugene Susladb77bc12020-03-03 12:09:00 -08003327 mContext.enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
3328 "Must hold " + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY);
3329
3330 List<String> result = new ArrayList<>();
3331 mPackageManagerInt.forEachInstalledPackage(pkg -> {
Eugene Susla49b84c32020-03-23 15:19:29 -07003332 if (pkg.getAutoRevokePermissions() == autoRevokePolicy) {
Eugene Susladb77bc12020-03-03 12:09:00 -08003333 result.add(pkg.getPackageName());
3334 }
3335 }, userId);
Eugene Susladb77bc12020-03-03 12:09:00 -08003336 return result;
3337 }
3338
Winson14ff7172019-10-23 10:42:27 -07003339 private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003340 boolean allowed = false;
3341 final int NP = PackageParser.NEW_PERMISSIONS.length;
3342 for (int ip=0; ip<NP; ip++) {
3343 final PackageParser.NewPermissionInfo npi
3344 = PackageParser.NEW_PERMISSIONS[ip];
3345 if (npi.name.equals(perm)
Winson14ff7172019-10-23 10:42:27 -07003346 && pkg.getTargetSdkVersion() < npi.sdkVersion) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003347 allowed = true;
3348 Log.i(TAG, "Auto-granting " + perm + " to old pkg "
Winson14ff7172019-10-23 10:42:27 -07003349 + pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003350 break;
3351 }
3352 }
3353 return allowed;
3354 }
3355
3356 /**
3357 * Determines whether a package is whitelisted for a particular privapp permission.
3358 *
3359 * <p>Does NOT check whether the package is a privapp, just whether it's whitelisted.
3360 *
3361 * <p>This handles parent/child apps.
3362 */
Winson14ff7172019-10-23 10:42:27 -07003363 private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) {
3364 ArraySet<String> wlPermissions;
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003365 if (pkg.isVendor()) {
3366 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003367 SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003368 } else if (pkg.isProduct()) {
3369 wlPermissions =
Winson14ff7172019-10-23 10:42:27 -07003370 SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName());
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003371 } else if (pkg.isSystemExt()) {
Dario Freni2bef1762018-06-01 14:02:08 +01003372 wlPermissions =
Jeongik Cha9ec059a2019-07-04 21:12:06 +09003373 SystemConfig.getInstance().getSystemExtPrivAppPermissions(
Winson14ff7172019-10-23 10:42:27 -07003374 pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003375 } else {
Winson14ff7172019-10-23 10:42:27 -07003376 wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName());
Jaekyun Seok1713d9e2018-01-12 21:47:26 +09003377 }
Winson14ff7172019-10-23 10:42:27 -07003378
3379 return wlPermissions != null && wlPermissions.contains(perm);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003380 }
3381
Winson14ff7172019-10-23 10:42:27 -07003382 private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
Winsone0756292020-01-31 12:21:54 -08003383 PackageSetting pkgSetting, BasePermission bp, PermissionsState origPermissions) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003384 boolean oemPermission = bp.isOEM();
Jiyong Park002fdbd2017-02-13 20:50:31 +09003385 boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
3386 boolean privilegedPermission = bp.isPrivileged() || bp.isVendorPrivileged();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003387 boolean privappPermissionsDisable =
3388 RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
3389 boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07003390 boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003391 if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
3392 && !platformPackage && platformPermission) {
3393 if (!hasPrivappWhitelistEntry(perm, pkg)) {
Philip P. Moltmannbd278012020-03-10 14:46:27 -07003394 // Only enforce whitelist this on boot
3395 if (!mSystemReady
3396 // Updated system apps do not need to be whitelisted
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003397 && !pkgSetting.getPkgState().isUpdatedSystemApp()) {
3398 ApexManager apexMgr = ApexManager.getInstance();
3399 String apexContainingPkg = apexMgr.getActiveApexPackageNameContainingPackage(
3400 pkg);
Fyodor Kupolovf5e600d2017-10-25 17:03:50 -07003401
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003402 // Apps that are in updated apexs' do not need to be whitelisted
3403 if (apexContainingPkg == null || apexMgr.isFactory(
3404 apexMgr.getPackageInfo(apexContainingPkg, MATCH_ACTIVE_PACKAGE))) {
3405 // it's only a reportable violation if the permission isn't explicitly
3406 // denied
3407 ArraySet<String> deniedPermissions = null;
3408 if (pkg.isVendor()) {
3409 deniedPermissions = SystemConfig.getInstance()
3410 .getVendorPrivAppDenyPermissions(pkg.getPackageName());
3411 } else if (pkg.isProduct()) {
3412 deniedPermissions = SystemConfig.getInstance()
3413 .getProductPrivAppDenyPermissions(pkg.getPackageName());
3414 } else if (pkg.isSystemExt()) {
3415 deniedPermissions = SystemConfig.getInstance()
3416 .getSystemExtPrivAppDenyPermissions(pkg.getPackageName());
3417 } else {
3418 deniedPermissions = SystemConfig.getInstance()
3419 .getPrivAppDenyPermissions(pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003420 }
Philip P. Moltmann67655a12020-03-26 17:22:40 -07003421 final boolean permissionViolation =
3422 deniedPermissions == null || !deniedPermissions.contains(perm);
3423 if (permissionViolation) {
3424 Slog.w(TAG, "Privileged permission " + perm + " for package "
3425 + pkg.getPackageName() + " (" + pkg.getCodePath()
3426 + ") not in privapp-permissions whitelist");
3427
3428 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3429 if (mPrivappPermissionsViolations == null) {
3430 mPrivappPermissionsViolations = new ArraySet<>();
3431 }
3432 mPrivappPermissionsViolations.add(
3433 pkg.getPackageName() + " (" + pkg.getCodePath() + "): "
3434 + perm);
3435 }
3436 } else {
3437 return false;
3438 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003439 }
3440 }
3441 if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
3442 return false;
3443 }
3444 }
3445 }
Chen Xu45c183d2019-10-07 00:24:41 -07003446 // expect single system package
3447 String systemPackageName = ArrayUtils.firstOrNull(mPackageManagerInt.getKnownPackageNames(
3448 PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM));
Winson655a5b92019-10-23 10:49:32 -07003449 final AndroidPackage systemPackage =
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003450 mPackageManagerInt.getPackage(systemPackageName);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003451
3452 // check if the package is allow to use this signature permission. A package is allowed to
3453 // use a signature permission if:
3454 // - it has the same set of signing certificates as the source package
3455 // - or its signing certificate was rotated from the source package's certificate
3456 // - or its signing certificate is a previous signing certificate of the defining
3457 // package, and the defining package still trusts the old certificate for permissions
3458 // - or it shares the above relationships with the system package
Songchun Fane5c0afe2020-04-22 12:22:52 -07003459 final PackageParser.SigningDetails sourceSigningDetails =
3460 getSourcePackageSigningDetails(bp);
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003461 boolean allowed =
Songchun Fane5c0afe2020-04-22 12:22:52 -07003462 pkg.getSigningDetails().hasAncestorOrSelf(sourceSigningDetails)
3463 || sourceSigningDetails.checkCapability(
Winson14ff7172019-10-23 10:42:27 -07003464 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003465 PackageParser.SigningDetails.CertCapabilities.PERMISSION)
Winson14ff7172019-10-23 10:42:27 -07003466 || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
3467 || systemPackage.getSigningDetails().checkCapability(
3468 pkg.getSigningDetails(),
Dan Cashman1dbe6d02018-01-23 11:18:28 -08003469 PackageParser.SigningDetails.CertCapabilities.PERMISSION);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003470 if (!allowed && (privilegedPermission || oemPermission)) {
3471 if (pkg.isSystem()) {
3472 // For updated system applications, a privileged/oem permission
3473 // is granted only if it had been defined by the original application.
Winsone0756292020-01-31 12:21:54 -08003474 if (pkgSetting.getPkgState().isUpdatedSystemApp()) {
3475 final PackageSetting disabledPs = mPackageManagerInt
Winson14ff7172019-10-23 10:42:27 -07003476 .getDisabledSystemPackage(pkg.getPackageName());
3477 final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003478 if (disabledPs != null
3479 && disabledPs.getPermissionsState().hasInstallPermission(perm)) {
3480 // If the original was granted this permission, we take
3481 // that grant decision as read and propagate it to the
3482 // update.
3483 if ((privilegedPermission && disabledPs.isPrivileged())
3484 || (oemPermission && disabledPs.isOem()
3485 && canGrantOemPermission(disabledPs, perm))) {
3486 allowed = true;
3487 }
3488 } else {
3489 // The system apk may have been updated with an older
3490 // version of the one on the data partition, but which
3491 // granted a new system permission that it didn't have
3492 // before. In this case we do want to allow the app to
3493 // now get the new permission if the ancestral apk is
3494 // privileged to get it.
Todd Kennedy1efb8332017-10-25 15:51:36 -07003495 if (disabledPs != null && disabledPkg != null
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003496 && isPackageRequestingPermission(disabledPkg, perm)
3497 && ((privilegedPermission && disabledPs.isPrivileged())
3498 || (oemPermission && disabledPs.isOem()
3499 && canGrantOemPermission(disabledPs, perm)))) {
3500 allowed = true;
3501 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003502 }
3503 } else {
Winson14ff7172019-10-23 10:42:27 -07003504 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3505 pkg.getPackageName());
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003506 allowed = (privilegedPermission && pkg.isPrivileged())
3507 || (oemPermission && pkg.isOem()
3508 && canGrantOemPermission(ps, perm));
3509 }
Jiyong Park002fdbd2017-02-13 20:50:31 +09003510 // In any case, don't grant a privileged permission to privileged vendor apps, if
3511 // the permission's protectionLevel does not have the extra 'vendorPrivileged'
3512 // flag.
3513 if (allowed && privilegedPermission &&
3514 !vendorPrivilegedPermission && pkg.isVendor()) {
3515 Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
Winson14ff7172019-10-23 10:42:27 -07003516 + pkg.getPackageName()
3517 + " because it isn't a 'vendorPrivileged' permission.");
Jiyong Park002fdbd2017-02-13 20:50:31 +09003518 allowed = false;
3519 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003520 }
3521 }
3522 if (!allowed) {
3523 if (!allowed
3524 && bp.isPre23()
Winson14ff7172019-10-23 10:42:27 -07003525 && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003526 // If this was a previously normal/dangerous permission that got moved
3527 // to a system permission as part of the runtime permission redesign, then
3528 // we still want to blindly grant it to old apps.
3529 allowed = true;
3530 }
Philip P. Moltmann8943ad62018-07-25 12:12:30 -07003531 // TODO (moltmann): The installer now shares the platforms signature. Hence it does not
3532 // need a separate flag anymore. Hence we need to check which
3533 // permissions are needed by the permission controller
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003534 if (!allowed && bp.isInstaller()
Chen Xu45c183d2019-10-07 00:24:41 -07003535 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3536 PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003537 pkg.getPackageName()) || ArrayUtils.contains(
3538 mPackageManagerInt.getKnownPackageNames(
3539 PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
3540 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003541 // If this permission is to be granted to the system installer and
3542 // this app is an installer, then it gets the permission.
3543 allowed = true;
3544 }
3545 if (!allowed && bp.isVerifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003546 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3547 PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003548 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003549 // If this permission is to be granted to the system verifier and
3550 // this app is a verifier, then it gets the permission.
3551 allowed = true;
3552 }
3553 if (!allowed && bp.isPreInstalled()
3554 && pkg.isSystem()) {
3555 // Any pre-installed system app is allowed to get this permission.
3556 allowed = true;
3557 }
3558 if (!allowed && bp.isDevelopment()) {
3559 // For development permissions, a development permission
3560 // is granted only if it was already granted.
3561 allowed = origPermissions.hasInstallPermission(perm);
3562 }
3563 if (!allowed && bp.isSetup()
Chen Xu45c183d2019-10-07 00:24:41 -07003564 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3565 PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003566 pkg.getPackageName())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003567 // If this permission is to be granted to the system setup wizard and
3568 // this app is a setup wizard, then it gets the permission.
3569 allowed = true;
3570 }
Makoto Onuki700feef2018-02-15 10:59:41 -08003571 if (!allowed && bp.isSystemTextClassifier()
Chen Xu45c183d2019-10-07 00:24:41 -07003572 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Makoto Onuki700feef2018-02-15 10:59:41 -08003573 PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
Winson655a5b92019-10-23 10:49:32 -07003574 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Makoto Onuki700feef2018-02-15 10:59:41 -08003575 // Special permissions for the system default text classifier.
3576 allowed = true;
3577 }
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003578 if (!allowed && bp.isConfigurator()
Chen Xu45c183d2019-10-07 00:24:41 -07003579 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3580 PackageManagerInternal.PACKAGE_CONFIGURATOR,
Winson655a5b92019-10-23 10:49:32 -07003581 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Stanislav Zholnin596437f2018-12-28 15:34:23 +00003582 // Special permissions for the device configurator.
3583 allowed = true;
3584 }
Varun Shah5f303652018-11-16 18:11:19 -08003585 if (!allowed && bp.isWellbeing()
Chen Xu45c183d2019-10-07 00:24:41 -07003586 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3587 PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003588 pkg.getPackageName())) {
Varun Shah5f303652018-11-16 18:11:19 -08003589 // Special permission granted only to the OEM specified wellbeing app
3590 allowed = true;
3591 }
Jeff Sharkey15707b32018-12-10 12:08:41 -07003592 if (!allowed && bp.isDocumenter()
Chen Xu45c183d2019-10-07 00:24:41 -07003593 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3594 PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003595 pkg.getPackageName())) {
Jeff Sharkey15707b32018-12-10 12:08:41 -07003596 // If this permission is to be granted to the documenter and
3597 // this app is the documenter, then it gets the permission.
3598 allowed = true;
3599 }
Joe Onorato5a15b552018-12-18 10:40:04 -08003600 if (!allowed && bp.isIncidentReportApprover()
Chen Xu45c183d2019-10-07 00:24:41 -07003601 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
Joe Onorato5a15b552018-12-18 10:40:04 -08003602 PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
Winson655a5b92019-10-23 10:49:32 -07003603 UserHandle.USER_SYSTEM), pkg.getPackageName())) {
Joe Onorato5a15b552018-12-18 10:40:04 -08003604 // If this permission is to be granted to the incident report approver and
3605 // this app is the incident report approver, then it gets the permission.
3606 allowed = true;
3607 }
George Hodulikcd7695d2019-01-29 18:17:05 -08003608 if (!allowed && bp.isAppPredictor()
Chen Xu45c183d2019-10-07 00:24:41 -07003609 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3610 PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM),
Winson655a5b92019-10-23 10:49:32 -07003611 pkg.getPackageName())) {
George Hodulikcd7695d2019-01-29 18:17:05 -08003612 // Special permissions for the system app predictor.
3613 allowed = true;
3614 }
Eugene Susla1fa23ed02019-07-24 16:30:16 -07003615 if (!allowed && bp.isCompanion()
3616 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3617 PackageManagerInternal.PACKAGE_COMPANION, UserHandle.USER_SYSTEM),
3618 pkg.getPackageName())) {
3619 // Special permissions for the system companion device manager.
3620 allowed = true;
3621 }
wayneyang8126b1f2020-01-09 14:10:31 +08003622 if (!allowed && bp.isRetailDemo()
3623 && ArrayUtils.contains(mPackageManagerInt.getKnownPackageNames(
3624 PackageManagerInternal.PACKAGE_RETAIL_DEMO, UserHandle.USER_SYSTEM),
3625 pkg.getPackageName()) && isProfileOwner(pkg.getUid())) {
3626 // Special permission granted only to the OEM specified retail demo app
3627 allowed = true;
3628 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003629 }
3630 return allowed;
3631 }
3632
Songchun Fane5c0afe2020-04-22 12:22:52 -07003633 @NonNull
3634 private PackageParser.SigningDetails getSourcePackageSigningDetails(
3635 @NonNull BasePermission bp) {
3636 final PackageSetting ps = getSourcePackageSetting(bp);
3637 if (ps == null) {
3638 return PackageParser.SigningDetails.UNKNOWN;
3639 }
3640 return ps.getSigningDetails();
3641 }
3642
3643 @Nullable
3644 private PackageSetting getSourcePackageSetting(@NonNull BasePermission bp) {
3645 final String sourcePackageName = bp.getSourcePackageName();
3646 return mPackageManagerInt.getPackageSetting(sourcePackageName);
3647 }
3648
wayneyang8126b1f2020-01-09 14:10:31 +08003649 private static boolean isProfileOwner(int uid) {
3650 DevicePolicyManagerInternal dpmInternal =
3651 LocalServices.getService(DevicePolicyManagerInternal.class);
3652 if (dpmInternal != null) {
3653 return dpmInternal
3654 .isActiveAdminWithPolicy(uid, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3655 }
3656 return false;
3657 }
3658
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003659 private static boolean canGrantOemPermission(PackageSetting ps, String permission) {
3660 if (!ps.isOem()) {
3661 return false;
3662 }
3663 // all oem permissions must explicitly be granted or denied
3664 final Boolean granted =
3665 SystemConfig.getInstance().getOemPermissions(ps.name).get(permission);
3666 if (granted == null) {
3667 throw new IllegalStateException("OEM permission" + permission + " requested by package "
3668 + ps.name + " must be explicitly declared granted or not");
3669 }
3670 return Boolean.TRUE == granted;
3671 }
3672
Winson14ff7172019-10-23 10:42:27 -07003673 private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
Philip P. Moltmannc91ff6f2019-06-14 14:35:42 -07003674 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003675 // Permission review applies only to apps not supporting the new permission model.
Winson14ff7172019-10-23 10:42:27 -07003676 if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003677 return false;
3678 }
3679
3680 // Legacy apps have the permission and get user consent on launch.
Winson14ff7172019-10-23 10:42:27 -07003681 final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3682 pkg.getPackageName());
3683 if (ps == null) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003684 return false;
3685 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003686 final PermissionsState permissionsState = ps.getPermissionsState();
3687 return permissionsState.isPermissionReviewRequired(userId);
3688 }
3689
Winson14ff7172019-10-23 10:42:27 -07003690 private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) {
3691 final int permCount = pkg.getRequestedPermissions().size();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003692 for (int j = 0; j < permCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003693 String requestedPermission = pkg.getRequestedPermissions().get(j);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003694 if (permission.equals(requestedPermission)) {
3695 return true;
3696 }
3697 }
3698 return false;
3699 }
3700
Winson14ff7172019-10-23 10:42:27 -07003701 private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003702 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
3703 for (int userId : userIds) {
3704 grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
3705 callback);
3706 }
3707 }
3708
Winson14ff7172019-10-23 10:42:27 -07003709 private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
Todd Kennedy0eb97382017-10-03 16:57:22 -07003710 String[] grantedPermissions, int callingUid, PermissionCallback callback) {
Winson14ff7172019-10-23 10:42:27 -07003711 PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
3712 pkg.getPackageName());
Todd Kennedy0eb97382017-10-03 16:57:22 -07003713 if (ps == null) {
3714 return;
3715 }
3716
3717 PermissionsState permissionsState = ps.getPermissionsState();
3718
3719 final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
3720 | PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3721
Hai Zhangfa291702019-09-19 16:35:44 -07003722 final int compatFlags = PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
3723 | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
3724
Winson14ff7172019-10-23 10:42:27 -07003725 final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
Todd Kennedy0eb97382017-10-03 16:57:22 -07003726 >= Build.VERSION_CODES.M;
3727
Winson14ff7172019-10-23 10:42:27 -07003728 final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003729
Winson14ff7172019-10-23 10:42:27 -07003730 for (String permission : pkg.getRequestedPermissions()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003731 final BasePermission bp;
3732 synchronized (mLock) {
3733 bp = mSettings.getPermissionLocked(permission);
3734 }
3735 if (bp != null && (bp.isRuntime() || bp.isDevelopment())
3736 && (!instantApp || bp.isInstant())
3737 && (supportsRuntimePermissions || !bp.isRuntimeOnly())
3738 && (grantedPermissions == null
3739 || ArrayUtils.contains(grantedPermissions, permission))) {
3740 final int flags = permissionsState.getPermissionFlags(permission, userId);
3741 if (supportsRuntimePermissions) {
3742 // Installer cannot change immutable permissions.
3743 if ((flags & immutableFlags) == 0) {
Winson14ff7172019-10-23 10:42:27 -07003744 grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
Todd Kennedyc971a452019-07-08 16:04:52 -07003745 callingUid, userId, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003746 }
Philip P. Moltmann6c644e62018-07-18 15:41:24 -07003747 } else {
Hai Zhangfa291702019-09-19 16:35:44 -07003748 // In permission review mode we clear the review flag and the revoked compat
3749 // flag when we are asked to install the app with all permissions granted.
3750 if ((flags & compatFlags) != 0) {
Winson14ff7172019-10-23 10:42:27 -07003751 updatePermissionFlagsInternal(permission, pkg.getPackageName(), compatFlags,
Hai Zhangfa291702019-09-19 16:35:44 -07003752 0, callingUid, userId, false, callback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003753 }
3754 }
3755 }
3756 }
3757 }
3758
Winson14ff7172019-10-23 10:42:27 -07003759 private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003760 @UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
3761 @PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003762 final PermissionsState permissionsState =
Winson14ff7172019-10-23 10:42:27 -07003763 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003764 if (permissionsState == null) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003765 return;
3766 }
3767
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003768 ArraySet<String> oldGrantedRestrictedPermissions = null;
3769 boolean updatePermissions = false;
3770
Winson14ff7172019-10-23 10:42:27 -07003771 final int permissionCount = pkg.getRequestedPermissions().size();
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003772 for (int i = 0; i < permissionCount; i++) {
Winson14ff7172019-10-23 10:42:27 -07003773 final String permissionName = pkg.getRequestedPermissions().get(i);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003774
3775 final BasePermission bp = mSettings.getPermissionLocked(permissionName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003776
Evan Seversoncdcaaaa2019-07-02 10:29:25 -07003777 if (bp == null || !bp.isHardOrSoftRestricted()) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003778 continue;
3779 }
3780
3781 if (permissionsState.hasPermission(permissionName, userId)) {
3782 if (oldGrantedRestrictedPermissions == null) {
3783 oldGrantedRestrictedPermissions = new ArraySet<>();
3784 }
3785 oldGrantedRestrictedPermissions.add(permissionName);
3786 }
3787
3788 final int oldFlags = permissionsState.getPermissionFlags(permissionName, userId);
3789
3790 int newFlags = oldFlags;
3791 int mask = 0;
3792 int whitelistFlagsCopy = whitelistFlags;
3793 while (whitelistFlagsCopy != 0) {
3794 final int flag = 1 << Integer.numberOfTrailingZeros(whitelistFlagsCopy);
3795 whitelistFlagsCopy &= ~flag;
3796 switch (flag) {
3797 case FLAG_PERMISSION_WHITELIST_SYSTEM: {
3798 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3799 if (permissions != null && permissions.contains(permissionName)) {
3800 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3801 } else {
3802 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT;
3803 }
3804 } break;
3805 case FLAG_PERMISSION_WHITELIST_UPGRADE: {
3806 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3807 if (permissions != null && permissions.contains(permissionName)) {
3808 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3809 } else {
3810 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
3811 }
3812 } break;
3813 case FLAG_PERMISSION_WHITELIST_INSTALLER: {
3814 mask |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3815 if (permissions != null && permissions.contains(permissionName)) {
3816 newFlags |= PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3817 } else {
3818 newFlags &= ~PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT;
3819 }
3820 } break;
3821 }
3822 }
3823
3824 if (oldFlags == newFlags) {
3825 continue;
3826 }
3827
3828 updatePermissions = true;
3829
Svet Ganovd563e932019-04-14 13:07:41 -07003830 final boolean wasWhitelisted = (oldFlags
3831 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3832 final boolean isWhitelisted = (newFlags
3833 & (PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT)) != 0;
3834
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003835 // If the permission is policy fixed as granted but it is no longer
3836 // on any of the whitelists we need to clear the policy fixed flag
3837 // as whitelisting trumps policy i.e. policy cannot grant a non
3838 // grantable permission.
3839 if ((oldFlags & PackageManager.FLAG_PERMISSION_POLICY_FIXED) != 0) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003840 final boolean isGranted = permissionsState.hasPermission(permissionName, userId);
3841 if (!isWhitelisted && isGranted) {
3842 mask |= PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3843 newFlags &= ~PackageManager.FLAG_PERMISSION_POLICY_FIXED;
3844 }
3845 }
3846
Svet Ganovd563e932019-04-14 13:07:41 -07003847 // If we are whitelisting an app that does not support runtime permissions
3848 // we need to make sure it goes through the permission review UI at launch.
Winson14ff7172019-10-23 10:42:27 -07003849 if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
Svet Ganovd563e932019-04-14 13:07:41 -07003850 && !wasWhitelisted && isWhitelisted) {
3851 mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3852 newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
3853 }
3854
Winson14ff7172019-10-23 10:42:27 -07003855 updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003856 callingUid, userId, false, null /*callback*/);
3857 }
3858
3859 if (updatePermissions) {
Philip P. Moltmannba742062019-04-08 13:22:44 -07003860 // Update permission of this app to take into account the new whitelist state.
Winson14ff7172019-10-23 10:42:27 -07003861 restorePermissionState(pkg, false, pkg.getPackageName(), callback);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003862
3863 // If this resulted in losing a permission we need to kill the app.
3864 if (oldGrantedRestrictedPermissions != null) {
3865 final int oldGrantedCount = oldGrantedRestrictedPermissions.size();
3866 for (int i = 0; i < oldGrantedCount; i++) {
3867 final String permission = oldGrantedRestrictedPermissions.valueAt(i);
3868 // Sometimes we create a new permission state instance during update.
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003869 final PermissionsState newPermissionsState =
Winson14ff7172019-10-23 10:42:27 -07003870 PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07003871 if (!newPermissionsState.hasPermission(permission, userId)) {
Winson14ff7172019-10-23 10:42:27 -07003872 callback.onPermissionRevoked(pkg.getUid(), userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07003873 break;
3874 }
3875 }
3876 }
3877 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07003878 }
3879
Andreas Gampea36dc622018-02-05 17:19:22 -08003880 @GuardedBy("mLock")
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003881 private int[] revokeUnusedSharedUserPermissionsLocked(
3882 SharedUserSetting suSetting, int[] allUserIds) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07003883 // Collect all used permissions in the UID
3884 final ArraySet<String> usedPermissions = new ArraySet<>();
Winson14ff7172019-10-23 10:42:27 -07003885 final List<AndroidPackage> pkgList = suSetting.getPackages();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003886 if (pkgList == null || pkgList.size() == 0) {
3887 return EmptyArray.INT;
3888 }
Winson14ff7172019-10-23 10:42:27 -07003889 for (AndroidPackage pkg : pkgList) {
Winsone23ae202020-01-24 11:56:44 -08003890 if (pkg.getRequestedPermissions().isEmpty()) {
Svet Ganovd8308072018-03-24 00:04:38 -07003891 continue;
3892 }
Winson14ff7172019-10-23 10:42:27 -07003893 final int requestedPermCount = pkg.getRequestedPermissions().size();
Todd Kennedy0eb97382017-10-03 16:57:22 -07003894 for (int j = 0; j < requestedPermCount; j++) {
Winson14ff7172019-10-23 10:42:27 -07003895 String permission = pkg.getRequestedPermissions().get(j);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003896 BasePermission bp = mSettings.getPermissionLocked(permission);
3897 if (bp != null) {
3898 usedPermissions.add(permission);
3899 }
3900 }
3901 }
3902
3903 PermissionsState permissionsState = suSetting.getPermissionsState();
3904 // Prune install permissions
3905 List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
3906 final int installPermCount = installPermStates.size();
3907 for (int i = installPermCount - 1; i >= 0; i--) {
3908 PermissionState permissionState = installPermStates.get(i);
3909 if (!usedPermissions.contains(permissionState.getName())) {
3910 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3911 if (bp != null) {
3912 permissionsState.revokeInstallPermission(bp);
3913 permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003914 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003915 }
3916 }
3917 }
3918
3919 int[] runtimePermissionChangedUserIds = EmptyArray.INT;
3920
3921 // Prune runtime permissions
3922 for (int userId : allUserIds) {
3923 List<PermissionState> runtimePermStates = permissionsState
3924 .getRuntimePermissionStates(userId);
3925 final int runtimePermCount = runtimePermStates.size();
3926 for (int i = runtimePermCount - 1; i >= 0; i--) {
3927 PermissionState permissionState = runtimePermStates.get(i);
3928 if (!usedPermissions.contains(permissionState.getName())) {
3929 BasePermission bp = mSettings.getPermissionLocked(permissionState.getName());
3930 if (bp != null) {
3931 permissionsState.revokeRuntimePermission(bp, userId);
3932 permissionsState.updatePermissionFlags(bp, userId,
Philip P. Moltmann76597692019-03-02 13:18:41 -08003933 MASK_PERMISSION_FLAGS_ALL, 0);
Todd Kennedy0eb97382017-10-03 16:57:22 -07003934 runtimePermissionChangedUserIds = ArrayUtils.appendInt(
3935 runtimePermissionChangedUserIds, userId);
3936 }
3937 }
3938 }
3939 }
3940
3941 return runtimePermissionChangedUserIds;
3942 }
3943
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003944 /**
3945 * Update permissions when a package changed.
3946 *
3947 * <p><ol>
3948 * <li>Reconsider the ownership of permission</li>
3949 * <li>Update the state (grant, flags) of the permissions</li>
3950 * </ol>
3951 *
3952 * @param packageName The package that is updated
3953 * @param pkg The package that is updated, or {@code null} if package is deleted
3954 * @param allPackages All currently known packages
3955 * @param callback Callback to call after permission changes
3956 */
Winson14ff7172019-10-23 10:42:27 -07003957 private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003958 @NonNull PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07003959 // If the package is being deleted, update the permissions of all the apps
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003960 final int flags =
Songchun Fanbcc899e2020-04-06 16:51:45 -07003961 (pkg == null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG
3962 : UPDATE_PERMISSIONS_REPLACE_PKG);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003963 updatePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07003964 packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003965 }
3966
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003967 /**
3968 * Update all permissions for all apps.
3969 *
3970 * <p><ol>
3971 * <li>Reconsider the ownership of permission</li>
3972 * <li>Update the state (grant, flags) of the permissions</li>
3973 * </ol>
3974 *
3975 * @param volumeUuid The volume of the packages to be updated, {@code null} for all volumes
3976 * @param allPackages All currently known packages
3977 * @param callback Callback to call after permission changes
3978 */
3979 private void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003980 @NonNull PermissionCallback callback) {
Daniel Colascione33fb4ef2020-03-04 17:27:56 -08003981 PackageManager.corkPackageInfoCache(); // Prevent invalidation storm
3982 try {
3983 final int flags = UPDATE_PERMISSIONS_ALL |
3984 (sdkUpdated
3985 ? UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL
3986 : 0);
3987 updatePermissions(null, null, volumeUuid, flags, callback);
3988 } finally {
3989 PackageManager.uncorkPackageInfoCache();
3990 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07003991 }
3992
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07003993 /**
3994 * Cache background->foreground permission mapping.
3995 *
3996 * <p>This is only run once.
3997 */
3998 private void cacheBackgroundToForegoundPermissionMapping() {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07003999 synchronized (mLock) {
4000 if (mBackgroundPermissions == null) {
4001 // Cache background -> foreground permission mapping.
4002 // Only system declares background permissions, hence mapping does never change.
4003 mBackgroundPermissions = new ArrayMap<>();
4004 for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
Winsonf00c7552020-01-28 12:52:01 -08004005 if (bp.perm != null && bp.perm.getBackgroundPermission() != null) {
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004006 String fgPerm = bp.name;
Winsonf00c7552020-01-28 12:52:01 -08004007 String bgPerm = bp.perm.getBackgroundPermission();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004008
4009 List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
4010 if (fgPerms == null) {
4011 fgPerms = new ArrayList<>();
4012 mBackgroundPermissions.put(bgPerm, fgPerms);
4013 }
4014
4015 fgPerms.add(fgPerm);
4016 }
4017 }
4018 }
4019 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004020 }
4021
4022 /**
4023 * Update all packages on the volume, <u>beside</u> the changing package. If the changing
4024 * package is set too, all packages are updated.
4025 */
4026 private static final int UPDATE_PERMISSIONS_ALL = 1 << 0;
4027 /** The changing package is replaced. Requires the changing package to be set */
4028 private static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1 << 1;
4029 /**
4030 * Schedule all packages <u>beside</u> the changing package for replacement. Requires
4031 * UPDATE_PERMISSIONS_ALL to be set
4032 */
4033 private static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1 << 2;
4034
4035 @IntDef(flag = true, prefix = { "UPDATE_PERMISSIONS_" }, value = {
4036 UPDATE_PERMISSIONS_ALL, UPDATE_PERMISSIONS_REPLACE_PKG,
4037 UPDATE_PERMISSIONS_REPLACE_ALL })
4038 @Retention(RetentionPolicy.SOURCE)
4039 private @interface UpdatePermissionFlags {}
4040
4041 /**
4042 * Update permissions when packages changed.
4043 *
4044 * <p><ol>
4045 * <li>Reconsider the ownership of permission</li>
4046 * <li>Update the state (grant, flags) of the permissions</li>
4047 * </ol>
4048 *
4049 * <p>Meaning of combination of package parameters:
4050 * <table>
4051 * <tr><th></th><th>changingPkgName != null</th><th>changingPkgName == null</th></tr>
4052 * <tr><th>changingPkg != null</th><td>package is updated</td><td>invalid</td></tr>
4053 * <tr><th>changingPkg == null</th><td>package is deleted</td><td>all packages are
4054 * updated</td></tr>
4055 * </table>
4056 *
4057 * @param changingPkgName The package that is updated, or {@code null} if all packages should be
4058 * updated
4059 * @param changingPkg The package that is updated, or {@code null} if all packages should be
4060 * updated or package is deleted
4061 * @param replaceVolumeUuid The volume of the packages to be updated are on, {@code null} for
4062 * all volumes
4063 * @param flags Control permission for which apps should be updated
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004064 * @param callback Callback to call after permission changes
4065 */
Todd Kennedyc971a452019-07-08 16:04:52 -07004066 private void updatePermissions(final @Nullable String changingPkgName,
Winson14ff7172019-10-23 10:42:27 -07004067 final @Nullable AndroidPackage changingPkg,
Todd Kennedyc971a452019-07-08 16:04:52 -07004068 final @Nullable String replaceVolumeUuid,
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004069 @UpdatePermissionFlags int flags,
Todd Kennedyc971a452019-07-08 16:04:52 -07004070 final @Nullable PermissionCallback callback) {
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004071 // TODO: Most of the methods exposing BasePermission internals [source package name,
4072 // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
4073 // have package settings, we should make note of it elsewhere [map between
4074 // source package name and BasePermission] and cycle through that here. Then we
4075 // define a single method on BasePermission that takes a PackageSetting, changing
4076 // package name and a package.
4077 // NOTE: With this approach, we also don't need to tree trees differently than
4078 // normal permissions. Today, we need two separate loops because these BasePermission
4079 // objects are stored separately.
4080 // Make sure there are no dangling permission trees.
4081 boolean permissionTreesSourcePackageChanged = updatePermissionTreeSourcePackage(
4082 changingPkgName, changingPkg);
4083 // Make sure all dynamic permissions have been assigned to a package,
4084 // and make sure there are no dangling permissions.
4085 boolean permissionSourcePackageChanged = updatePermissionSourcePackage(changingPkgName,
Hongming Jinbc4d0102019-08-16 14:28:30 -07004086 changingPkg, callback);
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004087
4088 if (permissionTreesSourcePackageChanged | permissionSourcePackageChanged) {
4089 // Permission ownership has changed. This e.g. changes which packages can get signature
4090 // permissions
Songchun Fanbcc899e2020-04-06 16:51:45 -07004091 Slog.i(TAG, "Permission ownership changed. Updating all permissions.");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004092 flags |= UPDATE_PERMISSIONS_ALL;
4093 }
4094
4095 cacheBackgroundToForegoundPermissionMapping();
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004096
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07004097 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "restorePermissionState");
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004098 // Now update the permissions for all packages.
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004099 if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004100 final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
Winson14ff7172019-10-23 10:42:27 -07004101 mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
Todd Kennedyc971a452019-07-08 16:04:52 -07004102 if (pkg == changingPkg) {
4103 return;
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004104 }
Todd Kennedyc971a452019-07-08 16:04:52 -07004105 // Only replace for packages on requested volume
4106 final String volumeUuid = getVolumeUuidForPackage(pkg);
4107 final boolean replace = replaceAll && Objects.equals(replaceVolumeUuid, volumeUuid);
4108 restorePermissionState(pkg, replace, changingPkgName, callback);
4109 });
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004110 }
4111
4112 if (changingPkg != null) {
4113 // Only replace for packages on requested volume
4114 final String volumeUuid = getVolumeUuidForPackage(changingPkg);
4115 final boolean replace = ((flags & UPDATE_PERMISSIONS_REPLACE_PKG) != 0)
4116 && Objects.equals(replaceVolumeUuid, volumeUuid);
Philip P. Moltmanne0f00ea2018-10-30 10:43:15 -07004117 restorePermissionState(changingPkg, replace, changingPkgName, callback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004118 }
4119 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
4120 }
4121
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004122 /**
4123 * Update which app declares a permission.
4124 *
4125 * <p>Possible parameter combinations
4126 * <table>
4127 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4128 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4129 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4130 * </table>
4131 *
4132 * @param packageName The package that is updated, or {@code null} if all packages should be
4133 * updated
4134 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4135 * package is deleted
4136 *
4137 * @return {@code true} if a permission source package might have changed
4138 */
4139 private boolean updatePermissionSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07004140 @Nullable AndroidPackage pkg,
Hongming Jinbc4d0102019-08-16 14:28:30 -07004141 final @Nullable PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004142 // Always need update if packageName is null
4143 if (packageName == null) {
4144 return true;
4145 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004146
Songchun Fanbcc899e2020-04-06 16:51:45 -07004147 boolean changed = false;
Todd Kennedyc8423932017-10-05 08:58:36 -07004148 Set<BasePermission> needsUpdate = null;
4149 synchronized (mLock) {
4150 final Iterator<BasePermission> it = mSettings.mPermissions.values().iterator();
4151 while (it.hasNext()) {
4152 final BasePermission bp = it.next();
4153 if (bp.isDynamic()) {
4154 bp.updateDynamicPermission(mSettings.mPermissionTrees.values());
4155 }
Songchun Fane5c0afe2020-04-22 12:22:52 -07004156 if (!packageName.equals(bp.getSourcePackageName())) {
4157 // Not checking sourcePackageSetting because it can be null when
4158 // the permission source package is the target package and the target package is
4159 // being uninstalled,
Todd Kennedyc8423932017-10-05 08:58:36 -07004160 continue;
4161 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004162 // The target package is the source of the current permission
4163 // Set to changed for either install or uninstall
4164 changed = true;
4165 // If the target package is being uninstalled, we need to revoke this permission
4166 // From all other packages
4167 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4168 Slog.i(TAG, "Removing permission " + bp.getName()
4169 + " that used to be declared by " + bp.getSourcePackageName());
4170 if (bp.isRuntime()) {
4171 final int[] userIds = mUserManagerInt.getUserIds();
4172 final int numUserIds = userIds.length;
4173 for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
4174 final int userId = userIds[userIdNum];
4175 mPackageManagerInt.forEachPackage((AndroidPackage p) ->
4176 revokePermissionFromPackageForUser(p.getPackageName(),
Evan Severson24f9d5a2020-04-28 18:45:22 -07004177 bp.getName(), true, userId, callback));
Songchun Fanbcc899e2020-04-06 16:51:45 -07004178 }
4179 }
4180 it.remove();
4181 }
Todd Kennedyc8423932017-10-05 08:58:36 -07004182 if (needsUpdate == null) {
4183 needsUpdate = new ArraySet<>(mSettings.mPermissions.size());
4184 }
4185 needsUpdate.add(bp);
4186 }
4187 }
4188 if (needsUpdate != null) {
4189 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07004190 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07004191 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07004192 final PackageSetting sourcePs =
4193 (PackageSetting) mPackageManagerInt.getPackageSetting(
4194 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07004195 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07004196 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004197 continue;
4198 }
4199 Slog.w(TAG, "Removing dangling permission: " + bp.getName()
4200 + " from package " + bp.getSourcePackageName());
4201 mSettings.removePermissionLocked(bp.getName());
4202 }
4203 }
4204 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004205 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07004206 }
4207
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004208 /**
Songchun Fanbcc899e2020-04-06 16:51:45 -07004209 * Revoke a runtime permission from a package for a given user ID.
4210 */
4211 private void revokePermissionFromPackageForUser(@NonNull String pName,
Evan Severson24f9d5a2020-04-28 18:45:22 -07004212 @NonNull String permissionName, boolean overridePolicy, int userId,
4213 @Nullable PermissionCallback callback) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004214 final ApplicationInfo appInfo =
4215 mPackageManagerInt.getApplicationInfo(pName, 0,
4216 Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
4217 if (appInfo != null
4218 && appInfo.targetSdkVersion < Build.VERSION_CODES.M) {
4219 return;
4220 }
4221
4222 if (checkPermissionImpl(permissionName, pName, userId)
4223 == PackageManager.PERMISSION_GRANTED) {
4224 try {
4225 revokeRuntimePermissionInternal(
4226 permissionName,
4227 pName,
Evan Severson24f9d5a2020-04-28 18:45:22 -07004228 overridePolicy,
Songchun Fanbcc899e2020-04-06 16:51:45 -07004229 Process.SYSTEM_UID,
4230 userId,
4231 callback);
4232 } catch (IllegalArgumentException e) {
4233 Slog.e(TAG,
4234 "Failed to revoke "
4235 + permissionName
4236 + " from "
4237 + pName,
4238 e);
4239 }
4240 }
4241 }
4242 /**
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004243 * Update which app owns a permission trees.
4244 *
4245 * <p>Possible parameter combinations
4246 * <table>
4247 * <tr><th></th><th>packageName != null</th><th>packageName == null</th></tr>
4248 * <tr><th>pkg != null</th><td>package is updated</td><td>invalid</td></tr>
4249 * <tr><th>pkg == null</th><td>package is deleted</td><td>all packages are updated</td></tr>
4250 * </table>
4251 *
4252 * @param packageName The package that is updated, or {@code null} if all packages should be
4253 * updated
4254 * @param pkg The package that is updated, or {@code null} if all packages should be updated or
4255 * package is deleted
4256 *
4257 * @return {@code true} if a permission tree ownership might have changed
4258 */
4259 private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
Winson14ff7172019-10-23 10:42:27 -07004260 @Nullable AndroidPackage pkg) {
Songchun Fanbcc899e2020-04-06 16:51:45 -07004261 // Always need update if packageName is null
4262 if (packageName == null) {
4263 return true;
4264 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004265 boolean changed = false;
4266
Todd Kennedyc8423932017-10-05 08:58:36 -07004267 Set<BasePermission> needsUpdate = null;
4268 synchronized (mLock) {
4269 final Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
4270 while (it.hasNext()) {
4271 final BasePermission bp = it.next();
Songchun Fane5c0afe2020-04-22 12:22:52 -07004272 if (!packageName.equals(bp.getSourcePackageName())) {
4273 // Not checking sourcePackageSetting because it can be null when
4274 // the permission source package is the target package and the target package is
4275 // being uninstalled,
Todd Kennedyc8423932017-10-05 08:58:36 -07004276 continue;
4277 }
Songchun Fanbcc899e2020-04-06 16:51:45 -07004278 // The target package is the source of the current permission tree
4279 // Set to changed for either install or uninstall
4280 changed = true;
4281 if (pkg == null || !hasPermission(pkg, bp.getName())) {
4282 Slog.i(TAG, "Removing permission tree " + bp.getName()
4283 + " that used to be declared by " + bp.getSourcePackageName());
4284 it.remove();
4285 }
Todd Kennedyc8423932017-10-05 08:58:36 -07004286 if (needsUpdate == null) {
4287 needsUpdate = new ArraySet<>(mSettings.mPermissionTrees.size());
4288 }
4289 needsUpdate.add(bp);
4290 }
4291 }
4292 if (needsUpdate != null) {
4293 for (final BasePermission bp : needsUpdate) {
Winson14ff7172019-10-23 10:42:27 -07004294 final AndroidPackage sourcePkg =
Todd Kennedyc8423932017-10-05 08:58:36 -07004295 mPackageManagerInt.getPackage(bp.getSourcePackageName());
Winson14ff7172019-10-23 10:42:27 -07004296 final PackageSetting sourcePs =
4297 (PackageSetting) mPackageManagerInt.getPackageSetting(
4298 bp.getSourcePackageName());
Todd Kennedyc8423932017-10-05 08:58:36 -07004299 synchronized (mLock) {
Winson14ff7172019-10-23 10:42:27 -07004300 if (sourcePkg != null && sourcePs != null) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004301 continue;
4302 }
4303 Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
4304 + " from package " + bp.getSourcePackageName());
4305 mSettings.removePermissionLocked(bp.getName());
4306 }
4307 }
4308 }
Philip P. Moltmanndc65aa32019-03-28 12:02:45 -07004309 return changed;
Todd Kennedyc8423932017-10-05 08:58:36 -07004310 }
4311
Todd Kennedy0eb97382017-10-03 16:57:22 -07004312 private void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4313 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4314 != PackageManager.PERMISSION_GRANTED
4315 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4316 != PackageManager.PERMISSION_GRANTED) {
4317 throw new SecurityException(message + " requires "
4318 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4319 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS);
4320 }
4321 }
4322
Philip P. Moltmannfc202f72019-03-05 20:17:00 -08004323 private void enforceGrantRevokeGetRuntimePermissionPermissions(@NonNull String message) {
4324 if (mContext.checkCallingOrSelfPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS)
4325 != PackageManager.PERMISSION_GRANTED
4326 && mContext.checkCallingOrSelfPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS)
4327 != PackageManager.PERMISSION_GRANTED
4328 && mContext.checkCallingOrSelfPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS)
4329 != PackageManager.PERMISSION_GRANTED) {
4330 throw new SecurityException(message + " requires "
4331 + Manifest.permission.GRANT_RUNTIME_PERMISSIONS + " or "
4332 + Manifest.permission.REVOKE_RUNTIME_PERMISSIONS + " or "
4333 + Manifest.permission.GET_RUNTIME_PERMISSIONS);
4334 }
4335 }
4336
Todd Kennedy0eb97382017-10-03 16:57:22 -07004337 /**
4338 * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS
4339 * or INTERACT_ACROSS_USERS_FULL permissions, if the userid is not for the caller.
4340 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4341 * @param message the message to log on security exception
4342 */
4343 private void enforceCrossUserPermission(int callingUid, int userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004344 boolean requireFullPermission, boolean checkShell,
4345 boolean requirePermissionWhenSameUser, String message) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004346 if (userId < 0) {
4347 throw new IllegalArgumentException("Invalid userId " + userId);
4348 }
4349 if (checkShell) {
Patrick Baumann2f2fd712019-07-31 15:18:53 -07004350 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
Todd Kennedy0eb97382017-10-03 16:57:22 -07004351 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4352 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004353 final int callingUserId = UserHandle.getUserId(callingUid);
4354 if (hasCrossUserPermission(
4355 callingUid, callingUserId, userId, requireFullPermission,
4356 requirePermissionWhenSameUser)) {
4357 return;
Todd Kennedy0eb97382017-10-03 16:57:22 -07004358 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004359 String errorMessage = buildInvalidCrossUserPermissionMessage(
4360 message, requireFullPermission);
4361 Slog.w(TAG, errorMessage);
4362 throw new SecurityException(errorMessage);
4363 }
4364
4365 /**
4366 * Checks if the request is from the system or an app that has the appropriate cross-user
4367 * permissions defined as follows:
4368 * <ul>
4369 * <li>INTERACT_ACROSS_USERS_FULL if {@code requireFullPermission} is true.</li>
4370 * <li>INTERACT_ACROSS_USERS if the given {@userId} is in a different profile group
4371 * to the caller.</li>
4372 * <li>Otherwise, INTERACT_ACROSS_PROFILES if the given {@userId} is in the same profile group
4373 * as the caller.</li>
4374 * </ul>
4375 *
4376 * @param checkShell whether to prevent shell from access if there's a debugging restriction
4377 * @param message the message to log on security exception
4378 */
4379 private void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4380 boolean requireFullPermission, boolean checkShell,
4381 String message) {
4382 if (userId < 0) {
4383 throw new IllegalArgumentException("Invalid userId " + userId);
4384 }
4385 if (checkShell) {
4386 PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt,
4387 UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId);
4388 }
4389 final int callingUserId = UserHandle.getUserId(callingUid);
4390 if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission,
4391 /*requirePermissionWhenSameUser= */ false)) {
4392 return;
4393 }
4394 final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId);
kholoud mohamed79a89f02020-01-15 15:30:07 +00004395 if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight(
4396 mContext,
4397 android.Manifest.permission.INTERACT_ACROSS_PROFILES,
4398 PermissionChecker.PID_UNKNOWN,
4399 callingUid,
4400 mPackageManagerInt.getPackage(callingUid).getPackageName())
4401 == PermissionChecker.PERMISSION_GRANTED) {
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004402 return;
4403 }
4404 String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage(
4405 message, requireFullPermission, isSameProfileGroup);
4406 Slog.w(TAG, errorMessage);
4407 throw new SecurityException(errorMessage);
4408 }
4409
4410 private boolean hasCrossUserPermission(
4411 int callingUid, int callingUserId, int userId, boolean requireFullPermission,
4412 boolean requirePermissionWhenSameUser) {
4413 if (!requirePermissionWhenSameUser && userId == callingUserId) {
4414 return true;
4415 }
4416 if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) {
4417 return true;
4418 }
4419 if (requireFullPermission) {
4420 return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4421 }
4422 return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
4423 || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS);
4424 }
4425
4426 private boolean hasPermission(String permission) {
4427 return mContext.checkCallingOrSelfPermission(permission)
4428 == PackageManager.PERMISSION_GRANTED;
4429 }
4430
4431 private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) {
4432 final long identity = Binder.clearCallingIdentity();
4433 try {
4434 return UserManagerService.getInstance().isSameProfileGroup(callerUserId, userId);
4435 } finally {
4436 Binder.restoreCallingIdentity(identity);
4437 }
4438 }
4439
4440 private static String buildInvalidCrossUserPermissionMessage(
4441 String message, boolean requireFullPermission) {
4442 StringBuilder builder = new StringBuilder();
4443 if (message != null) {
4444 builder.append(message);
4445 builder.append(": ");
4446 }
4447 builder.append("Requires ");
4448 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4449 if (requireFullPermission) {
4450 builder.append(".");
4451 return builder.toString();
4452 }
4453 builder.append(" or ");
4454 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4455 builder.append(".");
4456 return builder.toString();
4457 }
4458
4459 private static String buildInvalidCrossUserOrProfilePermissionMessage(
4460 String message, boolean requireFullPermission, boolean isSameProfileGroup) {
4461 StringBuilder builder = new StringBuilder();
4462 if (message != null) {
4463 builder.append(message);
4464 builder.append(": ");
4465 }
4466 builder.append("Requires ");
4467 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
4468 if (requireFullPermission) {
4469 builder.append(".");
4470 return builder.toString();
4471 }
4472 builder.append(" or ");
4473 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
4474 if (isSameProfileGroup) {
4475 builder.append(" or ");
4476 builder.append(android.Manifest.permission.INTERACT_ACROSS_PROFILES);
4477 }
4478 builder.append(".");
4479 return builder.toString();
Todd Kennedy0eb97382017-10-03 16:57:22 -07004480 }
4481
Andreas Gampea71bee82018-07-20 12:55:36 -07004482 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004483 private int calculateCurrentPermissionFootprintLocked(BasePermission tree) {
4484 int size = 0;
Todd Kennedyc8423932017-10-05 08:58:36 -07004485 for (BasePermission perm : mSettings.mPermissions.values()) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004486 size += tree.calculateFootprint(perm);
4487 }
4488 return size;
4489 }
4490
Andreas Gampea71bee82018-07-20 12:55:36 -07004491 @GuardedBy({"mSettings.mLock", "mLock"})
Todd Kennedy0eb97382017-10-03 16:57:22 -07004492 private void enforcePermissionCapLocked(PermissionInfo info, BasePermission tree) {
4493 // We calculate the max size of permissions defined by this uid and throw
4494 // if that plus the size of 'info' would exceed our stated maximum.
4495 if (tree.getUid() != Process.SYSTEM_UID) {
4496 final int curTreeSize = calculateCurrentPermissionFootprintLocked(tree);
4497 if (curTreeSize + info.calculateFootprint() > MAX_PERMISSION_TREE_FOOTPRINT) {
4498 throw new SecurityException("Permission tree size cap exceeded");
4499 }
4500 }
4501 }
4502
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004503 private void systemReady() {
4504 mSystemReady = true;
4505 if (mPrivappPermissionsViolations != null) {
4506 throw new IllegalStateException("Signature|privileged permissions not in "
4507 + "privapp-permissions whitelist: " + mPrivappPermissionsViolations);
4508 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004509
4510 mPermissionControllerManager = mContext.getSystemService(PermissionControllerManager.class);
Svet Ganov3c499ea2019-07-26 17:45:56 -07004511 mPermissionPolicyInternal = LocalServices.getService(PermissionPolicyInternal.class);
Todd Kennedy583378d2019-07-12 06:50:30 -07004512
4513 int[] grantPermissionsUserIds = EMPTY_INT_ARRAY;
4514 for (int userId : UserManagerService.getInstance().getUserIds()) {
Evan Severson0dc24cb2020-02-04 10:25:08 -08004515 if (mPackageManagerInt.isPermissionUpgradeNeeded(userId)) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004516 grantPermissionsUserIds = ArrayUtils.appendInt(
4517 grantPermissionsUserIds, userId);
4518 }
4519 }
4520 // If we upgraded grant all default permissions before kicking off.
4521 for (int userId : grantPermissionsUserIds) {
4522 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
4523 }
4524 if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
4525 // If we did not grant default permissions, we preload from this the
4526 // default permission exceptions lazily to ensure we don't hit the
4527 // disk on a new user creation.
4528 mDefaultPermissionGrantPolicy.scheduleReadDefaultPermissionExceptions();
4529 }
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004530 }
4531
Winson14ff7172019-10-23 10:42:27 -07004532 private static String getVolumeUuidForPackage(AndroidPackage pkg) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004533 if (pkg == null) {
4534 return StorageManager.UUID_PRIVATE_INTERNAL;
4535 }
Winson5e0a1d52020-01-24 12:00:33 -08004536 if (pkg.isExternalStorage()) {
Winson14ff7172019-10-23 10:42:27 -07004537 if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004538 return StorageManager.UUID_PRIMARY_PHYSICAL;
4539 } else {
Winson14ff7172019-10-23 10:42:27 -07004540 return pkg.getVolumeUuid();
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004541 }
4542 } else {
4543 return StorageManager.UUID_PRIVATE_INTERNAL;
4544 }
4545 }
4546
Winson14ff7172019-10-23 10:42:27 -07004547 private static boolean hasPermission(AndroidPackage pkg, String permName) {
Winsone23ae202020-01-24 11:56:44 -08004548 if (pkg.getPermissions().isEmpty()) {
Winson14ff7172019-10-23 10:42:27 -07004549 return false;
4550 }
4551
4552 for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
4553 if (pkg.getPermissions().get(i).getName().equals(permName)) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004554 return true;
4555 }
4556 }
4557 return false;
4558 }
4559
Todd Kennedy0eb97382017-10-03 16:57:22 -07004560 /**
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004561 * Log that a permission request was granted/revoked.
Todd Kennedy0eb97382017-10-03 16:57:22 -07004562 *
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004563 * @param action the action performed
Todd Kennedy0eb97382017-10-03 16:57:22 -07004564 * @param name name of the permission
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004565 * @param packageName package permission is for
Todd Kennedy0eb97382017-10-03 16:57:22 -07004566 */
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004567 private void logPermission(int action, @NonNull String name, @NonNull String packageName) {
4568 final LogMaker log = new LogMaker(action);
4569 log.setPackageName(packageName);
4570 log.addTaggedData(MetricsEvent.FIELD_PERMISSION, name);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004571
Philip P. Moltmann8cff8b92017-10-25 14:32:41 -07004572 mMetricsLogger.write(log);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004573 }
4574
Philip P. Moltmanne1b277a2018-11-01 16:22:50 -07004575 /**
4576 * Get the mapping of background permissions to their foreground permissions.
4577 *
4578 * <p>Only initialized in the system server.
4579 *
4580 * @return the map &lt;bg permission -> list&lt;fg perm&gt;&gt;
4581 */
4582 public @Nullable ArrayMap<String, List<String>> getBackgroundPermissions() {
4583 return mBackgroundPermissions;
4584 }
4585
Philip P. Moltmann48456672019-01-20 13:14:03 -08004586 private class PermissionManagerServiceInternalImpl extends PermissionManagerServiceInternal {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004587 @Override
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004588 public void systemReady() {
4589 PermissionManagerService.this.systemReady();
4590 }
4591 @Override
Winson14ff7172019-10-23 10:42:27 -07004592 public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
4593 @UserIdInt int userId) {
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004594 return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
4595 }
Winson14ff7172019-10-23 10:42:27 -07004596
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004597 @Override
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004598 public void revokeRuntimePermissionsIfGroupChanged(
Winson14ff7172019-10-23 10:42:27 -07004599 @NonNull AndroidPackage newPackage,
4600 @NonNull AndroidPackage oldPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004601 @NonNull ArrayList<String> allPackageNames) {
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004602 PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
Todd Kennedyc971a452019-07-08 16:04:52 -07004603 oldPackage, allPackageNames, mDefaultPermissionCallback);
Philip P. Moltmannfae8a5282018-04-10 12:15:32 -07004604 }
4605 @Override
Winson14ff7172019-10-23 10:42:27 -07004606 public void addAllPermissions(AndroidPackage pkg, boolean chatty) {
Todd Kennedyc8423932017-10-05 08:58:36 -07004607 PermissionManagerService.this.addAllPermissions(pkg, chatty);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004608 }
4609 @Override
Winson14ff7172019-10-23 10:42:27 -07004610 public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
Todd Kennedy460f28c2017-10-06 13:46:22 -07004611 PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
4612 }
4613 @Override
Winson14ff7172019-10-23 10:42:27 -07004614 public void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
Hongming Jinae750fb2018-09-27 23:00:20 +00004615 PermissionManagerService.this.removeAllPermissions(pkg, chatty);
Todd Kennedyc8423932017-10-05 08:58:36 -07004616 }
4617 @Override
Winson14ff7172019-10-23 10:42:27 -07004618 public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
Todd Kennedyc971a452019-07-08 16:04:52 -07004619 String[] grantedPermissions, int callingUid) {
Todd Kennedy0eb97382017-10-03 16:57:22 -07004620 PermissionManagerService.this.grantRequestedRuntimePermissions(
Todd Kennedyc971a452019-07-08 16:04:52 -07004621 pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004622 }
4623 @Override
Winson14ff7172019-10-23 10:42:27 -07004624 public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004625 @NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
Todd Kennedyc971a452019-07-08 16:04:52 -07004626 @PackageManager.PermissionWhitelistFlags int flags) {
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004627 for (int userId : userIds) {
4628 setWhitelistedRestrictedPermissionsForUser(pkg, userId, permissions,
Todd Kennedyc971a452019-07-08 16:04:52 -07004629 callingUid, flags, mDefaultPermissionCallback);
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004630 }
4631 }
4632 @Override
4633 public void setWhitelistedRestrictedPermissions(String packageName,
4634 List<String> permissions, int flags, int userId) {
4635 PermissionManagerService.this.setWhitelistedRestrictedPermissionsInternal(
4636 packageName, permissions, flags, userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004637 }
4638 @Override
Eugene Susla922cd082020-03-11 12:38:17 -07004639 public void setAutoRevokeWhitelisted(
4640 @NonNull String packageName, boolean whitelisted, int userId) {
4641 PermissionManagerService.this.setAutoRevokeWhitelisted(
4642 packageName, whitelisted, userId);
4643 }
4644 @Override
Winson14ff7172019-10-23 10:42:27 -07004645 public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004646 PermissionManagerService.this
4647 .updatePermissions(packageName, pkg, mDefaultPermissionCallback);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004648 }
4649 @Override
Todd Kennedyc971a452019-07-08 16:04:52 -07004650 public void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated) {
4651 PermissionManagerService.this
4652 .updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
Todd Kennedyc29b11a2017-10-23 15:55:59 -07004653 }
4654 @Override
Winson14ff7172019-10-23 10:42:27 -07004655 public void resetRuntimePermissions(AndroidPackage pkg, int userId) {
Todd Kennedyc971a452019-07-08 16:04:52 -07004656 PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
4657 }
4658 @Override
4659 public void resetAllRuntimePermissions(final int userId) {
4660 mPackageManagerInt.forEachPackage(
Winson14ff7172019-10-23 10:42:27 -07004661 (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
Todd Kennedy0eb97382017-10-03 16:57:22 -07004662 }
4663 @Override
Todd Kennedy8f135982019-07-02 07:35:15 -07004664 public String[] getAppOpPermissionPackages(String permName, int callingUid) {
4665 return PermissionManagerService.this
4666 .getAppOpPermissionPackagesInternal(permName, callingUid);
Todd Kennedyc8423932017-10-05 08:58:36 -07004667 }
4668 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004669 public void enforceCrossUserPermission(int callingUid, int userId,
4670 boolean requireFullPermission, boolean checkShell, String message) {
4671 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
Todd Kennedyef9acb62018-05-29 15:18:06 -07004672 requireFullPermission, checkShell, false, message);
4673 }
4674 @Override
4675 public void enforceCrossUserPermission(int callingUid, int userId,
4676 boolean requireFullPermission, boolean checkShell,
4677 boolean requirePermissionWhenSameUser, String message) {
4678 PermissionManagerService.this.enforceCrossUserPermission(callingUid, userId,
4679 requireFullPermission, checkShell, requirePermissionWhenSameUser, message);
Todd Kennedy0eb97382017-10-03 16:57:22 -07004680 }
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004681
4682 @Override
4683 public void enforceCrossUserOrProfilePermission(int callingUid, int userId,
4684 boolean requireFullPermission, boolean checkShell, String message) {
kholoud mohamed79a89f02020-01-15 15:30:07 +00004685 PermissionManagerService.this.enforceCrossUserOrProfilePermission(
4686 callingUid,
kholoud mohamed67ac7c62019-12-06 16:33:48 +00004687 userId,
4688 requireFullPermission,
4689 checkShell,
4690 message);
4691 }
4692
Todd Kennedy0eb97382017-10-03 16:57:22 -07004693 @Override
4694 public void enforceGrantRevokeRuntimePermissionPermissions(String message) {
4695 PermissionManagerService.this.enforceGrantRevokeRuntimePermissionPermissions(message);
4696 }
4697 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004698 public PermissionSettings getPermissionSettings() {
4699 return mSettings;
4700 }
4701 @Override
Todd Kennedy0eb97382017-10-03 16:57:22 -07004702 public BasePermission getPermissionTEMP(String permName) {
4703 synchronized (PermissionManagerService.this.mLock) {
4704 return mSettings.getPermissionLocked(permName);
4705 }
4706 }
Philip P. Moltmann48456672019-01-20 13:14:03 -08004707
4708 @Override
Hai Zhanga7c60c02020-03-05 16:03:35 -08004709 public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtection(
Hai Zhang57bc3122019-10-21 16:04:15 -07004710 @PermissionInfo.Protection int protection) {
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004711 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
4712
Hai Zhanga7c60c02020-03-05 16:03:35 -08004713 synchronized (mLock) {
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004714 int numTotalPermissions = mSettings.mPermissions.size();
4715
4716 for (int i = 0; i < numTotalPermissions; i++) {
4717 BasePermission bp = mSettings.mPermissions.valueAt(i);
4718
Winson655a5b92019-10-23 10:49:32 -07004719 if (bp.perm != null && bp.perm.getProtection() == protection) {
4720 matchingPermissions.add(
4721 PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -07004722 }
4723 }
4724 }
4725
4726 return matchingPermissions;
4727 }
4728
4729 @Override
Hai Zhanga7c60c02020-03-05 16:03:35 -08004730 public @NonNull ArrayList<PermissionInfo> getAllPermissionsWithProtectionFlags(
4731 @PermissionInfo.ProtectionFlags int protectionFlags) {
4732 ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();
4733
4734 synchronized (mLock) {
4735 int numTotalPermissions = mSettings.mPermissions.size();
4736
4737 for (int i = 0; i < numTotalPermissions; i++) {
4738 BasePermission bp = mSettings.mPermissions.valueAt(i);
4739
4740 if (bp.perm != null && (bp.perm.getProtectionFlags() & protectionFlags)
4741 == protectionFlags) {
4742 matchingPermissions.add(
4743 PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
4744 }
4745 }
4746 }
4747
4748 return matchingPermissions;
4749 }
4750
4751 @Override
Philip P. Moltmann48456672019-01-20 13:14:03 -08004752 public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
4753 return PermissionManagerService.this.backupRuntimePermissions(user);
4754 }
4755
4756 @Override
4757 public void restoreRuntimePermissions(@NonNull byte[] backup, @NonNull UserHandle user) {
4758 PermissionManagerService.this.restoreRuntimePermissions(backup, user);
4759 }
4760
4761 @Override
4762 public void restoreDelayedRuntimePermissions(@NonNull String packageName,
4763 @NonNull UserHandle user) {
4764 PermissionManagerService.this.restoreDelayedRuntimePermissions(packageName, user);
4765 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -07004766
4767 @Override
4768 public void addOnRuntimePermissionStateChangedListener(
4769 OnRuntimePermissionStateChangedListener listener) {
4770 PermissionManagerService.this.addOnRuntimePermissionStateChangedListener(
4771 listener);
4772 }
4773
4774 @Override
4775 public void removeOnRuntimePermissionStateChangedListener(
4776 OnRuntimePermissionStateChangedListener listener) {
4777 PermissionManagerService.this.removeOnRuntimePermissionStateChangedListener(
4778 listener);
4779 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004780
4781 @Override
4782 public CheckPermissionDelegate getCheckPermissionDelegate() {
4783 synchronized (mLock) {
4784 return mCheckPermissionDelegate;
4785 }
4786 }
4787
4788 @Override
4789 public void setCheckPermissionDelegate(CheckPermissionDelegate delegate) {
4790 synchronized (mLock) {
Daniel Colascionea3c6c092020-02-27 03:51:30 -08004791 if (delegate != null || mCheckPermissionDelegate != null) {
4792 PackageManager.invalidatePackageInfoCache();
4793 }
Todd Kennedyca1ea172019-07-03 15:02:28 -07004794 mCheckPermissionDelegate = delegate;
4795 }
4796 }
Todd Kennedy583378d2019-07-12 06:50:30 -07004797
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004798 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004799 public void setDefaultBrowserProvider(@NonNull DefaultBrowserProvider provider) {
4800 synchronized (mLock) {
4801 mDefaultBrowserProvider = provider;
4802 }
4803 }
4804
4805 @Override
4806 public void setDefaultBrowser(String packageName, boolean async, boolean doGrant,
4807 int userId) {
4808 setDefaultBrowserInternal(packageName, async, doGrant, userId);
4809 }
4810
4811 @Override
4812 public void setDefaultDialerProvider(@NonNull DefaultDialerProvider provider) {
4813 synchronized (mLock) {
4814 mDefaultDialerProvider = provider;
4815 }
4816 }
4817
4818 @Override
4819 public void setDefaultHomeProvider(@NonNull DefaultHomeProvider provider) {
4820 synchronized (mLock) {
4821 mDefaultHomeProvider = provider;
4822 }
4823 }
4824
4825 @Override
4826 public void setDefaultHome(String packageName, int userId, Consumer<Boolean> callback) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004827 if (userId == UserHandle.USER_ALL) {
4828 return;
Todd Kennedy583378d2019-07-12 06:50:30 -07004829 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004830 DefaultHomeProvider provider;
4831 synchronized (mLock) {
4832 provider = mDefaultHomeProvider;
4833 }
4834 if (provider == null) {
4835 return;
4836 }
4837 provider.setDefaultHomeAsync(packageName, userId, callback);
Todd Kennedy583378d2019-07-12 06:50:30 -07004838 }
4839
4840 @Override
4841 public void setDialerAppPackagesProvider(PackagesProvider provider) {
4842 synchronized (mLock) {
4843 mDefaultPermissionGrantPolicy.setDialerAppPackagesProvider(provider);
4844 }
4845 }
4846
4847 @Override
4848 public void setLocationExtraPackagesProvider(PackagesProvider provider) {
4849 synchronized (mLock) {
4850 mDefaultPermissionGrantPolicy.setLocationExtraPackagesProvider(provider);
4851 }
4852 }
4853
4854 @Override
4855 public void setLocationPackagesProvider(PackagesProvider provider) {
4856 synchronized (mLock) {
4857 mDefaultPermissionGrantPolicy.setLocationPackagesProvider(provider);
4858 }
4859 }
4860
4861 @Override
4862 public void setSimCallManagerPackagesProvider(PackagesProvider provider) {
4863 synchronized (mLock) {
4864 mDefaultPermissionGrantPolicy.setSimCallManagerPackagesProvider(provider);
4865 }
4866 }
4867
4868 @Override
4869 public void setSmsAppPackagesProvider(PackagesProvider provider) {
4870 synchronized (mLock) {
4871 mDefaultPermissionGrantPolicy.setSmsAppPackagesProvider(provider);
4872 }
4873 }
4874
4875 @Override
4876 public void setSyncAdapterPackagesProvider(SyncAdapterPackagesProvider provider) {
4877 synchronized (mLock) {
4878 mDefaultPermissionGrantPolicy.setSyncAdapterPackagesProvider(provider);
4879 }
4880 }
4881
4882 @Override
4883 public void setUseOpenWifiAppPackagesProvider(PackagesProvider provider) {
4884 synchronized (mLock) {
4885 mDefaultPermissionGrantPolicy.setUseOpenWifiAppPackagesProvider(provider);
4886 }
4887 }
4888
4889 @Override
4890 public void setVoiceInteractionPackagesProvider(PackagesProvider provider) {
4891 synchronized (mLock) {
4892 mDefaultPermissionGrantPolicy.setVoiceInteractionPackagesProvider(provider);
4893 }
4894 }
4895
4896 @Override
4897 public String getDefaultBrowser(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004898 DefaultBrowserProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004899 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004900 provider = mDefaultBrowserProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004901 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004902 return provider != null ? provider.getDefaultBrowser(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004903 }
4904
4905 @Override
4906 public String getDefaultDialer(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004907 DefaultDialerProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004908 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004909 provider = mDefaultDialerProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004910 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004911 return provider != null ? provider.getDefaultDialer(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004912 }
4913
4914 @Override
4915 public String getDefaultHome(int userId) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004916 DefaultHomeProvider provider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004917 synchronized (mLock) {
Hai Zhang109ff9d2019-09-24 17:18:05 -07004918 provider = mDefaultHomeProvider;
Todd Kennedy583378d2019-07-12 06:50:30 -07004919 }
Hai Zhang109ff9d2019-09-24 17:18:05 -07004920 return provider != null ? provider.getDefaultHome(userId) : null;
Todd Kennedy583378d2019-07-12 06:50:30 -07004921 }
4922
4923 @Override
4924 public void grantDefaultPermissionsToDefaultSimCallManager(String packageName, int userId) {
4925 synchronized (mLock) {
4926 mDefaultPermissionGrantPolicy
4927 .grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
4928 }
4929 }
4930
4931 @Override
4932 public void grantDefaultPermissionsToDefaultUseOpenWifiApp(String packageName, int userId) {
4933 synchronized (mLock) {
4934 mDefaultPermissionGrantPolicy
4935 .grantDefaultPermissionsToDefaultUseOpenWifiApp(packageName, userId);
4936 }
4937 }
4938
4939 @Override
4940 public void grantDefaultPermissionsToDefaultBrowser(String packageName, int userId) {
4941 synchronized (mLock) {
4942 mDefaultPermissionGrantPolicy
4943 .grantDefaultPermissionsToDefaultBrowser(packageName, userId);
4944 }
4945 }
4946
4947 @Override
Todd Kennedy583378d2019-07-12 06:50:30 -07004948 public void onNewUserCreated(int userId) {
Hai Zhang93236822020-01-09 13:15:17 -08004949 mDefaultPermissionGrantPolicy.grantDefaultPermissions(userId);
Todd Kennedy583378d2019-07-12 06:50:30 -07004950 synchronized (mLock) {
Todd Kennedy583378d2019-07-12 06:50:30 -07004951 // NOTE: This adds UPDATE_PERMISSIONS_REPLACE_PKG
4952 PermissionManagerService.this.updateAllPermissions(
4953 StorageManager.UUID_PRIVATE_INTERNAL, true, mDefaultPermissionCallback);
4954 }
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004955 }
Winson10d51882020-05-26 10:52:23 -07004956
4957 @Override
4958 public void retainHardAndSoftRestrictedPermissions(@NonNull List<String> permissions) {
4959 synchronized (mLock) {
4960 Iterator<String> iterator = permissions.iterator();
4961 while (iterator.hasNext()) {
4962 String permission = iterator.next();
4963 BasePermission basePermission = mSettings.mPermissions.get(permission);
4964 if (basePermission == null || !basePermission.isHardOrSoftRestricted()) {
4965 iterator.remove();
4966 }
4967 }
4968 }
4969 }
Todd Kennedy7e3dd3a2019-07-08 10:34:29 -07004970 }
4971
4972 private static final class OnPermissionChangeListeners extends Handler {
4973 private static final int MSG_ON_PERMISSIONS_CHANGED = 1;
4974
4975 private final RemoteCallbackList<IOnPermissionsChangeListener> mPermissionListeners =
4976 new RemoteCallbackList<>();
4977
4978 OnPermissionChangeListeners(Looper looper) {
4979 super(looper);
4980 }
4981
4982 @Override
4983 public void handleMessage(Message msg) {
4984 switch (msg.what) {
4985 case MSG_ON_PERMISSIONS_CHANGED: {
4986 final int uid = msg.arg1;
4987 handleOnPermissionsChanged(uid);
4988 } break;
4989 }
4990 }
4991
4992 public void addListenerLocked(IOnPermissionsChangeListener listener) {
4993 mPermissionListeners.register(listener);
4994
4995 }
4996
4997 public void removeListenerLocked(IOnPermissionsChangeListener listener) {
4998 mPermissionListeners.unregister(listener);
4999 }
5000
5001 public void onPermissionsChanged(int uid) {
5002 if (mPermissionListeners.getRegisteredCallbackCount() > 0) {
5003 obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
5004 }
5005 }
5006
5007 private void handleOnPermissionsChanged(int uid) {
5008 final int count = mPermissionListeners.beginBroadcast();
5009 try {
5010 for (int i = 0; i < count; i++) {
5011 IOnPermissionsChangeListener callback = mPermissionListeners
5012 .getBroadcastItem(i);
5013 try {
5014 callback.onPermissionsChanged(uid);
5015 } catch (RemoteException e) {
5016 Log.e(TAG, "Permission listener is dead", e);
5017 }
5018 }
5019 } finally {
5020 mPermissionListeners.finishBroadcast();
5021 }
5022 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07005023 }
Michael Groover56a84b22020-03-04 20:41:36 -08005024
5025 /**
5026 * Allows injection of services and method responses to facilitate testing.
5027 *
5028 * <p>Test classes can create a mock of this class and pass it to the PermissionManagerService
5029 * constructor to control behavior of services and external methods during execution.
5030 * @hide
5031 */
5032 @VisibleForTesting
5033 public static class Injector {
5034 private final Context mContext;
5035
5036 /**
5037 * Public constructor that accepts a {@code context} within which to operate.
5038 */
5039 public Injector(@NonNull Context context) {
5040 mContext = context;
5041 }
5042
5043 /**
5044 * Returns the UID of the calling package.
5045 */
5046 public int getCallingUid() {
5047 return Binder.getCallingUid();
5048 }
5049
5050 /**
5051 * Returns the process ID of the calling package.
5052 */
5053 public int getCallingPid() {
5054 return Binder.getCallingPid();
5055 }
5056
5057 /**
5058 * Invalidates the package info cache.
5059 */
5060 public void invalidatePackageInfoCache() {
5061 PackageManager.invalidatePackageInfoCache();
5062 }
5063
5064 /**
5065 * Disables the permission cache.
5066 */
5067 public void disablePermissionCache() {
5068 PermissionManager.disablePermissionCache();
5069 }
5070
5071 /**
5072 * Disables the package name permission cache.
5073 */
5074 public void disablePackageNamePermissionCache() {
5075 PermissionManager.disablePackageNamePermissionCache();
5076 }
5077
5078 /**
5079 * Checks if the package running under the specified {@code pid} and {@code uid} has been
5080 * granted the provided {@code permission}.
5081 *
5082 * @return {@link PackageManager#PERMISSION_GRANTED} if the package has been granted the
5083 * permission, {@link PackageManager#PERMISSION_DENIED} otherwise
5084 */
5085 public int checkPermission(@NonNull String permission, int pid, int uid) {
5086 return mContext.checkPermission(permission, pid, uid);
5087 }
5088
5089 /**
5090 * Clears the calling identity to allow subsequent calls to be treated as coming from this
5091 * package.
5092 *
5093 * @return a token that can be used to restore the calling identity
5094 */
5095 public long clearCallingIdentity() {
5096 return Binder.clearCallingIdentity();
5097 }
5098
5099 /**
5100 * Restores the calling identity to that of the calling package based on the provided
5101 * {@code token}.
5102 */
5103 public void restoreCallingIdentity(long token) {
5104 Binder.restoreCallingIdentity(token);
5105 }
5106
5107 /**
5108 * Returns the system service with the provided {@code name}.
5109 */
5110 public Object getSystemService(@NonNull String name) {
5111 return mContext.getSystemService(name);
5112 }
5113 }
Todd Kennedy0eb97382017-10-03 16:57:22 -07005114}