blob: 3a78aa2fbbf557bf8cc8eb52703e765ecfa2d912 [file] [log] [blame]
Svet Ganovd8eb8b22019-04-05 18:52:08 -07001/*
2 * Copyright (C) 2019 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.policy;
18
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -070019import static android.app.AppOpsManager.MODE_ALLOWED;
20import static android.app.AppOpsManager.MODE_DEFAULT;
21import static android.app.AppOpsManager.MODE_ERRORED;
Philip P. Moltmann404b51c2019-06-11 09:01:59 -070022import static android.app.AppOpsManager.MODE_FOREGROUND;
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -070023import static android.app.AppOpsManager.MODE_IGNORED;
24import static android.app.AppOpsManager.OP_NONE;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070025import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
Philip P. Moltmann4e369a72019-06-14 11:08:16 -070026import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
Philip P. Moltmann48687722019-04-11 10:40:30 -070027import static android.content.pm.PackageManager.GET_PERMISSIONS;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070028
29import android.annotation.NonNull;
Philip P. Moltmann48687722019-04-11 10:40:30 -070030import android.annotation.Nullable;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070031import android.annotation.UserIdInt;
32import android.app.AppOpsManager;
33import android.content.Context;
Hai Zhangf4da9be2019-05-01 13:46:06 +080034import android.content.Intent;
35import android.content.pm.ApplicationInfo;
Svet Ganov38a06312019-04-09 23:55:05 -070036import android.content.pm.PackageInfo;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070037import android.content.pm.PackageManager;
Svet Ganov38a06312019-04-09 23:55:05 -070038import android.content.pm.PackageManager.NameNotFoundException;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070039import android.content.pm.PackageManagerInternal;
40import android.content.pm.PackageManagerInternal.PackageListObserver;
41import android.content.pm.PackageParser;
42import android.content.pm.PermissionInfo;
Philip P. Moltmann9408f582019-04-10 16:58:24 -070043import android.os.Build;
Svet Ganov38a06312019-04-09 23:55:05 -070044import android.os.Process;
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -070045import android.os.RemoteException;
46import android.os.ServiceManager;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070047import android.os.UserHandle;
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -070048import android.os.UserManagerInternal;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070049import android.permission.PermissionControllerManager;
Hai Zhangf4da9be2019-05-01 13:46:06 +080050import android.provider.Telephony;
Hai Zhang114afc32019-05-01 14:16:23 +080051import android.telecom.TelecomManager;
Philip P. Moltmann78c155b2019-06-14 09:02:24 -070052import android.util.ArraySet;
53import android.util.Pair;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070054import android.util.Slog;
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -070055import android.util.SparseBooleanArray;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070056import android.util.SparseIntArray;
57
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -070058import com.android.internal.annotations.GuardedBy;
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -070059import com.android.internal.app.IAppOpsCallback;
60import com.android.internal.app.IAppOpsService;
Philip P. Moltmann78c155b2019-06-14 09:02:24 -070061import com.android.internal.util.function.pooled.PooledLambda;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070062import com.android.server.FgThread;
63import com.android.server.LocalServices;
64import com.android.server.SystemService;
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -070065import com.android.server.pm.permission.PermissionManagerServiceInternal;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070066
Svet Ganov38a06312019-04-09 23:55:05 -070067import java.util.ArrayList;
Svet Ganovd8eb8b22019-04-05 18:52:08 -070068import java.util.concurrent.CountDownLatch;
69
70/**
71 * This is a permission policy that governs over all permission mechanism
72 * such as permissions, app ops, etc. For example, the policy ensures that
73 * permission state and app ops is synchronized for cases where there is a
74 * dependency between permission state (permissions or permission flags)
75 * and app ops - and vise versa.
76 */
77public final class PermissionPolicyService extends SystemService {
Svet Ganovd8eb8b22019-04-05 18:52:08 -070078 private static final String LOG_TAG = PermissionPolicyService.class.getSimpleName();
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -070079 private static final boolean DEBUG = false;
80
81 private final Object mLock = new Object();
82
83 /** Whether the user is started but not yet stopped */
84 @GuardedBy("mLock")
85 private final SparseBooleanArray mIsStarted = new SparseBooleanArray();
Svet Ganovd8eb8b22019-04-05 18:52:08 -070086
Philip P. Moltmann78c155b2019-06-14 09:02:24 -070087 /**
88 * Whether an async {@link #synchronizePackagePermissionsAndAppOpsForUser} is currently
89 * scheduled for a package/user.
90 */
91 @GuardedBy("mLock")
92 private final ArraySet<Pair<String, Integer>> mIsPackageSyncsScheduled = new ArraySet<>();
93
Svet Ganovd8eb8b22019-04-05 18:52:08 -070094 public PermissionPolicyService(@NonNull Context context) {
95 super(context);
Hai Zhangf4da9be2019-05-01 13:46:06 +080096
97 LocalServices.addService(PermissionPolicyInternal.class, new Internal());
Svet Ganovd8eb8b22019-04-05 18:52:08 -070098 }
99
100 @Override
101 public void onStart() {
102 final PackageManagerInternal packageManagerInternal = LocalServices.getService(
103 PackageManagerInternal.class);
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700104 final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
105 PermissionManagerServiceInternal.class);
106 final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
107 ServiceManager.getService(Context.APP_OPS_SERVICE));
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700108
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700109 packageManagerInternal.getPackageList(new PackageListObserver() {
110 @Override
111 public void onPackageAdded(String packageName, int uid) {
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700112 onPackageChanged(packageName, uid);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700113 }
114
115 @Override
116 public void onPackageChanged(String packageName, int uid) {
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700117 final int userId = UserHandle.getUserId(uid);
118
119 if (isStarted(userId)) {
120 synchronizePackagePermissionsAndAppOpsForUser(packageName, userId);
121 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700122 }
123
124 @Override
125 public void onPackageRemoved(String packageName, int uid) {
126 /* do nothing */
127 }
128 });
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700129
130 permManagerInternal.addOnRuntimePermissionStateChangedListener(
Philip P. Moltmann78c155b2019-06-14 09:02:24 -0700131 this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700132
133 IAppOpsCallback appOpsListener = new IAppOpsCallback.Stub() {
134 public void opChanged(int op, int uid, String packageName) {
135 synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName,
136 UserHandle.getUserId(uid));
137 }
138 };
139
140 final ArrayList<PermissionInfo> dangerousPerms =
141 permManagerInternal.getAllPermissionWithProtectionLevel(
142 PermissionInfo.PROTECTION_DANGEROUS);
143
144 try {
145 int numDangerousPerms = dangerousPerms.size();
146 for (int i = 0; i < numDangerousPerms; i++) {
147 PermissionInfo perm = dangerousPerms.get(i);
148
149 if (perm.isHardRestricted() || perm.backgroundPermission != null) {
150 appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
151 null, appOpsListener);
152 } else if (perm.isSoftRestricted()) {
153 appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
154 null, appOpsListener);
155
156 SoftRestrictedPermissionPolicy policy =
157 SoftRestrictedPermissionPolicy.forPermission(null, null, null,
158 perm.name);
159 if (policy.resolveAppOp() != OP_NONE) {
160 appOpsService.startWatchingMode(policy.resolveAppOp(), null,
161 appOpsListener);
162 }
163 }
164 }
165 } catch (RemoteException doesNotHappen) {
166 Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
167 }
Philip P. Moltmann78c155b2019-06-14 09:02:24 -0700168 }
169
170 private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
171 @UserIdInt int changedUserId) {
172 if (isStarted(changedUserId)) {
173 synchronized (mLock) {
174 if (mIsPackageSyncsScheduled.add(new Pair<>(packageName, changedUserId))) {
175 FgThread.getHandler().sendMessage(PooledLambda.obtainMessage(
176 PermissionPolicyService
177 ::synchronizePackagePermissionsAndAppOpsForUser,
178 this, packageName, changedUserId));
179 } else {
180 if (DEBUG) {
181 Slog.v(LOG_TAG, "sync for " + packageName + "/" + changedUserId
182 + " already scheduled");
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700183 }
Philip P. Moltmann78c155b2019-06-14 09:02:24 -0700184 }
185 }
186 }
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700187 }
188
189 @Override
190 public void onBootPhase(int phase) {
191 if (DEBUG) Slog.i(LOG_TAG, "onBootPhase(" + phase + ")");
192
193 if (phase == PHASE_ACTIVITY_MANAGER_READY) {
194 final UserManagerInternal um = LocalServices.getService(UserManagerInternal.class);
195
196 // For some users we might not receive a onStartUser, hence force one here
197 for (int userId : um.getUserIds()) {
198 if (um.isUserRunning(userId)) {
199 onStartUser(userId);
200 }
201 }
202 }
203 }
204
205 /**
206 * @return Whether the user is started but not yet stopped
207 */
208 private boolean isStarted(@UserIdInt int userId) {
209 synchronized (mLock) {
210 return mIsStarted.get(userId);
211 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700212 }
213
214 @Override
215 public void onStartUser(@UserIdInt int userId) {
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700216 if (DEBUG) Slog.i(LOG_TAG, "onStartUser(" + userId + ")");
217
218 if (isStarted(userId)) {
219 return;
220 }
221
222 grantOrUpgradeDefaultRuntimePermissionsIfNeeded(userId);
223
224 synchronized (mLock) {
225 mIsStarted.put(userId, true);
226 }
227
228 // Force synchronization as permissions might have changed
229 synchronizePermissionsAndAppOpsForUser(userId);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700230 }
231
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700232 @Override
233 public void onStopUser(@UserIdInt int userId) {
234 if (DEBUG) Slog.i(LOG_TAG, "onStopUser(" + userId + ")");
235
236 synchronized (mLock) {
237 mIsStarted.delete(userId);
238 }
239 }
240
241 private void grantOrUpgradeDefaultRuntimePermissionsIfNeeded(@UserIdInt int userId) {
242 if (DEBUG) Slog.i(LOG_TAG, "grantOrUpgradeDefaultPermsIfNeeded(" + userId + ")");
243
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700244 final PackageManagerInternal packageManagerInternal = LocalServices.getService(
245 PackageManagerInternal.class);
246 if (packageManagerInternal.wereDefaultPermissionsGrantedSinceBoot(userId)) {
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700247 if (DEBUG) Slog.i(LOG_TAG, "defaultPermsWereGrantedSinceBoot(" + userId + ")");
248
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700249 // Now call into the permission controller to apply policy around permissions
250 final CountDownLatch latch = new CountDownLatch(1);
251
252 // We need to create a local manager that does not schedule work on the main
253 // there as we are on the main thread and want to block until the work is
254 // completed or we time out.
255 final PermissionControllerManager permissionControllerManager =
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700256 new PermissionControllerManager(
257 getUserContext(getContext(), UserHandle.of(userId)),
Philip P. Moltmann7870aa02019-05-10 15:01:32 -0700258 FgThread.getHandler());
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700259 permissionControllerManager.grantOrUpgradeDefaultRuntimePermissions(
260 FgThread.getExecutor(),
261 (Boolean success) -> {
262 if (!success) {
263 // We are in an undefined state now, let us crash and have
264 // rescue party suggest a wipe to recover to a good one.
265 final String message = "Error granting/upgrading runtime permissions";
266 Slog.wtf(LOG_TAG, message);
267 throw new IllegalStateException(message);
268 }
269 latch.countDown();
270 }
271 );
272 try {
273 latch.await();
274 } catch (InterruptedException e) {
275 /* ignore */
276 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700277
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700278 packageManagerInternal.setRuntimePermissionsFingerPrint(Build.FINGERPRINT, userId);
279 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700280 }
281
Philip P. Moltmann48687722019-04-11 10:40:30 -0700282 private static @Nullable Context getUserContext(@NonNull Context context,
Svet Ganovd563e932019-04-14 13:07:41 -0700283 @Nullable UserHandle user) {
Philip P. Moltmann48687722019-04-11 10:40:30 -0700284 if (context.getUser().equals(user)) {
285 return context;
286 } else {
287 try {
288 return context.createPackageContextAsUser(context.getPackageName(), 0, user);
289 } catch (NameNotFoundException e) {
290 Slog.e(LOG_TAG, "Cannot create context for user " + user, e);
291 return null;
292 }
293 }
294 }
295
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700296 /**
297 * Synchronize a single package.
298 */
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700299 private void synchronizePackagePermissionsAndAppOpsForUser(@NonNull String packageName,
300 @UserIdInt int userId) {
Philip P. Moltmann78c155b2019-06-14 09:02:24 -0700301 synchronized (mLock) {
302 mIsPackageSyncsScheduled.remove(new Pair<>(packageName, userId));
303 }
304
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700305 if (DEBUG) {
306 Slog.v(LOG_TAG,
Philip P. Moltmann78c155b2019-06-14 09:02:24 -0700307 "synchronizePackagePermissionsAndAppOpsForUser(" + packageName + ", "
308 + userId + ")");
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700309 }
310
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700311 final PackageManagerInternal packageManagerInternal = LocalServices.getService(
312 PackageManagerInternal.class);
Philip P. Moltmann48687722019-04-11 10:40:30 -0700313 final PackageInfo pkg = packageManagerInternal.getPackageInfo(packageName, 0,
314 Process.SYSTEM_UID, userId);
Svet Ganov38a06312019-04-09 23:55:05 -0700315 if (pkg == null) {
316 return;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700317 }
Philip P. Moltmann48687722019-04-11 10:40:30 -0700318 final PermissionToOpSynchroniser synchroniser = new PermissionToOpSynchroniser(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700319 getUserContext(getContext(), UserHandle.of(userId)));
Philip P. Moltmann48687722019-04-11 10:40:30 -0700320 synchroniser.addPackage(pkg.packageName);
Svet Ganov38a06312019-04-09 23:55:05 -0700321 final String[] sharedPkgNames = packageManagerInternal.getPackagesForSharedUserId(
Philip P. Moltmann48687722019-04-11 10:40:30 -0700322 pkg.sharedUserId, userId);
Svet Ganov38a06312019-04-09 23:55:05 -0700323 if (sharedPkgNames != null) {
324 for (String sharedPkgName : sharedPkgNames) {
325 final PackageParser.Package sharedPkg = packageManagerInternal
326 .getPackage(sharedPkgName);
327 if (sharedPkg != null) {
Philip P. Moltmann48687722019-04-11 10:40:30 -0700328 synchroniser.addPackage(sharedPkg.packageName);
Svet Ganov38a06312019-04-09 23:55:05 -0700329 }
330 }
331 }
332 synchroniser.syncPackages();
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700333 }
334
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700335 /**
336 * Synchronize all packages
337 */
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700338 private void synchronizePermissionsAndAppOpsForUser(@UserIdInt int userId) {
339 if (DEBUG) Slog.i(LOG_TAG, "synchronizePermissionsAndAppOpsForUser(" + userId + ")");
340
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700341 final PackageManagerInternal packageManagerInternal = LocalServices.getService(
342 PackageManagerInternal.class);
Philip P. Moltmann48687722019-04-11 10:40:30 -0700343 final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(
Philip P. Moltmann5f5783e2019-05-22 14:57:18 -0700344 getUserContext(getContext(), UserHandle.of(userId)));
Philip P. Moltmann48687722019-04-11 10:40:30 -0700345 packageManagerInternal.forEachPackage((pkg) -> synchronizer.addPackage(pkg.packageName));
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700346 synchronizer.syncPackages();
347 }
348
Svet Ganov38a06312019-04-09 23:55:05 -0700349 /**
350 * Synchronizes permission to app ops. You *must* always sync all packages
351 * in a shared UID at the same time to ensure proper synchronization.
352 */
353 private static class PermissionToOpSynchroniser {
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700354 private final @NonNull Context mContext;
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700355 private final @NonNull PackageManager mPackageManager;
356 private final @NonNull AppOpsManager mAppOpsManager;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700357
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700358 /** All uid that need to be synchronized */
359 private final @NonNull SparseIntArray mAllUids = new SparseIntArray();
360
361 /**
Svet Ganovd563e932019-04-14 13:07:41 -0700362 * All ops that need to be set to default
363 *
364 * Currently, only used by the restricted permissions logic.
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700365 *
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700366 * @see #syncPackages
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700367 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700368 private final @NonNull ArrayList<OpToChange> mOpsToDefault = new ArrayList<>();
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700369
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700370 /**
Svet Ganovd563e932019-04-14 13:07:41 -0700371 * All ops that need to be flipped to allow if default.
372 *
373 * Currently, only used by the restricted permissions logic.
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700374 *
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700375 * @see #syncPackages
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700376 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700377 private final @NonNull ArrayList<OpToChange> mOpsToAllowIfDefault = new ArrayList<>();
Philip P. Moltmann74065c82019-05-15 10:46:32 -0700378
379 /**
380 * All ops that need to be flipped to allow.
381 *
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700382 * @see #syncPackages
Philip P. Moltmann74065c82019-05-15 10:46:32 -0700383 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700384 private final @NonNull ArrayList<OpToChange> mOpsToAllow = new ArrayList<>();
Svet Ganovd563e932019-04-14 13:07:41 -0700385
386 /**
387 * All ops that need to be flipped to ignore if default.
388 *
389 * Currently, only used by the restricted permissions logic.
390 *
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700391 * @see #syncPackages
Svet Ganovd563e932019-04-14 13:07:41 -0700392 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700393 private final @NonNull ArrayList<OpToChange> mOpsToIgnoreIfDefault = new ArrayList<>();
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700394
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700395 /**
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700396 * All ops that need to be flipped to ignore.
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700397 *
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700398 * @see #syncPackages
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700399 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700400 private final @NonNull ArrayList<OpToChange> mOpsToIgnore = new ArrayList<>();
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700401
402 /**
403 * All ops that need to be flipped to foreground.
404 *
405 * Currently, only used by the foreground/background permissions logic.
406 *
407 * @see #syncPackages
408 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700409 private final @NonNull ArrayList<OpToChange> mOpsToForeground = new ArrayList<>();
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700410
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700411 /**
412 * All ops that need to be flipped to foreground if allow.
413 *
414 * Currently, only used by the foreground/background permissions logic.
415 *
416 * @see #syncPackages
417 */
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700418 private final @NonNull ArrayList<OpToChange> mOpsToForegroundIfAllow =
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700419 new ArrayList<>();
420
Svet Ganov38a06312019-04-09 23:55:05 -0700421 PermissionToOpSynchroniser(@NonNull Context context) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700422 mContext = context;
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700423 mPackageManager = context.getPackageManager();
424 mAppOpsManager = context.getSystemService(AppOpsManager.class);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700425 }
426
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700427 /**
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700428 * Set app ops that were added in {@link #addPackage}.
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700429 *
430 * <p>This processes ops previously added by {@link #addOpIfRestricted}
431 */
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700432 private void syncPackages() {
Svet Ganovd563e932019-04-14 13:07:41 -0700433 final int allowCount = mOpsToAllow.size();
434 for (int i = 0; i < allowCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700435 final OpToChange op = mOpsToAllow.get(i);
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700436 setUidModeAllowed(op.code, op.uid, op.packageName);
Philip P. Moltmann74065c82019-05-15 10:46:32 -0700437 }
438 final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
439 for (int i = 0; i < allowIfDefaultCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700440 final OpToChange op = mOpsToAllowIfDefault.get(i);
Svet Ganovd563e932019-04-14 13:07:41 -0700441 setUidModeAllowedIfDefault(op.code, op.uid, op.packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700442 }
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700443 final int foregroundCount = mOpsToForegroundIfAllow.size();
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700444 for (int i = 0; i < foregroundCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700445 final OpToChange op = mOpsToForegroundIfAllow.get(i);
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700446 setUidModeForegroundIfAllow(op.code, op.uid, op.packageName);
447 }
448 final int foregroundIfAllowCount = mOpsToForeground.size();
449 for (int i = 0; i < foregroundIfAllowCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700450 final OpToChange op = mOpsToForeground.get(i);
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700451 setUidModeForeground(op.code, op.uid, op.packageName);
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700452 }
453 final int ignoreCount = mOpsToIgnore.size();
454 for (int i = 0; i < ignoreCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700455 final OpToChange op = mOpsToIgnore.get(i);
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700456 setUidModeIgnored(op.code, op.uid, op.packageName);
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700457 }
Philip P. Moltmann74065c82019-05-15 10:46:32 -0700458 final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
459 for (int i = 0; i < ignoreIfDefaultCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700460 final OpToChange op = mOpsToIgnoreIfDefault.get(i);
Svet Ganovd563e932019-04-14 13:07:41 -0700461 setUidModeIgnoredIfDefault(op.code, op.uid, op.packageName);
462 }
463 final int defaultCount = mOpsToDefault.size();
464 for (int i = 0; i < defaultCount; i++) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700465 final OpToChange op = mOpsToDefault.get(i);
466 setUidModeDefault(op.code, op.uid, op.packageName);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700467 }
468 }
469
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700470 /**
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700471 * Add op that belong to a restricted permission for later processing in
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700472 * {@link #syncPackages()}.
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700473 *
474 * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
475 *
476 * @param permissionInfo The permission that is currently looked at
477 * @param pkg The package looked at
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700478 */
479 private void addOpIfRestricted(@NonNull PermissionInfo permissionInfo,
Philip P. Moltmann48687722019-04-11 10:40:30 -0700480 @NonNull PackageInfo pkg) {
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700481 final String permission = permissionInfo.name;
482 final int opCode = AppOpsManager.permissionToOpCode(permission);
Philip P. Moltmann48687722019-04-11 10:40:30 -0700483 final int uid = pkg.applicationInfo.uid;
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700484
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700485 if (!permissionInfo.isRestricted()) {
486 return;
487 }
488
Svet Ganov83a3a4a2019-05-03 18:50:43 -0700489 final boolean applyRestriction =
490 (mPackageManager.getPermissionFlags(permission, pkg.packageName,
Philip P. Moltmann48687722019-04-11 10:40:30 -0700491 mContext.getUser()) & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700492
493 if (permissionInfo.isHardRestricted()) {
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700494 if (opCode != OP_NONE) {
495 if (applyRestriction) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700496 mOpsToDefault.add(new OpToChange(uid, pkg.packageName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700497 } else {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700498 mOpsToAllowIfDefault.add(new OpToChange(uid, pkg.packageName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700499 }
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700500 }
501 } else if (permissionInfo.isSoftRestricted()) {
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700502 final SoftRestrictedPermissionPolicy policy =
503 SoftRestrictedPermissionPolicy.forPermission(mContext, pkg.applicationInfo,
Philip P. Moltmann69b645f2019-06-17 14:28:11 -0700504 mContext.getUser(), permission);
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700505
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700506 if (opCode != OP_NONE) {
507 if (policy.canBeGranted()) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700508 mOpsToAllowIfDefault.add(new OpToChange(uid, pkg.packageName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700509 } else {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700510 mOpsToDefault.add(new OpToChange(uid, pkg.packageName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700511 }
512 }
513
514 final int op = policy.resolveAppOp();
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700515 if (op != OP_NONE) {
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700516 switch (policy.getDesiredOpMode()) {
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700517 case MODE_DEFAULT:
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700518 mOpsToDefault.add(new OpToChange(uid, pkg.packageName, op));
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700519 break;
520 case MODE_ALLOWED:
521 if (policy.shouldSetAppOpIfNotDefault()) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700522 mOpsToAllow.add(new OpToChange(uid, pkg.packageName, op));
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700523 } else {
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700524 mOpsToAllowIfDefault.add(
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700525 new OpToChange(uid, pkg.packageName, op));
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700526 }
527 break;
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700528 case MODE_FOREGROUND:
529 Slog.wtf(LOG_TAG,
530 "Setting appop to foreground is not implemented");
531 break;
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700532 case MODE_IGNORED:
533 if (policy.shouldSetAppOpIfNotDefault()) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700534 mOpsToIgnore.add(new OpToChange(uid, pkg.packageName, op));
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700535 } else {
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700536 mOpsToIgnoreIfDefault.add(
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700537 new OpToChange(uid, pkg.packageName,
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700538 op));
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700539 }
540 break;
541 case MODE_ERRORED:
542 Slog.wtf(LOG_TAG, "Setting appop to errored is not implemented");
Svet Ganovd563e932019-04-14 13:07:41 -0700543 }
544 }
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700545 }
546 }
547
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700548 private boolean isBgPermRestricted(@NonNull String pkg, @NonNull String perm, int uid) {
549 try {
550 final PermissionInfo bgPermInfo = mPackageManager.getPermissionInfo(perm, 0);
551
552 if (bgPermInfo.isSoftRestricted()) {
553 Slog.wtf(LOG_TAG, "Support for soft restricted background permissions not "
554 + "implemented");
555 }
556
557 return bgPermInfo.isHardRestricted() && (mPackageManager.getPermissionFlags(
558 perm, pkg, UserHandle.getUserHandleForUid(uid))
559 & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
560 } catch (NameNotFoundException e) {
561 Slog.w(LOG_TAG, "Cannot read permission state of " + perm, e);
562 return false;
563 }
564 }
565
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700566 /**
567 * Add op that belong to a foreground permission for later processing in
568 * {@link #syncPackages()}.
569 *
570 * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
571 *
572 * @param permissionInfo The permission that is currently looked at
573 * @param pkg The package looked at
574 */
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700575 private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo,
576 @NonNull PackageInfo pkg) {
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700577 final String bgPermissionName = permissionInfo.backgroundPermission;
578
579 if (bgPermissionName == null) {
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700580 return;
581 }
582
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700583 final String permission = permissionInfo.name;
584 final int opCode = AppOpsManager.permissionToOpCode(permission);
585 final String pkgName = pkg.packageName;
586 final int uid = pkg.applicationInfo.uid;
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700587
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700588 // App does not support runtime permissions. Hence the state is encoded in the app-op.
589 // To not override unrecoverable state don't change app-op unless bg perm is reviewed.
590 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
591 // If the review is required for this permission, the grant state does not
592 // really matter. To have a stable state, don't change the app-op if review is still
593 // pending.
594 int flags = mPackageManager.getPermissionFlags(bgPermissionName,
595 pkg.packageName, UserHandle.getUserHandleForUid(uid));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700596
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700597 if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0
598 && isBgPermRestricted(pkgName, bgPermissionName, uid)) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700599 mOpsToForegroundIfAllow.add(new OpToChange(uid, pkgName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700600 }
601
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700602 return;
603 }
604
605 if (mPackageManager.checkPermission(permission, pkgName)
606 == PackageManager.PERMISSION_GRANTED) {
607 final boolean isBgHardRestricted = isBgPermRestricted(pkgName, bgPermissionName,
608 uid);
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700609 final boolean isBgPermGranted = mPackageManager.checkPermission(bgPermissionName,
610 pkgName) == PackageManager.PERMISSION_GRANTED;
611
612 if (!isBgHardRestricted && isBgPermGranted) {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700613 mOpsToAllow.add(new OpToChange(uid, pkgName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700614 } else {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700615 mOpsToForeground.add(new OpToChange(uid, pkgName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700616 }
617 } else {
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700618 mOpsToIgnore.add(new OpToChange(uid, pkgName, opCode));
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700619 }
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700620 }
621
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700622 /**
623 * Add a package for {@link #syncPackages() processing} later.
624 *
625 * <p>Note: Called with the package lock held. Do <u>not</u> call into app-op manager.
626 *
Philip P. Moltmann48687722019-04-11 10:40:30 -0700627 * @param pkgName The package to add for later processing.
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700628 */
Philip P. Moltmann48687722019-04-11 10:40:30 -0700629 void addPackage(@NonNull String pkgName) {
630 final PackageInfo pkg;
631 try {
632 pkg = mPackageManager.getPackageInfo(pkgName, GET_PERMISSIONS);
633 } catch (NameNotFoundException e) {
634 return;
635 }
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700636
Philip P. Moltmann48687722019-04-11 10:40:30 -0700637 mAllUids.put(pkg.applicationInfo.uid, pkg.applicationInfo.uid);
Svet Ganov38a06312019-04-09 23:55:05 -0700638
Philip P. Moltmann48687722019-04-11 10:40:30 -0700639 if (pkg.requestedPermissions == null) {
640 return;
641 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700642
Philip P. Moltmann48687722019-04-11 10:40:30 -0700643 for (String permission : pkg.requestedPermissions) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700644 final int opCode = AppOpsManager.permissionToOpCode(permission);
Philip P. Moltmannfaa788a2019-05-29 16:18:18 -0700645 if (opCode == OP_NONE) {
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700646 continue;
647 }
648
649 final PermissionInfo permissionInfo;
650 try {
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700651 permissionInfo = mPackageManager.getPermissionInfo(permission, 0);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700652 } catch (PackageManager.NameNotFoundException e) {
653 continue;
654 }
655
Philip P. Moltmann48687722019-04-11 10:40:30 -0700656 addOpIfRestricted(permissionInfo, pkg);
Philip P. Moltmann9408f582019-04-10 16:58:24 -0700657 addOpIfFgPermissions(permissionInfo, pkg);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700658 }
659 }
660
Svet Ganovd563e932019-04-14 13:07:41 -0700661 private void setUidModeAllowedIfDefault(int opCode, int uid, @NonNull String packageName) {
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700662 setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_ALLOWED, packageName);
Svet Ganovd563e932019-04-14 13:07:41 -0700663 }
664
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700665 private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
666 setUidMode(opCode, uid, MODE_ALLOWED, packageName);
Philip P. Moltmann74065c82019-05-15 10:46:32 -0700667 }
668
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700669 private void setUidModeForegroundIfAllow(int opCode, int uid, @NonNull String packageName) {
670 setUidModeIfMode(opCode, uid, MODE_ALLOWED, MODE_FOREGROUND, packageName);
671 }
672
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700673 private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
674 setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700675 }
676
Svet Ganovd563e932019-04-14 13:07:41 -0700677 private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700678 setUidModeIfMode(opCode, uid, MODE_DEFAULT, MODE_IGNORED, packageName);
Svet Ganovd563e932019-04-14 13:07:41 -0700679 }
680
Philip P. Moltmannfad1a8f2019-06-14 09:02:24 -0700681 private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
682 setUidMode(opCode, uid, MODE_IGNORED, packageName);
683 }
684
685 private void setUidMode(int opCode, int uid, int mode,
686 @NonNull String packageName) {
687 final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
688 .opToPublicName(opCode), uid, packageName);
689
690 if (currentMode != mode) {
691 mAppOpsManager.setUidMode(opCode, uid, mode);
692 }
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700693 }
694
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700695 private void setUidModeIfMode(int opCode, int uid, int requiredModeBefore, int newMode,
Svet Ganovd563e932019-04-14 13:07:41 -0700696 @NonNull String packageName) {
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700697 final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
Philip P. Moltmann78c155b2019-06-14 09:02:24 -0700698 .opToPublicName(opCode), uid, packageName);
Philip P. Moltmann404b51c2019-06-11 09:01:59 -0700699
Philip P. Moltmann4e369a72019-06-14 11:08:16 -0700700 if (currentMode == requiredModeBefore) {
701 mAppOpsManager.setUidMode(opCode, uid, newMode);
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700702 }
703 }
704
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700705 private void setUidModeDefault(int opCode, int uid, String packageName) {
706 setUidMode(opCode, uid, MODE_DEFAULT, packageName);
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700707 }
708
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700709 private class OpToChange {
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700710 final int uid;
711 final @NonNull String packageName;
712 final int code;
713
Philip P. Moltmanne9f4b5a2019-06-20 14:51:52 -0700714 OpToChange(int uid, @NonNull String packageName, int code) {
Philip P. Moltmannbd4943b2019-04-11 10:05:48 -0700715 this.uid = uid;
716 this.packageName = packageName;
717 this.code = code;
718 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700719 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700720 }
Hai Zhangf4da9be2019-05-01 13:46:06 +0800721
722 private class Internal extends PermissionPolicyInternal {
723
724 @Override
725 public boolean checkStartActivity(@NonNull Intent intent, int callingUid,
Hai Zhang639360a2019-05-20 15:35:33 -0700726 @Nullable String callingPackage) {
727 if (callingPackage != null && isActionRemovedForCallingPackage(intent.getAction(),
728 callingPackage)) {
Hai Zhangf4da9be2019-05-01 13:46:06 +0800729 Slog.w(LOG_TAG, "Action Removed: starting " + intent.toString() + " from "
730 + callingPackage + " (uid=" + callingUid + ")");
731 return false;
732 }
733 return true;
734 }
735
736 /**
737 * Check if the intent action is removed for the calling package (often based on target SDK
738 * version). If the action is removed, we'll silently cancel the activity launch.
739 */
740 private boolean isActionRemovedForCallingPackage(@Nullable String action,
741 @NonNull String callingPackage) {
742 if (action == null) {
743 return false;
744 }
745 switch (action) {
Hai Zhang114afc32019-05-01 14:16:23 +0800746 case TelecomManager.ACTION_CHANGE_DEFAULT_DIALER:
Hai Zhangf4da9be2019-05-01 13:46:06 +0800747 case Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT: {
748 ApplicationInfo applicationInfo;
749 try {
750 applicationInfo = getContext().getPackageManager().getApplicationInfo(
751 callingPackage, 0);
752 } catch (PackageManager.NameNotFoundException e) {
753 Slog.i(LOG_TAG, "Cannot find application info for " + callingPackage);
754 return false;
755 }
756 // Applications targeting Q should use RoleManager.createRequestRoleIntent()
757 // instead.
758 return applicationInfo.targetSdkVersion >= Build.VERSION_CODES.Q;
759 }
760 default:
761 return false;
762 }
763 }
764 }
Svet Ganovd8eb8b22019-04-05 18:52:08 -0700765}