blob: df48cd6a16e2bfa72b5c1ac8f3373b3fdbe0b6db [file] [log] [blame]
Grace Jiaef5a4cc2022-12-13 11:08:55 -08001/*
2 * Copyright (C) 2022 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.telecom;
18
19import android.annotation.IntDef;
20import android.annotation.NonNull;
21import android.annotation.SdkConstant;
Grace Jiaacd4dad2023-01-17 18:14:36 -080022import android.annotation.SystemApi;
Grace Jiaef5a4cc2022-12-13 11:08:55 -080023import android.app.Service;
24import android.content.Intent;
25import android.os.Handler;
26import android.os.IBinder;
27import android.os.Looper;
28import android.os.Message;
29import android.os.RemoteException;
30
31import androidx.annotation.Nullable;
32
33import com.android.internal.telecom.ICallStreamingService;
34import com.android.internal.telecom.IStreamingCallAdapter;
35
36import java.lang.annotation.Retention;
37import java.lang.annotation.RetentionPolicy;
38
39/**
40 * This service is implemented by an app that wishes to provide functionality for a general call
41 * streaming sender for voip calls.
Grace Jiaacd4dad2023-01-17 18:14:36 -080042 * <p>
43 * Below is an example manifest registration for a {@code CallStreamingService}.
44 * <pre>
45 * {@code
46 * <service android:name=".EgCallStreamingService"
47 * android:permission="android.permission.BIND_CALL_STREAMING_SERVICE" >
48 * ...
49 * <intent-filter>
50 * <action android:name="android.telecom.CallStreamingService" />
51 * </intent-filter>
52 * </service>
53 * }
54 * </pre>
Thomas Stuart6e377852023-04-18 16:54:52 -070055 *
Grace Jiaacd4dad2023-01-17 18:14:36 -080056 * @hide
Grace Jiaef5a4cc2022-12-13 11:08:55 -080057 */
Grace Jiaacd4dad2023-01-17 18:14:36 -080058@SystemApi
Grace Jiaef5a4cc2022-12-13 11:08:55 -080059public abstract class CallStreamingService extends Service {
60 /**
61 * The {@link android.content.Intent} that must be declared as handled by the service.
62 */
63 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
64 public static final String SERVICE_INTERFACE = "android.telecom.CallStreamingService";
65
66 private static final int MSG_SET_STREAMING_CALL_ADAPTER = 1;
67 private static final int MSG_CALL_STREAMING_STARTED = 2;
68 private static final int MSG_CALL_STREAMING_STOPPED = 3;
Thomas Stuart6e377852023-04-18 16:54:52 -070069 private static final int MSG_CALL_STREAMING_STATE_CHANGED = 4;
Grace Jiaef5a4cc2022-12-13 11:08:55 -080070
71 /** Default Handler used to consolidate binder method calls onto a single thread. */
72 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
73 @Override
74 public void handleMessage(Message msg) {
75 if (mStreamingCallAdapter == null && msg.what != MSG_SET_STREAMING_CALL_ADAPTER) {
76 return;
77 }
78
79 switch (msg.what) {
80 case MSG_SET_STREAMING_CALL_ADAPTER:
Thomas Stuart6e377852023-04-18 16:54:52 -070081 if (msg.obj != null) {
82 mStreamingCallAdapter = new StreamingCallAdapter(
83 (IStreamingCallAdapter) msg.obj);
84 }
Grace Jiaef5a4cc2022-12-13 11:08:55 -080085 break;
86 case MSG_CALL_STREAMING_STARTED:
87 mCall = (StreamingCall) msg.obj;
88 mCall.setAdapter(mStreamingCallAdapter);
89 CallStreamingService.this.onCallStreamingStarted(mCall);
90 break;
91 case MSG_CALL_STREAMING_STOPPED:
92 mCall = null;
93 mStreamingCallAdapter = null;
94 CallStreamingService.this.onCallStreamingStopped();
95 break;
Thomas Stuart6e377852023-04-18 16:54:52 -070096 case MSG_CALL_STREAMING_STATE_CHANGED:
Grace Jiaef5a4cc2022-12-13 11:08:55 -080097 int state = (int) msg.obj;
Thomas Stuart6e377852023-04-18 16:54:52 -070098 if (mStreamingCallAdapter != null) {
99 mCall.requestStreamingState(state);
100 CallStreamingService.this.onCallStreamingStateChanged(state);
101 }
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800102 break;
103 default:
104 break;
105 }
106 }
107 };
108
109 @Nullable
110 @Override
111 public IBinder onBind(@NonNull Intent intent) {
112 return new CallStreamingServiceBinder();
113 }
114
115 /** Manages the binder calls so that the implementor does not need to deal with it. */
116 private final class CallStreamingServiceBinder extends ICallStreamingService.Stub {
117 @Override
118 public void setStreamingCallAdapter(IStreamingCallAdapter streamingCallAdapter)
119 throws RemoteException {
120 mHandler.obtainMessage(MSG_SET_STREAMING_CALL_ADAPTER, mStreamingCallAdapter)
121 .sendToTarget();
122 }
123
124 @Override
125 public void onCallStreamingStarted(StreamingCall call) throws RemoteException {
126 mHandler.obtainMessage(MSG_CALL_STREAMING_STARTED, call).sendToTarget();
127 }
128
129 @Override
130 public void onCallStreamingStopped() throws RemoteException {
131 mHandler.obtainMessage(MSG_CALL_STREAMING_STOPPED).sendToTarget();
132 }
133
134 @Override
135 public void onCallStreamingStateChanged(int state) throws RemoteException {
Thomas Stuart6e377852023-04-18 16:54:52 -0700136 mHandler.obtainMessage(MSG_CALL_STREAMING_STATE_CHANGED, state).sendToTarget();
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800137 }
138 }
139
140 /**
141 * Call streaming request reject reason used with
142 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
Grace Jiaacd4dad2023-01-17 18:14:36 -0800143 * call streaming request due to unknown reason.
144 */
145 public static final int STREAMING_FAILED_UNKNOWN = 0;
146
147 /**
148 * Call streaming request reject reason used with
149 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800150 * call streaming request because there's an ongoing streaming call on this device.
151 */
152 public static final int STREAMING_FAILED_ALREADY_STREAMING = 1;
153
154 /**
155 * Call streaming request reject reason used with
156 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
157 * call streaming request because telecom can't find existing general streaming sender on this
158 * device.
159 */
160 public static final int STREAMING_FAILED_NO_SENDER = 2;
161
162 /**
163 * Call streaming request reject reason used with
164 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
165 * call streaming request because telecom can't bind to the general streaming sender app.
166 */
167 public static final int STREAMING_FAILED_SENDER_BINDING_ERROR = 3;
168
169 private StreamingCallAdapter mStreamingCallAdapter;
170 private StreamingCall mCall;
171
172 /**
173 * @hide
174 */
175 @IntDef(prefix = {"STREAMING_FAILED"},
176 value = {
Grace Jiaacd4dad2023-01-17 18:14:36 -0800177 STREAMING_FAILED_UNKNOWN,
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800178 STREAMING_FAILED_ALREADY_STREAMING,
179 STREAMING_FAILED_NO_SENDER,
180 STREAMING_FAILED_SENDER_BINDING_ERROR
Thomas Stuart6e377852023-04-18 16:54:52 -0700181 })
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800182 @Retention(RetentionPolicy.SOURCE)
Thomas Stuart6e377852023-04-18 16:54:52 -0700183 public @interface StreamingFailedReason {
184 }
185
186 ;
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800187
188 /**
189 * Called when a {@code StreamingCall} has been added to this call streaming session. The call
190 * streaming sender should start to intercept the device audio using audio records and audio
191 * tracks from Audio frameworks.
192 *
193 * @param call a newly added {@code StreamingCall}.
194 */
195 public void onCallStreamingStarted(@NonNull StreamingCall call) {
196 }
197
198 /**
199 * Called when a current {@code StreamingCall} has been removed from this call streaming
200 * session. The call streaming sender should notify the streaming receiver that the call is
201 * stopped streaming and stop the device audio interception.
202 */
203 public void onCallStreamingStopped() {
204 }
205
206 /**
207 * Called when the streaming state of current {@code StreamingCall} changed. General streaming
208 * sender usually get notified of the holding/unholding from the original owner voip app of the
209 * call.
210 */
211 public void onCallStreamingStateChanged(@StreamingCall.StreamingCallState int state) {
212 }
213}