| /* |
| * Copyright (C) 2018 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.telephony.mbms; |
| |
| import android.annotation.IntDef; |
| import android.os.RemoteException; |
| import android.telephony.MbmsGroupCallSession; |
| import android.telephony.mbms.vendor.IMbmsGroupCallService; |
| import android.util.Log; |
| |
| import java.lang.annotation.Retention; |
| import java.lang.annotation.RetentionPolicy; |
| |
| /** |
| * Class used to represent a single MBMS group call. After a call has been started with |
| * {@link MbmsGroupCallSession#startGroupCall}, |
| * this class is used to hold information about the call and control it. |
| */ |
| public class GroupCall implements AutoCloseable { |
| private static final String LOG_TAG = "MbmsGroupCall"; |
| |
| /** |
| * The state of a group call, reported via |
| * {@link GroupCallCallback#onGroupCallStateChanged(int, int)} |
| * @hide |
| */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef(prefix = { "STATE_" }, value = {STATE_STOPPED, STATE_STARTED, STATE_STALLED}) |
| public @interface GroupCallState {} |
| public static final int STATE_STOPPED = 1; |
| public static final int STATE_STARTED = 2; |
| public static final int STATE_STALLED = 3; |
| |
| /** |
| * The reason for a call state change, reported via |
| * {@link GroupCallCallback#onGroupCallStateChanged(int, int)} |
| * @hide |
| */ |
| @Retention(RetentionPolicy.SOURCE) |
| @IntDef(prefix = { "REASON_" }, |
| value = {REASON_BY_USER_REQUEST, REASON_FREQUENCY_CONFLICT, |
| REASON_OUT_OF_MEMORY, REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE, |
| REASON_LEFT_MBMS_BROADCAST_AREA, REASON_NONE}) |
| public @interface GroupCallStateChangeReason {} |
| |
| /** |
| * Indicates that the middleware does not have a reason to provide for the state change. |
| */ |
| public static final int REASON_NONE = 0; |
| |
| /** |
| * State changed due to a call to {@link #close()} or |
| * {@link MbmsGroupCallSession#startGroupCall} |
| */ |
| public static final int REASON_BY_USER_REQUEST = 1; |
| |
| // 2 is unused to match up with streaming. |
| |
| /** |
| * State changed due to a frequency conflict with another requested call. |
| */ |
| public static final int REASON_FREQUENCY_CONFLICT = 3; |
| |
| /** |
| * State changed due to the middleware running out of memory |
| */ |
| public static final int REASON_OUT_OF_MEMORY = 4; |
| |
| /** |
| * State changed due to the device leaving the home carrier's LTE network. |
| */ |
| public static final int REASON_NOT_CONNECTED_TO_HOMECARRIER_LTE = 5; |
| |
| /** |
| * State changed due to the device leaving the area where this call is being broadcast. |
| */ |
| public static final int REASON_LEFT_MBMS_BROADCAST_AREA = 6; |
| |
| private final int mSubscriptionId; |
| private final long mTmgi; |
| private final MbmsGroupCallSession mParentSession; |
| private final InternalGroupCallCallback mCallback; |
| private IMbmsGroupCallService mService; |
| |
| /** |
| * @hide |
| */ |
| public GroupCall(int subscriptionId, |
| IMbmsGroupCallService service, |
| MbmsGroupCallSession session, |
| long tmgi, |
| InternalGroupCallCallback callback) { |
| mSubscriptionId = subscriptionId; |
| mParentSession = session; |
| mService = service; |
| mTmgi = tmgi; |
| mCallback = callback; |
| } |
| |
| /** |
| * Retrieve the TMGI (Temporary Mobile Group Identity) corresponding to this call. |
| */ |
| public long getTmgi() { |
| return mTmgi; |
| } |
| |
| /** |
| * Send an update to the middleware when the SAI (Service Area Identifier) list and frequency |
| * information of the group call has * changed. Callers must obtain this information from the |
| * wireless carrier independently. |
| * @param saiArray New array of SAIs that the call is available on. |
| * @param frequencyArray New array of frequencies that the call is available on. |
| */ |
| public void updateGroupCall(int[] saiArray, int[] frequencyArray) { |
| if (mService == null) { |
| throw new IllegalStateException("No group call service attached"); |
| } |
| |
| try { |
| mService.updateGroupCall(mSubscriptionId, mTmgi, saiArray, frequencyArray); |
| } catch (RemoteException e) { |
| Log.w(LOG_TAG, "Remote process died"); |
| mService = null; |
| sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); |
| } finally { |
| mParentSession.onGroupCallStopped(this); |
| } |
| } |
| |
| /** |
| * Stop this group call. Further operations on this object will fail with an |
| * {@link IllegalStateException}. |
| * |
| * May throw an {@link IllegalStateException} |
| */ |
| @Override |
| public void close() { |
| if (mService == null) { |
| throw new IllegalStateException("No group call service attached"); |
| } |
| |
| try { |
| mService.stopGroupCall(mSubscriptionId, mTmgi); |
| } catch (RemoteException e) { |
| Log.w(LOG_TAG, "Remote process died"); |
| mService = null; |
| sendErrorToApp(MbmsErrors.ERROR_MIDDLEWARE_LOST, null); |
| } finally { |
| mParentSession.onGroupCallStopped(this); |
| } |
| } |
| |
| /** @hide */ |
| public InternalGroupCallCallback getCallback() { |
| return mCallback; |
| } |
| |
| private void sendErrorToApp(int errorCode, String message) { |
| mCallback.onError(errorCode, message); |
| } |
| } |
| |