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.provider.BlockedNumberContract; 30 import android.provider.BlockedNumbersManager; 31 import android.telecom.Log; 32 33 import android.telecom.CallerInfoAsyncQuery; 34 import android.view.accessibility.AccessibilityManager; 35 36 import com.android.internal.telecom.IInternalServiceRetriever; 37 import com.android.internal.telecom.ITelecomLoader; 38 import com.android.internal.telecom.ITelecomService; 39 import com.android.server.telecom.AsyncRingtonePlayer; 40 import com.android.server.telecom.CallAudioModeStateMachine; 41 import com.android.server.telecom.CallAudioRouteStateMachine; 42 import com.android.server.telecom.CallerInfoAsyncQueryFactory; 43 import com.android.server.telecom.CallsManager; 44 import com.android.server.telecom.ClockProxy; 45 import com.android.server.telecom.ConnectionServiceFocusManager; 46 import com.android.server.telecom.ContactsAsyncHelper; 47 import com.android.server.telecom.DefaultDialerCache; 48 import com.android.server.telecom.DeviceIdleControllerAdapter; 49 import com.android.server.telecom.flags.FeatureFlags; 50 import com.android.server.telecom.HeadsetMediaButton; 51 import com.android.server.telecom.HeadsetMediaButtonFactory; 52 import com.android.server.telecom.InCallWakeLockControllerFactory; 53 import com.android.server.telecom.CallAudioManager; 54 import com.android.server.telecom.InternalServiceRetrieverAdapter; 55 import com.android.server.telecom.PhoneAccountRegistrar; 56 import com.android.server.telecom.PhoneNumberUtilsAdapterImpl; 57 import com.android.server.telecom.ProximitySensorManagerFactory; 58 import com.android.server.telecom.InCallWakeLockController; 59 import com.android.server.telecom.ProximitySensorManager; 60 import com.android.server.telecom.Ringer; 61 import com.android.server.telecom.RoleManagerAdapterImpl; 62 import com.android.server.telecom.TelecomSystem; 63 import com.android.server.telecom.TelecomWakeLock; 64 import com.android.server.telecom.Timeouts; 65 import com.android.server.telecom.callfiltering.BlockedNumbersAdapter; 66 import com.android.server.telecom.flags.FeatureFlagsImpl; 67 import com.android.server.telecom.settings.BlockedNumbersUtil; 68 import com.android.server.telecom.ui.IncomingCallNotifier; 69 import com.android.server.telecom.ui.MissedCallNotifierImpl; 70 import com.android.server.telecom.ui.NotificationChannelManager; 71 72 import java.util.concurrent.Executors; 73 74 /** 75 * Implementation of the ITelecom interface. 76 */ 77 public class TelecomService extends Service implements TelecomSystem.Component { 78 79 @Override onBind(Intent intent)80 public IBinder onBind(Intent intent) { 81 Log.d(this, "onBind"); 82 return new ITelecomLoader.Stub() { 83 @Override 84 public ITelecomService createTelecomService(IInternalServiceRetriever retriever) { 85 InternalServiceRetrieverAdapter adapter = 86 new InternalServiceRetrieverAdapter(retriever); 87 initializeTelecomSystem(TelecomService.this, adapter); 88 synchronized (getTelecomSystem().getLock()) { 89 return getTelecomSystem().getTelecomServiceImpl().getBinder(); 90 } 91 } 92 }; 93 } 94 95 /** 96 * This method is to be called by components (Activitys, Services, ...) to initialize the 97 * Telecom singleton. It should only be called on the main thread. As such, it is atomic 98 * and needs no synchronization -- it will either perform its initialization, after which 99 * the {@link TelecomSystem#getInstance()} will be initialized, or some other invocation of 100 * this method on the main thread will have happened strictly prior to it, and this method 101 * will be a benign no-op. 102 * 103 * @param context 104 */ 105 static void initializeTelecomSystem(Context context, 106 InternalServiceRetrieverAdapter internalServiceRetriever) { 107 if (TelecomSystem.getInstance() == null) { 108 FeatureFlags featureFlags = new FeatureFlagsImpl(); 109 NotificationChannelManager notificationChannelManager = 110 new NotificationChannelManager(); 111 notificationChannelManager.createChannels(context); 112 113 TelecomSystem.setInstance( 114 new TelecomSystem( 115 context, 116 new MissedCallNotifierImpl.MissedCallNotifierImplFactory() { 117 @Override 118 public MissedCallNotifierImpl makeMissedCallNotifierImpl( 119 Context context, 120 PhoneAccountRegistrar phoneAccountRegistrar, 121 DefaultDialerCache defaultDialerCache, 122 DeviceIdleControllerAdapter idleControllerAdapter, 123 FeatureFlags featureFlags) { 124 return new MissedCallNotifierImpl(context, 125 phoneAccountRegistrar, defaultDialerCache, 126 idleControllerAdapter, featureFlags); 127 } 128 }, 129 new CallerInfoAsyncQueryFactory() { 130 @Override 131 public CallerInfoAsyncQuery startQuery( 132 int token, 133 Context context, 134 String number, 135 CallerInfoAsyncQuery.OnQueryCompleteListener listener, 136 Object cookie) { 137 Log.i(TelecomSystem.getInstance(), 138 "CallerInfoAsyncQuery.startQuery number=%s cookie=%s", 139 Log.pii(number), cookie); 140 return CallerInfoAsyncQuery.startQuery( 141 token, context, number, listener, cookie); 142 } 143 }, 144 new HeadsetMediaButtonFactory() { 145 @Override 146 public HeadsetMediaButton create( 147 Context context, 148 CallsManager callsManager, 149 TelecomSystem.SyncRoot lock) { 150 return new HeadsetMediaButton(context, callsManager, lock); 151 } 152 }, 153 new ProximitySensorManagerFactory() { 154 @Override 155 public ProximitySensorManager create( 156 Context context, 157 CallsManager callsManager) { 158 return new ProximitySensorManager( 159 new TelecomWakeLock( 160 context, 161 PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK, 162 ProximitySensorManager.class.getSimpleName()), 163 callsManager); 164 } 165 }, 166 new InCallWakeLockControllerFactory() { 167 @Override 168 public InCallWakeLockController create(Context context, 169 CallsManager callsManager) { 170 return new InCallWakeLockController( 171 new TelecomWakeLock(context, 172 PowerManager.FULL_WAKE_LOCK, 173 InCallWakeLockController.class.getSimpleName()), 174 callsManager); 175 } 176 }, 177 new CallAudioManager.AudioServiceFactory() { 178 @Override 179 public IAudioService getAudioService() { 180 return IAudioService.Stub.asInterface( 181 ServiceManager.getService(Context.AUDIO_SERVICE)); 182 } 183 }, 184 ConnectionServiceFocusManager::new, 185 new Timeouts.Adapter(), 186 new AsyncRingtonePlayer(), 187 new PhoneNumberUtilsAdapterImpl(), 188 new IncomingCallNotifier(context), 189 ToneGenerator::new, 190 new CallAudioRouteStateMachine.Factory(), 191 new CallAudioModeStateMachine.Factory(), 192 new ClockProxy() { 193 @Override 194 public long currentTimeMillis() { 195 return System.currentTimeMillis(); 196 } 197 198 @Override 199 public long elapsedRealtime() { 200 return SystemClock.elapsedRealtime(); 201 } 202 }, 203 new RoleManagerAdapterImpl(context, 204 (RoleManager) context.getSystemService(Context.ROLE_SERVICE)), 205 new ContactsAsyncHelper.Factory(), 206 internalServiceRetriever.getDeviceIdleController(), 207 new Ringer.AccessibilityManagerAdapter() { 208 @Override 209 public boolean startFlashNotificationSequence( 210 @androidx.annotation.NonNull Context context, int reason) { 211 return context.getSystemService(AccessibilityManager.class) 212 .startFlashNotificationSequence(context, reason); 213 } 214 215 @Override 216 public boolean stopFlashNotificationSequence( 217 @androidx.annotation.NonNull Context context) { 218 return context.getSystemService(AccessibilityManager.class) 219 .stopFlashNotificationSequence(context); 220 } 221 }, 222 Executors.newCachedThreadPool(), 223 Executors.newSingleThreadExecutor(), 224 new BlockedNumbersAdapter() { 225 @Override 226 public boolean shouldShowEmergencyCallNotification(Context 227 context) { 228 return featureFlags.telecomMainlineBlockedNumbersManager() 229 ? context.getSystemService(BlockedNumbersManager.class) 230 .shouldShowEmergencyCallNotification() 231 : BlockedNumberContract.SystemContract 232 .shouldShowEmergencyCallNotification(context); 233 } 234 235 @Override 236 public void updateEmergencyCallNotification(Context context, 237 boolean showNotification) { 238 BlockedNumbersUtil.updateEmergencyCallNotification(context, 239 showNotification); 240 } 241 }, 242 featureFlags, 243 new com.android.internal.telephony.flags.FeatureFlagsImpl())); 244 } 245 } 246 247 @Override 248 public TelecomSystem getTelecomSystem() { 249 return TelecomSystem.getInstance(); 250 } 251 } 252