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