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