blob: f4e10ede19d5e5bd870a6abe26cad9f7f6039f4e [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;
Eugene Susla34969062019-01-29 11:02:02 -080041import android.database.ContentObserver;
Hongming Jin08496b02019-01-25 13:41:52 -080042import android.database.CursorWindow;
Eugene Susla34969062019-01-29 11:02:02 -080043import android.net.Uri;
Eugene Susla4ab95112018-12-17 14:45:11 -080044import android.os.Binder;
Hongming Jin08496b02019-01-25 13:41:52 -080045import android.os.Bundle;
Hai Zhang31d06ba2018-12-06 18:14:42 -080046import android.os.Handler;
Hongming Jin08496b02019-01-25 13:41:52 -080047import android.os.RemoteCallback;
Hai Zhang31d06ba2018-12-06 18:14:42 -080048import android.os.RemoteCallbackList;
49import android.os.RemoteException;
Jeff Sharkey6260c582018-11-27 13:05:15 -070050import android.os.ResultReceiver;
51import android.os.ShellCallback;
Hai Zhangb7776682018-09-25 15:10:57 -070052import android.os.UserHandle;
53import android.os.UserManagerInternal;
Eugene Susla34969062019-01-29 11:02:02 -080054import android.provider.Settings;
Hongming Jin08496b02019-01-25 13:41:52 -080055import android.service.sms.FinancialSmsService;
56import android.telephony.IFinancialSmsCallback;
Hai Zhangb7776682018-09-25 15:10:57 -070057import android.text.TextUtils;
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -080058import android.util.ArrayMap;
Hai Zhangb7776682018-09-25 15:10:57 -070059import android.util.ArraySet;
Eugene Suslaabdefba2018-11-09 18:06:43 -080060import android.util.PackageUtils;
Hai Zhangb7776682018-09-25 15:10:57 -070061import android.util.Slog;
62import android.util.SparseArray;
Hai Zhang33456fb2018-12-05 17:30:35 -080063import android.util.proto.ProtoOutputStream;
Hai Zhangb7776682018-09-25 15:10:57 -070064
65import com.android.internal.annotations.GuardedBy;
Hai Zhang33456fb2018-12-05 17:30:35 -080066import com.android.internal.util.ArrayUtils;
Eugene Suslaabdefba2018-11-09 18:06:43 -080067import com.android.internal.util.BitUtils;
68import com.android.internal.util.CollectionUtils;
Hai Zhang33456fb2018-12-05 17:30:35 -080069import com.android.internal.util.DumpUtils;
Eugene Suslaabdefba2018-11-09 18:06:43 -080070import com.android.internal.util.FunctionalUtils;
Hai Zhang33456fb2018-12-05 17:30:35 -080071import com.android.internal.util.IndentingPrintWriter;
Hai Zhangb7776682018-09-25 15:10:57 -070072import com.android.internal.util.Preconditions;
Hai Zhang33456fb2018-12-05 17:30:35 -080073import com.android.internal.util.dump.DualDumpOutputStream;
Hai Zhang31d06ba2018-12-06 18:14:42 -080074import com.android.internal.util.function.pooled.PooledLambda;
75import com.android.server.FgThread;
Hai Zhangb7776682018-09-25 15:10:57 -070076import com.android.server.LocalServices;
77import com.android.server.SystemService;
78
Eugene Suslaabdefba2018-11-09 18:06:43 -080079import java.io.ByteArrayOutputStream;
Jeff Sharkey6260c582018-11-27 13:05:15 -070080import java.io.FileDescriptor;
Hai Zhang33456fb2018-12-05 17:30:35 -080081import java.io.PrintWriter;
Hai Zhangb7776682018-09-25 15:10:57 -070082import java.util.ArrayList;
83import java.util.Collections;
84import java.util.List;
Hai Zhang458cedb2018-12-03 15:41:11 -080085import java.util.Objects;
Eugene Suslaa4200f822018-11-09 18:06:43 -080086import java.util.concurrent.CompletableFuture;
87import java.util.concurrent.ExecutionException;
88import java.util.concurrent.TimeUnit;
89import java.util.concurrent.TimeoutException;
Hai Zhangb7776682018-09-25 15:10:57 -070090
91/**
92 * Service for role management.
93 *
94 * @see RoleManager
95 */
Hai Zhang31d06ba2018-12-06 18:14:42 -080096public class RoleManagerService extends SystemService implements RoleUserState.Callback {
Hai Zhangb7776682018-09-25 15:10:57 -070097
98 private static final String LOG_TAG = RoleManagerService.class.getSimpleName();
99
Hai Zhanga4959e52019-03-06 12:21:07 -0800100 private static final boolean DEBUG = false;
101
Hai Zhangb7776682018-09-25 15:10:57 -0700102 @NonNull
103 private final UserManagerInternal mUserManagerInternal;
104 @NonNull
105 private final AppOpsManager mAppOpsManager;
106
107 @NonNull
108 private final Object mLock = new Object();
109
Eugene Susla4ab95112018-12-17 14:45:11 -0800110 @NonNull
111 private final RoleHoldersResolver mLegacyRoleResolver;
112
113 /** @see #getRoleHolders(String, int) */
114 public interface RoleHoldersResolver {
115 /** @return a list of packages that hold a given role for a given user */
Hai Zhang8be463f2019-02-11 16:44:45 -0800116 @NonNull
117 List<String> getRoleHolders(@NonNull String roleName, @UserIdInt int userId);
Eugene Susla4ab95112018-12-17 14:45:11 -0800118 }
119
Hai Zhangb7776682018-09-25 15:10:57 -0700120 /**
121 * Maps user id to its state.
122 */
123 @GuardedBy("mLock")
124 @NonNull
125 private final SparseArray<RoleUserState> mUserStates = new SparseArray<>();
126
127 /**
Hai Zhanga4959e52019-03-06 12:21:07 -0800128 * Maps user id to its controller.
Hai Zhangb7776682018-09-25 15:10:57 -0700129 */
130 @GuardedBy("mLock")
131 @NonNull
Hai Zhanga4959e52019-03-06 12:21:07 -0800132 private final SparseArray<RoleControllerManager> mControllers = new SparseArray<>();
Hai Zhangb7776682018-09-25 15:10:57 -0700133
Hai Zhang31d06ba2018-12-06 18:14:42 -0800134 /**
135 * Maps user id to its list of listeners.
136 */
137 @GuardedBy("mLock")
138 @NonNull
139 private final SparseArray<RemoteCallbackList<IOnRoleHoldersChangedListener>> mListeners =
140 new SparseArray<>();
141
142 @NonNull
143 private final Handler mListenerHandler = FgThread.getHandler();
144
Eugene Susla4ab95112018-12-17 14:45:11 -0800145 public RoleManagerService(@NonNull Context context,
146 @NonNull RoleHoldersResolver legacyRoleResolver) {
Hai Zhangb7776682018-09-25 15:10:57 -0700147 super(context);
148
Eugene Susla4ab95112018-12-17 14:45:11 -0800149 mLegacyRoleResolver = legacyRoleResolver;
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 Zhang8be463f2019-02-11 16:44:45 -0800159 packageManagerInternal.setDefaultHomeProvider(new DefaultHomeProvider());
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800160
Hai Zhangb7776682018-09-25 15:10:57 -0700161 registerUserRemovedReceiver();
162 }
163
164 private void registerUserRemovedReceiver() {
165 IntentFilter intentFilter = new IntentFilter();
166 intentFilter.addAction(Intent.ACTION_USER_REMOVED);
167 getContext().registerReceiverAsUser(new BroadcastReceiver() {
168 @Override
Hai Zhang458cedb2018-12-03 15:41:11 -0800169 public void onReceive(@NonNull Context context, @NonNull Intent intent) {
Hai Zhangb7776682018-09-25 15:10:57 -0700170 if (TextUtils.equals(intent.getAction(), Intent.ACTION_USER_REMOVED)) {
171 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
172 onRemoveUser(userId);
173 }
174 }
175 }, UserHandle.ALL, intentFilter, null, null);
176 }
177
178 @Override
179 public void onStart() {
180 publishBinderService(Context.ROLE_SERVICE, new Stub());
Eugene Suslad469fc12018-11-20 17:09:07 -0800181
Eugene Susla6d4922722018-11-08 16:25:28 -0800182 //TODO add watch for new user creation and run default grants for them
Eugene Suslad469fc12018-11-20 17:09:07 -0800183
184 IntentFilter intentFilter = new IntentFilter();
185 intentFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
186 intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
187 intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
188 intentFilter.addDataScheme("package");
189 intentFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
190 getContext().registerReceiverAsUser(new BroadcastReceiver() {
191 @Override
192 public void onReceive(Context context, Intent intent) {
193 int userId = UserHandle.getUserId(intent.getIntExtra(Intent.EXTRA_UID, -1));
Hai Zhanga4959e52019-03-06 12:21:07 -0800194 if (DEBUG) {
195 Slog.i(LOG_TAG, "Packages changed - re-running initial grants for user "
196 + userId);
Eugene Suslad469fc12018-11-20 17:09:07 -0800197 }
198 performInitialGrantsIfNecessary(userId);
199 }
Hai Zhanga5d86322019-02-15 18:06:51 -0800200 }, UserHandle.ALL, intentFilter, null, null);
Eugene Susla34969062019-01-29 11:02:02 -0800201
202 getContext().getContentResolver().registerContentObserver(
203 Settings.Global.getUriFor(Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED), false,
204 new ContentObserver(getContext().getMainThreadHandler()) {
205 @Override
206 public void onChange(boolean selfChange, Uri uri, int userId) {
Eugene Susla95cd4bf2019-02-05 14:41:24 -0800207 boolean killSwitchEnabled = Settings.Global.getInt(
208 getContext().getContentResolver(),
209 Settings.Global.SMS_ACCESS_RESTRICTION_ENABLED, 0) == 1;
210 for (int user : mUserManagerInternal.getUserIds()) {
211 if (mUserManagerInternal.isUserRunning(user)) {
212 getOrCreateControllerService(user)
213 .onSmsKillSwitchToggled(killSwitchEnabled);
214 }
215 }
Eugene Susla34969062019-01-29 11:02:02 -0800216 }
217 }, UserHandle.USER_ALL);
Hai Zhangb7776682018-09-25 15:10:57 -0700218 }
219
220 @Override
221 public void onStartUser(@UserIdInt int userId) {
Eugene Suslad469fc12018-11-20 17:09:07 -0800222 performInitialGrantsIfNecessary(userId);
223 }
224
225 @MainThread
226 private void performInitialGrantsIfNecessary(@UserIdInt int userId) {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800227 RoleUserState userState;
Hai Zhangcdc85c52018-12-06 13:56:55 -0800228 userState = getOrCreateUserState(userId);
Eugene Susla4ab95112018-12-17 14:45:11 -0800229
Eugene Suslaabdefba2018-11-09 18:06:43 -0800230 String packagesHash = computeComponentStateHash(userId);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800231 String oldPackagesHash = userState.getPackagesHash();
Hai Zhang33456fb2018-12-05 17:30:35 -0800232 boolean needGrant = !Objects.equals(packagesHash, oldPackagesHash);
Eugene Suslaabdefba2018-11-09 18:06:43 -0800233 if (needGrant) {
Eugene Susla4ab95112018-12-17 14:45:11 -0800234
235 //TODO gradually add more role migrations statements here for remaining roles
236 // Make sure to implement LegacyRoleResolutionPolicy#getRoleHolders
237 // for a given role before adding a migration statement for it here
238 migrateRoleIfNecessary(RoleManager.ROLE_SMS, userId);
Philip P. Moltmann5d894502019-01-17 10:31:00 -0800239 migrateRoleIfNecessary(RoleManager.ROLE_ASSISTANT, userId);
Eugene Susla92b88c72019-01-11 13:31:20 -0800240 migrateRoleIfNecessary(RoleManager.ROLE_DIALER, userId);
Hongming Jin910cd7b2019-01-23 11:19:07 -0800241 migrateRoleIfNecessary(RoleManager.ROLE_EMERGENCY, userId);
Eugene Susla4ab95112018-12-17 14:45:11 -0800242
Eugene Suslaabdefba2018-11-09 18:06:43 -0800243 // Some vital packages state has changed since last role grant
244 // Run grants again
Eugene Susla6d4922722018-11-08 16:25:28 -0800245 Slog.i(LOG_TAG, "Granting default permissions...");
Eugene Suslaa4200f822018-11-09 18:06:43 -0800246 CompletableFuture<Void> result = new CompletableFuture<>();
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800247 getOrCreateControllerService(userId).grantDefaultRoles(FgThread.getExecutor(),
248 successful -> {
249 if (successful) {
Eugene Suslaa4200f822018-11-09 18:06:43 -0800250 result.complete(null);
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800251 } else {
Eugene Suslaa4200f822018-11-09 18:06:43 -0800252 result.completeExceptionally(new RuntimeException());
253 }
254 });
255 try {
Eugene Susla21fc69e2019-02-19 10:58:00 -0800256 result.get(30, TimeUnit.SECONDS);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800257 userState.setPackagesHash(packagesHash);
Eugene Suslaa4200f822018-11-09 18:06:43 -0800258 } catch (InterruptedException | ExecutionException | TimeoutException e) {
259 Slog.e(LOG_TAG, "Failed to grant defaults for user " + userId, e);
260 }
Hai Zhanga4959e52019-03-06 12:21:07 -0800261 } else if (DEBUG) {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800262 Slog.i(LOG_TAG, "Already ran grants for package state " + packagesHash);
Hai Zhangb7776682018-09-25 15:10:57 -0700263 }
264 }
265
Eugene Susla4ab95112018-12-17 14:45:11 -0800266 private void migrateRoleIfNecessary(String role, @UserIdInt int userId) {
267 // Any role for which we have a record are already migrated
268 RoleUserState userState = getOrCreateUserState(userId);
269 if (!userState.isRoleAvailable(role)) {
Eugene Susla4ab95112018-12-17 14:45:11 -0800270 List<String> roleHolders = mLegacyRoleResolver.getRoleHolders(role, userId);
Hai Zhang7876adb2019-01-15 21:18:41 -0800271 if (roleHolders.isEmpty()) {
272 return;
273 }
Eugene Susla4ab95112018-12-17 14:45:11 -0800274 Slog.i(LOG_TAG, "Migrating " + role + ", legacy holders: " + roleHolders);
Hai Zhang7876adb2019-01-15 21:18:41 -0800275 userState.addRoleName(role);
Eugene Susla4ab95112018-12-17 14:45:11 -0800276 int size = roleHolders.size();
277 for (int i = 0; i < size; i++) {
278 userState.addRoleHolder(role, roleHolders.get(i));
279 }
280 }
281 }
282
Hai Zhang458cedb2018-12-03 15:41:11 -0800283 @Nullable
Hai Zhang31d06ba2018-12-06 18:14:42 -0800284 private static String computeComponentStateHash(@UserIdInt int userId) {
Eugene Suslaabdefba2018-11-09 18:06:43 -0800285 PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
286 ByteArrayOutputStream out = new ByteArrayOutputStream();
287
288 pm.forEachPackage(FunctionalUtils.uncheckExceptions(pkg -> {
289 out.write(pkg.packageName.getBytes());
290 out.write(BitUtils.toBytes(pkg.getLongVersionCode()));
291 out.write(pm.getApplicationEnabledState(pkg.packageName, userId));
292
293 ArraySet<String> enabledComponents =
294 pm.getEnabledComponents(pkg.packageName, userId);
295 int numComponents = CollectionUtils.size(enabledComponents);
296 for (int i = 0; i < numComponents; i++) {
297 out.write(enabledComponents.valueAt(i).getBytes());
298 }
299
300 ArraySet<String> disabledComponents =
301 pm.getDisabledComponents(pkg.packageName, userId);
302 numComponents = CollectionUtils.size(disabledComponents);
303 for (int i = 0; i < numComponents; i++) {
304 out.write(disabledComponents.valueAt(i).getBytes());
305 }
306 for (Signature signature : pkg.mSigningDetails.signatures) {
307 out.write(signature.toByteArray());
308 }
309 }));
310
311 return PackageUtils.computeSha256Digest(out.toByteArray());
312 }
313
Hai Zhangb7776682018-09-25 15:10:57 -0700314 @NonNull
Hai Zhangcdc85c52018-12-06 13:56:55 -0800315 private RoleUserState getOrCreateUserState(@UserIdInt int userId) {
316 synchronized (mLock) {
317 RoleUserState userState = mUserStates.get(userId);
318 if (userState == null) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800319 userState = new RoleUserState(userId, this);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800320 mUserStates.put(userId, userState);
321 }
322 return userState;
Hai Zhangb7776682018-09-25 15:10:57 -0700323 }
Hai Zhangb7776682018-09-25 15:10:57 -0700324 }
325
Hai Zhangb7776682018-09-25 15:10:57 -0700326 @NonNull
Hai Zhanga4959e52019-03-06 12:21:07 -0800327 private RoleControllerManager getOrCreateControllerService(@UserIdInt int userId) {
Hai Zhangcdc85c52018-12-06 13:56:55 -0800328 synchronized (mLock) {
Hai Zhanga4959e52019-03-06 12:21:07 -0800329 RoleControllerManager controller = mControllers.get(userId);
330 if (controller == null) {
331 Context systemContext = getContext();
332 Context context;
333 try {
334 context = systemContext.createPackageContextAsUser(
335 systemContext.getPackageName(), 0, UserHandle.of(userId));
336 } catch (NameNotFoundException e) {
337 throw new RuntimeException(e);
338 }
339 controller = new RoleControllerManager(context, FgThread.getHandler());
340 mControllers.put(userId, controller);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800341 }
Hai Zhanga4959e52019-03-06 12:21:07 -0800342 return controller;
Hai Zhangb7776682018-09-25 15:10:57 -0700343 }
Hai Zhangb7776682018-09-25 15:10:57 -0700344 }
345
Hai Zhang31d06ba2018-12-06 18:14:42 -0800346 @Nullable
347 private RemoteCallbackList<IOnRoleHoldersChangedListener> getListeners(@UserIdInt int userId) {
348 synchronized (mLock) {
349 return mListeners.get(userId);
350 }
351 }
352
353 @NonNull
354 private RemoteCallbackList<IOnRoleHoldersChangedListener> getOrCreateListeners(
355 @UserIdInt int userId) {
356 synchronized (mLock) {
357 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = mListeners.get(userId);
358 if (listeners == null) {
359 listeners = new RemoteCallbackList<>();
360 mListeners.put(userId, listeners);
361 }
362 return listeners;
363 }
364 }
365
Hai Zhangb7776682018-09-25 15:10:57 -0700366 private void onRemoveUser(@UserIdInt int userId) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800367 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners;
Hai Zhangcdc85c52018-12-06 13:56:55 -0800368 RoleUserState userState;
Hai Zhangb7776682018-09-25 15:10:57 -0700369 synchronized (mLock) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800370 listeners = mListeners.removeReturnOld(userId);
Hai Zhanga4959e52019-03-06 12:21:07 -0800371 mControllers.remove(userId);
Hai Zhangcdc85c52018-12-06 13:56:55 -0800372 userState = mUserStates.removeReturnOld(userId);
373 }
Hai Zhang31d06ba2018-12-06 18:14:42 -0800374 if (listeners != null) {
375 listeners.kill();
376 }
Hai Zhangcdc85c52018-12-06 13:56:55 -0800377 if (userState != null) {
378 userState.destroy();
Hai Zhangb7776682018-09-25 15:10:57 -0700379 }
380 }
381
Hai Zhang31d06ba2018-12-06 18:14:42 -0800382 @Override
383 public void onRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
384 mListenerHandler.sendMessage(PooledLambda.obtainMessage(
385 RoleManagerService::notifyRoleHoldersChanged, this, roleName, userId));
386 }
387
388 @WorkerThread
389 private void notifyRoleHoldersChanged(@NonNull String roleName, @UserIdInt int userId) {
390 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800391 if (listeners != null) {
392 notifyRoleHoldersChangedForListeners(listeners, roleName, userId);
Hai Zhang31d06ba2018-12-06 18:14:42 -0800393 }
394
Hai Zhang85fd0622019-02-01 14:06:04 -0800395 RemoteCallbackList<IOnRoleHoldersChangedListener> allUsersListeners = getListeners(
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800396 UserHandle.USER_ALL);
Hai Zhang85fd0622019-02-01 14:06:04 -0800397 if (allUsersListeners != null) {
398 notifyRoleHoldersChangedForListeners(allUsersListeners, roleName, userId);
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800399 }
400 }
401
402 @WorkerThread
403 private void notifyRoleHoldersChangedForListeners(
404 @NonNull RemoteCallbackList<IOnRoleHoldersChangedListener> listeners,
405 @NonNull String roleName, @UserIdInt int userId) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800406 int broadcastCount = listeners.beginBroadcast();
407 try {
408 for (int i = 0; i < broadcastCount; i++) {
409 IOnRoleHoldersChangedListener listener = listeners.getBroadcastItem(i);
410 try {
411 listener.onRoleHoldersChanged(roleName, userId);
412 } catch (RemoteException e) {
413 Slog.e(LOG_TAG, "Error calling OnRoleHoldersChangedListener", e);
414 }
415 }
416 } finally {
417 listeners.finishBroadcast();
418 }
419 }
420
Hai Zhangb7776682018-09-25 15:10:57 -0700421 private class Stub extends IRoleManager.Stub {
422
423 @Override
424 public boolean isRoleAvailable(@NonNull String roleName) {
425 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
426
427 int userId = UserHandle.getUserId(getCallingUid());
Hai Zhang85fd0622019-02-01 14:06:04 -0800428 return getOrCreateUserState(userId).isRoleAvailable(roleName);
Hai Zhangb7776682018-09-25 15:10:57 -0700429 }
430
431 @Override
432 public boolean isRoleHeld(@NonNull String roleName, @NonNull String packageName) {
Hai Zhangb7776682018-09-25 15:10:57 -0700433 int callingUid = getCallingUid();
434 mAppOpsManager.checkPackage(callingUid, packageName);
435
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800436 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
437 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
438
Hai Zhangb7776682018-09-25 15:10:57 -0700439 int userId = UserHandle.getUserId(callingUid);
Hai Zhang85fd0622019-02-01 14:06:04 -0800440 ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
Hai Zhangb7776682018-09-25 15:10:57 -0700441 if (roleHolders == null) {
442 return false;
443 }
444 return roleHolders.contains(packageName);
445 }
446
447 @NonNull
448 @Override
449 public List<String> getRoleHoldersAsUser(@NonNull String roleName, @UserIdInt int userId) {
Hai Zhangb7776682018-09-25 15:10:57 -0700450 if (!mUserManagerInternal.exists(userId)) {
451 Slog.e(LOG_TAG, "user " + userId + " does not exist");
452 return Collections.emptyList();
453 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800454 userId = handleIncomingUser(userId, false, "getRoleHoldersAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700455 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
456 "getRoleHoldersAsUser");
457
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800458 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
459
Hai Zhang85fd0622019-02-01 14:06:04 -0800460 ArraySet<String> roleHolders = getOrCreateUserState(userId).getRoleHolders(roleName);
Hai Zhangb7776682018-09-25 15:10:57 -0700461 if (roleHolders == null) {
462 return Collections.emptyList();
463 }
464 return new ArrayList<>(roleHolders);
465 }
466
Hai Zhangb7776682018-09-25 15:10:57 -0700467 @Override
468 public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
Hai Zhang71d70362019-02-04 16:17:38 -0800469 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800470 @NonNull RemoteCallback callback) {
Hai Zhangb7776682018-09-25 15:10:57 -0700471 if (!mUserManagerInternal.exists(userId)) {
472 Slog.e(LOG_TAG, "user " + userId + " does not exist");
473 return;
474 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800475 userId = handleIncomingUser(userId, false, "addRoleHolderAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700476 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
477 "addRoleHolderAsUser");
478
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800479 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
480 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
481 Preconditions.checkNotNull(callback, "callback cannot be null");
482
Hai Zhang71d70362019-02-04 16:17:38 -0800483 getOrCreateControllerService(userId).onAddRoleHolder(roleName, packageName, flags,
484 callback);
Hai Zhangb7776682018-09-25 15:10:57 -0700485 }
486
487 @Override
488 public void removeRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
Hai Zhang71d70362019-02-04 16:17:38 -0800489 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800490 @NonNull RemoteCallback callback) {
Hai Zhangb7776682018-09-25 15:10:57 -0700491 if (!mUserManagerInternal.exists(userId)) {
492 Slog.e(LOG_TAG, "user " + userId + " does not exist");
493 return;
494 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800495 userId = handleIncomingUser(userId, false, "removeRoleHolderAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700496 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
497 "removeRoleHolderAsUser");
498
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800499 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
500 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
501 Preconditions.checkNotNull(callback, "callback cannot be null");
502
Hai Zhang71d70362019-02-04 16:17:38 -0800503 getOrCreateControllerService(userId).onRemoveRoleHolder(roleName, packageName, flags,
Hai Zhangb7776682018-09-25 15:10:57 -0700504 callback);
505 }
506
507 @Override
Hai Zhang71d70362019-02-04 16:17:38 -0800508 public void clearRoleHoldersAsUser(@NonNull String roleName,
509 @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800510 @NonNull RemoteCallback callback) {
Hai Zhangb7776682018-09-25 15:10:57 -0700511 if (!mUserManagerInternal.exists(userId)) {
512 Slog.e(LOG_TAG, "user " + userId + " does not exist");
513 return;
514 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800515 userId = handleIncomingUser(userId, false, "clearRoleHoldersAsUser");
Hai Zhangb7776682018-09-25 15:10:57 -0700516 getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
517 "clearRoleHoldersAsUser");
Hai Zhang87ed09a2018-10-22 10:43:31 -0700518
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800519 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
520 Preconditions.checkNotNull(callback, "callback cannot be null");
521
Hai Zhang71d70362019-02-04 16:17:38 -0800522 getOrCreateControllerService(userId).onClearRoleHolders(roleName, flags, callback);
Hai Zhangb7776682018-09-25 15:10:57 -0700523 }
524
Hai Zhang87ed09a2018-10-22 10:43:31 -0700525 @Override
Hai Zhang31d06ba2018-12-06 18:14:42 -0800526 public void addOnRoleHoldersChangedListenerAsUser(
527 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800528 if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800529 Slog.e(LOG_TAG, "user " + userId + " does not exist");
530 return;
531 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800532 userId = handleIncomingUser(userId, true, "addOnRoleHoldersChangedListenerAsUser");
Hai Zhang31d06ba2018-12-06 18:14:42 -0800533 getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
534 "addOnRoleHoldersChangedListenerAsUser");
535
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800536 Preconditions.checkNotNull(listener, "listener cannot be null");
537
Hai Zhang31d06ba2018-12-06 18:14:42 -0800538 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getOrCreateListeners(
539 userId);
540 listeners.register(listener);
541 }
542
543 @Override
544 public void removeOnRoleHoldersChangedListenerAsUser(
545 @NonNull IOnRoleHoldersChangedListener listener, @UserIdInt int userId) {
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800546 if (userId != UserHandle.USER_ALL && !mUserManagerInternal.exists(userId)) {
Hai Zhang31d06ba2018-12-06 18:14:42 -0800547 Slog.e(LOG_TAG, "user " + userId + " does not exist");
548 return;
549 }
Hai Zhang85fd0622019-02-01 14:06:04 -0800550 userId = handleIncomingUser(userId, true, "removeOnRoleHoldersChangedListenerAsUser");
Hai Zhang31d06ba2018-12-06 18:14:42 -0800551 getContext().enforceCallingOrSelfPermission(Manifest.permission.OBSERVE_ROLE_HOLDERS,
552 "removeOnRoleHoldersChangedListenerAsUser");
553
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800554 Preconditions.checkNotNull(listener, "listener cannot be null");
555
Hai Zhang31d06ba2018-12-06 18:14:42 -0800556 RemoteCallbackList<IOnRoleHoldersChangedListener> listeners = getListeners(userId);
557 if (listener == null) {
558 return;
559 }
560 listeners.unregister(listener);
561 }
562
563 @Override
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800564 public void setRoleNamesFromController(@NonNull List<String> roleNames) {
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800565 getContext().enforceCallingOrSelfPermission(
566 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
567 "setRoleNamesFromController");
568
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800569 Preconditions.checkNotNull(roleNames, "roleNames cannot be null");
570
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800571 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800572 getOrCreateUserState(userId).setRoleNames(roleNames);
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800573 }
574
575 @Override
Hai Zhang87ed09a2018-10-22 10:43:31 -0700576 public boolean addRoleHolderFromController(@NonNull String roleName,
577 @NonNull String packageName) {
Hai Zhang87ed09a2018-10-22 10:43:31 -0700578 getContext().enforceCallingOrSelfPermission(
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800579 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
Hai Zhang87ed09a2018-10-22 10:43:31 -0700580 "addRoleHolderFromController");
581
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800582 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
583 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
584
Hai Zhang87ed09a2018-10-22 10:43:31 -0700585 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800586 return getOrCreateUserState(userId).addRoleHolder(roleName, packageName);
Hai Zhang87ed09a2018-10-22 10:43:31 -0700587 }
588
589 @Override
590 public boolean removeRoleHolderFromController(@NonNull String roleName,
591 @NonNull String packageName) {
Hai Zhang87ed09a2018-10-22 10:43:31 -0700592 getContext().enforceCallingOrSelfPermission(
Hai Zhang8e60a8f2018-11-20 11:21:09 -0800593 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
Hai Zhang87ed09a2018-10-22 10:43:31 -0700594 "removeRoleHolderFromController");
595
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800596 Preconditions.checkStringNotEmpty(roleName, "roleName cannot be null or empty");
597 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
598
Hai Zhang87ed09a2018-10-22 10:43:31 -0700599 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800600 return getOrCreateUserState(userId).removeRoleHolder(roleName, packageName);
Hai Zhang87ed09a2018-10-22 10:43:31 -0700601 }
602
Eugene Suslaa2a80322018-12-12 17:09:38 -0800603 @Override
604 public List<String> getHeldRolesFromController(@NonNull String packageName) {
Eugene Suslaa2a80322018-12-12 17:09:38 -0800605 getContext().enforceCallingOrSelfPermission(
606 RoleManager.PERMISSION_MANAGE_ROLES_FROM_CONTROLLER,
607 "getRolesHeldFromController");
608
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800609 Preconditions.checkStringNotEmpty(packageName, "packageName cannot be null or empty");
610
Eugene Suslaa2a80322018-12-12 17:09:38 -0800611 int userId = UserHandle.getCallingUserId();
Hai Zhang85fd0622019-02-01 14:06:04 -0800612 return getOrCreateUserState(userId).getHeldRoles(packageName);
Eugene Suslaa2a80322018-12-12 17:09:38 -0800613 }
614
Hai Zhangb7776682018-09-25 15:10:57 -0700615 @CheckResult
Hai Zhang85fd0622019-02-01 14:06:04 -0800616 private int handleIncomingUser(@UserIdInt int userId, boolean allowAll,
617 @NonNull String name) {
Hai Zhangb7776682018-09-25 15:10:57 -0700618 return ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
Philip P. Moltmann3c4a4802019-01-17 10:31:00 -0800619 allowAll, true, name, null);
Hai Zhangb7776682018-09-25 15:10:57 -0700620 }
Jeff Sharkey6260c582018-11-27 13:05:15 -0700621
622 @Override
Hai Zhang458cedb2018-12-03 15:41:11 -0800623 public void onShellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
624 @Nullable FileDescriptor err, @NonNull String[] args,
625 @Nullable ShellCallback callback, @NonNull ResultReceiver resultReceiver) {
626 new RoleManagerShellCommand(this).exec(this, in, out, err, args, callback,
627 resultReceiver);
Jeff Sharkey6260c582018-11-27 13:05:15 -0700628 }
Hai Zhang33456fb2018-12-05 17:30:35 -0800629
630 @Override
Eugene Susla4ab95112018-12-17 14:45:11 -0800631 public String getDefaultSmsPackage(int userId) {
632 long identity = Binder.clearCallingIdentity();
633 try {
634 return CollectionUtils.firstOrNull(
635 getRoleHoldersAsUser(RoleManager.ROLE_SMS, userId));
636 } finally {
637 Binder.restoreCallingIdentity(identity);
638 }
639 }
640
641 @Override
Hai Zhang33456fb2018-12-05 17:30:35 -0800642 protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
643 @Nullable String[] args) {
644 if (!DumpUtils.checkDumpPermission(getContext(), LOG_TAG, fout)) {
645 return;
646 }
647
648 boolean dumpAsProto = args != null && ArrayUtils.contains(args, "--proto");
649 DualDumpOutputStream dumpOutputStream;
650 if (dumpAsProto) {
651 dumpOutputStream = new DualDumpOutputStream(new ProtoOutputStream(fd));
652 } else {
653 fout.println("ROLE MANAGER STATE (dumpsys role):");
654 dumpOutputStream = new DualDumpOutputStream(new IndentingPrintWriter(fout, " "));
655 }
656
Hai Zhangcdc85c52018-12-06 13:56:55 -0800657 int[] userIds = mUserManagerInternal.getUserIds();
658 int userIdsLength = userIds.length;
659 for (int i = 0; i < userIdsLength; i++) {
660 int userId = userIds[i];
Hai Zhang33456fb2018-12-05 17:30:35 -0800661
Hai Zhangcdc85c52018-12-06 13:56:55 -0800662 RoleUserState userState = getOrCreateUserState(userId);
663 userState.dump(dumpOutputStream, "user_states",
664 RoleManagerServiceDumpProto.USER_STATES);
Hai Zhang33456fb2018-12-05 17:30:35 -0800665 }
666
667 dumpOutputStream.flush();
668 }
Hongming Jin08496b02019-01-25 13:41:52 -0800669
670 /**
671 * Get filtered SMS messages for financial app.
672 */
673 @Override
674 public void getSmsMessagesForFinancialApp(
675 String callingPkg, Bundle params, IFinancialSmsCallback callback) {
676 int mode = PermissionChecker.checkCallingOrSelfPermission(
677 getContext(),
678 AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS);
679
680 if (mode == PermissionChecker.PERMISSION_GRANTED) {
681 FinancialSmsManager financialSmsManager = new FinancialSmsManager(getContext());
682 financialSmsManager.getSmsMessages(new RemoteCallback((result) -> {
683 CursorWindow messages = null;
684 if (result == null) {
685 Slog.w(LOG_TAG, "result is null.");
686 } else {
687 messages = result.getParcelable(FinancialSmsService.EXTRA_SMS_MSGS);
688 }
689 try {
690 callback.onGetSmsMessagesForFinancialApp(messages);
691 } catch (RemoteException e) {
692 // do nothing
693 }
694 }), params);
695 } else {
696 try {
697 callback.onGetSmsMessagesForFinancialApp(null);
698 } catch (RemoteException e) {
699 // do nothing
700 }
701 }
702 }
703
704 private int getUidForPackage(String packageName) {
705 long ident = Binder.clearCallingIdentity();
706 try {
707 return getContext().getPackageManager().getApplicationInfo(packageName,
708 PackageManager.MATCH_ANY_USER).uid;
709 } catch (NameNotFoundException nnfe) {
710 return -1;
711 } finally {
712 Binder.restoreCallingIdentity(ident);
713 }
714 }
Hai Zhangb7776682018-09-25 15:10:57 -0700715 }
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800716
Hai Zhang85fd0622019-02-01 14:06:04 -0800717 private class Internal extends RoleManagerInternal {
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800718
719 @NonNull
720 @Override
Hai Zhang85fd0622019-02-01 14:06:04 -0800721 public ArrayMap<String, ArraySet<String>> getRolesAndHolders(@UserIdInt int userId) {
722 return getOrCreateUserState(userId).getRolesAndHolders();
723 }
724 }
725
726 private class DefaultBrowserProvider implements PackageManagerInternal.DefaultBrowserProvider {
727
728 @Nullable
729 @Override
730 public String getDefaultBrowser(@UserIdInt int userId) {
731 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
732 RoleManager.ROLE_BROWSER));
733 }
734
735 @Override
736 public boolean setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) {
737 CompletableFuture<Void> future = new CompletableFuture<>();
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800738 RemoteCallback callback = new RemoteCallback(result -> {
739 boolean successful = result != null;
740 if (successful) {
Hai Zhang85fd0622019-02-01 14:06:04 -0800741 future.complete(null);
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800742 } else {
Hai Zhang85fd0622019-02-01 14:06:04 -0800743 future.completeExceptionally(new RuntimeException());
744 }
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800745 });
Hai Zhang85fd0622019-02-01 14:06:04 -0800746 if (packageName != null) {
747 getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
Hai Zhang71d70362019-02-04 16:17:38 -0800748 packageName, 0, callback);
Hai Zhang85fd0622019-02-01 14:06:04 -0800749 } else {
Hai Zhang71d70362019-02-04 16:17:38 -0800750 getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
Hai Zhang85fd0622019-02-01 14:06:04 -0800751 callback);
752 }
753 try {
754 future.get(5, TimeUnit.SECONDS);
755 return true;
756 } catch (InterruptedException | ExecutionException | TimeoutException e) {
757 Slog.e(LOG_TAG, "Exception while setting default browser: " + packageName, e);
758 return false;
759 }
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800760 }
Hai Zhangfafe5252019-02-27 15:29:48 -0800761
762 @Override
763 public void setDefaultBrowserAsync(@Nullable String packageName, @UserIdInt int userId) {
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800764 RemoteCallback callback = new RemoteCallback(result -> {
765 boolean successful = result != null;
766 if (!successful) {
Hai Zhangfafe5252019-02-27 15:29:48 -0800767 Slog.e(LOG_TAG, "Failed to set default browser: " + packageName);
768 }
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800769 });
Hai Zhangfafe5252019-02-27 15:29:48 -0800770 if (packageName != null) {
771 getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_BROWSER,
772 packageName, 0, callback);
773 } else {
774 getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_BROWSER, 0,
775 callback);
776 }
777 }
Philip P. Moltmann70b42ae2019-01-29 16:24:19 -0800778 }
Hai Zhang8be463f2019-02-11 16:44:45 -0800779
780 private class DefaultHomeProvider implements PackageManagerInternal.DefaultHomeProvider {
781
782 @Nullable
783 @Override
784 public String getDefaultHome(@UserIdInt int userId) {
785 return CollectionUtils.firstOrNull(getOrCreateUserState(userId).getRoleHolders(
786 RoleManager.ROLE_HOME));
787 }
788
789 @Override
790 public void setDefaultHomeAsync(@Nullable String packageName, @UserIdInt int userId) {
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800791 RemoteCallback callback = new RemoteCallback(result -> {
792 boolean successful = result != null;
793 if (!successful) {
Hai Zhang8be463f2019-02-11 16:44:45 -0800794 Slog.e(LOG_TAG, "Failed to set default home: " + packageName);
795 }
Hai Zhangf5e8ccd2019-03-06 20:12:24 -0800796 });
Hai Zhang8be463f2019-02-11 16:44:45 -0800797 if (packageName != null) {
798 getOrCreateControllerService(userId).onAddRoleHolder(RoleManager.ROLE_HOME,
799 packageName, 0, callback);
800 } else {
801 getOrCreateControllerService(userId).onClearRoleHolders(RoleManager.ROLE_HOME, 0,
802 callback);
803 }
804 }
805 }
Hai Zhangb7776682018-09-25 15:10:57 -0700806}