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