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