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