• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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.ims;
18 
19 import android.content.Context;
20 import android.net.Uri;
21 import android.os.IBinder;
22 import android.os.RemoteException;
23 import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
24 import android.telephony.ims.aidl.IImsCapabilityCallback;
25 import android.telephony.ims.aidl.IImsConfig;
26 import android.telephony.ims.aidl.IImsRcsFeature;
27 import android.telephony.ims.aidl.IImsRegistration;
28 import android.telephony.ims.aidl.IImsRegistrationCallback;
29 import android.telephony.ims.aidl.IPublishResponseCallback;
30 import android.telephony.ims.aidl.IOptionsResponseCallback;
31 import android.telephony.ims.aidl.ISipTransport;
32 import android.telephony.ims.aidl.ISubscribeResponseCallback;
33 import android.telephony.ims.feature.CapabilityChangeRequest;
34 
35 import com.android.internal.annotations.VisibleForTesting;
36 import com.android.telephony.Rlog;
37 
38 import java.util.List;
39 
40 /**
41  * A container of the IImsServiceController binder, which implements all of the RcsFeatures that
42  * the platform currently supports: RCS
43  */
44 public class RcsFeatureConnection extends FeatureConnection {
45     private static final String TAG = "RcsFeatureConnection";
46 
47     public class AvailabilityCallbackManager extends
48             ImsCallbackAdapterManager<IImsCapabilityCallback> {
49 
AvailabilityCallbackManager(Context context)50         AvailabilityCallbackManager(Context context) {
51             super(context, new Object() /* Lock object */, mSlotId, mSubId);
52         }
53 
54         @Override
registerCallback(IImsCapabilityCallback localCallback)55         public void registerCallback(IImsCapabilityCallback localCallback) {
56             try {
57                 addCapabilityCallback(localCallback);
58             } catch (RemoteException e) {
59                 loge("Register capability callback error: " + e);
60                 throw new IllegalStateException(
61                         " CapabilityCallbackManager: Register callback error");
62             }
63         }
64 
65         @Override
unregisterCallback(IImsCapabilityCallback localCallback)66         public void unregisterCallback(IImsCapabilityCallback localCallback) {
67             try {
68                 removeCapabilityCallback(localCallback);
69             } catch (RemoteException e) {
70                 loge("Cannot remove capability callback: " + e);
71             }
72         }
73     }
74 
75     private class RegistrationCallbackManager extends
76             ImsCallbackAdapterManager<IImsRegistrationCallback> {
77 
RegistrationCallbackManager(Context context)78         public RegistrationCallbackManager(Context context) {
79             super(context, new Object() /* Lock object */, mSlotId, mSubId);
80         }
81 
82         @Override
registerCallback(IImsRegistrationCallback localCallback)83         public void registerCallback(IImsRegistrationCallback localCallback) {
84             IImsRegistration imsRegistration = getRegistration();
85             if (imsRegistration == null) {
86                 loge("Register IMS registration callback: ImsRegistration is null");
87                 throw new IllegalStateException("RegistrationCallbackAdapter: RcsFeature is"
88                         + " not available!");
89             }
90 
91             try {
92                 imsRegistration.addRegistrationCallback(localCallback);
93             } catch (RemoteException e) {
94                 throw new IllegalStateException("RegistrationCallbackAdapter: RcsFeature"
95                         + " binder is dead.");
96             }
97         }
98 
99         @Override
unregisterCallback(IImsRegistrationCallback localCallback)100         public void unregisterCallback(IImsRegistrationCallback localCallback) {
101             IImsRegistration imsRegistration = getRegistration();
102             if (imsRegistration == null) {
103                 logi("Unregister IMS registration callback: ImsRegistration is null");
104                 return;
105             }
106 
107             try {
108                 imsRegistration.removeRegistrationCallback(localCallback);
109             } catch (RemoteException e) {
110                 loge("Cannot remove registration callback: " + e);
111             }
112         }
113     }
114 
115     private final AvailabilityCallbackManager mAvailabilityCallbackManager;
116     private final RegistrationCallbackManager mRegistrationCallbackManager;
117 
RcsFeatureConnection(Context context, int slotId, int subId, IImsRcsFeature feature, IImsConfig c, IImsRegistration r, ISipTransport s)118     public RcsFeatureConnection(Context context, int slotId, int subId, IImsRcsFeature feature,
119             IImsConfig c, IImsRegistration r, ISipTransport s) {
120         super(context, slotId, subId, c, r, s);
121         mAvailabilityCallbackManager = new AvailabilityCallbackManager(mContext);
122         mRegistrationCallbackManager = new RegistrationCallbackManager(mContext);
123         setBinder(feature != null ? feature.asBinder() : null);
124     }
125 
close()126     public void close() {
127         removeCapabilityExchangeEventListener();
128         mAvailabilityCallbackManager.close();
129         mRegistrationCallbackManager.close();
130     }
131 
132     @Override
onRemovedOrDied()133     protected void onRemovedOrDied() {
134         close();
135         super.onRemovedOrDied();
136     }
137 
setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener)138     public void setCapabilityExchangeEventListener(ICapabilityExchangeEventListener listener)
139             throws RemoteException {
140         synchronized (mLock) {
141             // Only check if service is alive. The feature status may not be READY.
142             checkServiceIsAlive();
143             getServiceInterface(mBinder).setCapabilityExchangeEventListener(listener);
144         }
145     }
146 
removeCapabilityExchangeEventListener()147     public void removeCapabilityExchangeEventListener() {
148         try {
149             setCapabilityExchangeEventListener(null);
150         } catch (RemoteException e) {
151             // If we are not still connected, there is no need to fail removing.
152         }
153     }
154 
checkServiceIsAlive()155     private void checkServiceIsAlive() throws RemoteException {
156         if (!sImsSupportedOnDevice) {
157             throw new RemoteException("IMS is not supported on this device.");
158         }
159         if (!isBinderAlive()) {
160             throw new RemoteException("ImsServiceProxy is not alive.");
161         }
162     }
163 
queryCapabilityStatus()164     public int queryCapabilityStatus() throws RemoteException {
165         synchronized (mLock) {
166             checkServiceIsReady();
167             return getServiceInterface(mBinder).queryCapabilityStatus();
168         }
169     }
170 
addCallbackForSubscription(int subId, IImsCapabilityCallback cb)171     public void addCallbackForSubscription(int subId, IImsCapabilityCallback cb) {
172         mAvailabilityCallbackManager.addCallbackForSubscription(cb, subId);
173     }
174 
addCallbackForSubscription(int subId, IImsRegistrationCallback cb)175     public void addCallbackForSubscription(int subId, IImsRegistrationCallback cb) {
176         mRegistrationCallbackManager.addCallbackForSubscription(cb, subId);
177     }
178 
addCallback(IImsRegistrationCallback cb)179     public void addCallback(IImsRegistrationCallback cb) {
180         mRegistrationCallbackManager.addCallback(cb);
181     }
182 
removeCallbackForSubscription(int subId, IImsCapabilityCallback cb)183     public void removeCallbackForSubscription(int subId, IImsCapabilityCallback cb) {
184         mAvailabilityCallbackManager.removeCallback(cb);
185     }
186 
removeCallbackForSubscription(int subId, IImsRegistrationCallback cb)187     public void removeCallbackForSubscription(int subId, IImsRegistrationCallback cb) {
188         mRegistrationCallbackManager.removeCallback(cb);
189     }
190 
removeCallback(IImsRegistrationCallback cb)191     public void removeCallback(IImsRegistrationCallback cb) {
192         mRegistrationCallbackManager.removeCallback(cb);
193     }
194 
195     // Add callback to remote service
addCapabilityCallback(IImsCapabilityCallback callback)196     private void addCapabilityCallback(IImsCapabilityCallback callback) throws RemoteException {
197         synchronized (mLock) {
198             checkServiceIsReady();
199             getServiceInterface(mBinder).addCapabilityCallback(callback);
200         }
201     }
202 
203     // Remove callback to remote service
removeCapabilityCallback(IImsCapabilityCallback callback)204     private void removeCapabilityCallback(IImsCapabilityCallback callback) throws RemoteException {
205         synchronized (mLock) {
206             checkServiceIsReady();
207             getServiceInterface(mBinder).removeCapabilityCallback(callback);
208         }
209     }
210 
queryCapabilityConfiguration(int capability, int radioTech, IImsCapabilityCallback c)211     public void queryCapabilityConfiguration(int capability, int radioTech,
212             IImsCapabilityCallback c) throws RemoteException {
213         synchronized (mLock) {
214             checkServiceIsReady();
215             getServiceInterface(mBinder).queryCapabilityConfiguration(capability, radioTech, c);
216         }
217     }
218 
changeEnabledCapabilities(CapabilityChangeRequest request, IImsCapabilityCallback callback)219     public void changeEnabledCapabilities(CapabilityChangeRequest request,
220             IImsCapabilityCallback callback) throws RemoteException {
221         synchronized (mLock) {
222             checkServiceIsReady();
223             getServiceInterface(mBinder).changeCapabilitiesConfiguration(request, callback);
224         }
225     }
226 
requestPublication(String pidfXml, IPublishResponseCallback responseCallback)227     public void requestPublication(String pidfXml, IPublishResponseCallback responseCallback)
228             throws RemoteException {
229         synchronized (mLock) {
230             checkServiceIsReady();
231             getServiceInterface(mBinder).publishCapabilities(pidfXml, responseCallback);
232         }
233     }
234 
requestCapabilities(List<Uri> uris, ISubscribeResponseCallback c)235     public void requestCapabilities(List<Uri> uris, ISubscribeResponseCallback c)
236             throws RemoteException {
237         synchronized (mLock) {
238             checkServiceIsReady();
239             getServiceInterface(mBinder).subscribeForCapabilities(uris, c);
240         }
241     }
242 
sendOptionsCapabilityRequest(Uri contactUri, List<String> myCapabilities, IOptionsResponseCallback callback)243     public void sendOptionsCapabilityRequest(Uri contactUri, List<String> myCapabilities,
244             IOptionsResponseCallback callback) throws RemoteException {
245         synchronized (mLock) {
246             checkServiceIsReady();
247             getServiceInterface(mBinder).sendOptionsCapabilityRequest(contactUri, myCapabilities,
248                     callback);
249         }
250     }
251 
252     @Override
253     @VisibleForTesting
retrieveFeatureState()254     public Integer retrieveFeatureState() {
255         if (mBinder != null) {
256             try {
257                 return getServiceInterface(mBinder).getFeatureState();
258             } catch (RemoteException e) {
259                 // Status check failed, don't update cache
260             }
261         }
262         return null;
263     }
264 
265     @Override
onFeatureCapabilitiesUpdated(long capabilities)266     public void onFeatureCapabilitiesUpdated(long capabilities)
267     {
268         // doesn't do anything for RCS yet.
269     }
270 
271     @VisibleForTesting
getServiceInterface(IBinder b)272     public IImsRcsFeature getServiceInterface(IBinder b) {
273         return IImsRcsFeature.Stub.asInterface(b);
274     }
log(String s)275     private void log(String s) {
276         Rlog.d(TAG + " [" + mSlotId + "]", s);
277     }
278 
logi(String s)279     private void logi(String s) {
280         Rlog.i(TAG + " [" + mSlotId + "]", s);
281     }
282 
loge(String s)283     private void loge(String s) {
284         Rlog.e(TAG + " [" + mSlotId + "]", s);
285     }
286 }
287