TelecomSystem.java revision 6140bf27aa9bc1e473db01f769808ccb06bb6328
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
17package com.android.server.telecom;
18
19import com.android.internal.annotations.VisibleForTesting;
20import com.android.server.telecom.bluetooth.BluetoothDeviceManager;
21import com.android.server.telecom.bluetooth.BluetoothRouteManager;
22import com.android.server.telecom.components.UserCallIntentProcessor;
23import com.android.server.telecom.components.UserCallIntentProcessorFactory;
24import com.android.server.telecom.ui.IncomingCallNotifier;
25import com.android.server.telecom.ui.IncomingCallNotifier.IncomingCallNotifierFactory;
26import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
27import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
28import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
29import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
30
31import android.Manifest;
32import android.content.BroadcastReceiver;
33import android.content.Context;
34import android.content.Intent;
35import android.content.IntentFilter;
36import android.content.pm.ApplicationInfo;
37import android.content.pm.PackageManager;
38import android.net.Uri;
39import android.os.UserHandle;
40import android.telecom.Log;
41import android.telecom.PhoneAccountHandle;
42
43import java.io.FileNotFoundException;
44import java.io.InputStream;
45
46/**
47 * Top-level Application class for Telecom.
48 */
49public 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 {
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
94                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
95        DIALER_SECRET_CODE_FILTER
96                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
97        DIALER_SECRET_CODE_FILTER
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
167    public static TelecomSystem getInstance() {
168        return INSTANCE;
169    }
170
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
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
311    public PhoneAccountRegistrar getPhoneAccountRegistrar() {
312        return mPhoneAccountRegistrar;
313    }
314
315    @VisibleForTesting
316    public CallsManager getCallsManager() {
317        return mCallsManager;
318    }
319
320    public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
321        return mBluetoothPhoneServiceImpl;
322    }
323
324    public CallIntentProcessor getCallIntentProcessor() {
325        return mCallIntentProcessor;
326    }
327
328    public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
329        return mTelecomBroadcastIntentProcessor;
330    }
331
332    public TelecomServiceImpl getTelecomServiceImpl() {
333        return mTelecomServiceImpl;
334    }
335
336    public Object getLock() {
337        return mLock;
338    }
339
340    public boolean isBootComplete() {
341        return mIsBootComplete;
342    }
343}
344