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