• 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.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, DeviceIdleControllerAdapter deviceIdleControllerAdapter)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             DeviceIdleControllerAdapter deviceIdleControllerAdapter) {
212         mContext = context.getApplicationContext();
213         LogUtils.initLogging(mContext);
214         DefaultDialerManagerAdapter defaultDialerAdapter =
215                 new DefaultDialerCache.DefaultDialerManagerAdapterImpl();
216 
217         DefaultDialerCache defaultDialerCache = new DefaultDialerCache(mContext,
218                 defaultDialerAdapter, roleManagerAdapter, mLock);
219 
220         Log.startSession("TS.init");
221         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache,
222                 packageName -> AppLabelProxy.Util.getAppLabel(
223                         mContext.getPackageManager(), packageName));
224 
225         mContactsAsyncHelper = contactsAsyncHelperFactory.create(
226                 new ContactsAsyncHelper.ContentResolverAdapter() {
227                     @Override
228                     public InputStream openInputStream(Context context, Uri uri)
229                             throws FileNotFoundException {
230                         return context.getContentResolver().openInputStream(uri);
231                     }
232                 });
233         BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
234                 new BluetoothAdapterProxy());
235         BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
236                 bluetoothDeviceManager, new Timeouts.Adapter());
237         BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
238                 bluetoothDeviceManager, bluetoothRouteManager);
239         mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER);
240 
241         WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
242         SystemStateHelper systemStateHelper = new SystemStateHelper(mContext);
243 
244         mMissedCallNotifier = missedCallNotifierImplFactory
245                 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, defaultDialerCache,
246                         deviceIdleControllerAdapter);
247         DisconnectedCallNotifier.Factory disconnectedCallNotifierFactory =
248                 new DisconnectedCallNotifier.Default();
249 
250         CallerInfoLookupHelper callerInfoLookupHelper =
251                 new CallerInfoLookupHelper(context, callerInfoAsyncQueryFactory,
252                         mContactsAsyncHelper, mLock);
253 
254         EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
255                 defaultDialerCache, timeoutsAdapter);
256 
257         InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
258             @Override
259             public InCallController create(Context context, SyncRoot lock,
260                     CallsManager callsManager, SystemStateHelper systemStateProvider,
261                     DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
262                     EmergencyCallHelper emergencyCallHelper) {
263                 return new InCallController(context, lock, callsManager, systemStateProvider,
264                         defaultDialerCache, timeoutsAdapter, emergencyCallHelper,
265                         new CarModeTracker(), clockProxy);
266             }
267         };
268 
269         AudioProcessingNotification audioProcessingNotification =
270                 new AudioProcessingNotification(mContext);
271 
272         ToastFactory toastFactory = new ToastFactory() {
273             @Override
274             public Toast makeText(Context context, int resId, int duration) {
275                 return Toast.makeText(context, context.getMainLooper(), context.getString(resId),
276                         duration);
277             }
278 
279             @Override
280             public Toast makeText(Context context, CharSequence text, int duration) {
281                 return Toast.makeText(context, context.getMainLooper(), text, duration);
282             }
283         };
284 
285         mCallsManager = new CallsManager(
286                 mContext,
287                 mLock,
288                 callerInfoLookupHelper,
289                 mMissedCallNotifier,
290                 disconnectedCallNotifierFactory,
291                 mPhoneAccountRegistrar,
292                 headsetMediaButtonFactory,
293                 proximitySensorManagerFactory,
294                 inCallWakeLockControllerFactory,
295                 connectionServiceFocusManagerFactory,
296                 audioServiceFactory,
297                 bluetoothRouteManager,
298                 wiredHeadsetManager,
299                 systemStateHelper,
300                 defaultDialerCache,
301                 timeoutsAdapter,
302                 asyncRingtonePlayer,
303                 phoneNumberUtilsAdapter,
304                 emergencyCallHelper,
305                 toneGeneratorFactory,
306                 clockProxy,
307                 audioProcessingNotification,
308                 bluetoothStateReceiver,
309                 callAudioRouteStateMachineFactory,
310                 callAudioModeStateMachineFactory,
311                 inCallControllerFactory,
312                 roleManagerAdapter,
313                 incomingCallFilterFactory,
314                 toastFactory);
315 
316         mIncomingCallNotifier = incomingCallNotifier;
317         incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
318             @Override
319             public boolean hasUnholdableCallsForOtherConnectionService(
320                     PhoneAccountHandle phoneAccountHandle) {
321                 return mCallsManager.hasUnholdableCallsForOtherConnectionService(
322                         phoneAccountHandle);
323             }
324 
325             @Override
326             public int getNumUnholdableCallsForOtherConnectionService(
327                     PhoneAccountHandle phoneAccountHandle) {
328                 return mCallsManager.getNumUnholdableCallsForOtherConnectionService(
329                         phoneAccountHandle);
330             }
331 
332             @Override
333             public Call getActiveCall() {
334                 return mCallsManager.getActiveCall();
335             }
336         });
337         mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);
338 
339         mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
340         mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
341 
342         mContext.registerReceiverAsUser(mUserSwitchedReceiver, UserHandle.ALL,
343                 USER_SWITCHED_FILTER, null, null);
344         mContext.registerReceiverAsUser(mUserStartingReceiver, UserHandle.ALL,
345                 USER_STARTING_FILTER, null, null);
346         mContext.registerReceiverAsUser(mBootCompletedReceiver, UserHandle.ALL,
347                 BOOT_COMPLETE_FILTER, null, null);
348 
349         // Set current user explicitly since USER_SWITCHED_FILTER intent can be missed at startup
350         synchronized(mLock) {
351             UserHandle currentUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
352             mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
353             mCallsManager.onUserSwitch(currentUserHandle);
354         }
355 
356         mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
357                 mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
358         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager, defaultDialerCache);
359         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
360                 mContext, mCallsManager);
361 
362         // Register the receiver for the dialer secret codes, used to enable extended logging.
363         mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
364         mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
365                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
366 
367         // There is no USER_SWITCHED broadcast for user 0, handle it here explicitly.
368         final UserManager userManager = UserManager.get(mContext);
369         mTelecomServiceImpl = new TelecomServiceImpl(
370                 mContext, mCallsManager, mPhoneAccountRegistrar,
371                 new CallIntentProcessor.AdapterImpl(defaultDialerCache),
372                 new UserCallIntentProcessorFactory() {
373                     @Override
374                     public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
375                         return new UserCallIntentProcessor(context, userHandle);
376                     }
377                 },
378                 defaultDialerCache,
379                 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
380                 new TelecomServiceImpl.SettingsSecureAdapterImpl(),
381                 mLock);
382         Log.endSession();
383     }
384 
385     @VisibleForTesting
getPhoneAccountRegistrar()386     public PhoneAccountRegistrar getPhoneAccountRegistrar() {
387         return mPhoneAccountRegistrar;
388     }
389 
390     @VisibleForTesting
getCallsManager()391     public CallsManager getCallsManager() {
392         return mCallsManager;
393     }
394 
getBluetoothPhoneServiceImpl()395     public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
396         return mBluetoothPhoneServiceImpl;
397     }
398 
getCallIntentProcessor()399     public CallIntentProcessor getCallIntentProcessor() {
400         return mCallIntentProcessor;
401     }
402 
getTelecomBroadcastIntentProcessor()403     public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
404         return mTelecomBroadcastIntentProcessor;
405     }
406 
getTelecomServiceImpl()407     public TelecomServiceImpl getTelecomServiceImpl() {
408         return mTelecomServiceImpl;
409     }
410 
getLock()411     public Object getLock() {
412         return mLock;
413     }
414 
isBootComplete()415     public boolean isBootComplete() {
416         return mIsBootComplete;
417     }
418 }
419