Home | History | Annotate | Download | only in testapps
      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.graphics.Bitmap;
     28 import android.graphics.BitmapFactory;
     29 import android.graphics.Color;
     30 import android.net.Uri;
     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      */
     67     public static CallServiceNotifier getInstance() {
     68         return INSTANCE;
     69     }
     70 
     71     /**
     72      * Creates a CallService & initializes notification manager.
     73      */
     74     private CallServiceNotifier() {
     75     }
     76 
     77     /**
     78      * Updates the notification in the notification pane.
     79      */
     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      */
     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      */
     99     public void registerPhoneAccount(Context context) {
    100         TelecomManager telecomManager =
    101                 (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
    102 
    103         telecomManager.clearAccounts();
    104 
    105         telecomManager.registerPhoneAccount(PhoneAccount.builder(
    106                 new PhoneAccountHandle(
    107                         new ComponentName(context, TestConnectionService.class),
    108                         CALL_PROVIDER_ID),
    109                 "TelecomTestApp Call Provider")
    110                 .setAddress(Uri.parse("tel:555-TEST"))
    111                 .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
    112                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
    113                 .setIcon(context, R.drawable.stat_sys_phone_call, Color.RED)
    114                 .setHighlightColor(Color.RED)
    115                 .setShortDescription("a short description for the call provider")
    116                 .setSupportedUriSchemes(Arrays.asList("tel"))
    117                 .build());
    118 
    119         telecomManager.registerPhoneAccount(PhoneAccount.builder(
    120                 new PhoneAccountHandle(
    121                         new ComponentName(context, TestConnectionService.class),
    122                         SIM_SUBSCRIPTION_ID),
    123                 "TelecomTestApp SIM Subscription")
    124                 .setAddress(Uri.parse("tel:555-TSIM"))
    125                 .setSubscriptionAddress(Uri.parse("tel:555-TSIM"))
    126                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
    127                         PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
    128                 .setIcon(context, R.drawable.stat_sys_phone_call, Color.GREEN)
    129                 .setHighlightColor(Color.GREEN)
    130                 .setShortDescription("a short description for the sim subscription")
    131                 .build());
    132 
    133         telecomManager.registerPhoneAccount(PhoneAccount.builder(
    134                         new PhoneAccountHandle(
    135                                 new ComponentName(context, TestConnectionManager.class),
    136                                 CONNECTION_MANAGER_ID),
    137                         "TelecomTestApp CONNECTION MANAGER")
    138                 .setAddress(Uri.parse("tel:555-CMGR"))
    139                 .setSubscriptionAddress(Uri.parse("tel:555-CMGR"))
    140                 .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
    141                 .setIcon(context, R.drawable.stat_sys_phone_call, Color.BLUE)
    142                 .setShortDescription("a short description for the connection manager")
    143                 .build());
    144     }
    145 
    146     /**
    147      * Displays all phone accounts registered with telecom.
    148      */
    149     public void showAllPhoneAccounts(Context context) {
    150         TelecomManager telecomManager =
    151                 (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
    152         List<PhoneAccountHandle> accounts = telecomManager.getCallCapablePhoneAccounts();
    153 
    154         Toast.makeText(context, accounts.toString(), Toast.LENGTH_LONG).show();
    155     }
    156 
    157     /**
    158      * Returns the system's notification manager needed to add/remove notifications.
    159      */
    160     private NotificationManager getNotificationManager(Context context) {
    161         return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    162     }
    163 
    164     /**
    165      * Creates a notification object for using the telecom APIs.
    166      */
    167     private Notification getPhoneAccountNotification(Context context) {
    168         final Notification.Builder builder = new Notification.Builder(context);
    169         // Both notifications have buttons and only the first one with buttons will show its
    170         // buttons.  Since the phone accounts notification is always first, setting false ensures
    171         // it can be dismissed to use the other notification.
    172         builder.setOngoing(false);
    173         builder.setPriority(Notification.PRIORITY_HIGH);
    174 
    175         final PendingIntent intent = createShowAllPhoneAccountsIntent(context);
    176         builder.setContentIntent(intent);
    177 
    178         builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
    179         // TODO: Consider moving this into a strings.xml
    180         builder.setContentText("Test phone accounts via telecom APIs.");
    181         builder.setContentTitle("Test Phone Accounts");
    182 
    183         addRegisterPhoneAccountAction(builder, context);
    184         addShowAllPhoneAccountsAction(builder, context);
    185 
    186         return builder.build();
    187     }
    188 
    189     /**
    190      * Creates a notification object out of the current calls state.
    191      */
    192     private Notification getMainNotification(Context context) {
    193         final Notification.Builder builder = new Notification.Builder(context);
    194         builder.setOngoing(true);
    195         builder.setPriority(Notification.PRIORITY_HIGH);
    196         builder.setSmallIcon(android.R.drawable.stat_sys_phone_call);
    197         builder.setContentText("Test calls via CallService API");
    198         builder.setContentTitle("Test Connection Service");
    199 
    200         addAddVideoCallAction(builder, context);
    201         addAddCallAction(builder, context);
    202         addExitAction(builder, context);
    203 
    204         return builder.build();
    205     }
    206 
    207     /**
    208      * Creates the intent to remove the notification.
    209      */
    210     private PendingIntent createExitIntent(Context context) {
    211         final Intent intent = new Intent(CallNotificationReceiver.ACTION_CALL_SERVICE_EXIT, null,
    212                 context, CallNotificationReceiver.class);
    213 
    214         return PendingIntent.getBroadcast(context, 0, intent, 0);
    215     }
    216 
    217     /**
    218      * Creates the intent to register a phone account.
    219      */
    220     private PendingIntent createRegisterPhoneAccountIntent(Context context) {
    221         final Intent intent = new Intent(CallNotificationReceiver.ACTION_REGISTER_PHONE_ACCOUNT,
    222                 null, context, CallNotificationReceiver.class);
    223         return PendingIntent.getBroadcast(context, 0, intent, 0);
    224     }
    225 
    226     /**
    227      * Creates the intent to show all phone accounts.
    228      */
    229     private PendingIntent createShowAllPhoneAccountsIntent(Context context) {
    230         final Intent intent = new Intent(CallNotificationReceiver.ACTION_SHOW_ALL_PHONE_ACCOUNTS,
    231                 null, context, CallNotificationReceiver.class);
    232         return PendingIntent.getBroadcast(context, 0, intent, 0);
    233     }
    234 
    235     /**
    236      * Creates the intent to start an incoming video call
    237      */
    238     private PendingIntent createIncomingVideoCall(Context context) {
    239         final Intent intent = new Intent(CallNotificationReceiver.ACTION_VIDEO_CALL,
    240                 null, context, CallNotificationReceiver.class);
    241         return PendingIntent.getBroadcast(context, 0, intent, 0);
    242     }
    243 
    244     /**
    245      * Creates the intent to start an incoming audio call
    246      */
    247     private PendingIntent createIncomingAudioCall(Context context) {
    248         final Intent intent = new Intent(CallNotificationReceiver.ACTION_AUDIO_CALL,
    249                 null, context, CallNotificationReceiver.class);
    250         return PendingIntent.getBroadcast(context, 0, intent, 0);
    251     }
    252 
    253     /**
    254      * Adds an action to the Notification Builder for adding an incoming call through Telecom.
    255      * @param builder The Notification Builder.
    256      */
    257     private void addAddCallAction(Notification.Builder builder, Context context) {
    258         builder.addAction(0, "Add Call", createIncomingAudioCall(context));
    259     }
    260 
    261     /**
    262      * Adds an action to the Notification Builder to add an incoming video call through Telecom.
    263      */
    264     private void addAddVideoCallAction(Notification.Builder builder, Context context) {
    265         builder.addAction(0, "Add Video", createIncomingVideoCall(context));
    266     }
    267 
    268     /**
    269      * Adds an action to remove the notification.
    270      */
    271     private void addExitAction(Notification.Builder builder, Context context) {
    272         builder.addAction(0, "Exit", createExitIntent(context));
    273     }
    274 
    275     /**
    276      * Adds an action to show all registered phone accounts on a device.
    277      */
    278     private void addShowAllPhoneAccountsAction(Notification.Builder builder, Context context) {
    279         builder.addAction(0, "Show Accts", createShowAllPhoneAccountsIntent(context));
    280     }
    281 
    282     /**
    283      * Adds an action to register a new phone account.
    284      */
    285     private void addRegisterPhoneAccountAction(Notification.Builder builder, Context context) {
    286         builder.addAction(0, "Reg.Acct.", createRegisterPhoneAccountIntent(context));
    287     }
    288 
    289     public boolean shouldStartVideoCall() {
    290         return mStartVideoCall;
    291     }
    292 
    293     private static void log(String msg) {
    294         Log.w("testcallservice", "[CallServiceNotifier] " + msg);
    295     }
    296 }
    297