blob: 3f538a7f262d1d6a325a477ef657f2b21cb2e3c9 [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>
55 * @hide
Grace Jiaef5a4cc2022-12-13 11:08:55 -080056 */
Grace Jiaacd4dad2023-01-17 18:14:36 -080057@SystemApi
Grace Jiaef5a4cc2022-12-13 11:08:55 -080058public abstract class CallStreamingService extends Service {
59 /**
60 * The {@link android.content.Intent} that must be declared as handled by the service.
61 */
62 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
63 public static final String SERVICE_INTERFACE = "android.telecom.CallStreamingService";
64
65 private static final int MSG_SET_STREAMING_CALL_ADAPTER = 1;
66 private static final int MSG_CALL_STREAMING_STARTED = 2;
67 private static final int MSG_CALL_STREAMING_STOPPED = 3;
68 private static final int MSG_CALL_STREAMING_CHANGED_CHANGED = 4;
69
70 /** Default Handler used to consolidate binder method calls onto a single thread. */
71 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
72 @Override
73 public void handleMessage(Message msg) {
74 if (mStreamingCallAdapter == null && msg.what != MSG_SET_STREAMING_CALL_ADAPTER) {
75 return;
76 }
77
78 switch (msg.what) {
79 case MSG_SET_STREAMING_CALL_ADAPTER:
80 mStreamingCallAdapter = new StreamingCallAdapter(
81 (IStreamingCallAdapter) msg.obj);
82 break;
83 case MSG_CALL_STREAMING_STARTED:
84 mCall = (StreamingCall) msg.obj;
85 mCall.setAdapter(mStreamingCallAdapter);
86 CallStreamingService.this.onCallStreamingStarted(mCall);
87 break;
88 case MSG_CALL_STREAMING_STOPPED:
89 mCall = null;
90 mStreamingCallAdapter = null;
91 CallStreamingService.this.onCallStreamingStopped();
92 break;
93 case MSG_CALL_STREAMING_CHANGED_CHANGED:
94 int state = (int) msg.obj;
Grace Jiaefb63a72023-01-19 14:15:25 -080095 mCall.requestStreamingState(state);
Grace Jiaef5a4cc2022-12-13 11:08:55 -080096 CallStreamingService.this.onCallStreamingStateChanged(state);
97 break;
98 default:
99 break;
100 }
101 }
102 };
103
104 @Nullable
105 @Override
106 public IBinder onBind(@NonNull Intent intent) {
107 return new CallStreamingServiceBinder();
108 }
109
110 /** Manages the binder calls so that the implementor does not need to deal with it. */
111 private final class CallStreamingServiceBinder extends ICallStreamingService.Stub {
112 @Override
113 public void setStreamingCallAdapter(IStreamingCallAdapter streamingCallAdapter)
114 throws RemoteException {
115 mHandler.obtainMessage(MSG_SET_STREAMING_CALL_ADAPTER, mStreamingCallAdapter)
116 .sendToTarget();
117 }
118
119 @Override
120 public void onCallStreamingStarted(StreamingCall call) throws RemoteException {
121 mHandler.obtainMessage(MSG_CALL_STREAMING_STARTED, call).sendToTarget();
122 }
123
124 @Override
125 public void onCallStreamingStopped() throws RemoteException {
126 mHandler.obtainMessage(MSG_CALL_STREAMING_STOPPED).sendToTarget();
127 }
128
129 @Override
130 public void onCallStreamingStateChanged(int state) throws RemoteException {
131 mHandler.obtainMessage(MSG_CALL_STREAMING_CHANGED_CHANGED, state).sendToTarget();
132 }
133 }
134
135 /**
136 * Call streaming request reject reason used with
137 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
Grace Jiaacd4dad2023-01-17 18:14:36 -0800138 * call streaming request due to unknown reason.
139 */
140 public static final int STREAMING_FAILED_UNKNOWN = 0;
141
142 /**
143 * Call streaming request reject reason used with
144 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800145 * call streaming request because there's an ongoing streaming call on this device.
146 */
147 public static final int STREAMING_FAILED_ALREADY_STREAMING = 1;
148
149 /**
150 * Call streaming request reject reason used with
151 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
152 * call streaming request because telecom can't find existing general streaming sender on this
153 * device.
154 */
155 public static final int STREAMING_FAILED_NO_SENDER = 2;
156
157 /**
158 * Call streaming request reject reason used with
159 * {@link CallEventCallback#onCallStreamingFailed(int)} to indicate that telecom is rejecting a
160 * call streaming request because telecom can't bind to the general streaming sender app.
161 */
162 public static final int STREAMING_FAILED_SENDER_BINDING_ERROR = 3;
163
164 private StreamingCallAdapter mStreamingCallAdapter;
165 private StreamingCall mCall;
166
167 /**
168 * @hide
169 */
170 @IntDef(prefix = {"STREAMING_FAILED"},
171 value = {
Grace Jiaacd4dad2023-01-17 18:14:36 -0800172 STREAMING_FAILED_UNKNOWN,
Grace Jiaef5a4cc2022-12-13 11:08:55 -0800173 STREAMING_FAILED_ALREADY_STREAMING,
174 STREAMING_FAILED_NO_SENDER,
175 STREAMING_FAILED_SENDER_BINDING_ERROR
176 })
177 @Retention(RetentionPolicy.SOURCE)
178 public @interface StreamingFailedReason {};
179
180 /**
181 * Called when a {@code StreamingCall} has been added to this call streaming session. The call
182 * streaming sender should start to intercept the device audio using audio records and audio
183 * tracks from Audio frameworks.
184 *
185 * @param call a newly added {@code StreamingCall}.
186 */
187 public void onCallStreamingStarted(@NonNull StreamingCall call) {
188 }
189
190 /**
191 * Called when a current {@code StreamingCall} has been removed from this call streaming
192 * session. The call streaming sender should notify the streaming receiver that the call is
193 * stopped streaming and stop the device audio interception.
194 */
195 public void onCallStreamingStopped() {
196 }
197
198 /**
199 * Called when the streaming state of current {@code StreamingCall} changed. General streaming
200 * sender usually get notified of the holding/unholding from the original owner voip app of the
201 * call.
202 */
203 public void onCallStreamingStateChanged(@StreamingCall.StreamingCallState int state) {
204 }
205}