blob: e883d25ab0bdf266dd46e1fbab3714289b5c1880 [file] [log] [blame]
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -08001/*
2 * Copyright (C) 2016 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 android.permission;
18
Philip P. Moltmann41df9f92019-02-08 13:07:57 -080019import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
20import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
21import static android.app.admin.DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
Philip P. Moltmanne1436e852019-01-31 14:22:39 -080022import static android.permission.PermissionControllerManager.COUNT_ONLY_WHEN_GRANTED;
23import static android.permission.PermissionControllerManager.COUNT_WHEN_SYSTEM;
24
Philip P. Moltmann78689522018-12-17 20:45:40 -080025import static com.android.internal.util.Preconditions.checkArgument;
Joel Galenson5f63b832018-12-19 15:38:04 -080026import static com.android.internal.util.Preconditions.checkArgumentNonnegative;
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -080027import static com.android.internal.util.Preconditions.checkCollectionElementsNotNull;
Philip P. Moltmanne1436e852019-01-31 14:22:39 -080028import static com.android.internal.util.Preconditions.checkFlagsArgument;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080029import static com.android.internal.util.Preconditions.checkNotNull;
Hai Zhang19821872019-01-23 16:48:40 -080030import static com.android.internal.util.Preconditions.checkStringNotEmpty;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080031import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
32
Philip P. Moltmannbc054d82018-12-21 09:41:58 -080033import android.Manifest;
Philip P. Moltmann7532c612019-01-20 09:01:19 -080034import android.annotation.BinderThread;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080035import android.annotation.NonNull;
36import android.annotation.SystemApi;
37import android.app.Service;
Philip P. Moltmann41df9f92019-02-08 13:07:57 -080038import android.app.admin.DevicePolicyManager.PermissionGrantState;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080039import android.content.Context;
40import android.content.Intent;
Philip P. Moltmann78689522018-12-17 20:45:40 -080041import android.content.pm.PackageInfo;
42import android.content.pm.PackageManager;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080043import android.os.Bundle;
44import android.os.Handler;
45import android.os.IBinder;
Philip P. Moltmann97142e22019-01-10 17:03:42 -080046import android.os.ParcelFileDescriptor;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080047import android.os.RemoteCallback;
Philip P. Moltmann97142e22019-01-10 17:03:42 -080048import android.os.UserHandle;
Philip P. Moltmanne1436e852019-01-31 14:22:39 -080049import android.permission.PermissionControllerManager.CountPermissionAppsFlag;
Philip P. Moltmann78689522018-12-17 20:45:40 -080050import android.util.ArrayMap;
Philip P. Moltmann97142e22019-01-10 17:03:42 -080051import android.util.Log;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080052
Philip P. Moltmann78689522018-12-17 20:45:40 -080053import com.android.internal.util.Preconditions;
54
Philip P. Moltmann97142e22019-01-10 17:03:42 -080055import java.io.IOException;
Philip P. Moltmann7532c612019-01-20 09:01:19 -080056import java.io.InputStream;
Philip P. Moltmann97142e22019-01-10 17:03:42 -080057import java.io.OutputStream;
Philip P. Moltmann78689522018-12-17 20:45:40 -080058import java.util.ArrayList;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080059import java.util.List;
Philip P. Moltmann78689522018-12-17 20:45:40 -080060import java.util.Map;
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080061
62/**
Philip P. Moltmannbc054d82018-12-21 09:41:58 -080063 * This service is meant to be implemented by the app controlling permissions.
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080064 *
Philip P. Moltmann9b12e372019-01-20 09:01:19 -080065 * @see PermissionControllerManager
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080066 *
67 * @hide
68 */
69@SystemApi
Philip P. Moltmannbc054d82018-12-21 09:41:58 -080070public abstract class PermissionControllerService extends Service {
Philip P. Moltmann97142e22019-01-10 17:03:42 -080071 private static final String LOG_TAG = PermissionControllerService.class.getSimpleName();
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080072
73 /**
74 * The {@link Intent} action that must be declared as handled by a service
75 * in its manifest for the system to recognize it as a runtime permission
76 * presenter service.
77 */
Philip P. Moltmannbc054d82018-12-21 09:41:58 -080078 public static final String SERVICE_INTERFACE = "android.permission.PermissionControllerService";
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -080079
80 // No need for locking - always set first and never modified
81 private Handler mHandler;
82
83 @Override
84 public final void attachBaseContext(Context base) {
85 super.attachBaseContext(base);
86 mHandler = new Handler(base.getMainLooper());
87 }
88
89 /**
Philip P. Moltmann78689522018-12-17 20:45:40 -080090 * Revoke a set of runtime permissions for various apps.
91 *
92 * @param requests The permissions to revoke as {@code Map<packageName, List<permission>>}
93 * @param doDryRun Compute the permissions that would be revoked, but not actually revoke them
94 * @param reason Why the permission should be revoked
95 * @param callerPackageName The package name of the calling app
96 *
97 * @return the actually removed permissions as {@code Map<packageName, List<permission>>}
98 */
99 public abstract @NonNull Map<String, List<String>> onRevokeRuntimePermissions(
100 @NonNull Map<String, List<String>> requests, boolean doDryRun,
101 @PermissionControllerManager.Reason int reason, @NonNull String callerPackageName);
102
103 /**
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800104 * Create a backup of the runtime permissions.
105 *
106 * @param user The user to back up
Philip P. Moltmann9b12e372019-01-20 09:01:19 -0800107 * @param backup The stream to write the backup to
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800108 */
109 public abstract void onGetRuntimePermissionsBackup(@NonNull UserHandle user,
Philip P. Moltmann9b12e372019-01-20 09:01:19 -0800110 @NonNull OutputStream backup);
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800111
112 /**
Philip P. Moltmann7532c612019-01-20 09:01:19 -0800113 * Restore a backup of the runtime permissions.
114 *
115 * @param user The user to restore
116 * @param backup The stream to read the backup from
117 */
118 @BinderThread
119 public abstract void onRestoreRuntimePermissionsBackup(@NonNull UserHandle user,
120 @NonNull InputStream backup);
121
122 /**
123 * Restore a delayed backup of the runtime permissions.
124 *
125 * @param packageName The app to restore
126 * @param user The user to restore
127 *
128 * @return {@code true} iff there is still delayed backup left
129 */
130 @BinderThread
131 public abstract boolean onRestoreDelayedRuntimePermissionsBackup(@NonNull String packageName,
132 @NonNull UserHandle user);
133
134 /**
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800135 * Gets the runtime permissions for an app.
136 *
137 * @param packageName The package for which to query.
138 *
139 * @return descriptions of the runtime permissions of the app
140 */
141 public abstract @NonNull List<RuntimePermissionPresentationInfo> onGetAppPermissions(
142 @NonNull String packageName);
143
144 /**
145 * Revokes the permission {@code permissionName} for app {@code packageName}
146 *
147 * @param packageName The package for which to revoke
148 * @param permissionName The permission to revoke
149 */
150 public abstract void onRevokeRuntimePermission(@NonNull String packageName,
151 @NonNull String permissionName);
152
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800153 /**
154 * Count how many apps have one of a set of permissions.
155 *
156 * @param permissionNames The permissions the app might have
Philip P. Moltmanne1436e852019-01-31 14:22:39 -0800157 * @param flags Modify which apps to count. By default all non-system apps that request a
158 * permission are counted
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800159 *
160 * @return the number of apps that have one of the permissions
161 */
162 public abstract int onCountPermissionApps(@NonNull List<String> permissionNames,
Philip P. Moltmanne1436e852019-01-31 14:22:39 -0800163 @CountPermissionAppsFlag int flags);
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800164
Joel Galenson5f63b832018-12-19 15:38:04 -0800165 /**
166 * Count how many apps have used permissions.
167 *
168 * @param countSystem Also count system apps
169 * @param numMillis The number of milliseconds in the past to check for uses
170 *
171 * @return descriptions of the users of permissions
172 */
Hai Zhang19821872019-01-23 16:48:40 -0800173 public abstract @NonNull List<RuntimePermissionUsageInfo> onGetPermissionUsages(
174 boolean countSystem, long numMillis);
175
176 /**
177 * Check whether an application is qualified for a role.
178 *
179 * @param roleName name of the role to check for
180 * @param packageName package name of the application to check for
181 *
182 * @return whether the application is qualified for the role.
183 */
184 public abstract boolean onIsApplicationQualifiedForRole(@NonNull String roleName,
185 @NonNull String packageName);
Joel Galenson5f63b832018-12-19 15:38:04 -0800186
Philip P. Moltmann41df9f92019-02-08 13:07:57 -0800187 /**
188 * Set the runtime permission state from a device admin.
189 *
190 * @param callerPackageName The package name of the admin requesting the change
191 * @param packageName Package the permission belongs to
192 * @param permission Permission to change
193 * @param grantState State to set the permission into
194 */
195 public abstract boolean onSetRuntimePermissionGrantStateByDeviceAdmin(
196 @NonNull String callerPackageName, @NonNull String packageName,
197 @NonNull String permission, @PermissionGrantState int grantState);
198
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800199 @Override
200 public final IBinder onBind(Intent intent) {
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800201 return new IPermissionController.Stub() {
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800202 @Override
Philip P. Moltmann78689522018-12-17 20:45:40 -0800203 public void revokeRuntimePermissions(
204 Bundle bundleizedRequest, boolean doDryRun, int reason,
205 String callerPackageName, RemoteCallback callback) {
206 checkNotNull(bundleizedRequest, "bundleizedRequest");
207 checkNotNull(callerPackageName);
208 checkNotNull(callback);
209
210 Map<String, List<String>> request = new ArrayMap<>();
211 for (String packageName : bundleizedRequest.keySet()) {
212 Preconditions.checkNotNull(packageName);
213
214 ArrayList<String> permissions =
215 bundleizedRequest.getStringArrayList(packageName);
216 Preconditions.checkCollectionElementsNotNull(permissions, "permissions");
217
218 request.put(packageName, permissions);
219 }
220
221 enforceCallingPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, null);
222
223 // Verify callerPackageName
224 try {
225 PackageInfo pkgInfo = getPackageManager().getPackageInfo(callerPackageName, 0);
226 checkArgument(getCallingUid() == pkgInfo.applicationInfo.uid);
227 } catch (PackageManager.NameNotFoundException e) {
228 throw new RuntimeException(e);
229 }
230
231 mHandler.sendMessage(obtainMessage(
232 PermissionControllerService::revokeRuntimePermissions,
233 PermissionControllerService.this, request, doDryRun, reason,
234 callerPackageName, callback));
235 }
236
237 @Override
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800238 public void getRuntimePermissionBackup(UserHandle user, ParcelFileDescriptor pipe) {
239 checkNotNull(user);
240 checkNotNull(pipe);
241
242 enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
243
244 mHandler.sendMessage(obtainMessage(
245 PermissionControllerService::getRuntimePermissionsBackup,
246 PermissionControllerService.this, user, pipe));
247 }
248
249 @Override
Philip P. Moltmann7532c612019-01-20 09:01:19 -0800250 public void restoreRuntimePermissionBackup(UserHandle user, ParcelFileDescriptor pipe) {
251 checkNotNull(user);
252 checkNotNull(pipe);
253
254 enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);
255
256 try (InputStream backup = new ParcelFileDescriptor.AutoCloseInputStream(pipe)) {
257 onRestoreRuntimePermissionsBackup(user, backup);
258 } catch (IOException e) {
259 Log.e(LOG_TAG, "Could not open pipe to read backup from", e);
260 }
261 }
262
263 @Override
264 public void restoreDelayedRuntimePermissionBackup(String packageName, UserHandle user,
265 RemoteCallback callback) {
266 checkNotNull(packageName);
267 checkNotNull(user);
268 checkNotNull(callback);
269
270 enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);
271
272 boolean hasMoreBackup = onRestoreDelayedRuntimePermissionsBackup(packageName, user);
273
274 Bundle result = new Bundle();
275 result.putBoolean(PermissionControllerManager.KEY_RESULT, hasMoreBackup);
276 callback.sendResult(result);
277 }
278
279 @Override
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800280 public void getAppPermissions(String packageName, RemoteCallback callback) {
281 checkNotNull(packageName, "packageName");
282 checkNotNull(callback, "callback");
283
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800284 enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
285
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800286 mHandler.sendMessage(
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800287 obtainMessage(PermissionControllerService::getAppPermissions,
288 PermissionControllerService.this, packageName, callback));
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800289 }
290
291 @Override
292 public void revokeRuntimePermission(String packageName, String permissionName) {
293 checkNotNull(packageName, "packageName");
294 checkNotNull(permissionName, "permissionName");
295
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800296 enforceCallingPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, null);
297
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800298 mHandler.sendMessage(
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800299 obtainMessage(PermissionControllerService::onRevokeRuntimePermission,
300 PermissionControllerService.this, packageName, permissionName));
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800301 }
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800302
303 @Override
Philip P. Moltmanne1436e852019-01-31 14:22:39 -0800304 public void countPermissionApps(List<String> permissionNames, int flags,
305 RemoteCallback callback) {
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800306 checkCollectionElementsNotNull(permissionNames, "permissionNames");
Philip P. Moltmanne1436e852019-01-31 14:22:39 -0800307 checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED);
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800308 checkNotNull(callback, "callback");
309
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800310 enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
311
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800312 mHandler.sendMessage(
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800313 obtainMessage(PermissionControllerService::countPermissionApps,
Philip P. Moltmanne1436e852019-01-31 14:22:39 -0800314 PermissionControllerService.this, permissionNames, flags,
315 callback));
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800316 }
Joel Galenson5f63b832018-12-19 15:38:04 -0800317
318 @Override
319 public void getPermissionUsages(boolean countSystem, long numMillis,
320 RemoteCallback callback) {
321 checkArgumentNonnegative(numMillis);
322 checkNotNull(callback, "callback");
323
324 enforceCallingPermission(Manifest.permission.GET_RUNTIME_PERMISSIONS, null);
325
326 mHandler.sendMessage(
327 obtainMessage(PermissionControllerService::getPermissionUsages,
328 PermissionControllerService.this, countSystem, numMillis,
329 callback));
330 }
Hai Zhang19821872019-01-23 16:48:40 -0800331
332 @Override
333 public void isApplicationQualifiedForRole(String roleName, String packageName,
334 RemoteCallback callback) {
335 checkStringNotEmpty(roleName);
336 checkStringNotEmpty(packageName);
337 checkNotNull(callback, "callback");
338
339 enforceCallingPermission(Manifest.permission.MANAGE_ROLE_HOLDERS, null);
340
341 mHandler.sendMessage(obtainMessage(
342 PermissionControllerService::isApplicationQualifiedForRole,
343 PermissionControllerService.this, roleName, packageName, callback));
344 }
Philip P. Moltmann41df9f92019-02-08 13:07:57 -0800345
346 @Override
347 public void setRuntimePermissionGrantStateByDeviceAdmin(String callerPackageName,
348 String packageName, String permission, int grantState,
349 RemoteCallback callback) {
350 checkStringNotEmpty(callerPackageName);
351 checkStringNotEmpty(packageName);
352 checkStringNotEmpty(permission);
353 checkArgument(grantState == PERMISSION_GRANT_STATE_GRANTED
354 || grantState == PERMISSION_GRANT_STATE_DENIED
355 || grantState == PERMISSION_GRANT_STATE_DEFAULT);
356 checkNotNull(callback);
357
358 if (grantState == PERMISSION_GRANT_STATE_DENIED) {
359 enforceCallingPermission(Manifest.permission.GRANT_RUNTIME_PERMISSIONS, null);
360 }
361
362 if (grantState == PERMISSION_GRANT_STATE_DENIED) {
363 enforceCallingPermission(Manifest.permission.REVOKE_RUNTIME_PERMISSIONS, null);
364 }
365
366 enforceCallingPermission(Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
367 null);
368
369 mHandler.sendMessage(obtainMessage(
370 PermissionControllerService::setRuntimePermissionGrantStateByDeviceAdmin,
371 PermissionControllerService.this, callerPackageName, packageName,
372 permission, grantState, callback));
373 }
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800374 };
375 }
376
Philip P. Moltmann78689522018-12-17 20:45:40 -0800377 private void revokeRuntimePermissions(@NonNull Map<String, List<String>> requests,
378 boolean doDryRun, @PermissionControllerManager.Reason int reason,
379 @NonNull String callerPackageName, @NonNull RemoteCallback callback) {
380 Map<String, List<String>> revoked = onRevokeRuntimePermissions(requests,
381 doDryRun, reason, callerPackageName);
382
383 checkNotNull(revoked);
384 Bundle bundledizedRevoked = new Bundle();
385 for (Map.Entry<String, List<String>> appRevocation : revoked.entrySet()) {
386 checkNotNull(appRevocation.getKey());
387 checkCollectionElementsNotNull(appRevocation.getValue(), "permissions");
388
389 bundledizedRevoked.putStringArrayList(appRevocation.getKey(),
390 new ArrayList<>(appRevocation.getValue()));
391 }
392
393 Bundle result = new Bundle();
394 result.putBundle(PermissionControllerManager.KEY_RESULT, bundledizedRevoked);
395 callback.sendResult(result);
396 }
397
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800398 private void getRuntimePermissionsBackup(@NonNull UserHandle user,
Philip P. Moltmann9b12e372019-01-20 09:01:19 -0800399 @NonNull ParcelFileDescriptor backupFile) {
400 try (OutputStream backup = new ParcelFileDescriptor.AutoCloseOutputStream(backupFile)) {
401 onGetRuntimePermissionsBackup(user, backup);
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800402 } catch (IOException e) {
Philip P. Moltmann9b12e372019-01-20 09:01:19 -0800403 Log.e(LOG_TAG, "Could not open pipe to write backup to", e);
Philip P. Moltmann97142e22019-01-10 17:03:42 -0800404 }
405 }
406
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800407 private void getAppPermissions(@NonNull String packageName, @NonNull RemoteCallback callback) {
408 List<RuntimePermissionPresentationInfo> permissions = onGetAppPermissions(packageName);
409 if (permissions != null && !permissions.isEmpty()) {
410 Bundle result = new Bundle();
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800411 result.putParcelableList(PermissionControllerManager.KEY_RESULT, permissions);
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800412 callback.sendResult(result);
413 } else {
414 callback.sendResult(null);
415 }
416 }
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800417
418 private void countPermissionApps(@NonNull List<String> permissionNames,
Philip P. Moltmanne1436e852019-01-31 14:22:39 -0800419 @CountPermissionAppsFlag int flags, @NonNull RemoteCallback callback) {
420 int numApps = onCountPermissionApps(permissionNames, flags);
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800421
422 Bundle result = new Bundle();
Philip P. Moltmannbc054d82018-12-21 09:41:58 -0800423 result.putInt(PermissionControllerManager.KEY_RESULT, numApps);
Philip P. Moltmann08cac8e2018-12-04 15:09:59 -0800424 callback.sendResult(result);
425 }
Joel Galenson5f63b832018-12-19 15:38:04 -0800426
427 private void getPermissionUsages(boolean countSystem, long numMillis,
428 @NonNull RemoteCallback callback) {
429 List<RuntimePermissionUsageInfo> users =
Hai Zhang19821872019-01-23 16:48:40 -0800430 onGetPermissionUsages(countSystem, numMillis);
Joel Galenson5f63b832018-12-19 15:38:04 -0800431 if (users != null && !users.isEmpty()) {
432 Bundle result = new Bundle();
433 result.putParcelableList(PermissionControllerManager.KEY_RESULT, users);
434 callback.sendResult(result);
435 } else {
436 callback.sendResult(null);
437 }
438 }
Hai Zhang19821872019-01-23 16:48:40 -0800439
440 private void isApplicationQualifiedForRole(@NonNull String roleName,
441 @NonNull String packageName, @NonNull RemoteCallback callback) {
442 boolean qualified = onIsApplicationQualifiedForRole(roleName, packageName);
443 Bundle result = new Bundle();
444 result.putBoolean(PermissionControllerManager.KEY_RESULT, qualified);
445 callback.sendResult(result);
446 }
Philip P. Moltmann41df9f92019-02-08 13:07:57 -0800447
448 private void setRuntimePermissionGrantStateByDeviceAdmin(@NonNull String callerPackageName,
449 @NonNull String packageName, @NonNull String permission,
450 @PermissionGrantState int grantState, @NonNull RemoteCallback callback) {
451 boolean wasSet = onSetRuntimePermissionGrantStateByDeviceAdmin(callerPackageName,
452 packageName, permission, grantState);
453
454 Bundle result = new Bundle();
455 result.putBoolean(PermissionControllerManager.KEY_RESULT, wasSet);
456 callback.sendResult(result);
457 }
Philip P. Moltmanndbf78b82018-12-04 13:44:27 -0800458}