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.bluetooth.BluetoothDeviceManager;
     21 import com.android.server.telecom.bluetooth.BluetoothRouteManager;
     22 import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
     23 import com.android.server.telecom.components.UserCallIntentProcessor;
     24 import com.android.server.telecom.components.UserCallIntentProcessorFactory;
     25 import com.android.server.telecom.ui.IncomingCallNotifier;
     26 import com.android.server.telecom.ui.MissedCallNotifierImpl.MissedCallNotifierImplFactory;
     27 import com.android.server.telecom.BluetoothPhoneServiceImpl.BluetoothPhoneServiceImplFactory;
     28 import com.android.server.telecom.CallAudioManager.AudioServiceFactory;
     29 import com.android.server.telecom.DefaultDialerCache.DefaultDialerManagerAdapter;
     30 
     31 import android.Manifest;
     32 import android.content.BroadcastReceiver;
     33 import android.content.Context;
     34 import android.content.Intent;
     35 import android.content.IntentFilter;
     36 import android.content.pm.ApplicationInfo;
     37 import android.content.pm.PackageManager;
     38 import android.net.Uri;
     39 import android.os.UserHandle;
     40 import android.telecom.Log;
     41 import android.telecom.PhoneAccountHandle;
     42 
     43 import java.io.FileNotFoundException;
     44 import java.io.InputStream;
     45 
     46 /**
     47  * Top-level Application class for Telecom.
     48  */
     49 public 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             ConnectionServiceFocusManager.ConnectionServiceFocusManagerFactory
    190                     connectionServiceFocusManagerFactory,
    191             Timeouts.Adapter timeoutsAdapter,
    192             AsyncRingtonePlayer asyncRingtonePlayer,
    193             PhoneNumberUtilsAdapter phoneNumberUtilsAdapter,
    194             IncomingCallNotifier incomingCallNotifier,
    195             InCallTonePlayer.ToneGeneratorFactory toneGeneratorFactory,
    196             ClockProxy clockProxy) {
    197         mContext = context.getApplicationContext();
    198         LogUtils.initLogging(mContext);
    199         DefaultDialerManagerAdapter defaultDialerAdapter =
    200                 new DefaultDialerCache.DefaultDialerManagerAdapterImpl();
    201 
    202         DefaultDialerCache defaultDialerCache = new DefaultDialerCache(mContext,
    203                 defaultDialerAdapter, mLock);
    204 
    205         Log.startSession("TS.init");
    206         mPhoneAccountRegistrar = new PhoneAccountRegistrar(mContext, defaultDialerCache,
    207                 new PhoneAccountRegistrar.AppLabelProxy() {
    208                     @Override
    209                     public CharSequence getAppLabel(String packageName) {
    210                         PackageManager pm = mContext.getPackageManager();
    211                         try {
    212                             ApplicationInfo info = pm.getApplicationInfo(packageName, 0);
    213                             return pm.getApplicationLabel(info);
    214                         } catch (PackageManager.NameNotFoundException nnfe) {
    215                             Log.w(this, "Could not determine package name.");
    216                         }
    217 
    218                         return null;
    219                     }
    220                 });
    221         mContactsAsyncHelper = new ContactsAsyncHelper(
    222                 new ContactsAsyncHelper.ContentResolverAdapter() {
    223                     @Override
    224                     public InputStream openInputStream(Context context, Uri uri)
    225                             throws FileNotFoundException {
    226                         return context.getContentResolver().openInputStream(uri);
    227                     }
    228                 });
    229         BluetoothDeviceManager bluetoothDeviceManager = new BluetoothDeviceManager(mContext,
    230                 new BluetoothAdapterProxy(), mLock);
    231         BluetoothRouteManager bluetoothRouteManager = new BluetoothRouteManager(mContext, mLock,
    232                 bluetoothDeviceManager, new Timeouts.Adapter());
    233         BluetoothStateReceiver bluetoothStateReceiver = new BluetoothStateReceiver(
    234                 bluetoothDeviceManager, bluetoothRouteManager);
    235         mContext.registerReceiver(bluetoothStateReceiver, BluetoothStateReceiver.INTENT_FILTER);
    236 
    237         WiredHeadsetManager wiredHeadsetManager = new WiredHeadsetManager(mContext);
    238         SystemStateProvider systemStateProvider = new SystemStateProvider(mContext);
    239 
    240         mMissedCallNotifier = missedCallNotifierImplFactory
    241                 .makeMissedCallNotifierImpl(mContext, mPhoneAccountRegistrar, defaultDialerCache);
    242 
    243         EmergencyCallHelper emergencyCallHelper = new EmergencyCallHelper(mContext,
    244                 mContext.getResources().getString(R.string.ui_default_package), timeoutsAdapter);
    245 
    246         InCallControllerFactory inCallControllerFactory = new InCallControllerFactory() {
    247             @Override
    248             public InCallController create(Context context, SyncRoot lock,
    249                     CallsManager callsManager, SystemStateProvider systemStateProvider,
    250                     DefaultDialerCache defaultDialerCache, Timeouts.Adapter timeoutsAdapter,
    251                     EmergencyCallHelper emergencyCallHelper) {
    252                 return new InCallController(context, lock, callsManager, systemStateProvider,
    253                         defaultDialerCache, timeoutsAdapter, emergencyCallHelper);
    254             }
    255         };
    256 
    257         mCallsManager = new CallsManager(
    258                 mContext,
    259                 mLock,
    260                 mContactsAsyncHelper,
    261                 callerInfoAsyncQueryFactory,
    262                 mMissedCallNotifier,
    263                 mPhoneAccountRegistrar,
    264                 headsetMediaButtonFactory,
    265                 proximitySensorManagerFactory,
    266                 inCallWakeLockControllerFactory,
    267                 connectionServiceFocusManagerFactory,
    268                 audioServiceFactory,
    269                 bluetoothRouteManager,
    270                 wiredHeadsetManager,
    271                 systemStateProvider,
    272                 defaultDialerCache,
    273                 timeoutsAdapter,
    274                 asyncRingtonePlayer,
    275                 phoneNumberUtilsAdapter,
    276                 emergencyCallHelper,
    277                 toneGeneratorFactory,
    278                 clockProxy,
    279                 bluetoothStateReceiver,
    280                 inCallControllerFactory);
    281 
    282         mIncomingCallNotifier = incomingCallNotifier;
    283         incomingCallNotifier.setCallsManagerProxy(new IncomingCallNotifier.CallsManagerProxy() {
    284             @Override
    285             public boolean hasCallsForOtherPhoneAccount(PhoneAccountHandle phoneAccountHandle) {
    286                 return mCallsManager.hasCallsForOtherPhoneAccount(phoneAccountHandle);
    287             }
    288 
    289             @Override
    290             public int getNumCallsForOtherPhoneAccount(PhoneAccountHandle phoneAccountHandle) {
    291                 return mCallsManager.getNumCallsForOtherPhoneAccount(phoneAccountHandle);
    292             }
    293 
    294             @Override
    295             public Call getActiveCall() {
    296                 return mCallsManager.getActiveCall();
    297             }
    298         });
    299         mCallsManager.setIncomingCallNotifier(mIncomingCallNotifier);
    300 
    301         mRespondViaSmsManager = new RespondViaSmsManager(mCallsManager, mLock);
    302         mCallsManager.setRespondViaSmsManager(mRespondViaSmsManager);
    303 
    304         mContext.registerReceiver(mUserSwitchedReceiver, USER_SWITCHED_FILTER);
    305         mContext.registerReceiver(mUserStartingReceiver, USER_STARTING_FILTER);
    306         mContext.registerReceiver(mBootCompletedReceiver, BOOT_COMPLETE_FILTER);
    307 
    308         mBluetoothPhoneServiceImpl = bluetoothPhoneServiceImplFactory.makeBluetoothPhoneServiceImpl(
    309                 mContext, mLock, mCallsManager, mPhoneAccountRegistrar);
    310         mCallIntentProcessor = new CallIntentProcessor(mContext, mCallsManager);
    311         mTelecomBroadcastIntentProcessor = new TelecomBroadcastIntentProcessor(
    312                 mContext, mCallsManager);
    313 
    314         // Register the receiver for the dialer secret codes, used to enable extended logging.
    315         mDialerCodeReceiver = new DialerCodeReceiver(mCallsManager);
    316         mContext.registerReceiver(mDialerCodeReceiver, DIALER_SECRET_CODE_FILTER,
    317                 Manifest.permission.CONTROL_INCALL_EXPERIENCE, null);
    318 
    319         mTelecomServiceImpl = new TelecomServiceImpl(
    320                 mContext, mCallsManager, mPhoneAccountRegistrar,
    321                 new CallIntentProcessor.AdapterImpl(),
    322                 new UserCallIntentProcessorFactory() {
    323                     @Override
    324                     public UserCallIntentProcessor create(Context context, UserHandle userHandle) {
    325                         return new UserCallIntentProcessor(context, userHandle);
    326                     }
    327                 },
    328                 defaultDialerCache,
    329                 new TelecomServiceImpl.SubscriptionManagerAdapterImpl(),
    330                 mLock);
    331         Log.endSession();
    332     }
    333 
    334     @VisibleForTesting
    335     public PhoneAccountRegistrar getPhoneAccountRegistrar() {
    336         return mPhoneAccountRegistrar;
    337     }
    338 
    339     @VisibleForTesting
    340     public CallsManager getCallsManager() {
    341         return mCallsManager;
    342     }
    343 
    344     public BluetoothPhoneServiceImpl getBluetoothPhoneServiceImpl() {
    345         return mBluetoothPhoneServiceImpl;
    346     }
    347 
    348     public CallIntentProcessor getCallIntentProcessor() {
    349         return mCallIntentProcessor;
    350     }
    351 
    352     public TelecomBroadcastIntentProcessor getTelecomBroadcastIntentProcessor() {
    353         return mTelecomBroadcastIntentProcessor;
    354     }
    355 
    356     public TelecomServiceImpl getTelecomServiceImpl() {
    357         return mTelecomServiceImpl;
    358     }
    359 
    360     public Object getLock() {
    361         return mLock;
    362     }
    363 
    364     public boolean isBootComplete() {
    365         return mIsBootComplete;
    366     }
    367 }
    368