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.util.CollectionUtils;
28 import com.android.server.FgThread;
29 
30 import java.util.concurrent.Executor;
31 import java.util.function.Consumer;
32 import java.util.function.Supplier;
33 
34 /**
35  * Interacts with {@link RoleManager} to provide and manage default apps.
36  */
37 public class DefaultAppProvider {
38     @NonNull
39     private final Supplier<RoleManager> mRoleManagerSupplier;
40     @NonNull
41     private final Supplier<UserManagerInternal> mUserManagerInternalSupplier;
42 
43     /**
44      * Create a new instance of this class
45      *
46      * @param roleManagerSupplier the supplier for {@link RoleManager}
47      */
DefaultAppProvider(@onNull Supplier<RoleManager> roleManagerSupplier, @NonNull Supplier<UserManagerInternal> userManagerInternalSupplier)48     public DefaultAppProvider(@NonNull Supplier<RoleManager> roleManagerSupplier,
49             @NonNull Supplier<UserManagerInternal> userManagerInternalSupplier) {
50         mRoleManagerSupplier = roleManagerSupplier;
51         mUserManagerInternalSupplier = userManagerInternalSupplier;
52     }
53 
54     /**
55      * Get the package name of the default browser.
56      *
57      * @param userId the user ID
58      * @return the package name of the default browser, or {@code null} if none
59      */
60     @Nullable
getDefaultBrowser(@serIdInt int userId)61     public String getDefaultBrowser(@UserIdInt int userId) {
62         return getRoleHolder(RoleManager.ROLE_BROWSER, userId);
63     }
64 
65     /**
66      * Set the package name of the default browser.
67      *
68      * @param packageName package name of the default browser, or {@code null} to unset
69      * @param userId the user ID
70      */
setDefaultBrowser(@ullable String packageName, @UserIdInt int userId)71     public void setDefaultBrowser(@Nullable String packageName, @UserIdInt int userId) {
72         final RoleManager roleManager = mRoleManagerSupplier.get();
73         if (roleManager == null) {
74             return;
75         }
76         final UserHandle user = UserHandle.of(userId);
77         final Executor executor = FgThread.getExecutor();
78         final Consumer<Boolean> callback = successful -> {
79             if (!successful) {
80                 Slog.e(PackageManagerService.TAG, "Failed to set default browser to "
81                         + packageName);
82             }
83         };
84         final long identity = Binder.clearCallingIdentity();
85         try {
86             if (packageName != null) {
87                 roleManager.addRoleHolderAsUser(RoleManager.ROLE_BROWSER, packageName, 0, user,
88                         executor, callback);
89             } else {
90                 roleManager.clearRoleHoldersAsUser(RoleManager.ROLE_BROWSER, 0, user, executor,
91                         callback);
92             }
93         } finally {
94             Binder.restoreCallingIdentity(identity);
95         }
96     }
97 
98     /**
99      * Get the package name of the default dialer.
100      *
101      * @param userId the user ID
102      * @return the package name of the default dialer, or {@code null} if none
103      */
104     @Nullable
getDefaultDialer(@onNull int userId)105     public String getDefaultDialer(@NonNull int userId) {
106         return getRoleHolder(RoleManager.ROLE_DIALER, userId);
107     }
108 
109     /**
110      * Get the package name of the default home.
111      *
112      * @param userId the user ID
113      * @return the package name of the default home, or {@code null} if none
114      */
115     @Nullable
getDefaultHome(@onNull int userId)116     public String getDefaultHome(@NonNull int userId) {
117         return getRoleHolder(RoleManager.ROLE_HOME,
118                 mUserManagerInternalSupplier.get().getProfileParentId(userId));
119     }
120 
121     /**
122      * Set the package name of the default home.
123      *
124      * @param packageName package name of the default home
125      * @param userId the user ID
126      * @param executor the {@link Executor} to execute callback on
127      * @param callback the callback made after the default home as been updated
128      * @return whether the default home was set
129      */
setDefaultHome(@onNull String packageName, @UserIdInt int userId, @NonNull Executor executor, @NonNull Consumer<Boolean> callback)130     public boolean setDefaultHome(@NonNull String packageName, @UserIdInt int userId,
131             @NonNull Executor executor, @NonNull Consumer<Boolean> callback) {
132         final RoleManager roleManager = mRoleManagerSupplier.get();
133         if (roleManager == null) {
134             return false;
135         }
136         final long identity = Binder.clearCallingIdentity();
137         try {
138             roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, packageName, 0,
139                     UserHandle.of(userId), executor, callback);
140         } finally {
141             Binder.restoreCallingIdentity(identity);
142         }
143         return true;
144     }
145 
146     @Nullable
getRoleHolder(@onNull String roleName, @NonNull int userId)147     private String getRoleHolder(@NonNull String roleName, @NonNull int userId) {
148         final RoleManager roleManager = mRoleManagerSupplier.get();
149         if (roleManager == null) {
150             return null;
151         }
152         final long identity = Binder.clearCallingIdentity();
153         try {
154             return CollectionUtils.firstOrNull(roleManager.getRoleHoldersAsUser(roleName,
155                     UserHandle.of(userId)));
156         } finally {
157             Binder.restoreCallingIdentity(identity);
158         }
159     }
160 }
161