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.components.UserCallIntentProcessor;
21 import com.android.server.telecom.components.UserCallIntentProcessorFactory;
22 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
23 import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
24 import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
25 import com.android.server.telecom.TelecomServiceImpl.DefaultDialerManagerAdapter;
26 
27 import android.Manifest;
28 import android.content.BroadcastReceiver;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.net.Uri;
33 import android.os.UserHandle;
34 
35 import java.io.FileNotFoundException;
36 import java.io.InputStream;
37 
38 /**
39  * Top-level Application class for Telecom.
40  */
41 public final class TelecomSystem {
42 
43     /**
44      * This interface is implemented by system-instantiated components (e.g., Services and
45      * Activity-s) that wish to use the TelecomSystem but would like to be testable. Such a
46      * component should implement the getTelecomSystem() method to return the global singleton,
47      * and use its own method. Tests can subclass the component to return a non-singleton.
48      *
49      * A refactoring goal for Telecom is to limit use of the TelecomSystem singleton to those
50      * system-instantiated components, and have all other parts of the system just take all their
51      * dependencies as explicit arguments to their constructor or other methods.
52      */
53     public interface Component {
getTelecomSystem()54         TelecomSystem getTelecomSystem();
55     }
56 
57 
58     /**
59      * Tagging interface for the object used for synchronizing multi-threaded operations in
60      * the Telecom system.
61      */
62     public interface SyncRoot {
63     }
64 
65     private static final IntentFilter USER_SWITCHED_FILTER =
66             new IntentFilter(Intent.ACTION_USER_SWITCHED);
67 
68     private static final IntentFilter USER_STARTING_FILTER =
69             new IntentFilter(Intent.ACTION_USER_STARTING);
70 
71     /** Intent filter for dialer secret codes. */
72     private static final IntentFilter DIALER_SECRET_CODE_FILTER;
73 
74     /**
75      * Initializes the dialer secret code intent filter.  Setup to handle the various secret codes
76      * which can be dialed (e.g. in format *#*#code#*#*) to trigger various behavior in Telecom.
77      */
78     static {
79         DIALER_SECRET_CODE_FILTER = new IntentFilter(
80                 "android.provider.Telephony.SECRET_CODE");
81         DIALER_SECRET_CODE_FILTER.addDataScheme("android_secret_code");
82         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null)83                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
84         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null)85                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
86         DIALER_SECRET_CODE_FILTER
addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null)87                 .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_MARK, null);
88     }
89 
90     private static TelecomSystem INSTANCE = null;
91 
92     private final SyncRoot mLock = new SyncRoot() { };
93     private final MissedCallNotifier mMissedCallNotifier;
94     private final PhoneAccountRegistrar mPhoneAccountRegistrar;
95     private final CallsManager mCallsManager;
96     private final RespondViaSmsManager mRespondViaSmsManager;
97     private final Context mContext;
98     private final BluetoothPhoneServiceImpl mBluetoothPhoneServiceImpl;
99     private final CallIntentProcessor mCallIntentProcessor;
100     private final TelecomBroadcastIntentProcessor mTelecomBroadcastIntentProcessor;
101     private final TelecomServiceImpl mTelecomServiceImpl;
102     private final ContactsAsyncHelper mContactsAsyncHelper;
103     private final DialerCodeReceiver mDialerCodeReceiver;
104 
105     private final BroadcastReceiver mUserSwitchedReceiver = new BroadcastReceiver() {
106         @Override
107         public void onReceive(Context context, Intent intent) {
108             Log.startSession("TSSwR.oR");
109             try {
110                 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
111                 UserHandle currentUserHandle = new UserHandle(userHandleId);
112                 mPhoneAccountRegistrar.setCurrentUserHandle(currentUserHandle);
113                 mCallsManager.onUserSwitch(currentUserHandle);
114             } finally {
115                 Log.endSession();
116             }
117         }
118     };
119 
120     private final BroadcastReceiver mUserStartingReceiver = new BroadcastReceiver() {
121         @Override
122         public void onReceive(Context context, Intent intent) {
123             Log.startSession("TSStR.oR");
124             try {
125                 int userHandleId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
126                 UserHandle addingUserHandle = new UserHandle(userHandleId);
127                 mCallsManager.onUserStarting(addingUserHandle);
128             } finally {
129                 Log.endSession();
130             }
131         }
132     };
133 
getInstance()134     public static TelecomSystem getInstance() {
135         return INSTANCE;
136     }
137 
setInstance(TelecomSystem instance)138     public static void setInstance(TelecomSystem instance) {
139         if (INSTANCE != null) {
140             throw new RuntimeException("Attempt to set TelecomSystem.INSTANCE twice");
141         }
142         Log.i(TelecomSystem.class, "TelecomSystem.INSTANCE being set");
143         INSTANCE = instance;
144     }
145 
TelecomSystem( Context context, MissedCallNotifierImplFactory missedCallNotifierImplFactory, CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory, HeadsetMediaButtonFactory headsetMediaButtonFactory, ProximitySensorManagerFactory proximitySensorManagerFactory, InCallWakeLockControllerFactory inCallWakeLockControllerFactory, AudioServiceFactory audioServiceFactory, BluetoothPhoneServiceImplFactory bluetoothPhoneServiceImplFactory, Timeouts.Adapter timeoutsAdapter, AsyncRingtonePlayer asyncRingtonePlayer)146     public TelecomSystem(
147             Context context,
148             MissedCallNotifierImplFactory missedCallNotifierImplFactory,
149             CallerInfoAsyncQueryFactory callerInfoAsyncQueryFactory,
150             HeadsetMediaButtonFactory headsetMediaButtonFactory,
151             ProximitySensorManagerFactory proximitySensorManagerFactory,
152             InCallWakeLockControllerFactory inCallWakeLockControllerFactory,
153             AudioServiceFactory audioServiceFactory,
154             BluetoothPhoneServiceImplFactory
155                     bluetoothPhoneServiceImplFactory,
156             Timeouts.Adapter timeoutsAdapter,
157             AsyncRingtonePlayer asyncRingtonePlayer) {
158         mContext = context.getApplicationContext();
159         Log.setContext(mContext);
160         Log.initMd5Sum();
161 
162         Log.startSession("TS.init");
163         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext);
164         mContactsAsyncHelper = new ContactsAsyncHelper(
165                 new ContactsAsyncHelper.ContentResolverAdapter() {
166                     @Override
167                     public InputStream openInputStream(Context context, Uri uri)
168                             throws FileNotFoundException {
169                         return context.getContentResolver().openInputStream(uri);
170                     }
171                 });
172         BluetoothManager bluetoothManager = new BluetoothManager(mContext,
173                 new BluetoothAdapterProxy());
174         WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
175         SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
176 
177         mMissedCallNotifier = missedCallNotifierImplFactory
178                 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar);
179 
180         DefaultDialerManagerAdapter defaultDialerAdapter =
181                 new TelecomServiceImpl.DefaultDialerManagerAdapterImpl();
182 
183         mCallsManager = new CallsManager(
184                 mContext,
185                 mLock,
186                 mContactsAsyncHelper,
187                 callerInfoAsyncQueryFactory,
188                 mMissedCallNotifier,
189                 mPhoneAccountRegistrar,
190                 headsetMediaButtonFactory,
191                 proximitySensorManagerFactory,
192                 inCallWakeLockControllerFactory,
193                 audioServiceFactory,
194                 bluetoothManager,
195                 wiredHeadsetManager,
196                 systemStateProvider,
197                 defaultDialerAdapter,
198                 timeoutsAdapter,
199                 asyncRingtonePlayer);
200 
201         mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
202         mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
203 
204         mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
205         mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
206 
207         mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
208                 mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
209         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
210         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
211                 mContext, mCallsManager);
212 
213         // Register the receiver for the dialer secret codes, used to enable extended logging.
214         mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
215         mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
216                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
217 
218         mTelecomServiceImpl = new TelecomServiceImpl(
219                 mContext, mCallsManager, mPhoneAccountRegistrar,
220                 new CallIntentProcessor.AdapterImpl(),
221                 new UserCallIntentProcessorFactory() {
222                     @Override
223                     public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
224                         return new UserCallIntentProcessor(context, userHandle);
225                     }
226                 },
227                 defaultDialerAdapter,
228                 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
229                 mLock);
230         Log.endSession();
231     }
232 
233     @VisibleForTesting
getPhoneAccountRegistrar()234     public PhoneAccountRegistrar getPhoneAccountRegistrar() {
235         return mPhoneAccountRegistrar;
236     }
237 
238     @VisibleForTesting
getCallsManager()239     public CallsManager getCallsManager() {
240         return mCallsManager;
241     }
242 
getBluetoothPhoneServiceImpl()243     public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
244         return mBluetoothPhoneServiceImpl;
245     }
246 
getCallIntentProcessor()247     public CallIntentProcessor getCallIntentProcessor() {
248         return mCallIntentProcessor;
249     }
250 
getTelecomBroadcastIntentProcessor()251     public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
252         return mTelecomBroadcastIntentProcessor;
253     }
254 
getTelecomServiceImpl()255     public TelecomServiceImpl getTelecomServiceImpl() {
256         return mTelecomServiceImpl;
257     }
258 
getLock()259     public Object getLock() {
260         return mLock;
261     }
262 }
263