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.components; 18 19 import android.app.Service; 20 import android.app.role.RoleManager; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.media.IAudioService; 24 import android.media.ToneGenerator; 25 import android.os.IBinder; 26 import android.os.PowerManager; 27 import android.os.ServiceManager; 28 import android.os.SystemClock; 29 import android.telecom.Log; 30 31 import android.telecom.CallerInfoAsyncQuery; 32 33 import com.android.internal.telecom.IInternalServiceRetriever; 34 import com.android.internal.telecom.ITelecomLoader; 35 import com.android.internal.telecom.ITelecomService; 36 import com.android.server.telecom.AsyncRingtonePlayer; 37 import com.android.server.telecom.CallAudioModeStateMachine; 38 import com.android.server.telecom.CallAudioRouteStateMachine; 39 import com.android.server.telecom.CallerInfoAsyncQueryFactory; 40 import com.android.server.telecom.CallsManager; 41 import com.android.server.telecom.ClockProxy; 42 import com.android.server.telecom.ConnectionServiceFocusManager; 43 import com.android.server.telecom.ContactsAsyncHelper; 44 import com.android.server.telecom.DefaultDialerCache; 45 import com.android.server.telecom.DeviceIdleControllerAdapter; 46 import com.android.server.telecom.HeadsetMediaButton; 47 import com.android.server.telecom.HeadsetMediaButtonFactory; 48 import com.android.server.telecom.InCallWakeLockControllerFactory; 49 import com.android.server.telecom.CallAudioManager; 50 import com.android.server.telecom.InternalServiceRetrieverAdapter; 51 import com.android.server.telecom.PhoneAccountRegistrar; 52 import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; 53 import com.android.server.telecom.ProximitySensorManagerFactory; 54 import com.android.server.telecom.InCallWakeLockController; 55 import com.android.server.telecom.ProximitySensorManager; 56 import com.android.server.telecom.RoleManagerAdapterImpl; 57 import com.android.server.telecom.TelecomSystem; 58 import com.android.server.telecom.TelecomWakeLock; 59 import com.android.server.telecom.Timeouts; 60 import com.android.server.telecom.ui.IncomingCallNotifier; 61 import com.android.server.telecom.ui.MissedCallNotifierImpl; 62 import com.android.server.telecom.ui.NotificationChannelManager; 63 64 /** 65 * Implementation of the ITelecom interface. 66 */ 67 public class TelecomService extends Service implements TelecomSystem.Component { 68 69 @Override onBind(Intent intent)70 public IBinder onBind(Intent intent) { 71 Log.d(this, "onBind"); 72 return new ITelecomLoader.Stub() { 73 @Override 74 public ITelecomService createTelecomService(IInternalServiceRetriever retriever) { 75 InternalServiceRetrieverAdapter adapter = 76 new InternalServiceRetrieverAdapter(retriever); 77 initializeTelecomSystem(TelecomService.this, adapter); 78 synchronized (getTelecomSystem().getLock()) { 79 return getTelecomSystem().getTelecomServiceImpl().getBinder(); 80 } 81 } 82 }; 83 } 84 85 /** 86 * This method is to be called by components (Activitys, Services, ...) to initialize the 87 * Telecom singleton. It should only be called on the main thread. As such, it is atomic 88 * and needs no synchronization -- it will either perform its initialization, after which 89 * the {@link TelecomSystem#getInstance()} will be initialized, or some other invocation of 90 * this method on the main thread will have happened strictly prior to it, and this method 91 * will be a benign no-op. 92 * 93 * @param context 94 */ 95 static void initializeTelecomSystem(Context context, 96 InternalServiceRetrieverAdapter internalServiceRetriever) { 97 if (TelecomSystem.getInstance() == null) { 98 NotificationChannelManager notificationChannelManager = 99 new NotificationChannelManager(); 100 notificationChannelManager.createChannels(context); 101 102 TelecomSystem.setInstance( 103 new TelecomSystem( 104 context, 105 new MissedCallNotifierImpl.MissedCallNotifierImplFactory() { 106 @Override 107 public MissedCallNotifierImpl makeMissedCallNotifierImpl( 108 Context context, 109 PhoneAccountRegistrar phoneAccountRegistrar, 110 DefaultDialerCache defaultDialerCache, 111 DeviceIdleControllerAdapter idleControllerAdapter) { 112 return new MissedCallNotifierImpl(context, 113 phoneAccountRegistrar, defaultDialerCache, 114 idleControllerAdapter); 115 } 116 }, 117 new CallerInfoAsyncQueryFactory() { 118 @Override 119 public CallerInfoAsyncQuery startQuery( 120 int token, 121 Context context, 122 String number, 123 CallerInfoAsyncQuery.OnQueryCompleteListener listener, 124 Object cookie) { 125 Log.i(TelecomSystem.getInstance(), 126 "CallerInfoAsyncQuery.startQuery number=%s cookie=%s", 127 Log.pii(number), cookie); 128 return CallerInfoAsyncQuery.startQuery( 129 token, context, number, listener, cookie); 130 } 131 }, 132 new HeadsetMediaButtonFactory() { 133 @Override 134 public HeadsetMediaButton create( 135 Context context, 136 CallsManager callsManager, 137 TelecomSystem.SyncRoot lock) { 138 return new HeadsetMediaButton(context, callsManager, lock); 139 } 140 }, 141 new ProximitySensorManagerFactory() { 142 @Override 143 public ProximitySensorManager create( 144 Context context, 145 CallsManager callsManager) { 146 return new ProximitySensorManager( 147 new TelecomWakeLock( 148 context, 149 PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, 150 ProximitySensorManager.class.getSimpleName()), 151 callsManager); 152 } 153 }, 154 new InCallWakeLockControllerFactory() { 155 @Override 156 public InCallWakeLockController create(Context context, 157 CallsManager callsManager) { 158 return new InCallWakeLockController( 159 new TelecomWakeLock(context, 160 PowerManager.FULL_WAKE_LOCK, 161 InCallWakeLockController.class.getSimpleName()), 162 callsManager); 163 } 164 }, 165 new CallAudioManager.AudioServiceFactory() { 166 @Override 167 public IAudioService getAudioService() { 168 return IAudioService.Stub.asInterface( 169 ServiceManager.getService(Context.AUDIO_SERVICE)); 170 } 171 }, 172 ConnectionServiceFocusManager::new, 173 new Timeouts.Adapter(), 174 new AsyncRingtonePlayer(), 175 new PhoneNumberUtilsAdapterImpl(), 176 new IncomingCallNotifier(context), 177 ToneGenerator::new, 178 new CallAudioRouteStateMachine.Factory(), 179 new CallAudioModeStateMachine.Factory(), 180 new ClockProxy() { 181 @Override 182 public long currentTimeMillis() { 183 return System.currentTimeMillis(); 184 } 185 186 @Override 187 public long elapsedRealtime() { 188 return SystemClock.elapsedRealtime(); 189 } 190 }, 191 new RoleManagerAdapterImpl(context, 192 (RoleManager) context.getSystemService(Context.ROLE_SERVICE)), 193 new ContactsAsyncHelper.Factory(), 194 internalServiceRetriever.getDeviceIdleController())); 195 } 196 } 197 198 @Override 199 public TelecomSystem getTelecomSystem() { 200 return TelecomSystem.getInstance(); 201 } 202 } 203