15d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon/* 25d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * Copyright (C) 2014 The Android Open Source Project 35d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * 45d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * Licensed under the Apache License, Version 2.0 (the "License"); 55d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * you may not use this file except in compliance with the License. 65d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * You may obtain a copy of the License at 75d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * 85d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * http://www.apache.org/licenses/LICENSE-2.0 95d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * 105d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * Unless required by applicable law or agreed to in writing, software 115d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * distributed under the License is distributed on an "AS IS" BASIS, 125d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * See the License for the specific language governing permissions and 145d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * limitations under the License. 155d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon */ 165d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 175d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonpackage com.android.server.telecom; 185d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 195d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.content.ComponentName; 205d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.content.Context; 215d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.content.Intent; 225d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.content.ServiceConnection; 235d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.os.IBinder; 245d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.os.RemoteException; 255d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.os.ServiceManager; 265d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.os.UserHandle; 275d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport android.util.Slog; 285d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 295d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonimport com.android.server.SystemService; 305d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 315d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon/** 325d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup 335d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * to run in the system-server process so once it is loaded into memory it will stay running. 345d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon * @hide 355d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon */ 365d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordonpublic class TelecomLoaderService extends SystemService { 375d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private static final String TAG = "TelecomLoaderService"; 385d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 395d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private class TelecomServiceConnection implements ServiceConnection { 405d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon @Override 415d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon public void onServiceConnected(ComponentName name, IBinder service) { 425d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon // Normally, we would listen for death here, but since telecom runs in the same process 435d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon // as this loader (process="system") thats redundant here. 445d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon try { 455d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon service.linkToDeath(new IBinder.DeathRecipient() { 465d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon @Override 475d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon public void binderDied() { 485d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon connectToTelecom(); 495d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 505d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon }, 0); 515d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 525d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon ServiceManager.addService(Context.TELECOM_SERVICE, service); 535d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } catch (RemoteException e) { 545d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon Slog.w(TAG, "Failed linking to death."); 555d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 565d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 575d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 585d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon @Override 595d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon public void onServiceDisconnected(ComponentName name) { 605d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon connectToTelecom(); 615d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 625d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 635d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 645d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private static final ComponentName SERVICE_COMPONENT = new ComponentName( 655d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon "com.android.server.telecom", 665d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon "com.android.server.telecom.TelecomService"); 675d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 685d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private static final String SERVICE_ACTION = "com.android.ITelecomService"; 695d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 705d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private final Context mContext; 715d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private TelecomServiceConnection mServiceConnection; 725d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 735d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon public TelecomLoaderService(Context context) { 745d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon super(context); 755d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon mContext = context; 765d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 775d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 785d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon @Override 795d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon public void onStart() { 805d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 815d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 825d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon @Override 835d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon public void onBootPhase(int phase) { 845d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon if (phase == PHASE_ACTIVITY_MANAGER_READY) { 855d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon connectToTelecom(); 865d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 875d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 885d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 895d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon private void connectToTelecom() { 905d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon if (mServiceConnection != null) { 915d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon // TODO: Is unbinding worth doing or wait for system to rebind? 925d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon mContext.unbindService(mServiceConnection); 935d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon mServiceConnection = null; 945d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 955d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 965d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon TelecomServiceConnection serviceConnection = new TelecomServiceConnection(); 975d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon Intent intent = new Intent(SERVICE_ACTION); 985d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon intent.setComponent(SERVICE_COMPONENT); 995d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon int flags = Context.BIND_IMPORTANT | Context.BIND_AUTO_CREATE; 1005d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon 1015d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon // Bind to Telecom and register the service 1025d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon if (mContext.bindServiceAsUser(intent, serviceConnection, flags, UserHandle.OWNER)) { 1035d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon mServiceConnection = serviceConnection; 1045d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 1055d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon } 1065d2c1e69ecb851121177396ac376dee1fb41d421Santos Cordon} 107