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