1 /*
2  * Copyright (C) 2020 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 android.telephony.ims.aidl;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.net.Uri;
22 import android.os.Binder;
23 import android.os.RemoteException;
24 import android.telephony.ims.ImsException;
25 import android.telephony.ims.RcsContactUceCapability;
26 import android.telephony.ims.SipDetails;
27 import android.telephony.ims.stub.CapabilityExchangeEventListener;
28 import android.util.Log;
29 
30 import java.util.ArrayList;
31 import java.util.Set;
32 
33 /**
34  * The ICapabilityExchangeEventListener wrapper class to store the listener which is registered by
35  * the framework. This wrapper class also delivers the request to the framework when receive the
36  * request from the network.
37  * @hide
38  */
39 public class CapabilityExchangeAidlWrapper implements CapabilityExchangeEventListener {
40 
41     private static final String LOG_TAG = "CapExchangeListener";
42 
43     private final ICapabilityExchangeEventListener mListenerBinder;
44 
CapabilityExchangeAidlWrapper(@ullable ICapabilityExchangeEventListener listener)45     public CapabilityExchangeAidlWrapper(@Nullable ICapabilityExchangeEventListener listener) {
46         mListenerBinder = listener;
47     }
48 
49     /**
50      * Receives the request of publishing capabilities from the network and deliver this request
51      * to the framework via the registered capability exchange event listener.
52      */
onRequestPublishCapabilities(int publishTriggerType)53     public void onRequestPublishCapabilities(int publishTriggerType) throws ImsException {
54         ICapabilityExchangeEventListener listener = mListenerBinder;
55         if (listener == null) {
56             return;
57         }
58         try {
59             listener.onRequestPublishCapabilities(publishTriggerType);
60         } catch (RemoteException e) {
61             Log.w(LOG_TAG, "request publish capabilities exception: " + e);
62             throw new ImsException("Remote is not available",
63                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
64         }
65     }
66 
67     /**
68      * Receives the unpublish notification and deliver this callback to the framework.
69      */
onUnpublish()70     public void onUnpublish() throws ImsException {
71         ICapabilityExchangeEventListener listener = mListenerBinder;
72         if (listener == null) {
73             return;
74         }
75         try {
76             listener.onUnpublish();
77         } catch (RemoteException e) {
78             Log.w(LOG_TAG, "Unpublish exception: " + e);
79             throw new ImsException("Remote is not available",
80                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
81         }
82     }
83 
84     /**
85      * Receives the status of changes in the publishing connection from ims service
86      * and deliver this callback to the framework.
87      *
88      * @deprecated Replaced by {@link #onPublishUpdated(SipDetails)}, deprecated for
89      * sip information.
90      */
91     @Deprecated
onPublishUpdated(int reasonCode, @NonNull String reasonPhrase, int reasonHeaderCause, @NonNull String reasonHeaderText)92     public void onPublishUpdated(int reasonCode, @NonNull String reasonPhrase,
93             int reasonHeaderCause, @NonNull String reasonHeaderText) throws ImsException {
94         ICapabilityExchangeEventListener listener = mListenerBinder;
95         if (listener == null) {
96             return;
97         }
98         try {
99             SipDetails details = new SipDetails.Builder(SipDetails.METHOD_PUBLISH)
100                     .setSipResponseCode(reasonCode, reasonPhrase)
101                     .setSipResponseReasonHeader(reasonHeaderCause, reasonHeaderText)
102                     .build();
103             listener.onPublishUpdated(details);
104         } catch (RemoteException e) {
105             Log.w(LOG_TAG, "onPublishUpdated exception: " + e);
106             throw new ImsException("Remote is not available",
107                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
108         }
109     }
110 
111     /**
112      * Receives the status of changes in the publishing connection from ims service
113      * and deliver this callback to the framework.
114      */
onPublishUpdated(@onNull SipDetails details)115     public void onPublishUpdated(@NonNull SipDetails details) throws ImsException {
116         ICapabilityExchangeEventListener listener = mListenerBinder;
117         if (listener == null) {
118             return;
119         }
120         try {
121             listener.onPublishUpdated(details);
122         } catch (RemoteException e) {
123             Log.w(LOG_TAG, "onPublishUpdated exception: " + e);
124             throw new ImsException("Remote is not available",
125                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
126         }
127     }
128 
129     /**
130      * Receives the callback of the remote capability request from the network and deliver this
131      * request to the framework.
132      */
onRemoteCapabilityRequest(@onNull Uri contactUri, @NonNull Set<String> remoteCapabilities, @NonNull OptionsRequestCallback callback)133     public void onRemoteCapabilityRequest(@NonNull Uri contactUri,
134             @NonNull Set<String> remoteCapabilities, @NonNull OptionsRequestCallback callback)
135             throws ImsException {
136         ICapabilityExchangeEventListener listener = mListenerBinder;
137         if (listener == null) {
138             return;
139         }
140 
141         IOptionsRequestCallback internalCallback = new IOptionsRequestCallback.Stub() {
142             @Override
143             public void respondToCapabilityRequest(RcsContactUceCapability ownCapabilities,
144                     boolean isBlocked) {
145                 final long callingIdentity = Binder.clearCallingIdentity();
146                 try {
147                     callback.onRespondToCapabilityRequest(ownCapabilities, isBlocked);
148                 } finally {
149                     restoreCallingIdentity(callingIdentity);
150                 }
151             }
152             @Override
153             public void respondToCapabilityRequestWithError(int code, String reason) {
154                 final long callingIdentity = Binder.clearCallingIdentity();
155                 try {
156                     callback.onRespondToCapabilityRequestWithError(code, reason);
157                 } finally {
158                     restoreCallingIdentity(callingIdentity);
159                 }
160             }
161         };
162 
163         try {
164             listener.onRemoteCapabilityRequest(contactUri, new ArrayList<>(remoteCapabilities),
165                     internalCallback);
166         } catch (RemoteException e) {
167             Log.w(LOG_TAG, "Remote capability request exception: " + e);
168             throw new ImsException("Remote is not available",
169                     ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
170         }
171     }
172 }
173