• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 
17 package com.android.server.pm;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.annotation.UserIdInt;
22 import android.app.role.RoleManager;
23 import android.os.Binder;
24 import android.os.UserHandle;
25 import android.util.Slog;
26 
27 import com.android.internal.infra.AndroidFuture;
28 import com.android.internal.util.CollectionUtils;
29 import com.android.server.FgThread;
30 
31 import java.util.concurrent.ExecutionException;
32 import java.util.concurrent.Executor;
33 import java.util.concurrent.TimeUnit;
34 import java.util.concurrent.TimeoutException;
35 import java.util.function.Consumer;
36 import java.util.function.Supplier;
37 
38 /**
39  * Interacts with {@link RoleManager} to provide and manage default apps.
40  */
41 public class DefaultAppProvider {
42     @NonNull
43     private final Supplier<RoleManager> mRoleManagerSupplier;
44     @NonNull
45     private final Supplier<UserManagerInternal> mUserManagerInternalSupplier;
46 
47     /**
48      * Create a new instance of this class
49      *
50      * @param roleManagerSupplier the supplier for {@link RoleManager}
51      */
DefaultAppProvider(@onNull Supplier<RoleManager> roleManagerSupplier, @NonNull Supplier<UserManagerInternal> userManagerInternalSupplier)52     public DefaultAppProvider(@NonNull Supplier<RoleManager> roleManagerSupplier,
53             @NonNull Supplier<UserManagerInternal> userManagerInternalSupplier) {
54         mRoleManagerSupplier = roleManagerSupplier;
55         mUserManagerInternalSupplier = userManagerInternalSupplier;
56     }
57 
58     /**
59      * Get the package name of the default browser.
60      *
61      * @param userId the user ID
62      * @return the package name of the default browser, or {@code null} if none
63      */
64     @Nullable
getDefaultBrowser(@serIdInt int userId)65     public String getDefaultBrowser(@UserIdInt int userId) {
66         return getRoleHolder(RoleManager.ROLE_BROWSER, userId);
67     }
68 
69     /**
70      * Set the package name of the default browser.
71      *
72      * @param packageName package name of the default browser, or {@code null} to unset
73      * @param async whether the operation should be asynchronous
74      * @param userId the user ID
75      * @return whether the default browser was successfully set.
76      */
setDefaultBrowser(@ullable String packageName, boolean async, @UserIdInt int userId)77     public boolean setDefaultBrowser(@Nullable String packageName, boolean async,
78             @UserIdInt int userId) {
79         if (userId == UserHandle.USER_ALL) {
80             return false;
81         }
82         final RoleManager roleManager = mRoleManagerSupplier.get();
83         if (roleManager == null) {
84             return false;
85         }
86         final UserHandle user = UserHandle.of(userId);
87         final Executor executor = FgThread.getExecutor();
88         final AndroidFuture<Void> future = new AndroidFuture<>();
89         final Consumer<Boolean> callback = successful -> {
90             if (successful) {
91                 future.complete(null);
92             } else {
93                 future.completeExceptionally(new RuntimeException());
94             }
95         };
96         final long identity = Binder.clearCallingIdentity();
97         try {
98             if (packageName != null) {
99                 roleManager.addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, user,
100                         executor, callback);
101             } else {
102                 roleManager.clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, user, executor,
103                         callback);
104             }
105             if (!async) {
106                 try {
107                     future.get(5, TimeUnit.SECONDS);
108                 } catch (InterruptedException | ExecutionException | TimeoutException e) {
109                     Slog.e(PackageManagerService.TAG, "Exception while setting default browser: "
110                             + packageName, e);
111                     return false;
112                 }
113             }
114         } finally {
115             Binder.restoreCallingIdentity(identity);
116         }
117         return true;
118     }
119 
120     /**
121      * Get the package name of the default dialer.
122      *
123      * @param userId the user ID
124      * @return the package name of the default dialer, or {@code null} if none
125      */
126     @Nullable
getDefaultDialer(@onNull int userId)127     public String getDefaultDialer(@NonNull int userId) {
128         return getRoleHolder(RoleManager.ROLE_DIALER, userId);
129     }
130 
131     /**
132      * Get the package name of the default home.
133      *
134      * @param userId the user ID
135      * @return the package name of the default home, or {@code null} if none
136      */
137     @Nullable
getDefaultHome(@onNull int userId)138     public String getDefaultHome(@NonNull int userId) {
139         return getRoleHolder(RoleManager.ROLE_HOME,
140                 mUserManagerInternalSupplier.get().getProfileParentId(userId));
141     }
142 
143     /**
144      * Set the package name of the default home.
145      *
146      * @param packageName package name of the default home
147      * @param userId the user ID
148      * @param executor the {@link Executor} to execute callback on
149      * @param callback the callback made after the default home as been updated
150      * @return whether the default home was set
151      */
setDefaultHome(@onNull String packageName, @UserIdInt int userId, @NonNull Executor executor, @NonNull Consumer<Boolean> callback)152     public boolean setDefaultHome(@NonNull String packageName, @UserIdInt int userId,
153             @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
154         final RoleManager roleManager = mRoleManagerSupplier.get();
155         if (roleManager == null) {
156             return false;
157         }
158         final long identity = Binder.clearCallingIdentity();
159         try {
160             roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, packageName, 0,
161                     UserHandle.of(userId), executor, callback);
162         } finally {
163             Binder.restoreCallingIdentity(identity);
164         }
165         return true;
166     }
167 
168     @Nullable
getRoleHolder(@onNull String roleName, @NonNull int userId)169     private String getRoleHolder(@NonNull String roleName, @NonNull int userId) {
170         final RoleManager roleManager = mRoleManagerSupplier.get();
171         if (roleManager == null) {
172             return null;
173         }
174         final long identity = Binder.clearCallingIdentity();
175         try {
176             return CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser(roleName,
177                     UserHandle.of(userId)));
178         } finally {
179             Binder.restoreCallingIdentity(identity);
180         }
181     }
182 }
183