Home | History | Annotate | Download | only in telecom
      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 {
     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             Timeouts.Adapter timeoutsAdapter,
    157             AsyncRingtonePlayer asyncRingtonePlayer,
    158             PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
    159             InterruptionFilterProxy interruptionFilterProxy) {
    160         mContext = context.getApplicationContext();
    161         Log.setContext(mContext);
    162         Log.initMd5Sum();
    163 
    164         Log.startSession("TS.init");
    165         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext);
    166         mContactsAsyncHelper = new ContactsAsyncHelper(
    167                 new ContactsAsyncHelper.ContentResolverAdapter() {
    168                     @Override
    169                     public InputStream openInputStream(Context context, Uri uri)
    170                             throws FileNotFoundException {
    171                         return context.getContentResolver().openInputStream(uri);
    172                     }
    173                 });
    174         BluetoothManager bluetoothManager = new BluetoothManager(mContext,
    175                 new BluetoothAdapterProxy());
    176         WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
    177         SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
    178 
    179         mMissedCallNotifier = missedCallNotifierImplFactory
    180                 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar,
    181                         phoneNumberUtilsAdapter);
    182 
    183         DefaultDialerManagerAdapter defaultDialerAdapter =
    184                 new TelecomServiceImpl.DefaultDialerManagerAdapterImpl();
    185 
    186         mCallsManager = new CallsManager(
    187                 mContext,
    188                 mLock,
    189                 mContactsAsyncHelper,
    190                 callerInfoAsyncQueryFactory,
    191                 mMissedCallNotifier,
    192                 mPhoneAccountRegistrar,
    193                 headsetMediaButtonFactory,
    194                 proximitySensorManagerFactory,
    195                 inCallWakeLockControllerFactory,
    196                 audioServiceFactory,
    197                 bluetoothManager,
    198                 wiredHeadsetManager,
    199                 systemStateProvider,
    200                 defaultDialerAdapter,
    201                 timeoutsAdapter,
    202                 asyncRingtonePlayer,
    203                 phoneNumberUtilsAdapter,
    204                 interruptionFilterProxy);
    205 
    206         mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
    207         mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
    208 
    209         mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
    210         mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
    211 
    212         mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
    213                 mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
    214         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
    215         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
    216                 mContext, mCallsManager);
    217 
    218         // Register the receiver for the dialer secret codes, used to enable extended logging.
    219         mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
    220         mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
    221                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
    222 
    223         mTelecomServiceImpl = new TelecomServiceImpl(
    224                 mContext, mCallsManager, mPhoneAccountRegistrar,
    225                 new CallIntentProcessor.AdapterImpl(),
    226                 new UserCallIntentProcessorFactory() {
    227                     @Override
    228                     public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
    229                         return new UserCallIntentProcessor(context, userHandle);
    230                     }
    231                 },
    232                 defaultDialerAdapter,
    233                 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
    234                 mLock);
    235         Log.endSession();
    236     }
    237 
    238     @VisibleForTesting
    239     public PhoneAccountRegistrar getPhoneAccountRegistrar() {
    240         return mPhoneAccountRegistrar;
    241     }
    242 
    243     @VisibleForTesting
    244     public CallsManager getCallsManager() {
    245         return mCallsManager;
    246     }
    247 
    248     public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
    249         return mBluetoothPhoneServiceImpl;
    250     }
    251 
    252     public CallIntentProcessor getCallIntentProcessor() {
    253         return mCallIntentProcessor;
    254     }
    255 
    256     public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
    257         return mTelecomBroadcastIntentProcessor;
    258     }
    259 
    260     public TelecomServiceImpl getTelecomServiceImpl() {
    261         return mTelecomServiceImpl;
    262     }
    263 
    264     public Object getLock() {
    265         return mLock;
    266     }
    267 }
    268