1 /*
2  * Copyright (C) 2014 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.BroadcastReceiver;
21 import android.content.ComponentName;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.ServiceConnection;
26 import android.os.IBinder;
27 import android.os.RemoteException;
28 import android.os.ServiceManager;
29 import android.os.UserHandle;
30 import android.telecom.DefaultDialerManager;
31 import android.telecom.PhoneAccountHandle;
32 import android.telecom.TelecomManager;
33 import android.telephony.CarrierConfigManager;
34 import android.util.IntArray;
35 import android.util.Slog;
36 
37 import com.android.internal.annotations.GuardedBy;
38 import com.android.internal.telephony.SmsApplication;
39 import com.android.server.LocalServices;
40 import com.android.server.SystemService;
41 import com.android.server.pm.UserManagerService;
42 import com.android.server.pm.permission.PermissionManagerServiceInternal;
43 
44 /**
45  * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup
46  * to run in the system-server process so once it is loaded into memory it will stay running.
47  * @hide
48  */
49 public class TelecomLoaderService extends SystemService {
50     private static final String TAG = "TelecomLoaderService";
51 
52     private class TelecomServiceConnection implements ServiceConnection {
53         @Override
onServiceConnected(ComponentName name, IBinder service)54         public void onServiceConnected(ComponentName name, IBinder service) {
55             // Normally, we would listen for death here, but since telecom runs in the same process
56             // as this loader (process="system") thats redundant here.
57             try {
58                 service.linkToDeath(new IBinder.DeathRecipient() {
59                     @Override
60                     public void binderDied() {
61                         connectToTelecom();
62                     }
63                 }, 0);
64                 SmsApplication.getDefaultMmsApplication(mContext, false);
65                 ServiceManager.addService(Context.TELECOM_SERVICE, service);
66 
67                 synchronized (mLock) {
68                     final PermissionManagerServiceInternal permissionManager =
69                             LocalServices.getService(PermissionManagerServiceInternal.class);
70                     if (mDefaultSimCallManagerRequests != null) {
71                         if (mDefaultSimCallManagerRequests != null) {
72                             TelecomManager telecomManager =
73                                 (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
74                             PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager();
75                             if (phoneAccount != null) {
76                                 final int requestCount = mDefaultSimCallManagerRequests.size();
77                                 final String packageName =
78                                     phoneAccount.getComponentName().getPackageName();
79                                 for (int i = requestCount - 1; i >= 0; i--) {
80                                     final int userId = mDefaultSimCallManagerRequests.get(i);
81                                     mDefaultSimCallManagerRequests.remove(i);
82                                     permissionManager
83                                             .grantDefaultPermissionsToDefaultSimCallManager(
84                                                     packageName, userId);
85                                 }
86                             }
87                         }
88                     }
89                 }
90             } catch (RemoteException e) {
91                 Slog.w(TAG, "Failed linking to death.");
92             }
93         }
94 
95         @Override
onServiceDisconnected(ComponentName name)96         public void onServiceDisconnected(ComponentName name) {
97             connectToTelecom();
98         }
99     }
100 
101     private static final ComponentName SERVICE_COMPONENT = new ComponentName(
102             "com.android.server.telecom",
103             "com.android.server.telecom.components.TelecomService");
104 
105     private static final String SERVICE_ACTION = "com.android.ITelecomService";
106 
107     private final Object mLock = new Object();
108 
109     @GuardedBy("mLock")
110     private IntArray mDefaultSimCallManagerRequests;
111 
112     private final Context mContext;
113 
114     @GuardedBy("mLock")
115     private TelecomServiceConnection mServiceConnection;
116 
TelecomLoaderService(Context context)117     public TelecomLoaderService(Context context) {
118         super(context);
119         mContext = context;
120         registerDefaultAppProviders();
121     }
122 
123     @Override
onStart()124     public void onStart() {
125     }
126 
127     @Override
onBootPhase(int phase)128     public void onBootPhase(int phase) {
129         if (phase == PHASE_ACTIVITY_MANAGER_READY) {
130             registerDefaultAppNotifier();
131             registerCarrierConfigChangedReceiver();
132             connectToTelecom();
133         }
134     }
135 
connectToTelecom()136     private void connectToTelecom() {
137         synchronized (mLock) {
138             if (mServiceConnection != null) {
139                 // TODO: Is unbinding worth doing or wait for system to rebind?
140                 mContext.unbindService(mServiceConnection);
141                 mServiceConnection = null;
142             }
143 
144             TelecomServiceConnection serviceConnection = new TelecomServiceConnection();
145             Intent intent = new Intent(SERVICE_ACTION);
146             intent.setComponent(SERVICE_COMPONENT);
147             int flags = Context.BIND_IMPORTANT | Context.BIND_FOREGROUND_SERVICE
148                     | Context.BIND_AUTO_CREATE;
149 
150             // Bind to Telecom and register the service
151             if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.SYSTEM)) {
152                 mServiceConnection = serviceConnection;
153             }
154         }
155     }
156 
157 
registerDefaultAppProviders()158     private void registerDefaultAppProviders() {
159         final PermissionManagerServiceInternal permissionManager =
160                 LocalServices.getService(PermissionManagerServiceInternal.class);
161 
162         // Set a callback for the permission grant policy to query the default sms app.
163         permissionManager.setSmsAppPackagesProvider(userId -> {
164             synchronized (mLock) {
165                 if (mServiceConnection == null) {
166                     return null;
167                 }
168             }
169             ComponentName smsComponent = SmsApplication.getDefaultSmsApplication(
170                     mContext, true);
171             if (smsComponent != null) {
172                 return new String[]{smsComponent.getPackageName()};
173             }
174             return null;
175         });
176 
177         // Set a callback for the permission grant policy to query the default dialer app.
178         permissionManager.setDialerAppPackagesProvider(userId -> {
179             synchronized (mLock) {
180                 if (mServiceConnection == null) {
181                     return null;
182                 }
183             }
184             String packageName = DefaultDialerManager.getDefaultDialerApplication(mContext);
185             if (packageName != null) {
186                 return new String[]{packageName};
187             }
188             return null;
189         });
190 
191         // Set a callback for the permission grant policy to query the default sim call manager.
192         permissionManager.setSimCallManagerPackagesProvider(userId -> {
193             synchronized (mLock) {
194                 if (mServiceConnection == null) {
195                     if (mDefaultSimCallManagerRequests == null) {
196                         mDefaultSimCallManagerRequests = new IntArray();
197                     }
198                     mDefaultSimCallManagerRequests.add(userId);
199                     return null;
200                 }
201             }
202             TelecomManager telecomManager =
203                     (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
204             PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
205             if (phoneAccount != null) {
206                 return new String[]{phoneAccount.getComponentName().getPackageName()};
207             }
208             return null;
209         });
210     }
211 
registerDefaultAppNotifier()212     private void registerDefaultAppNotifier() {
213         // Notify the package manager on default app changes
214         final RoleManager roleManager = mContext.getSystemService(RoleManager.class);
215         roleManager.addOnRoleHoldersChangedListenerAsUser(mContext.getMainExecutor(),
216                 (roleName, user) -> updateSimCallManagerPermissions(user.getIdentifier()),
217                 UserHandle.ALL);
218     }
219 
220 
registerCarrierConfigChangedReceiver()221     private void registerCarrierConfigChangedReceiver() {
222         BroadcastReceiver receiver = new BroadcastReceiver() {
223             @Override
224             public void onReceive(Context context, Intent intent) {
225                 if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
226                     for (int userId : UserManagerService.getInstance().getUserIds()) {
227                         updateSimCallManagerPermissions(userId);
228                     }
229                 }
230             }
231         };
232 
233         mContext.registerReceiverAsUser(receiver, UserHandle.ALL,
234             new IntentFilter(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED), null, null);
235     }
236 
updateSimCallManagerPermissions(int userId)237     private void updateSimCallManagerPermissions(int userId) {
238         final PermissionManagerServiceInternal permissionManager =
239                 LocalServices.getService(PermissionManagerServiceInternal.class);
240         TelecomManager telecomManager =
241             (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
242         PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
243         if (phoneAccount != null) {
244             Slog.i(TAG, "updating sim call manager permissions for userId:" + userId);
245             String packageName = phoneAccount.getComponentName().getPackageName();
246             permissionManager.grantDefaultPermissionsToDefaultSimCallManager(packageName, userId);
247         }
248     }
249 }
250