• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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 
17 package com.android.server.telecom.testapps;
18 
19 import com.android.server.telecom.testapps.R;
20 
21 import android.app.Notification;
22 import android.app.NotificationManager;
23 import android.app.PendingIntent;
24 import android.content.ComponentName;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.graphics.Color;
28 import android.graphics.drawable.Icon;
29 import android.net.Uri;
30 import android.os.Bundle;
31 import android.telecom.PhoneAccount;
32 import android.telecom.PhoneAccountHandle;
33 import android.telecom.TelecomManager;
34 import android.util.Log;
35 import android.widget.Toast;
36 
37 import java.util.Arrays;
38 import java.util.List;
39 
40 /**
41  * Class used to create, update and cancel the notification used to display and update call state
42  * for {@link TestConnectionService}.
43  */
44 public class CallServiceNotifier {
45     private static final CallServiceNotifier INSTANCE = new CallServiceNotifier();
46 
47     static final String CALL_PROVIDER_ID = "testapps_TestConnectionService_CALL_PROVIDER_ID";
48     static final String SIM_SUBSCRIPTION_ID = "testapps_TestConnectionService_SIM_SUBSCRIPTION_ID";
49     static final String CONNECTION_MANAGER_ID =
50             "testapps_TestConnectionService_CONNECTION_MANAGER_ID";
51 
52     /**
53      * Static notification IDs.
54      */
55     private static final int CALL_NOTIFICATION_ID = 1;
56     private static final int PHONE_ACCOUNT_NOTIFICATION_ID = 2;
57 
58     /**
59      * Whether the added call should be started as a video call. Referenced by
60      * {@link TestConnectionService} to know whether to provide a call video provider.
61      */
62     public static boolean mStartVideoCall;
63 
64     /**
65      * Singleton accessor.
66      */
getInstance()67     public static CallServiceNotifier getInstance() {
68         return INSTANCE;
69     }
70 
71     /**
72      * Creates a CallService & initializes notification manager.
73      */
CallServiceNotifier()74     private CallServiceNotifier() {
75     }
76 
77     /**
78      * Updates the notification in the notification pane.
79      */
updateNotification(Context context)80     public void updateNotification(Context context) {
81         log("adding the notification ------------");
82         getNotificationManager(context).notify(CALL_NOTIFICATION_ID, getMainNotification(context));
83         getNotificationManager(context).notify(
84                 PHONE_ACCOUNT_NOTIFICATION_ID, getPhoneAccountNotification(context));
85     }
86 
87     /**
88      * Cancels the notification.
89      */
cancelNotifications(Context context)90     public void cancelNotifications(Context context) {
91         log("canceling notification");
92         getNotificationManager(context).cancel(CALL_NOTIFICATION_ID);
93         getNotificationManager(context).cancel(PHONE_ACCOUNT_NOTIFICATION_ID);
94     }
95 
96     /**
97      * Registers a phone account with telecom.
98      */
registerPhoneAccount(Context context)99     public void registerPhoneAccount(Context context) {
100         TelecomManager telecomManager =
101                 (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
102 
103         telecomManager.clearAccounts();
104 
105         Bundle testBundle = new Bundle();
106         testBundle.putInt("EXTRA_INT_1", 1);
107         testBundle.putInt("EXTRA_INT_100", 100);
108         testBundle.putBoolean("EXTRA_BOOL_TRUE", true);
109         testBundle.putBoolean("EXTRA_BOOL_FALSE", false);
110         testBundle.putString("EXTRA_STR1", "Hello");
111         testBundle.putString("EXTRA_STR2", "There");
112 
113         telecomManager.registerPhoneAccount(PhoneAccount.builder(
114                 new PhoneAccountHandle(
115                         new ComponentName(context, TestConnectionService.class),
116                         CALL_PROVIDER_ID),
117                 "TelecomTestApp Call Provider")
118                 .setAddress(Uri.parse("tel:555-TEST"))
119                 .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
120                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
121                         PhoneAccount.CAPABILITY_VIDEO_CALLING |
122                         PhoneAccount.CAPABILITY_RTT |
123                         PhoneAccount.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)
124                 .setIcon(Icon.createWithResource(
125                         context.getResources(), R.drawable.stat_sys_phone_call))
126                 .setHighlightColor(Color.RED)
127                 // TODO: Add icon tint (Color.RED)
128                 .setShortDescription("a short description for the call provider")
129                 .setSupportedUriSchemes(Arrays.asList("tel"))
130                 .setExtras(testBundle)
131                 .build());
132 
133         telecomManager.registerPhoneAccount(PhoneAccount.builder(
134                 new PhoneAccountHandle(
135                         new ComponentName(context, TestConnectionService.class),
136                         SIM_SUBSCRIPTION_ID),
137                 "TelecomTestApp SIM Subscription")
138                 .setAddress(Uri.parse("tel:555-TSIM"))
139                 .setSubscriptionAddress(Uri.parse("tel:555-TSIM"))
140                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
141                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION |
142                         PhoneAccount.CAPABILITY_VIDEO_CALLING |
143                         PhoneAccount.CAPABILITY_RTT |
144                         PhoneAccount.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)
145                 .setIcon(Icon.createWithResource(
146                         context.getResources(), R.drawable.stat_sys_phone_call))
147                 .setHighlightColor(Color.GREEN)
148                 // TODO: Add icon tint (Color.GREEN)
149                 .setShortDescription("a short description for the sim subscription")
150                 .build());
151 
152         telecomManager.registerPhoneAccount(PhoneAccount.builder(
153                         new PhoneAccountHandle(
154                                 new ComponentName(context, TestConnectionManager.class),
155                                 CONNECTION_MANAGER_ID),
156                         "TelecomTestApp CONNECTION MANAGER")
157                 .setAddress(Uri.parse("tel:555-CMGR"))
158                 .setSubscriptionAddress(Uri.parse("tel:555-CMGR"))
159                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
160                 .setIcon(Icon.createWithResource(
161                         context.getResources(), R.drawable.stat_sys_phone_call))
162                 // TODO: Add icon tint (Color.BLUE)
163                 .setShortDescription("a short description for the connection manager")
164                 .build());
165     }
166 
167     /**
168      * Displays all phone accounts registered with telecom.
169      */
showAllPhoneAccounts(Context context)170     public void showAllPhoneAccounts(Context context) {
171         TelecomManager telecomManager =
172                 (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
173         List<PhoneAccountHandle> accounts = telecomManager.getCallCapablePhoneAccounts();
174 
175         Toast.makeText(context, accounts.toString(), Toast.LENGTH_LONG).show();
176     }
177 
178     /**
179      * Returns the system's notification manager needed to add/remove notifications.
180      */
getNotificationManager(Context context)181     private NotificationManager getNotificationManager(Context context) {
182         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
183     }
184 
185     /**
186      * Creates a notification object for using the telecom APIs.
187      */
getPhoneAccountNotification(Context context)188     private Notification getPhoneAccountNotification(Context context) {
189         final Notification.Builder builder = new Notification.Builder(context);
190         // Both notifications have buttons and only the first one with buttons will show its
191         // buttons.  Since the phone accounts notification is always first, setting false ensures
192         // it can be dismissed to use the other notification.
193         builder.setOngoing(false);
194         builder.setPriority(Notification.PRIORITY_HIGH);
195 
196         final PendingIntent intent = createShowAllPhoneAccountsIntent(context);
197         builder.setContentIntent(intent);
198 
199         builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
200         // TODO: Consider moving this into a strings.xml
201         builder.setContentText("Test phone accounts via telecom APIs.");
202         builder.setContentTitle("Test Phone Accounts");
203 
204         addRegisterPhoneAccountAction(builder, context);
205         addShowAllPhoneAccountsAction(builder, context);
206 
207         return builder.build();
208     }
209 
210     /**
211      * Creates a notification object out of the current calls state.
212      */
getMainNotification(Context context)213     private Notification getMainNotification(Context context) {
214         final Notification.Builder builder = new Notification.Builder(context);
215         builder.setOngoing(true);
216         builder.setPriority(Notification.PRIORITY_HIGH);
217         builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
218         builder.setContentText("Test calls via CallService API");
219         builder.setContentTitle("Test Connection Service");
220 
221         addAddOneWayVideoCallAction(builder, context);
222         addAddTwoWayVideoCallAction(builder, context);
223         addAddCallAction(builder, context);
224         addExitAction(builder, context);
225 
226         return builder.build();
227     }
228 
229     /**
230      * Creates the intent to remove the notification.
231      */
createExitIntent(Context context)232     private PendingIntent createExitIntent(Context context) {
233         final Intent intent = new Intent(CallNotificationReceiver.ACTION_CALL_SERVICE_EXIT, null,
234                 context, CallNotificationReceiver.class);
235 
236         return PendingIntent.getBroadcast(context, 0, intent, 0);
237     }
238 
239     /**
240      * Creates the intent to register a phone account.
241      */
createRegisterPhoneAccountIntent(Context context)242     private PendingIntent createRegisterPhoneAccountIntent(Context context) {
243         final Intent intent = new Intent(CallNotificationReceiver.ACTION_REGISTER_PHONE_ACCOUNT,
244                 null, context, CallNotificationReceiver.class);
245         return PendingIntent.getBroadcast(context, 0, intent, 0);
246     }
247 
248     /**
249      * Creates the intent to show all phone accounts.
250      */
createShowAllPhoneAccountsIntent(Context context)251     private PendingIntent createShowAllPhoneAccountsIntent(Context context) {
252         final Intent intent = new Intent(CallNotificationReceiver.ACTION_SHOW_ALL_PHONE_ACCOUNTS,
253                 null, context, CallNotificationReceiver.class);
254         return PendingIntent.getBroadcast(context, 0, intent, 0);
255     }
256 
257     /**
258      * Creates the intent to start an incoming 1-way video call (receive-only)
259      */
createOneWayVideoCallIntent(Context context)260     private PendingIntent createOneWayVideoCallIntent(Context context) {
261         final Intent intent = new Intent(CallNotificationReceiver.ACTION_ONE_WAY_VIDEO_CALL,
262                 null, context, CallNotificationReceiver.class);
263         return PendingIntent.getBroadcast(context, 0, intent, 0);
264     }
265 
266     /**
267      * Creates the intent to start an incoming 2-way video call
268      */
createTwoWayVideoCallIntent(Context context)269     private PendingIntent createTwoWayVideoCallIntent(Context context) {
270         final Intent intent = new Intent(CallNotificationReceiver.ACTION_TWO_WAY_VIDEO_CALL,
271                 null, context, CallNotificationReceiver.class);
272         return PendingIntent.getBroadcast(context, 0, intent, 0);
273     }
274 
275     /**
276      * Creates the intent to start an incoming audio call
277      */
createIncomingAudioCall(Context context)278     private PendingIntent createIncomingAudioCall(Context context) {
279         final Intent intent = new Intent(CallNotificationReceiver.ACTION_AUDIO_CALL,
280                 null, context, CallNotificationReceiver.class);
281         return PendingIntent.getBroadcast(context, 0, intent, 0);
282     }
283 
284     /**
285      * Adds an action to the Notification Builder for adding an incoming call through Telecom.
286      * @param builder The Notification Builder.
287      */
addAddCallAction(Notification.Builder builder, Context context)288     private void addAddCallAction(Notification.Builder builder, Context context) {
289         builder.addAction(0, "Add Call", createIncomingAudioCall(context));
290     }
291 
292     /**
293      * Adds an action to the Notification Builder to add an incoming one-way video call through
294      * Telecom.
295      */
addAddOneWayVideoCallAction(Notification.Builder builder, Context context)296     private void addAddOneWayVideoCallAction(Notification.Builder builder, Context context) {
297         builder.addAction(0, "1-way Video", createOneWayVideoCallIntent(context));
298     }
299 
300     /**
301      * Adds an action to the Notification Builder to add an incoming 2-way video call through
302      * Telecom.
303      */
addAddTwoWayVideoCallAction(Notification.Builder builder, Context context)304     private void addAddTwoWayVideoCallAction(Notification.Builder builder, Context context) {
305         builder.addAction(0, "2-way Video", createTwoWayVideoCallIntent(context));
306     }
307 
308     /**
309      * Adds an action to remove the notification.
310      */
addExitAction(Notification.Builder builder, Context context)311     private void addExitAction(Notification.Builder builder, Context context) {
312         builder.addAction(0, "Exit", createExitIntent(context));
313     }
314 
315     /**
316      * Adds an action to show all registered phone accounts on a device.
317      */
addShowAllPhoneAccountsAction(Notification.Builder builder, Context context)318     private void addShowAllPhoneAccountsAction(Notification.Builder builder, Context context) {
319         builder.addAction(0, "Show Accts", createShowAllPhoneAccountsIntent(context));
320     }
321 
322     /**
323      * Adds an action to register a new phone account.
324      */
addRegisterPhoneAccountAction(Notification.Builder builder, Context context)325     private void addRegisterPhoneAccountAction(Notification.Builder builder, Context context) {
326         builder.addAction(0, "Reg.Acct.", createRegisterPhoneAccountIntent(context));
327     }
328 
shouldStartVideoCall()329     public boolean shouldStartVideoCall() {
330         return mStartVideoCall;
331     }
332 
log(String msg)333     private static void log(String msg) {
334         Log.w("testcallservice", "[CallServiceNotifier] " + msg);
335     }
336 }
337