blob: 9cd6b0d32793760570392275f76467cb54db08ec [file] [log] [blame]
Hai Zhangb7776682018-09-25 15:10:57 -07001/*
2 * Copyright (C) 2018 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.role;
18
19import android.Manifest;
20import android.annotation.CheckResult;
Eugene Suslad469fc12018-11-20 17:09:07 -080021import android.annotation.MainThread;
Hai Zhangb7776682018-09-25 15:10:57 -070022import android.annotation.NonNull;
23import android.annotation.Nullable;
24import android.annotation.UserIdInt;
Hai Zhang31d06ba2018-12-06 18:14:42 -080025import android.annotation.WorkerThread;
Hai Zhangb7776682018-09-25 15:10:57 -070026import android.app.ActivityManager;
27import android.app.AppOpsManager;
Hai Zhang31d06ba2018-12-06 18:14:42 -080028import android.app.role.IOnRoleHoldersChangedListener;
Hai Zhangb7776682018-09-25 15:10:57 -070029import android.app.role.IRoleManager;
Hai Zhanga4959e52019-03-06 12:21:07 -080030import android.app.role.RoleControllerManager;
Hai Zhangb7776682018-09-25 15:10:57 -070031import android.app.role.RoleManager;
32import android.content.BroadcastReceiver;
33import android.content.Context;
34import android.content.Intent;
35import android.content.IntentFilter;
Hongming Jin08496b02019-01-25 13:41:52 -080036import android.content.PermissionChecker;
37import android.content.pm.PackageManager;
38import android.content.pm.PackageManager.NameNotFoundException;
Eugene Suslaabdefba2018-11-09 18:06:43 -080039import android.content.pm.PackageManagerInternal;
40import android.content.pm.Signature;
Hongming Jin08496b02019-01-25 13:41:52 -080041import android.database.CursorWindow;
Eugene Susla4ab95112018-12-17 14:45:11 -080042import android.os.Binder;
Hongming Jin08496b02019-01-25 13:41:52 -080043import android.os.Bundle;
Hai Zhang31d06ba2018-12-06 18:14:42 -080044import android.os.Handler;
Hongming Jin08496b02019-01-25 13:41:52 -080045import android.os.RemoteCallback;
Hai Zhang31d06ba2018-12-06 18:14:42 -080046import android.os.RemoteCallbackList;
47import android.os.RemoteException;
Jeff Sharkey6260c582018-11-27 13:05:15 -070048import android.os.ResultReceiver;
49import android.os.ShellCallback;
Hai Zhangb7776682018-09-25 15:10:57 -070050import android.os.UserHandle;
51import android.os.UserManagerInternal;
Hongming Jin08496b02019-01-25 13:41:52 -080052import android.service.sms.FinancialSmsService;
53import android.telephony.IFinancialSmsCallback;
Hai Zhangb7776682018-09-25 15:10:57 -070054import android.text.TextUtils;
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -080055import android.util.ArrayMap;
Hai Zhangb7776682018-09-25 15:10:57 -070056import android.util.ArraySet;
Eugene Suslaabdefba2018-11-09 18:06:43 -080057import android.util.PackageUtils;
Hai Zhangb7776682018-09-25 15:10:57 -070058import android.util.Slog;
59import android.util.SparseArray;
Hai Zhang33456fb2018-12-05 17:30:35 -080060import android.util.proto.ProtoOutputStream;
Hai Zhangb7776682018-09-25 15:10:57 -070061
62import com.android.internal.annotations.GuardedBy;
Hai Zhang33456fb2018-12-05 17:30:35 -080063import com.android.internal.util.ArrayUtils;
Eugene Suslaabdefba2018-11-09 18:06:43 -080064import com.android.internal.util.BitUtils;
65import com.android.internal.util.CollectionUtils;
Hai Zhang33456fb2018-12-05 17:30:35 -080066import com.android.internal.util.DumpUtils;
Eugene Suslaabdefba2018-11-09 18:06:43 -080067import com.android.internal.util.FunctionalUtils;
Hai Zhang33456fb2018-12-05 17:30:35 -080068import com.android.internal.util.IndentingPrintWriter;
Hai Zhangb7776682018-09-25 15:10:57 -070069import com.android.internal.util.Preconditions;
Hai Zhang33456fb2018-12-05 17:30:35 -080070import com.android.internal.util.dump.DualDumpOutputStream;
Hai Zhang31d06ba2018-12-06 18:14:42 -080071import com.android.internal.util.function.pooled.PooledLambda;
72import com.android.server.FgThread;
Hai Zhangb7776682018-09-25 15:10:57 -070073import com.android.server.LocalServices;
74import com.android.server.SystemService;
75
Eugene Suslaabdefba2018-11-09 18:06:43 -080076import java.io.ByteArrayOutputStream;
Jeff Sharkey6260c582018-11-27 13:05:15 -070077import java.io.FileDescriptor;
Hai Zhang33456fb2018-12-05 17:30:35 -080078import java.io.PrintWriter;
Hai Zhangb7776682018-09-25 15:10:57 -070079import java.util.ArrayList;
80import java.util.Collections;
81import java.util.List;
Hai Zhang458cedb2018-12-03 15:41:11 -080082import java.util.Objects;
Eugene Suslaa4200f822018-11-09 18:06:43 -080083import java.util.concurrent.CompletableFuture;
84import java.util.concurrent.ExecutionException;
85import java.util.concurrent.TimeUnit;
86import java.util.concurrent.TimeoutException;
Winson Chungb41314b2019-04-04 16:24:59 -070087import java.util.function.Consumer;
Hai Zhangb7776682018-09-25 15:10:57 -070088
89/**
90 * Service for role management.
91 *
92 * @see RoleManager
93 */
Hai Zhang31d06ba2018-12-06 18:14:42 -080094public class RoleManagerService extends SystemService implements RoleUserState.Callback {
Hai Zhangb7776682018-09-25 15:10:57 -070095
96 private static final String LOG_TAG = RoleManagerService.class.getSimpleName();
97
Hai Zhanga4959e52019-03-06 12:21:07 -080098 private static final boolean DEBUG = false;
99
Hai Zhangb7776682018-09-25 15:10:57 -0700100 @NonNull
101 private final UserManagerInternal mUserManagerInternal;
102 @NonNull
103 private final AppOpsManager mAppOpsManager;
104
105 @NonNull
106 private final Object mLock = new Object();
107
Eugene Susla4ab95112018-12-17 14:45:11 -0800108 @NonNull
109 private final RoleHoldersResolver mLegacyRoleResolver;
110
111 /** @see #getRoleHolders(String, int) */
112 public interface RoleHoldersResolver {
113 /** @return a list of packages that hold a given role for a given user */
Hai Zhang8be463f2019-02-11 16:44:45 -0800114 @NonNull
115 List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId);
Eugene Susla4ab95112018-12-17 14:45:11 -0800116 }
117
Hai Zhangb7776682018-09-25 15:10:57 -0700118 /**
119 * Maps user id to its state.
120 */
121 @GuardedBy("mLock")
122 @NonNull
123 private final SparseArray<RoleUserState> mUserStates = new SparseArray<>();
124
125 /**
Hai Zhanga4959e52019-03-06 12:21:07 -0800126 * Maps user id to its controller.
Hai Zhangb7776682018-09-25 15:10:57 -0700127 */
128 @GuardedBy("mLock")
129 @NonNull
Hai Zhanga4959e52019-03-06 12:21:07 -0800130 private final SparseArray<RoleControllerManager> mControllers = new SparseArray<>();
Hai Zhangb7776682018-09-25 15:10:57 -0700131
Hai Zhang31d06ba2018-12-06 18:14:42 -0800132 /**
133 * Maps user id to its list of listeners.
134 */
135 @GuardedBy("mLock")
136 @NonNull
137 private final SparseArray<RemoteCallbackList<IOnRoleHoldersChangedListener>> mListeners =
138 new SparseArray<>();
139
140 @NonNull
141 private final Handler mListenerHandler = FgThread.getHandler();
142
Eugene Susla4ab95112018-12-17 14:45:11 -0800143 public RoleManagerService(@NonNull Context context,
144 @NonNull RoleHoldersResolver legacyRoleResolver) {
Hai Zhangb7776682018-09-25 15:10:57 -0700145 super(context);
146
Eugene Susla4ab95112018-12-17 14:45:11 -0800147 mLegacyRoleResolver = legacyRoleResolver;
148
Hai Zhang48f36c62019-04-12 21:37:21 +0800149 RoleControllerManager.initializeRemoteServiceComponentName(context);
150
Hai Zhangb7776682018-09-25 15:10:57 -0700151 mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
152 mAppOpsManager = context.getSystemService(AppOpsManager.class);
153
Hai Zhang85fd0622019-02-01 14:06:04 -0800154 LocalServices.addService(RoleManagerInternal.class, new Internal());
155
156 PackageManagerInternal packageManagerInternal = LocalServices.getService(
157 PackageManagerInternal.class);
158 packageManagerInternal.setDefaultBrowserProvider(new DefaultBrowserProvider());
Hai Zhangc1399272019-05-07 15:50:58 -0700159 packageManagerInternal.setDefaultDialerProvider(new DefaultDialerProvider());
Hai Zhang8be463f2019-02-11 16:44:45 -0800160 packageManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800161
Hai Zhangb7776682018-09-25 15:10:57 -0700162 registerUserRemovedReceiver();
163 }
164
165 private void registerUserRemovedReceiver() {
166 IntentFilter intentFilter = new IntentFilter();
167 intentFilter.addAction(Intent.ACTION_USER_REMOVED);
168 getContext().registerReceiverAsUser(new BroadcastReceiver() {
169 @Override
Hai Zhang458cedb2018-12-03 15:41:11 -0800170 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Hai Zhangb7776682018-09-25 15:10:57 -0700171 if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) {
172 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
173 onRemoveUser(userId);
174 }
175 }
176 }, UserHandle.ALL, intentFilter, null, null);
177 }
178
179 @Override
180 public void onStart() {
181 publishBinderService(Context.ROLE_SERVICE, new Stub());
Eugene Suslad469fc12018-11-20 17:09:07 -0800182
Eugene Susla6d4922722018-11-08 16:25:28 -0800183 //TODO add watch for new user creation and run default grants for them
Eugene Suslad469fc12018-11-20 17:09:07 -0800184
185 IntentFilter intentFilter = new IntentFilter();
186 intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
187 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
188 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
189 intentFilter.addDataScheme("package");
190 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
191 getContext().registerReceiverAsUser(new BroadcastReceiver() {
192 @Override
193 public void onReceive(Context context, Intent intent) {
194 int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1));
Hai Zhanga4959e52019-03-06 12:21:07 -0800195 if (DEBUG) {
196 Slog.i(LOG_TAG, "Packages changed - re-running initial grants for user "
197 + userId);
Eugene Suslad469fc12018-11-20 17:09:07 -0800198 }
Eugene Susla84ee5572019-04-04 10:07:33 -0700199 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
200 && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
201 // Package is being upgraded - we're about to get ACTION_PACKAGE_ADDED
202 return;
203 }
Hai Zhang22ce5e52019-04-18 12:08:30 +0800204 performInitialGrantsIfNecessaryAsync(userId);
Eugene Suslad469fc12018-11-20 17:09:07 -0800205 }
Hai Zhanga5d86322019-02-15 18:06:51 -0800206 }, UserHandle.ALL, intentFilter, null, null);
Hai Zhangb7776682018-09-25 15:10:57 -0700207 }
208
209 @Override
210 public void onStartUser(@UserIdInt int userId) {
Eugene Suslad469fc12018-11-20 17:09:07 -0800211 performInitialGrantsIfNecessary(userId);
212 }
213
Eugene Susla84ee5572019-04-04 10:07:33 -0700214 private CompletableFuture<Void> performInitialGrantsIfNecessaryAsync(@UserIdInt int userId) {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800215 RoleUserState userState;
Hai Zhangcdc85c52018-12-06 13:56:55 -0800216 userState = getOrCreateUserState(userId);
Eugene Susla4ab95112018-12-17 14:45:11 -0800217
Eugene Suslaabdefba2018-11-09 18:06:43 -0800218 String packagesHash = computeComponentStateHash(userId);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800219 String oldPackagesHash = userState.getPackagesHash();
Hai Zhang33456fb2018-12-05 17:30:35 -0800220 boolean needGrant = !Objects.equals(packagesHash, oldPackagesHash);
Eugene Suslaabdefba2018-11-09 18:06:43 -0800221 if (needGrant) {
Eugene Susla4ab95112018-12-17 14:45:11 -0800222
223 //TODO gradually add more role migrations statements here for remaining roles
224 // Make sure to implement LegacyRoleResolutionPolicy#getRoleHolders
225 // for a given role before adding a migration statement for it here
226 migrateRoleIfNecessary(RoleManager.ROLE_SMS, userId);
Philip P. Moltmann5d894502019-01-17 10:31:00 -0800227 migrateRoleIfNecessary(RoleManager.ROLE_ASSISTANT, userId);
Eugene Susla92b88c72019-01-11 13:31:20 -0800228 migrateRoleIfNecessary(RoleManager.ROLE_DIALER, userId);
Hongming Jin910cd7b2019-01-23 11:19:07 -0800229 migrateRoleIfNecessary(RoleManager.ROLE_EMERGENCY, userId);
Eugene Susla4ab95112018-12-17 14:45:11 -0800230
Eugene Suslaabdefba2018-11-09 18:06:43 -0800231 // Some vital packages state has changed since last role grant
232 // Run grants again
Eugene Susla6d4922722018-11-08 16:25:28 -0800233 Slog.i(LOG_TAG, "Granting default permissions...");
Eugene Suslaa4200f822018-11-09 18:06:43 -0800234 CompletableFuture<Void> result = new CompletableFuture<>();
Hai Zhang48f36c62019-04-12 21:37:21 +0800235 getOrCreateController(userId).grantDefaultRoles(FgThread.getExecutor(),
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800236 successful -> {
237 if (successful) {
Eugene Susla84ee5572019-04-04 10:07:33 -0700238 userState.setPackagesHash(packagesHash);
Eugene Suslaa4200f822018-11-09 18:06:43 -0800239 result.complete(null);
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800240 } else {
Eugene Suslaa4200f822018-11-09 18:06:43 -0800241 result.completeExceptionally(new RuntimeException());
242 }
243 });
Eugene Susla84ee5572019-04-04 10:07:33 -0700244 return result;
Hai Zhanga4959e52019-03-06 12:21:07 -0800245 } else if (DEBUG) {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800246 Slog.i(LOG_TAG, "Already ran grants for package state " + packagesHash);
Hai Zhangb7776682018-09-25 15:10:57 -0700247 }
Eugene Susla84ee5572019-04-04 10:07:33 -0700248 return CompletableFuture.completedFuture(null);
249 }
250
251 @MainThread
252 private void performInitialGrantsIfNecessary(@UserIdInt int userId) {
253 CompletableFuture<Void> result = performInitialGrantsIfNecessaryAsync(userId);
254 try {
255 result.get(30, TimeUnit.SECONDS);
256 } catch (InterruptedException | ExecutionException | TimeoutException e) {
257 Slog.e(LOG_TAG, "Failed to grant defaults for user " + userId, e);
258 }
Hai Zhangb7776682018-09-25 15:10:57 -0700259 }
260
Eugene Susla4ab95112018-12-17 14:45:11 -0800261 private void migrateRoleIfNecessary(String role, @UserIdInt int userId) {
262 // Any role for which we have a record are already migrated
263 RoleUserState userState = getOrCreateUserState(userId);
264 if (!userState.isRoleAvailable(role)) {
Eugene Susla4ab95112018-12-17 14:45:11 -0800265 List<String> roleHolders = mLegacyRoleResolver.getRoleHolders(role, userId);
Hai Zhang7876adb2019-01-15 21:18:41 -0800266 if (roleHolders.isEmpty()) {
267 return;
268 }
Eugene Susla4ab95112018-12-17 14:45:11 -0800269 Slog.i(LOG_TAG, "Migrating " + role + ", legacy holders: " + roleHolders);
Hai Zhang7876adb2019-01-15 21:18:41 -0800270 userState.addRoleName(role);
Eugene Susla4ab95112018-12-17 14:45:11 -0800271 int size = roleHolders.size();
272 for (int i = 0; i < size; i++) {
273 userState.addRoleHolder(role, roleHolders.get(i));
274 }
275 }
276 }
277
Hai Zhang458cedb2018-12-03 15:41:11 -0800278 @Nullable
Hai Zhang31d06ba2018-12-06 18:14:42 -0800279 private static String computeComponentStateHash(@UserIdInt int userId) {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800280 PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
281 ByteArrayOutputStream out = new ByteArrayOutputStream();
282
Hai Zhangeb8b4602019-05-22 13:04:12 -0700283 pm.forEachInstalledPackage(FunctionalUtils.uncheckExceptions(pkg -> {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800284 out.write(pkg.packageName.getBytes());
285 out.write(BitUtils.toBytes(pkg.getLongVersionCode()));
286 out.write(pm.getApplicationEnabledState(pkg.packageName, userId));
287
288 ArraySet<String> enabledComponents =
289 pm.getEnabledComponents(pkg.packageName, userId);
290 int numComponents = CollectionUtils.size(enabledComponents);
Hai Zhangeb8b4602019-05-22 13:04:12 -0700291 out.write(numComponents);
Eugene Suslaabdefba2018-11-09 18:06:43 -0800292 for (int i = 0; i < numComponents; i++) {
293 out.write(enabledComponents.valueAt(i).getBytes());
294 }
295
296 ArraySet<String> disabledComponents =
297 pm.getDisabledComponents(pkg.packageName, userId);
298 numComponents = CollectionUtils.size(disabledComponents);
299 for (int i = 0; i < numComponents; i++) {
300 out.write(disabledComponents.valueAt(i).getBytes());
301 }
302 for (Signature signature : pkg.mSigningDetails.signatures) {
303 out.write(signature.toByteArray());
304 }
Hai Zhangeb8b4602019-05-22 13:04:12 -0700305 }), userId);
Eugene Suslaabdefba2018-11-09 18:06:43 -0800306
307 return PackageUtils.computeSha256Digest(out.toByteArray());
308 }
309
Hai Zhangb7776682018-09-25 15:10:57 -0700310 @NonNull
Hai Zhangcdc85c52018-12-06 13:56:55 -0800311 private RoleUserState getOrCreateUserState(@UserIdInt int userId) {
312 synchronized (mLock) {
313 RoleUserState userState = mUserStates.get(userId);
314 if (userState == null) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800315 userState = new RoleUserState(userId, this);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800316 mUserStates.put(userId, userState);
317 }
318 return userState;
Hai Zhangb7776682018-09-25 15:10:57 -0700319 }
Hai Zhangb7776682018-09-25 15:10:57 -0700320 }
321
Hai Zhangb7776682018-09-25 15:10:57 -0700322 @NonNull
Hai Zhang48f36c62019-04-12 21:37:21 +0800323 private RoleControllerManager getOrCreateController(@UserIdInt int userId) {
Hai Zhangcdc85c52018-12-06 13:56:55 -0800324 synchronized (mLock) {
Hai Zhanga4959e52019-03-06 12:21:07 -0800325 RoleControllerManager controller = mControllers.get(userId);
326 if (controller == null) {
327 Context systemContext = getContext();
328 Context context;
329 try {
330 context = systemContext.createPackageContextAsUser(
331 systemContext.getPackageName(), 0, UserHandle.of(userId));
332 } catch (NameNotFoundException e) {
333 throw new RuntimeException(e);
334 }
Hai Zhang48f36c62019-04-12 21:37:21 +0800335 controller = RoleControllerManager.createWithInitializedRemoteServiceComponentName(
336 FgThread.getHandler(), context);
Hai Zhanga4959e52019-03-06 12:21:07 -0800337 mControllers.put(userId, controller);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800338 }
Hai Zhanga4959e52019-03-06 12:21:07 -0800339 return controller;
Hai Zhangb7776682018-09-25 15:10:57 -0700340 }
Hai Zhangb7776682018-09-25 15:10:57 -0700341 }
342
Hai Zhang31d06ba2018-12-06 18:14:42 -0800343 @Nullable
344 private RemoteCallbackList<IOnRoleHoldersChangedListener> getListeners(@UserIdInt int userId) {
345 synchronized (mLock) {
346 return mListeners.get(userId);
347 }
348 }
349
350 @NonNull
351 private RemoteCallbackList<IOnRoleHoldersChangedListener> getOrCreateListeners(
352 @UserIdInt int userId) {
353 synchronized (mLock) {
354 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = mListeners.get(userId);
355 if (listeners == null) {
356 listeners = new RemoteCallbackList<>();
357 mListeners.put(userId, listeners);
358 }
359 return listeners;
360 }
361 }
362
Hai Zhangb7776682018-09-25 15:10:57 -0700363 private void onRemoveUser(@UserIdInt int userId) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800364 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners;
Hai Zhangcdc85c52018-12-06 13:56:55 -0800365 RoleUserState userState;
Hai Zhangb7776682018-09-25 15:10:57 -0700366 synchronized (mLock) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800367 listeners = mListeners.removeReturnOld(userId);
Hai Zhanga4959e52019-03-06 12:21:07 -0800368 mControllers.remove(userId);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800369 userState = mUserStates.removeReturnOld(userId);
370 }
Hai Zhang31d06ba2018-12-06 18:14:42 -0800371 if (listeners != null) {
372 listeners.kill();
373 }
Hai Zhangcdc85c52018-12-06 13:56:55 -0800374 if (userState != null) {
375 userState.destroy();
Hai Zhangb7776682018-09-25 15:10:57 -0700376 }
377 }
378
Hai Zhang31d06ba2018-12-06 18:14:42 -0800379 @Override
380 public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
381 mListenerHandler.sendMessage(PooledLambda.obtainMessage(
382 RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId));
383 }
384
385 @WorkerThread
386 private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
387 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800388 if (listeners != null) {
389 notifyRoleHoldersChangedForListeners(listeners, roleName, userId);
Hai Zhang31d06ba2018-12-06 18:14:42 -0800390 }
391
Hai Zhang85fd0622019-02-01 14:06:04 -0800392 RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners(
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800393 UserHandle.USER_ALL);
Hai Zhang85fd0622019-02-01 14:06:04 -0800394 if (allUsersListeners != null) {
395 notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId);
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800396 }
397 }
398
399 @WorkerThread
400 private void notifyRoleHoldersChangedForListeners(
401 @NonNull RemoteCallbackList<IOnRoleHoldersChangedListener> listeners,
402 @NonNull String roleName, @UserIdInt int userId) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800403 int broadcastCount = listeners.beginBroadcast();
404 try {
405 for (int i = 0; i < broadcastCount; i++) {
406 IOnRoleHoldersChangedListener listener = listeners.getBroadcastItem(i);
407 try {
408 listener.onRoleHoldersChanged(roleName, userId);
409 } catch (RemoteException e) {
410 Slog.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e);
411 }
412 }
413 } finally {
414 listeners.finishBroadcast();
415 }
416 }
417
Hai Zhangb7776682018-09-25 15:10:57 -0700418 private class Stub extends IRoleManager.Stub {
419
420 @Override
421 public boolean isRoleAvailable(@NonNull String roleName) {
422 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
423
424 int userId = UserHandle.getUserId(getCallingUid());
Hai Zhang85fd0622019-02-01 14:06:04 -0800425 return getOrCreateUserState(userId).isRoleAvailable(roleName);
Hai Zhangb7776682018-09-25 15:10:57 -0700426 }
427
428 @Override
429 public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) {
Hai Zhangb7776682018-09-25 15:10:57 -0700430 int callingUid = getCallingUid();
431 mAppOpsManager.checkPackage(callingUid, packageName);
432
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800433 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
434 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
435
Hai Zhangb7776682018-09-25 15:10:57 -0700436 int userId = UserHandle.getUserId(callingUid);
Hai Zhang85fd0622019-02-01 14:06:04 -0800437 ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
Hai Zhangb7776682018-09-25 15:10:57 -0700438 if (roleHolders == null) {
439 return false;
440 }
441 return roleHolders.contains(packageName);
442 }
443
444 @NonNull
445 @Override
446 public List<String> getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) {
Hai Zhangb7776682018-09-25 15:10:57 -0700447 if (!mUserManagerInternal.exists(userId)) {
448 Slog.e(LOG_TAG, "user " + userId + " does not exist");
449 return Collections.emptyList();
450 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800451 userId = handleIncomingUser(userId, false, "getRoleHoldersAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700452 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
453 "getRoleHoldersAsUser");
454
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800455 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
456
Hai Zhang85fd0622019-02-01 14:06:04 -0800457 ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
Hai Zhangb7776682018-09-25 15:10:57 -0700458 if (roleHolders == null) {
459 return Collections.emptyList();
460 }
461 return new ArrayList<>(roleHolders);
462 }
463
Hai Zhangb7776682018-09-25 15:10:57 -0700464 @Override
465 public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
Hai Zhang71d70362019-02-04 16:17:38 -0800466 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800467 @NonNull RemoteCallback callback) {
Hai Zhangb7776682018-09-25 15:10:57 -0700468 if (!mUserManagerInternal.exists(userId)) {
469 Slog.e(LOG_TAG, "user " + userId + " does not exist");
470 return;
471 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800472 userId = handleIncomingUser(userId, false, "addRoleHolderAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700473 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
474 "addRoleHolderAsUser");
475
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800476 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
477 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
478 Preconditions.checkNotNull(callback, "callback cannot be null");
479
Hai Zhang48f36c62019-04-12 21:37:21 +0800480 getOrCreateController(userId).onAddRoleHolder(roleName, packageName, flags,
Hai Zhang71d70362019-02-04 16:17:38 -0800481 callback);
Hai Zhangb7776682018-09-25 15:10:57 -0700482 }
483
484 @Override
485 public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
Hai Zhang71d70362019-02-04 16:17:38 -0800486 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800487 @NonNull RemoteCallback callback) {
Hai Zhangb7776682018-09-25 15:10:57 -0700488 if (!mUserManagerInternal.exists(userId)) {
489 Slog.e(LOG_TAG, "user " + userId + " does not exist");
490 return;
491 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800492 userId = handleIncomingUser(userId, false, "removeRoleHolderAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700493 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
494 "removeRoleHolderAsUser");
495
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800496 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
497 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
498 Preconditions.checkNotNull(callback, "callback cannot be null");
499
Hai Zhang48f36c62019-04-12 21:37:21 +0800500 getOrCreateController(userId).onRemoveRoleHolder(roleName, packageName, flags,
Hai Zhangb7776682018-09-25 15:10:57 -0700501 callback);
502 }
503
504 @Override
Hai Zhang71d70362019-02-04 16:17:38 -0800505 public void clearRoleHoldersAsUser(@NonNull String roleName,
506 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800507 @NonNull RemoteCallback callback) {
Hai Zhangb7776682018-09-25 15:10:57 -0700508 if (!mUserManagerInternal.exists(userId)) {
509 Slog.e(LOG_TAG, "user " + userId + " does not exist");
510 return;
511 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800512 userId = handleIncomingUser(userId, false, "clearRoleHoldersAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700513 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
514 "clearRoleHoldersAsUser");
Hai Zhang87ed09a2018-10-22 10:43:31 -0700515
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800516 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
517 Preconditions.checkNotNull(callback, "callback cannot be null");
518
Hai Zhang48f36c62019-04-12 21:37:21 +0800519 getOrCreateController(userId).onClearRoleHolders(roleName, flags, callback);
Hai Zhangb7776682018-09-25 15:10:57 -0700520 }
521
Hai Zhang87ed09a2018-10-22 10:43:31 -0700522 @Override
Hai Zhang31d06ba2018-12-06 18:14:42 -0800523 public void addOnRoleHoldersChangedListenerAsUser(
524 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800525 if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800526 Slog.e(LOG_TAG, "user " + userId + " does not exist");
527 return;
528 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800529 userId = handleIncomingUser(userId, true, "addOnRoleHoldersChangedListenerAsUser");
Hai Zhang31d06ba2018-12-06 18:14:42 -0800530 getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
531 "addOnRoleHoldersChangedListenerAsUser");
532
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800533 Preconditions.checkNotNull(listener, "listener cannot be null");
534
Hai Zhang31d06ba2018-12-06 18:14:42 -0800535 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getOrCreateListeners(
536 userId);
537 listeners.register(listener);
538 }
539
540 @Override
541 public void removeOnRoleHoldersChangedListenerAsUser(
542 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800543 if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800544 Slog.e(LOG_TAG, "user " + userId + " does not exist");
545 return;
546 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800547 userId = handleIncomingUser(userId, true, "removeOnRoleHoldersChangedListenerAsUser");
Hai Zhang31d06ba2018-12-06 18:14:42 -0800548 getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
549 "removeOnRoleHoldersChangedListenerAsUser");
550
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800551 Preconditions.checkNotNull(listener, "listener cannot be null");
552
Hai Zhang31d06ba2018-12-06 18:14:42 -0800553 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
554 if (listener == null) {
555 return;
556 }
557 listeners.unregister(listener);
558 }
559
560 @Override
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800561 public void setRoleNamesFromController(@NonNull List<String> roleNames) {
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800562 getContext().enforceCallingOrSelfPermission(
563 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
564 "setRoleNamesFromController");
565
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800566 Preconditions.checkNotNull(roleNames, "roleNames cannot be null");
567
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800568 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800569 getOrCreateUserState(userId).setRoleNames(roleNames);
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800570 }
571
572 @Override
Hai Zhang87ed09a2018-10-22 10:43:31 -0700573 public boolean addRoleHolderFromController(@NonNull String roleName,
574 @NonNull String packageName) {
Hai Zhang87ed09a2018-10-22 10:43:31 -0700575 getContext().enforceCallingOrSelfPermission(
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800576 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
Hai Zhang87ed09a2018-10-22 10:43:31 -0700577 "addRoleHolderFromController");
578
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800579 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
580 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
581
Hai Zhang87ed09a2018-10-22 10:43:31 -0700582 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800583 return getOrCreateUserState(userId).addRoleHolder(roleName, packageName);
Hai Zhang87ed09a2018-10-22 10:43:31 -0700584 }
585
586 @Override
587 public boolean removeRoleHolderFromController(@NonNull String roleName,
588 @NonNull String packageName) {
Hai Zhang87ed09a2018-10-22 10:43:31 -0700589 getContext().enforceCallingOrSelfPermission(
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800590 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
Hai Zhang87ed09a2018-10-22 10:43:31 -0700591 "removeRoleHolderFromController");
592
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800593 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
594 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
595
Hai Zhang87ed09a2018-10-22 10:43:31 -0700596 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800597 return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName);
Hai Zhang87ed09a2018-10-22 10:43:31 -0700598 }
599
Eugene Suslaa2a80322018-12-12 17:09:38 -0800600 @Override
601 public List<String> getHeldRolesFromController(@NonNull String packageName) {
Eugene Suslaa2a80322018-12-12 17:09:38 -0800602 getContext().enforceCallingOrSelfPermission(
603 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
604 "getRolesHeldFromController");
605
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800606 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
607
Eugene Suslaa2a80322018-12-12 17:09:38 -0800608 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800609 return getOrCreateUserState(userId).getHeldRoles(packageName);
Eugene Suslaa2a80322018-12-12 17:09:38 -0800610 }
611
Hai Zhangb7776682018-09-25 15:10:57 -0700612 @CheckResult
Hai Zhang85fd0622019-02-01 14:06:04 -0800613 private int handleIncomingUser(@UserIdInt int userId, boolean allowAll,
614 @NonNull String name) {
Hai Zhangb7776682018-09-25 15:10:57 -0700615 return ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800616 allowAll, true, name, null);
Hai Zhangb7776682018-09-25 15:10:57 -0700617 }
Jeff Sharkey6260c582018-11-27 13:05:15 -0700618
619 @Override
Hai Zhang458cedb2018-12-03 15:41:11 -0800620 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
621 @Nullable FileDescriptor err, @NonNull String[] args,
622 @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
623 new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback,
624 resultReceiver);
Jeff Sharkey6260c582018-11-27 13:05:15 -0700625 }
Hai Zhang33456fb2018-12-05 17:30:35 -0800626
627 @Override
Eugene Susla4ab95112018-12-17 14:45:11 -0800628 public String getDefaultSmsPackage(int userId) {
629 long identity = Binder.clearCallingIdentity();
630 try {
631 return CollectionUtils.firstOrNull(
632 getRoleHoldersAsUser(RoleManager.ROLE_SMS, userId));
633 } finally {
634 Binder.restoreCallingIdentity(identity);
635 }
636 }
637
638 @Override
Hai Zhang33456fb2018-12-05 17:30:35 -0800639 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
640 @Nullable String[] args) {
641 if (!DumpUtils.checkDumpPermission(getContext(), LOG_TAG, fout)) {
642 return;
643 }
644
645 boolean dumpAsProto = args != null && ArrayUtils.contains(args, "--proto");
646 DualDumpOutputStream dumpOutputStream;
647 if (dumpAsProto) {
648 dumpOutputStream = new DualDumpOutputStream(new ProtoOutputStream(fd));
649 } else {
650 fout.println("ROLE MANAGER STATE (dumpsys role):");
651 dumpOutputStream = new DualDumpOutputStream(new IndentingPrintWriter(fout, " "));
652 }
653
Hai Zhangcdc85c52018-12-06 13:56:55 -0800654 int[] userIds = mUserManagerInternal.getUserIds();
655 int userIdsLength = userIds.length;
656 for (int i = 0; i < userIdsLength; i++) {
657 int userId = userIds[i];
Hai Zhang33456fb2018-12-05 17:30:35 -0800658
Hai Zhangcdc85c52018-12-06 13:56:55 -0800659 RoleUserState userState = getOrCreateUserState(userId);
660 userState.dump(dumpOutputStream, "user_states",
661 RoleManagerServiceDumpProto.USER_STATES);
Hai Zhang33456fb2018-12-05 17:30:35 -0800662 }
663
664 dumpOutputStream.flush();
665 }
Hongming Jin08496b02019-01-25 13:41:52 -0800666
667 /**
668 * Get filtered SMS messages for financial app.
669 */
670 @Override
671 public void getSmsMessagesForFinancialApp(
672 String callingPkg, Bundle params, IFinancialSmsCallback callback) {
673 int mode = PermissionChecker.checkCallingOrSelfPermission(
674 getContext(),
675 AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS);
676
677 if (mode == PermissionChecker.PERMISSION_GRANTED) {
678 FinancialSmsManager financialSmsManager = new FinancialSmsManager(getContext());
679 financialSmsManager.getSmsMessages(new RemoteCallback((result) -> {
680 CursorWindow messages = null;
681 if (result == null) {
682 Slog.w(LOG_TAG, "result is null.");
683 } else {
684 messages = result.getParcelable(FinancialSmsService.EXTRA_SMS_MSGS);
685 }
686 try {
687 callback.onGetSmsMessagesForFinancialApp(messages);
688 } catch (RemoteException e) {
689 // do nothing
690 }
691 }), params);
692 } else {
693 try {
694 callback.onGetSmsMessagesForFinancialApp(null);
695 } catch (RemoteException e) {
696 // do nothing
697 }
698 }
699 }
700
701 private int getUidForPackage(String packageName) {
702 long ident = Binder.clearCallingIdentity();
703 try {
704 return getContext().getPackageManager().getApplicationInfo(packageName,
705 PackageManager.MATCH_ANY_USER).uid;
706 } catch (NameNotFoundException nnfe) {
707 return -1;
708 } finally {
709 Binder.restoreCallingIdentity(ident);
710 }
711 }
Hai Zhangb7776682018-09-25 15:10:57 -0700712 }
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800713
Hai Zhang85fd0622019-02-01 14:06:04 -0800714 private class Internal extends RoleManagerInternal {
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800715
716 @NonNull
717 @Override
Hai Zhang85fd0622019-02-01 14:06:04 -0800718 public ArrayMap<String, ArraySet<String>> getRolesAndHolders(@UserIdInt int userId) {
719 return getOrCreateUserState(userId).getRolesAndHolders();
720 }
721 }
722
723 private class DefaultBrowserProvider implements PackageManagerInternal.DefaultBrowserProvider {
724
725 @Nullable
726 @Override
727 public String getDefaultBrowser(@UserIdInt int userId) {
728 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
729 RoleManager.ROLE_BROWSER));
730 }
731
732 @Override
733 public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) {
734 CompletableFuture<Void> future = new CompletableFuture<>();
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800735 RemoteCallback callback = new RemoteCallback(result -> {
736 boolean successful = result != null;
737 if (successful) {
Hai Zhang85fd0622019-02-01 14:06:04 -0800738 future.complete(null);
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800739 } else {
Hai Zhang85fd0622019-02-01 14:06:04 -0800740 future.completeExceptionally(new RuntimeException());
741 }
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800742 });
Hai Zhang85fd0622019-02-01 14:06:04 -0800743 if (packageName != null) {
Hai Zhang48f36c62019-04-12 21:37:21 +0800744 getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
Hai Zhang71d70362019-02-04 16:17:38 -0800745 packageName, 0, callback);
Hai Zhang85fd0622019-02-01 14:06:04 -0800746 } else {
Hai Zhang48f36c62019-04-12 21:37:21 +0800747 getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
Hai Zhang85fd0622019-02-01 14:06:04 -0800748 callback);
749 }
750 try {
751 future.get(5, TimeUnit.SECONDS);
752 return true;
753 } catch (InterruptedException | ExecutionException | TimeoutException e) {
754 Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
755 return false;
756 }
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800757 }
Hai Zhangfafe5252019-02-27 15:29:48 -0800758
759 @Override
760 public void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId) {
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800761 RemoteCallback callback = new RemoteCallback(result -> {
762 boolean successful = result != null;
763 if (!successful) {
Hai Zhangfafe5252019-02-27 15:29:48 -0800764 Slog.e(LOG_TAG, "Failed to set default browser: " + packageName);
765 }
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800766 });
Hai Zhangfafe5252019-02-27 15:29:48 -0800767 if (packageName != null) {
Hai Zhang48f36c62019-04-12 21:37:21 +0800768 getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
Hai Zhangfafe5252019-02-27 15:29:48 -0800769 packageName, 0, callback);
770 } else {
Hai Zhang48f36c62019-04-12 21:37:21 +0800771 getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
Hai Zhangfafe5252019-02-27 15:29:48 -0800772 callback);
773 }
774 }
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800775 }
Hai Zhang8be463f2019-02-11 16:44:45 -0800776
Hai Zhangc1399272019-05-07 15:50:58 -0700777 private class DefaultDialerProvider implements PackageManagerInternal.DefaultDialerProvider {
778
779 @Nullable
780 @Override
781 public String getDefaultDialer(@UserIdInt int userId) {
782 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
783 RoleManager.ROLE_DIALER));
784 }
785 }
786
Hai Zhang8be463f2019-02-11 16:44:45 -0800787 private class DefaultHomeProvider implements PackageManagerInternal.DefaultHomeProvider {
788
789 @Nullable
790 @Override
791 public String getDefaultHome(@UserIdInt int userId) {
792 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
793 RoleManager.ROLE_HOME));
794 }
795
796 @Override
Winson Chungb41314b2019-04-04 16:24:59 -0700797 public void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId,
798 @NonNull Consumer<Boolean> callback) {
799 RemoteCallback remoteCallback = new RemoteCallback(result -> {
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800800 boolean successful = result != null;
801 if (!successful) {
Hai Zhang8be463f2019-02-11 16:44:45 -0800802 Slog.e(LOG_TAG, "Failed to set default home: " + packageName);
803 }
Winson Chungb41314b2019-04-04 16:24:59 -0700804 callback.accept(successful);
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800805 });
Hai Zhang8be463f2019-02-11 16:44:45 -0800806 if (packageName != null) {
Hai Zhang48f36c62019-04-12 21:37:21 +0800807 getOrCreateController(userId).onAddRoleHolder(RoleManager.ROLE_HOME,
Winson Chungb41314b2019-04-04 16:24:59 -0700808 packageName, 0, remoteCallback);
Hai Zhang8be463f2019-02-11 16:44:45 -0800809 } else {
Hai Zhang48f36c62019-04-12 21:37:21 +0800810 getOrCreateController(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0,
Winson Chungb41314b2019-04-04 16:24:59 -0700811 remoteCallback);
Hai Zhang8be463f2019-02-11 16:44:45 -0800812 }
813 }
814 }
Hai Zhangb7776682018-09-25 15:10:57 -0700815}