TelecomSystem.java revision 501b9b3775232bb3033afd9f1fd608dd07d0b91e
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.components.UserCallIntentProcessor;
21import com.android.server.telecom.components.UserCallIntentProcessorFactory;
22import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
23import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
24import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
25import com.android.server.telecom.TelecomServiceImpl.DefaultDialerManagerAdapter;
26
27import android.Manifest;
28import android.content.BroadcastReceiver;
29import android.content.Context;
30import android.content.Intent;
31import android.content.IntentFilter;
32import android.net.Uri;
33import android.os.UserHandle;
34
35import java.io.FileNotFoundException;
36import java.io.InputStream;
37
38/**
39 * Top-level Application class for Telecom.
40 */
41public 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 {
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
83                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_ON, null);
84        DIALER_SECRET_CODE_FILTER
85                .addDataAuthority(DialerCodeReceiver.TELECOM_SECRET_CODE_DEBUG_OFF, null);
86        DIALER_SECRET_CODE_FILTER
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
134    public static TelecomSystem getInstance() {
135        return INSTANCE;
136    }
137
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
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        mContext = context.getApplicationContext();
157        Log.setContext(mContext);
158        Log.initMd5Sum();
159
160        mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext);
161        mContactsAsyncHelper = new ContactsAsyncHelper(
162                new ContactsAsyncHelper.ContentResolverAdapter() {
163                    @Override
164                    public InputStream openInputStream(Context context, Uri uri)
165                            throws FileNotFoundException {
166                        return context.getContentResolver().openInputStream(uri);
167                    }
168                });
169        BluetoothManager bluetoothManager = new BluetoothManager(mContext,
170                new BluetoothAdapterProxy());
171        WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
172        SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
173
174        mMissedCallNotifier = missedCallNotifierImplFactory
175                .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar);
176
177        DefaultDialerManagerAdapter defaultDialerAdapter =
178                new TelecomServiceImpl.DefaultDialerManagerAdapterImpl();
179
180        mCallsManager = new CallsManager(
181                mContext,
182                mLock,
183                mContactsAsyncHelper,
184                callerInfoAsyncQueryFactory,
185                mMissedCallNotifier,
186                mPhoneAccountRegistrar,
187                headsetMediaButtonFactory,
188                proximitySensorManagerFactory,
189                inCallWakeLockControllerFactory,
190                audioServiceFactory,
191                bluetoothManager,
192                wiredHeadsetManager,
193                systemStateProvider,
194                defaultDialerAdapter);
195
196        mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
197        mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
198
199        mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
200        mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
201
202        mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
203                mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
204        mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
205        mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
206                mContext, mCallsManager);
207
208        // Register the receiver for the dialer secret codes, used to enable extended logging.
209        mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
210        mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
211                Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
212
213        mTelecomServiceImpl = new TelecomServiceImpl(
214                mContext, mCallsManager, mPhoneAccountRegistrar,
215                new CallIntentProcessor.AdapterImpl(),
216                new UserCallIntentProcessorFactory() {
217                    @Override
218                    public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
219                        return new UserCallIntentProcessor(context, userHandle);
220                    }
221                },
222                defaultDialerAdapter,
223                new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
224                mLock);
225    }
226
227    @VisibleForTesting
228    public PhoneAccountRegistrar getPhoneAccountRegistrar() {
229        return mPhoneAccountRegistrar;
230    }
231
232    public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
233        return mBluetoothPhoneServiceImpl;
234    }
235
236    public CallIntentProcessor getCallIntentProcessor() {
237        return mCallIntentProcessor;
238    }
239
240    public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
241        return mTelecomBroadcastIntentProcessor;
242    }
243
244    public TelecomServiceImpl getTelecomServiceImpl() {
245        return mTelecomServiceImpl;
246    }
247
248    public Object getLock() {
249        return mLock;
250    }
251}
252