blob: 9c874bf305b1783ad0415c05de711522c3df4edc [file] [log] [blame]
sqianea8970c2018-06-06 22:54:04 -07001/*
2 * Copyright (C) 2018 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.SdkConstant;
20import android.app.Service;
21import android.content.Intent;
22import android.net.Uri;
23import android.os.Handler;
24import android.os.IBinder;
25import android.os.Looper;
26import android.os.Message;
27import android.os.RemoteException;
28
29import com.android.internal.os.SomeArgs;
30import com.android.internal.telecom.ICallRedirectionService;
31import com.android.internal.telecom.ICallRedirectionAdapter;
32
33/**
34 * This service can be implemented to interact between Telecom and its implementor
35 * for making outgoing call with optional redirection/cancellation purposes.
36 *
37 * <p>
38 * Below is an example manifest registration for a {@code CallRedirectionService}.
39 * <pre>
40 * {@code
41 * <service android:name="your.package.YourCallRedirectionServiceImplementation"
42 * android:permission="android.permission.BIND_REDIRECTION_SERVICE">
43 * <intent-filter>
44 * <action android:name="android.telecom.CallRedirectionService"/>
45 * </intent-filter>
46 * </service>
47 * }
48 * </pre>
49 */
50public abstract class CallRedirectionService extends Service {
51 /**
52 * The {@link Intent} that must be declared as handled by the service.
53 */
54 @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
55 public static final String SERVICE_INTERFACE = "android.telecom.CallRedirectionService";
56
57 /**
58 * An adapter to inform Telecom the response from the implementor of the Call
59 * Redirection service
60 */
61 private ICallRedirectionAdapter mCallRedirectionAdapter;
62
63 /**
64 * Telecom calls this method to inform the implemented {@link CallRedirectionService} of
65 * a new outgoing call which is being placed.
66 * @param handle the phone number dialed by the user
67 * @param targetPhoneAccount the {@link PhoneAccountHandle} on which the call will be placed.
68 */
69 public abstract void onPlaceCall(Uri handle, PhoneAccountHandle targetPhoneAccount);
70
71 /**
72 * The implemented {@link CallRedirectionService} calls this method to response a request
73 * received via {@link #onPlaceCall(Uri, PhoneAccountHandle)} to inform Telecom that no changes
74 * are required to the outgoing call, and that the call should be placed as-is.
75 */
76 public final void placeCallUnmodified() {
77 try {
78 mCallRedirectionAdapter.placeCallUnmodified();
79 } catch (RemoteException e) {
80 }
81 }
82
83 /**
84 * The implemented {@link CallRedirectionService} calls this method to response a request
85 * received via {@link #onPlaceCall(Uri, PhoneAccountHandle)} to inform Telecom that changes
86 * are required to the phone number or/and {@link PhoneAccountHandle} for the outgoing call.
87 * @param handle the new phone number to dial
88 * @param targetPhoneAccount the {@link PhoneAccountHandle} to use when placing the call.
89 * If {@code null}, no change will be made to the
90 * {@link PhoneAccountHandle} used to place the call.
91 */
92 public final void redirectCall(Uri handle, PhoneAccountHandle targetPhoneAccount) {
93 try {
94 mCallRedirectionAdapter.redirectCall(handle, targetPhoneAccount);
95 } catch (RemoteException e) {
96 }
97 }
98
99 /**
100 * The implemented {@link CallRedirectionService} calls this method to response a request
101 * received via {@link #onPlaceCall(Uri, PhoneAccountHandle)} to inform Telecom that an outgoing
102 * call should be canceled entirely.
103 */
104 public final void cancelCall() {
105 try {
106 mCallRedirectionAdapter.cancelCall();
107 } catch (RemoteException e) {
108 }
109 }
110
111 /**
112 * A handler message to process the attempt to place call with redirection service from Telecom
113 */
114 private static final int MSG_PLACE_CALL = 1;
115
116 /**
117 * A handler to process the attempt to place call with redirection service from Telecom
118 */
119 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
120 @Override
121 public void handleMessage(Message msg) {
122 switch (msg.what) {
123 case MSG_PLACE_CALL:
124 SomeArgs args = (SomeArgs) msg.obj;
125 try {
126 mCallRedirectionAdapter = (ICallRedirectionAdapter) args.arg1;
127 onPlaceCall((Uri) args.arg2, (PhoneAccountHandle) args.arg3);
128 } finally {
129 args.recycle();
130 }
131 break;
132 }
133 }
134 };
135
136 private final class CallRedirectionBinder extends ICallRedirectionService.Stub {
137
138 /**
139 * Telecom calls this method to inform the CallRedirectionService of a new outgoing call
140 * which is about to be placed.
141 * @param handle the phone number dialed by the user
142 * @param targetPhoneAccount the URI of the number the user dialed
143 */
144 @Override
145 public void placeCall(ICallRedirectionAdapter adapter, Uri handle,
146 PhoneAccountHandle targetPhoneAccount) {
147 Log.v(this, "placeCall");
148 SomeArgs args = SomeArgs.obtain();
149 args.arg1 = adapter;
150 args.arg2 = handle;
151 args.arg3 = targetPhoneAccount;
152 mHandler.obtainMessage(MSG_PLACE_CALL, args).sendToTarget();
153 }
154 }
155
156 @Override
157 public IBinder onBind(Intent intent) {
158 Log.v(this, "onBind");
159 return new CallRedirectionBinder();
160 }
161
162 @Override
163 public boolean onUnbind(Intent intent) {
164 Log.v(this, "onUnbind");
165 return false;
166 }
167}