1 /* 2 * Copyright (C) 2021 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.googlecode.android_scripting.facade.telephony; 18 19 import android.content.Context; 20 import android.telephony.SubscriptionManager; 21 import android.telephony.ims.ImsException; 22 import android.telephony.ims.ImsManager; 23 import android.telephony.ims.RcsClientConfiguration; 24 import android.util.Log; 25 26 import com.android.libraries.rcs.simpleclient.SimpleRcsClient; 27 import com.android.libraries.rcs.simpleclient.protocol.cpim.SimpleCpimMessage; 28 import com.android.libraries.rcs.simpleclient.protocol.sip.SipSession; 29 import com.android.libraries.rcs.simpleclient.provisioning.ProvisioningStateChangeCallback; 30 import com.android.libraries.rcs.simpleclient.provisioning.StaticConfigProvisioningController; 31 import com.android.libraries.rcs.simpleclient.registration.RegistrationController; 32 import com.android.libraries.rcs.simpleclient.registration.RegistrationControllerImpl; 33 import com.android.libraries.rcs.simpleclient.registration.RegistrationStateChangeCallback; 34 import com.android.libraries.rcs.simpleclient.service.ImsService; 35 import com.android.libraries.rcs.simpleclient.service.chat.ChatServiceListener; 36 import com.android.libraries.rcs.simpleclient.service.chat.ChatSessionListener; 37 import com.android.libraries.rcs.simpleclient.service.chat.MinimalCpmChatService; 38 import com.android.libraries.rcs.simpleclient.service.chat.SimpleChatSession; 39 40 import com.googlecode.android_scripting.facade.FacadeManager; 41 import com.googlecode.android_scripting.jsonrpc.RpcReceiver; 42 import com.googlecode.android_scripting.rpc.Rpc; 43 44 import java.nio.charset.StandardCharsets; 45 import java.util.concurrent.Executor; 46 import java.util.concurrent.Executors; 47 48 /** 49 * Exposes RCS single registration functionality based on SimpleClient lib implementation 50 */ 51 public class RcsFacade extends RpcReceiver { 52 53 private static final String TAG = RcsFacade.class.getSimpleName(); 54 55 private final Context mContext; 56 private final ChatSessionListener mSessionListener = new ChatSessionListener() { 57 @Override 58 public void onMessageReceived(SimpleCpimMessage message) { 59 Log.i(TAG, "Received message: " + message.content()); 60 } 61 }; 62 private ImsManager mImsManager; 63 private StaticConfigProvisioningController mProvisioningController; 64 private RegistrationController mRegistrationController; 65 private MinimalCpmChatService mChatService; 66 private SimpleRcsClient mSimpleRcsClient; 67 private Executor mExecutor; 68 private SimpleChatSession mChatsession; 69 private final ChatServiceListener mServiceListener = new ChatServiceListener() { 70 @Override 71 public void onIncomingSession(SimpleChatSession chatSession) { 72 Log.i(TAG, "Received incoming session"); 73 mChatsession = chatSession; 74 mChatsession.setListener(mSessionListener); 75 } 76 }; 77 private String mConfigXml = ""; 78 private RegistrationStateChangeCallback mRegistrationCB = 79 new RegistrationStateChangeCallback() { 80 @Override 81 public void notifyRegStateChanged(ImsService imsService) { 82 Log.i(TAG, "RegistrationStateChangeCallback"); 83 } 84 85 @Override 86 public void onFailure(String error) { 87 Log.i(TAG, "Registration Failure:" + error); 88 } 89 90 @Override 91 public void onSuccess(SipSession sipSession) { 92 Log.i(TAG, "Registration Success"); 93 } 94 }; 95 private ProvisioningStateChangeCallback mProvisioningCB = 96 new ProvisioningStateChangeCallback() { 97 @Override 98 public void notifyConfigChanged(byte[] configXml) { 99 Log.i(TAG, "Provisioning State Change Callback with configXML? " + (configXml != null)); 100 mConfigXml = new String(configXml, StandardCharsets.UTF_8); 101 } 102 }; 103 RcsFacade(FacadeManager manager)104 public RcsFacade(FacadeManager manager) { 105 super(manager); 106 107 int subId = SubscriptionManager.getActiveDataSubscriptionId(); 108 mContext = manager.getService().getBaseContext(); 109 mImsManager = mContext.getSystemService(ImsManager.class); 110 mExecutor = Executors.newCachedThreadPool(); 111 mChatService = new MinimalCpmChatService(mContext); 112 mChatService.setListener(mServiceListener); 113 mProvisioningController = StaticConfigProvisioningController 114 .createForSubscriptionId(subId, mContext); 115 mRegistrationController = new RegistrationControllerImpl(subId, mExecutor, mImsManager); 116 mProvisioningController.onConfigurationChange(mProvisioningCB); 117 mSimpleRcsClient = SimpleRcsClient.newBuilder() 118 .registrationController(mRegistrationController) 119 .provisioningController(mProvisioningController) 120 .imsService(mChatService).build(); 121 } 122 123 /** 124 * Start RCS provisioning. 125 * 126 * @param rcsVersion rcs version 127 * @param rcsProfile rcsProfile 128 * @param clientVendor clientVendor 129 * @param clientVersion clientVersion 130 */ 131 @Rpc(description = "Set RCS Client Configuration Parameters") startRCSProvisioning( String rcsVersion, String rcsProfile, String clientVendor, String clientVersion)132 public void startRCSProvisioning( 133 String rcsVersion, 134 String rcsProfile, 135 String clientVendor, 136 String clientVersion) throws ImsException { 137 RcsClientConfiguration config = 138 new RcsClientConfiguration(rcsVersion, rcsProfile, clientVendor, clientVersion); 139 Log.i(TAG, "Start RCS Provisioning with client configuratoin parameters: " 140 + "rcsVersion = " + rcsVersion 141 + ", rcsProfile = " + rcsProfile 142 + ", clientVendor = " + clientVendor 143 + ", clientVersion = " + clientVersion); 144 try { 145 mProvisioningController.register(config); 146 } catch (Exception e) { 147 Log.i(TAG, "Unable to register RCS Configuration: " + e.getLocalizedMessage()); 148 } 149 } 150 151 /** 152 * Unregister provisioning config change listener 153 */ 154 @Rpc(description = "Unregister provisioning config change listener") unregisterRCSProvisioningCallback()155 public void unregisterRCSProvisioningCallback() throws IllegalStateException { 156 Log.i(TAG, "Unregister Provision Manager Callback"); 157 mProvisioningController.unRegister(); 158 } 159 160 /** 161 * Get RCS configuration xml 162 */ 163 @Rpc(description = "Get RCS configuration XML.") getRCSConfigXml()164 public String getRCSConfigXml() throws ImsException { 165 return mConfigXml; 166 } 167 168 /** 169 * Check if the current subscription is RCS VOLTE Single Registartion capable 170 */ 171 @Rpc(description = "Examine if RCS VoLTE Single Registration is available.") isRcsVolteSingleRegistrationCapable()172 public boolean isRcsVolteSingleRegistrationCapable() throws ImsException { 173 return mProvisioningController.isRcsVolteSingleRegistrationCapable(); 174 } 175 176 /** 177 * Get latest RCS configuration xml 178 */ 179 @Rpc(description = "Get the latest configuration") getLatestConfiguration()180 synchronized byte[] getLatestConfiguration() throws IllegalStateException { 181 return mProvisioningController.getLatestConfiguration(); 182 } 183 184 /** 185 * Register RCS. This is essential for chat. 186 */ 187 @Rpc(description = "RCS Register") register()188 public void register() { 189 Log.i(TAG, "Register"); 190 mRegistrationController.register(mChatService, mRegistrationCB); 191 } 192 193 /** 194 * Deregister RCS 195 */ 196 @Rpc(description = "RCS Deregister") deregister()197 public void deregister() { 198 Log.i(TAG, "Deregister"); 199 mRegistrationController.deregister(); 200 } 201 202 @Override shutdown()203 public void shutdown() { 204 } 205 } 206