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