blob: e085dec105460fa45c09d93482e0c426f0daa282 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
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
17package android.telephony.ims;
18
19import android.Manifest;
20import android.annotation.CallbackExecutor;
21import android.annotation.IntDef;
22import android.annotation.NonNull;
23import android.annotation.Nullable;
24import android.annotation.RequiresPermission;
25import android.net.Uri;
26import android.os.Binder;
27import android.telephony.AccessNetworkConstants;
28import android.telephony.ims.aidl.IImsRegistrationCallback;
29import android.telephony.ims.feature.ImsFeature;
30import android.telephony.ims.stub.ImsRegistrationImplBase;
31import android.util.Log;
32
33import java.lang.annotation.Retention;
34import java.lang.annotation.RetentionPolicy;
35import java.util.HashMap;
36import java.util.Map;
37import java.util.concurrent.Executor;
38import java.util.function.Consumer;
39
40/**
41 * Manages IMS Service registration state for associated {@link ImsFeature}s.
42 */
43public interface RegistrationManager {
44
45 /**
46 * @hide
47 */
48 // Defines the underlying radio technology type that we have registered for IMS over.
49 @IntDef(prefix = "REGISTRATION_STATE_",
50 value = {
51 REGISTRATION_STATE_NOT_REGISTERED,
52 REGISTRATION_STATE_REGISTERING,
53 REGISTRATION_STATE_REGISTERED
54 })
55 @Retention(RetentionPolicy.SOURCE)
56 public @interface ImsRegistrationState {}
57
58 /**
59 * The IMS service is currently not registered to the carrier network.
60 */
61 int REGISTRATION_STATE_NOT_REGISTERED = 0;
62
63 /**
64 * The IMS service is currently in the process of registering to the carrier network.
65 */
66 int REGISTRATION_STATE_REGISTERING = 1;
67
68 /**
69 * The IMS service is currently registered to the carrier network.
70 */
71 int REGISTRATION_STATE_REGISTERED = 2;
72
73
74 /**@hide*/
75 // Translate ImsRegistrationImplBase API to new AccessNetworkConstant because WLAN
76 // and WWAN are more accurate constants.
77 Map<Integer, Integer> IMS_REG_TO_ACCESS_TYPE_MAP =
78 new HashMap<Integer, Integer>() {{
79 // Map NONE to -1 to make sure that we handle the REGISTRATION_TECH_NONE
80 // case, since it is defined.
81 put(ImsRegistrationImplBase.REGISTRATION_TECH_NONE, -1);
82 put(ImsRegistrationImplBase.REGISTRATION_TECH_LTE,
83 AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
84 put(ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN,
85 AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
86 }};
87
88 /**
89 * Callback class for receiving IMS network Registration callback events.
90 * @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
91 * @see #unregisterImsRegistrationCallback(RegistrationCallback)
92 */
93 class RegistrationCallback {
94
95 private static class RegistrationBinder extends IImsRegistrationCallback.Stub {
96
97 private final RegistrationCallback mLocalCallback;
98 private Executor mExecutor;
99
100 RegistrationBinder(RegistrationCallback localCallback) {
101 mLocalCallback = localCallback;
102 }
103
104 @Override
105 public void onRegistered(int imsRadioTech) {
106 if (mLocalCallback == null) return;
107
108 long callingIdentity = Binder.clearCallingIdentity();
109 try {
110 mExecutor.execute(() ->
111 mLocalCallback.onRegistered(getAccessType(imsRadioTech)));
112 } finally {
113 restoreCallingIdentity(callingIdentity);
114 }
115 }
116
117 @Override
118 public void onRegistering(int imsRadioTech) {
119 if (mLocalCallback == null) return;
120
121 long callingIdentity = Binder.clearCallingIdentity();
122 try {
123 mExecutor.execute(() ->
124 mLocalCallback.onRegistering(getAccessType(imsRadioTech)));
125 } finally {
126 restoreCallingIdentity(callingIdentity);
127 }
128 }
129
130 @Override
131 public void onDeregistered(ImsReasonInfo info) {
132 if (mLocalCallback == null) return;
133
134 long callingIdentity = Binder.clearCallingIdentity();
135 try {
136 mExecutor.execute(() -> mLocalCallback.onUnregistered(info));
137 } finally {
138 restoreCallingIdentity(callingIdentity);
139 }
140 }
141
142 @Override
143 public void onTechnologyChangeFailed(int imsRadioTech, ImsReasonInfo info) {
144 if (mLocalCallback == null) return;
145
146 long callingIdentity = Binder.clearCallingIdentity();
147 try {
148 mExecutor.execute(() -> mLocalCallback.onTechnologyChangeFailed(
149 getAccessType(imsRadioTech), info));
150 } finally {
151 restoreCallingIdentity(callingIdentity);
152 }
153 }
154
155 public void onSubscriberAssociatedUriChanged(Uri[] uris) {
156 if (mLocalCallback == null) return;
157
158 long callingIdentity = Binder.clearCallingIdentity();
159 try {
160 mExecutor.execute(() -> mLocalCallback.onSubscriberAssociatedUriChanged(uris));
161 } finally {
162 restoreCallingIdentity(callingIdentity);
163 }
164 }
165
166 private void setExecutor(Executor executor) {
167 mExecutor = executor;
168 }
169
170 private static int getAccessType(int regType) {
171 if (!RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.containsKey(regType)) {
172 Log.w("RegistrationManager", "RegistrationBinder - invalid regType returned: "
173 + regType);
174 return -1;
175 }
176 return RegistrationManager.IMS_REG_TO_ACCESS_TYPE_MAP.get(regType);
177 }
178 }
179
180 private final RegistrationBinder mBinder = new RegistrationBinder(this);
181
182 /**
183 * Notifies the framework when the IMS Provider is registered to the IMS network.
184 *
185 * @param imsTransportType the radio access technology.
186 */
187 public void onRegistered(@AccessNetworkConstants.TransportType int imsTransportType) {
188 }
189
190 /**
191 * Notifies the framework when the IMS Provider is trying to register the IMS network.
192 *
193 * @param imsTransportType the radio access technology.
194 */
195 public void onRegistering(@AccessNetworkConstants.TransportType int imsTransportType) {
196 }
197
198 /**
199 * Notifies the framework when the IMS Provider is unregistered from the IMS network.
200 *
201 * @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
202 */
203 public void onUnregistered(@NonNull ImsReasonInfo info) {
204 }
205
206 /**
207 * A failure has occurred when trying to handover registration to another technology type.
208 *
209 * @param imsTransportType The transport type that has failed to handover registration to.
210 * @param info A {@link ImsReasonInfo} that identifies the reason for failure.
211 */
212 public void onTechnologyChangeFailed(
213 @AccessNetworkConstants.TransportType int imsTransportType,
214 @NonNull ImsReasonInfo info) {
215 }
216
217 /**
218 * Returns a list of subscriber {@link Uri}s associated with this IMS subscription when
219 * it changes. Per RFC3455, an associated URI is a URI that the service provider has
220 * allocated to a user for their own usage. A user's phone number is typically one of the
221 * associated URIs.
222 * @param uris new array of subscriber {@link Uri}s that are associated with this IMS
223 * subscription.
224 * @hide
225 */
226 public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
227 }
228
229 /**@hide*/
230 public final IImsRegistrationCallback getBinder() {
231 return mBinder;
232 }
233
234 /**@hide*/
235 //Only exposed as public for compatibility with deprecated ImsManager APIs.
236 public void setExecutor(Executor executor) {
237 mBinder.setExecutor(executor);
238 }
239 }
240
241 /**
242 * Registers a {@link RegistrationCallback} with the system. Use
243 * @param executor The {@link Executor} that will be used to call the IMS registration state
244 * callback.
245 * @param c A callback called on the supplied {@link Executor} that will contain the
246 * registration state of the IMS service, which will be one of the
247 * {@see SubscriptionManager.OnSubscriptionsChangedListener} to listen to Subscription changed
248 * events and call {@link #unregisterImsRegistrationCallback(RegistrationCallback)} to clean up.
249 *
250 * When the callback is registered, it will initiate the callback c to be called with the
251 * current registration state.
252 *
253 * @param executor The executor the callback events should be run on.
254 * @param c The {@link RegistrationCallback} to be added.
255 * @see #unregisterImsRegistrationCallback(RegistrationCallback)
256 * @throws ImsException if the subscription associated with this callback is valid, but
257 * the {@link ImsService} associated with the subscription is not available. This can happen if
258 * the service crashed, for example. See {@link ImsException#getCode()} for a more detailed
259 * reason.
260 */
261 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
262 void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
263 @NonNull RegistrationCallback c) throws ImsException;
264
265 /**
266 * Removes an existing {@link RegistrationCallback}.
267 *
268 * When the subscription associated with this callback is removed (SIM removed, ESIM swap,
269 * etc...), this callback will automatically be removed. If this method is called for an
270 * inactive subscription, it will result in a no-op.
271 *
272 * @param c The {@link RegistrationCallback} to be removed.
273 * @see android.telephony.SubscriptionManager.OnSubscriptionsChangedListener
274 * @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
275 */
276 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
277 void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c);
278
279 /**
280 * Gets the registration state of the IMS service.
281 * @param executor The {@link Executor} that will be used to call the IMS registration state
282 * callback.
283 * @param stateCallback A callback called on the supplied {@link Executor} that will contain the
284 * registration state of the IMS service, which will be one of the
285 * following: {@link #REGISTRATION_STATE_NOT_REGISTERED},
286 * {@link #REGISTRATION_STATE_REGISTERING}, or
287 * {@link #REGISTRATION_STATE_REGISTERED}.
288 */
289 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
290 void getRegistrationState(@NonNull @CallbackExecutor Executor executor,
291 @NonNull @ImsRegistrationState Consumer<Integer> stateCallback);
292
293 /**
294 * Gets the Transport Type associated with the current IMS registration.
295 * @param executor The {@link Executor} that will be used to call the transportTypeCallback.
296 * @param transportTypeCallback The transport type associated with the current IMS registration,
297 * which will be one of following:
298 * {@see AccessNetworkConstants#TRANSPORT_TYPE_WWAN},
299 * {@see AccessNetworkConstants#TRANSPORT_TYPE_WLAN}, or
300 * {@see AccessNetworkConstants#TRANSPORT_TYPE_INVALID}.
301 */
302 @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
303 void getRegistrationTransportType(
304 @NonNull @CallbackExecutor Executor executor,
305 @NonNull @AccessNetworkConstants.TransportType Consumer<Integer> transportTypeCallback);
306}