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