1 /*
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 
17 package com.android.server.telecom;
18 
19 import android.app.role.RoleManager;
20 import android.content.Context;
21 import android.content.pm.ApplicationInfo;
22 import android.content.pm.PackageManager;
23 import android.os.Binder;
24 import android.os.UserHandle;
25 import android.telecom.Log;
26 
27 import com.android.internal.util.IndentingPrintWriter;
28 
29 import java.util.ArrayList;
30 import java.util.List;
31 import java.util.concurrent.Executor;
32 import java.util.function.IntConsumer;
33 import java.util.stream.Collectors;
34 
35 public class RoleManagerAdapterImpl implements RoleManagerAdapter {
36     private static final String ROLE_CALL_REDIRECTION_APP = RoleManager.ROLE_CALL_REDIRECTION;
37     private static final String ROLE_CALL_SCREENING = RoleManager.ROLE_CALL_SCREENING;
38     private static final String ROLE_DIALER = RoleManager.ROLE_DIALER;
39 
40     private String mOverrideDefaultCallRedirectionApp = null;
41     private String mOverrideDefaultCallScreeningApp = null;
42     private String mOverrideDefaultDialerApp = null;
43     private List<String> mOverrideCallCompanionApps = new ArrayList<>();
44     private String mOverrideBTInCallService = null;
45     private Context mContext;
46     private RoleManager mRoleManager;
47     private UserHandle mCurrentUserHandle;
48 
RoleManagerAdapterImpl(Context context, RoleManager roleManager)49     public RoleManagerAdapterImpl(Context context, RoleManager roleManager) {
50         mContext = context;
51         mRoleManager = roleManager;
52     }
53 
54     @Override
getDefaultCallRedirectionApp(UserHandle userHandleForCallRedirection)55     public String getDefaultCallRedirectionApp(UserHandle userHandleForCallRedirection) {
56         if (mOverrideDefaultCallRedirectionApp != null) {
57             return mOverrideDefaultCallRedirectionApp;
58         }
59         return getRoleManagerCallRedirectionApp(userHandleForCallRedirection);
60     }
61 
62     @Override
setTestDefaultCallRedirectionApp(String packageName)63     public void setTestDefaultCallRedirectionApp(String packageName) {
64         mOverrideDefaultCallRedirectionApp = packageName;
65     }
66 
67     @Override
getDefaultCallScreeningApp(UserHandle userHandleForCallScreening)68     public String getDefaultCallScreeningApp(UserHandle userHandleForCallScreening) {
69         if (mOverrideDefaultCallScreeningApp != null) {
70             return mOverrideDefaultCallScreeningApp;
71         }
72         return getRoleManagerCallScreeningApp(userHandleForCallScreening);
73     }
74 
75     @Override
setTestDefaultCallScreeningApp(String packageName)76     public void setTestDefaultCallScreeningApp(String packageName) {
77         mOverrideDefaultCallScreeningApp = packageName;
78     }
79 
80     @Override
getBTInCallService()81     public String[] getBTInCallService() {
82         if (mOverrideBTInCallService != null) {
83             return new String [] {mOverrideBTInCallService};
84         }
85         return getBluetoothInCallServicePackageName();
86     }
87 
88     @Override
setTestBTInCallService(String packageName)89     public void setTestBTInCallService(String packageName) {
90         mOverrideBTInCallService = packageName;
91     }
92 
93 
94     @Override
getDefaultDialerApp(int user)95     public String getDefaultDialerApp(int user) {
96         if (mOverrideDefaultDialerApp != null) {
97             return mOverrideDefaultDialerApp;
98         }
99         return getRoleManagerDefaultDialerApp(user);
100     }
101 
102     @Override
observeDefaultDialerApp(Executor executor, IntConsumer observer)103     public void observeDefaultDialerApp(Executor executor, IntConsumer observer) {
104         mRoleManager.addOnRoleHoldersChangedListenerAsUser(executor, (roleName, user) -> {
105                     if (ROLE_DIALER.equals(roleName)) {
106                         observer.accept(user.getIdentifier());
107                     }
108                 }, UserHandle.ALL);
109     }
110 
111     @Override
setTestDefaultDialer(String packageName)112     public void setTestDefaultDialer(String packageName) {
113         mOverrideDefaultDialerApp = packageName;
114     }
115 
116     @Override
getCallCompanionApps()117     public List<String> getCallCompanionApps() {
118         List<String> callCompanionApps = new ArrayList<>();
119         callCompanionApps.addAll(mOverrideCallCompanionApps);
120         return callCompanionApps;
121     }
122 
123     @Override
addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded)124     public void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded) {
125         if (isAdded) {
126             mOverrideCallCompanionApps.add(packageName);
127         } else {
128             mOverrideCallCompanionApps.remove(packageName);
129         }
130     }
131 
132     @Override
setCurrentUserHandle(UserHandle currentUserHandle)133     public void setCurrentUserHandle(UserHandle currentUserHandle) {
134         mCurrentUserHandle = currentUserHandle;
135     }
136 
getRoleManagerCallScreeningApp(UserHandle userHandle)137     private String getRoleManagerCallScreeningApp(UserHandle userHandle) {
138         List<String> roleHolders = mRoleManager.getRoleHoldersAsUser(ROLE_CALL_SCREENING,
139                 userHandle);
140         if (roleHolders == null || roleHolders.isEmpty()) {
141             return null;
142         }
143         return roleHolders.get(0);
144     }
145 
getRoleManagerDefaultDialerApp(int user)146     private String getRoleManagerDefaultDialerApp(int user) {
147         List<String> roleHolders = mRoleManager.getRoleHoldersAsUser(ROLE_DIALER,
148                 new UserHandle(user));
149         if (roleHolders == null || roleHolders.isEmpty()) {
150             return null;
151         }
152         return roleHolders.get(0);
153     }
154 
155     // TODO in R: Use companion app manager
getRoleManagerCallCompanionApps()156     private List<String> getRoleManagerCallCompanionApps() {
157         return new ArrayList<>();
158     }
159 
getRoleManagerCallRedirectionApp(UserHandle userHandle)160     private String getRoleManagerCallRedirectionApp(UserHandle userHandle) {
161         List<String> roleHolders = mRoleManager.getRoleHoldersAsUser(ROLE_CALL_REDIRECTION_APP,
162                 userHandle);
163         if (roleHolders == null || roleHolders.isEmpty()) {
164             return null;
165         }
166         return roleHolders.get(0);
167     }
168 
getBluetoothInCallServicePackageName()169     private String[] getBluetoothInCallServicePackageName() {
170         return mContext.getResources().getStringArray(R.array.system_bluetooth_stack_package_name);
171     }
172 
173     /**
174      * Returns the application label that corresponds to the given package name
175      *
176      * @param packageName A valid package name.
177      *
178      * @return Application label for the given package name, or null if not found.
179      */
180     @Override
getApplicationLabelForPackageName(String packageName)181     public String getApplicationLabelForPackageName(String packageName) {
182         PackageManager pm = mContext.getPackageManager();
183         ApplicationInfo info = null;
184         try {
185             info = pm.getApplicationInfo(packageName, 0);
186         } catch (PackageManager.NameNotFoundException e) {
187             Log.d(this, "Application info not found for packageName " + packageName);
188         }
189         if (info == null) {
190             return packageName;
191         } else {
192             return info.loadLabel(pm).toString();
193         }
194     }
195 
196     /**
197      * Dumps the state of the {@link InCallController}.
198      *
199      * @param pw The {@code IndentingPrintWriter} to write the state to.
200      */
dump(IndentingPrintWriter pw)201     public void dump(IndentingPrintWriter pw) {
202         pw.print("DefaultCallRedirectionApp: ");
203         if (mOverrideDefaultCallRedirectionApp != null) {
204             pw.print("(override ");
205             pw.print(mOverrideDefaultCallRedirectionApp);
206             pw.print(") ");
207             pw.print(getRoleManagerCallRedirectionApp(Binder.getCallingUserHandle()));
208         }
209         pw.println();
210 
211         pw.print("DefaultCallScreeningApp: ");
212         if (mOverrideDefaultCallScreeningApp != null) {
213             pw.print("(override ");
214             pw.print(mOverrideDefaultCallScreeningApp);
215             pw.print(") ");
216             pw.print(getRoleManagerCallScreeningApp(Binder.getCallingUserHandle()));
217         }
218         pw.println();
219 
220         pw.print("DefaultCallCompanionApps: ");
221         if (mOverrideCallCompanionApps != null) {
222             pw.print("(override ");
223             pw.print(mOverrideCallCompanionApps.stream().collect(Collectors.joining(", ")));
224             pw.print(") ");
225             List<String> appsInRole = getRoleManagerCallCompanionApps();
226             if (appsInRole != null) {
227                 pw.print(appsInRole.stream().collect(Collectors.joining(", ")));
228             }
229         }
230         pw.println();
231     }
232 }
233