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 com.android.internal.annotations.VisibleForTesting;
20 import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
21 import com.android.server.telecom.bluetooth.BluetoothRouteManager;
22 import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
23 import com.android.server.telecom.callfiltering.IncomingCallFilter;
24 import com.android.server.telecom.components.UserCallIntentProcessor;
25 import com.android.server.telecom.components.UserCallIntentProcessorFactory;
26 import com.android.server.telecom.ui.AudioProcessingNotification;
27 import com.android.server.telecom.ui.DisconnectedCallNotifier;
28 import com.android.server.telecom.ui.IncomingCallNotifier;
29 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
30 import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
31 import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
32 import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
33 import com.android.server.telecom.ui.ToastFactory;
34 
35 import android.app.ActivityManager;
36 import android.Manifest;
37 import android.content.BroadcastReceiver;
38 import android.content.Context;
39 import android.content.Intent;
40 import android.content.IntentFilter;
41 import android.content.pm.ApplicationInfo;
42 import android.content.pm.PackageManager;
43 import android.net.Uri;
44 import android.os.UserHandle;
45 import android.os.UserManager;
46 import android.telecom.Log;
47 import android.telecom.PhoneAccountHandle;
48 import android.widget.Toast;
49 
50 import java.io.FileNotFoundException;
51 import java.io.InputStream;
52 
53 /**
54  * Top-level Application class for Telecom.
55  */
56 public class TelecomSystem {
57 
58     /**
59      * This interface is implemented by system-instantiated components (e.g., Services and
60      * Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a
61      * component should implement the getTelecomSystem() method to return the global singleton,
62      * and use its own method. Tests can subclass the component to return a non-singleton.
63      *
64      * A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those
65      * system-instantiated components, and have all other parts of the system just take all their
66      * dependencies as explicit arguments to their constructor or other methods.
67      */
68     public interface Component {
getTelecomSystem()69         TelecomSystem getTelecomSystem();
70     }
71 
72 
73     /**
74      * Tagging interface for the object used for synchronizing multi-threaded operations in
75      * the Telecom system.
76      */
77     public interface SyncRoot {
78     }
79 
80     private static final IntentFilter USER_SWITCHED_FILTER =
81             new IntentFilter(Intent.ACTION_USER_SWITCHED);
82 
83     private static final IntentFilter USER_STARTING_FILTER =
84             new IntentFilter(Intent.ACTION_USER_STARTING);
85 
86     private static final IntentFilter BOOT_COMPLETE_FILTER =
87             new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
88 
89     /** Intent filter for dialer secret codes. */
90     private static final IntentFilter DIALER_SECRET_CODE_FILTER;
91 
92     /**
93      * Initializes the dialer secret code intent filter.  Setup to handle the various secret codes
94      * which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom.
95      */
96     static {
97         DIALER_SECRET_CODE_FILTER = new IntentFilter(
98                 "android.provider.Telephony.SECRET_CODE");
99         DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code");
100         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null)101                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
102         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null)103                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
104         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null)105                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null);
106         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MENU, null)107                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MENU, null);
108     }
109 
110     private static TelecomSystem INSTANCE = null;
111 
112     private final SyncRoot mLock = new SyncRoot() { };
113     private final MissedCallNotifier mMissedCallNotifier;
114     private final IncomingCallNotifier mIncomingCallNotifier;
115     private final PhoneAccountRegistrar mPhoneAccountRegistrar;
116     private final CallsManager mCallsManager;
117     private final RespondViaSmsManager mRespondViaSmsManager;
118     private final Context mContext;
119     private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
120     private final CallIntentProcessor mCallIntentProcessor;
121     private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
122     private final TelecomServiceImpl mTelecomServiceImpl;
123     private final ContactsAsyncHelper mContactsAsyncHelper;
124     private final DialerCodeReceiver mDialerCodeReceiver;
125 
126     private boolean mIsBootComplete = false;
127 
128     private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
129         @Override
130         public void onReceive(Context context, Intent intent) {
131             Log.startSession("TSSwR.oR");
132             try {
133                 synchronized (mLock) {
134                     int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
135                     UserHandle currentUserHandle = new UserHandle(userHandleId);
136                     mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
137                     mCallsManager.onUserSwitch(currentUserHandle);
138                 }
139             } finally {
140                 Log.endSession();
141             }
142         }
143     };
144 
145     private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() {
146         @Override
147         public void onReceive(Context context, Intent intent) {
148             Log.startSession("TSStR.oR");
149             try {
150                 synchronized (mLock) {
151                     int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
152                     UserHandle addingUserHandle = new UserHandle(userHandleId);
153                     mCallsManager.onUserStarting(addingUserHandle);
154                 }
155             } finally {
156                 Log.endSession();
157             }
158         }
159     };
160 
161     private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
162         @Override
163         public void onReceive(Context context, Intent intent) {
164             Log.startSession("TSBCR.oR");
165             try {
166                 synchronized (mLock) {
167                     mIsBootComplete = true;
168                     mCallsManager.onBootCompleted();
169                 }
170             } finally {
171                 Log.endSession();
172             }
173         }
174     };
175 
getInstance()176     public static TelecomSystem getInstance() {
177         return INSTANCE;
178     }
179 
setInstance(TelecomSystem instance)180     public static void setInstance(TelecomSystem instance) {
181         if (INSTANCE != null) {
182             Log.w("TelecomSystem", "Attempt to set TelecomSystem.INSTANCE twice");
183         }
184         Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set");
185         INSTANCE = instance;
186     }
187 
TelecomSystem( Context context, MissedCallNotifierImplFactory missedCallNotifierImplFactory, CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory, HeadsetMediaButtonFactory headsetMediaButtonFactory, ProximitySensorManagerFactory proximitySensorManagerFactory, InCallWakeLockControllerFactory inCallWakeLockControllerFactory, AudioServiceFactory audioServiceFactory, BluetoothPhoneServiceImplFactory bluetoothPhoneServiceImplFactory, ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory connectionServiceFocusManagerFactory, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer, PhoneNumberUtilsAdapter phoneNumberUtilsAdapter, IncomingCallNotifier incomingCallNotifier, InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory, CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory, CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory, ClockProxy clockProxy, RoleManagerAdapter roleManagerAdapter, IncomingCallFilter.Factory incomingCallFilterFactory, ContactsAsyncHelper.Factory contactsAsyncHelperFactory)188     public TelecomSystem(
189             Context context,
190             MissedCallNotifierImplFactory missedCallNotifierImplFactory,
191             CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
192             HeadsetMediaButtonFactory headsetMediaButtonFactory,
193             ProximitySensorManagerFactory proximitySensorManagerFactory,
194             InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
195             AudioServiceFactory audioServiceFactory,
196             BluetoothPhoneServiceImplFactory
197                     bluetoothPhoneServiceImplFactory,
198             ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
199                     connectionServiceFocusManagerFactory,
200             Timeouts.Adapter timeoutsAdapter,
201             AsyncRingtonePlayer asyncRingtonePlayer,
202             PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
203             IncomingCallNotifier incomingCallNotifier,
204             InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
205             CallAudioRouteStateMachine.Factory callAudioRouteStateMachineFactory,
206             CallAudioModeStateMachine.Factory callAudioModeStateMachineFactory,
207             ClockProxy clockProxy,
208             RoleManagerAdapter roleManagerAdapter,
209             IncomingCallFilter.Factory incomingCallFilterFactory,
210             ContactsAsyncHelper.Factory contactsAsyncHelperFactory) {
211         mContext = context.getApplicationContext();
212         LogUtils.initLogging(mContext);
213         DefaultDialerManagerAdapter defaultDialerAdapter =
214                 new DefaultDialerCache.DefaultDialerManagerAdapterImpl();
215 
216         DefaultDialerCache defaultDialerCache = new DefaultDialerCache(mContext,
217                 defaultDialerAdapter, roleManagerAdapter, mLock);
218 
219         Log.startSession("TS.init");
220         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache,
221                 packageName -> AppLabelProxy.Util.getAppLabel(
222                         mContext.getPackageManager(), packageName));
223 
224         mContactsAsyncHelper = contactsAsyncHelperFactory.create(
225                 new ContactsAsyncHelper.ContentResolverAdapter() {
226                     @Override
227                     public InputStream openInputStream(Context context, Uri uri)
228                             throws FileNotFoundException {
229                         return context.getContentResolver().openInputStream(uri);
230                     }
231                 });
232         BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
233                 new BluetoothAdapterProxy());
234         BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
235                 bluetoothDeviceManager, new Timeouts.Adapter());
236         BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
237                 bluetoothDeviceManager, bluetoothRouteManager);
238         mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER);
239 
240         WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
241         SystemStateHelper systemStateHelper = new SystemStateHelper(mContext);
242 
243         mMissedCallNotifier = missedCallNotifierImplFactory
244                 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, defaultDialerCache);
245         DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory =
246                 new DisconnectedCallNotifier.Default();
247 
248         CallerInfoLookupHelper callerInfoLookupHelper =
249                 new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory,
250                         mContactsAsyncHelper, mLock);
251 
252         EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
253                 defaultDialerCache, timeoutsAdapter);
254 
255         InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
256             @Override
257             public InCallController create(Context context, SyncRoot lock,
258                     CallsManager callsManager, SystemStateHelper systemStateProvider,
259                     DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
260                     EmergencyCallHelper emergencyCallHelper) {
261                 return new InCallController(context, lock, callsManager, systemStateProvider,
262                         defaultDialerCache, timeoutsAdapter, emergencyCallHelper,
263                         new CarModeTracker(), clockProxy);
264             }
265         };
266 
267         AudioProcessingNotification audioProcessingNotification =
268                 new AudioProcessingNotification(mContext);
269 
270         ToastFactory toastFactory = new ToastFactory() {
271             @Override
272             public Toast makeText(Context context, int resId, int duration) {
273                 return Toast.makeText(context, context.getMainLooper(), context.getString(resId),
274                         duration);
275             }
276 
277             @Override
278             public Toast makeText(Context context, CharSequence text, int duration) {
279                 return Toast.makeText(context, context.getMainLooper(), text, duration);
280             }
281         };
282 
283         mCallsManager = new CallsManager(
284                 mContext,
285                 mLock,
286                 callerInfoLookupHelper,
287                 mMissedCallNotifier,
288                 disconnectedCallNotifierFactory,
289                 mPhoneAccountRegistrar,
290                 headsetMediaButtonFactory,
291                 proximitySensorManagerFactory,
292                 inCallWakeLockControllerFactory,
293                 connectionServiceFocusManagerFactory,
294                 audioServiceFactory,
295                 bluetoothRouteManager,
296                 wiredHeadsetManager,
297                 systemStateHelper,
298                 defaultDialerCache,
299                 timeoutsAdapter,
300                 asyncRingtonePlayer,
301                 phoneNumberUtilsAdapter,
302                 emergencyCallHelper,
303                 toneGeneratorFactory,
304                 clockProxy,
305                 audioProcessingNotification,
306                 bluetoothStateReceiver,
307                 callAudioRouteStateMachineFactory,
308                 callAudioModeStateMachineFactory,
309                 inCallControllerFactory,
310                 roleManagerAdapter,
311                 incomingCallFilterFactory,
312                 toastFactory);
313 
314         mIncomingCallNotifier = incomingCallNotifier;
315         incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
316             @Override
317             public boolean hasUnholdableCallsForOtherConnectionService(
318                     PhoneAccountHandle phoneAccountHandle) {
319                 return mCallsManager.hasUnholdableCallsForOtherConnectionService(
320                         phoneAccountHandle);
321             }
322 
323             @Override
324             public int getNumUnholdableCallsForOtherConnectionService(
325                     PhoneAccountHandle phoneAccountHandle) {
326                 return mCallsManager.getNumUnholdableCallsForOtherConnectionService(
327                         phoneAccountHandle);
328             }
329 
330             @Override
331             public Call getActiveCall() {
332                 return mCallsManager.getActiveCall();
333             }
334         });
335         mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);
336 
337         mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
338         mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
339 
340         mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL,
341                 USER_SWITCHED_FILTER, null, null);
342         mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL,
343                 USER_STARTING_FILTER, null, null);
344         mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL,
345                 BOOT_COMPLETE_FILTER, null, null);
346 
347         // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at startup
348         synchronized(mLock) {
349             UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
350             mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
351             mCallsManager.onUserSwitch(currentUserHandle);
352         }
353 
354         mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
355                 mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
356         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
357         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
358                 mContext, mCallsManager);
359 
360         // Register the receiver for the dialer secret codes, used to enable extended logging.
361         mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
362         mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
363                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
364 
365         // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
366         final UserManager userManager = UserManager.get(mContext);
367         mTelecomServiceImpl = new TelecomServiceImpl(
368                 mContext, mCallsManager, mPhoneAccountRegistrar,
369                 new CallIntentProcessor.AdapterImpl(defaultDialerCache),
370                 new UserCallIntentProcessorFactory() {
371                     @Override
372                     public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
373                         return new UserCallIntentProcessor(context, userHandle);
374                     }
375                 },
376                 defaultDialerCache,
377                 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
378                 new TelecomServiceImpl.SettingsSecureAdapterImpl(),
379                 mLock);
380         Log.endSession();
381     }
382 
383     @VisibleForTesting
getPhoneAccountRegistrar()384     public PhoneAccountRegistrar getPhoneAccountRegistrar() {
385         return mPhoneAccountRegistrar;
386     }
387 
388     @VisibleForTesting
getCallsManager()389     public CallsManager getCallsManager() {
390         return mCallsManager;
391     }
392 
getBluetoothPhoneServiceImpl()393     public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
394         return mBluetoothPhoneServiceImpl;
395     }
396 
getCallIntentProcessor()397     public CallIntentProcessor getCallIntentProcessor() {
398         return mCallIntentProcessor;
399     }
400 
getTelecomBroadcastIntentProcessor()401     public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
402         return mTelecomBroadcastIntentProcessor;
403     }
404 
getTelecomServiceImpl()405     public TelecomServiceImpl getTelecomServiceImpl() {
406         return mTelecomServiceImpl;
407     }
408 
getLock()409     public Object getLock() {
410         return mLock;
411     }
412 
isBootComplete()413     public boolean isBootComplete() {
414         return mIsBootComplete;
415     }
416 }
417