Home | History | Annotate | Download | only in testapps
      1 /*
      2  * Copyright (C) 2017 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 android.app.Notification;
     20 import android.app.NotificationManager;
     21 import android.app.PendingIntent;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.graphics.drawable.Icon;
     25 import android.media.MediaPlayer;
     26 import android.os.Bundle;
     27 import android.telecom.Call;
     28 import android.telecom.CallAudioState;
     29 import android.telecom.Connection;
     30 import android.telecom.ConnectionService;
     31 import android.telecom.DisconnectCause;
     32 import android.telecom.VideoProfile;
     33 
     34 import com.android.server.telecom.testapps.R;
     35 
     36 /**
     37  * Sample self-managed {@link Connection} for a self-managed {@link ConnectionService}.
     38  * <p>
     39  * See {@link android.telecom} for more information on self-managed {@link ConnectionService}s.
     40  */
     41 public class SelfManagedConnection extends Connection {
     42     public static class Listener {
     43         public void onConnectionStateChanged(SelfManagedConnection connection) {}
     44         public void onConnectionRemoved(SelfManagedConnection connection) {}
     45     }
     46 
     47     public static final String EXTRA_PHONE_ACCOUNT_HANDLE =
     48             "com.android.server.telecom.testapps.extra.PHONE_ACCOUNT_HANDLE";
     49     public static final String CALL_NOTIFICATION = "com.android.server.telecom.testapps.CALL";
     50 
     51     private static int sNextCallId = 1;
     52 
     53     private final int mCallId;
     54     private final Context mContext;
     55     private final SelfManagedCallList mCallList;
     56     private final MediaPlayer mMediaPlayer;
     57     private final boolean mIsIncomingCall;
     58     private boolean mIsIncomingCallUiShowing;
     59     private Listener mListener;
     60     private boolean mIsHandover;
     61 
     62     SelfManagedConnection(SelfManagedCallList callList, Context context, boolean isIncoming) {
     63         mCallList = callList;
     64         mMediaPlayer = createMediaPlayer(context);
     65         mIsIncomingCall = isIncoming;
     66         mContext = context;
     67         mCallId = sNextCallId++;
     68     }
     69 
     70     public void setListener(Listener listener) {
     71         mListener = listener;
     72     }
     73 
     74     /**
     75      * Handles updates to the audio state of the connection.
     76      * @param state The new connection audio state.
     77      */
     78     @Override
     79     public void onCallAudioStateChanged(CallAudioState state) {
     80         mCallList.notifyCallModified();
     81     }
     82 
     83     @Override
     84     public void onShowIncomingCallUi() {
     85         if (isHandover()) {
     86             return;
     87         }
     88         // Create the fullscreen intent used to show the fullscreen incoming call UX.
     89         Intent intent = new Intent(Intent.ACTION_MAIN, null);
     90         intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
     91         intent.setClass(mContext, IncomingSelfManagedCallActivity.class);
     92         intent.putExtra(IncomingSelfManagedCallActivity.EXTRA_CALL_ID, mCallId);
     93         PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 1, intent, 0);
     94 
     95         // Build the notification as an ongoing high priority item.
     96         final Notification.Builder builder = new Notification.Builder(mContext);
     97         builder.setOngoing(true);
     98         builder.setPriority(Notification.PRIORITY_HIGH);
     99 
    100         // Set up the main intent to send the user to the incoming call screen.
    101         builder.setContentIntent(pendingIntent);
    102         builder.setFullScreenIntent(pendingIntent, true);
    103 
    104         // Setup notification content.
    105         builder.setSmallIcon(R.drawable.ic_android_black_24dp);
    106         builder.setContentTitle("Incoming call...");
    107         builder.setContentText("Incoming test call from " + getAddress());
    108 
    109         // Setup answer and reject call button
    110         final Intent answerIntent = new Intent(
    111                 SelfManagedCallNotificationReceiver.ACTION_ANSWER_CALL, null, mContext,
    112                 SelfManagedCallNotificationReceiver.class);
    113         answerIntent.putExtra(IncomingSelfManagedCallActivity.EXTRA_CALL_ID, mCallId);
    114         final Intent rejectIntent = new Intent(
    115                 SelfManagedCallNotificationReceiver.ACTION_REJECT_CALL, null, mContext,
    116                 SelfManagedCallNotificationReceiver.class);
    117         rejectIntent.putExtra(IncomingSelfManagedCallActivity.EXTRA_CALL_ID, mCallId);
    118 
    119         builder.addAction(
    120                 new Notification.Action.Builder(
    121                         Icon.createWithResource(mContext, R.drawable.ic_android_black_24dp),
    122                         "Answer",
    123                         PendingIntent.getBroadcast(mContext, 0, answerIntent,
    124                                 PendingIntent.FLAG_UPDATE_CURRENT))
    125                         .build());
    126         builder.addAction(
    127                 new Notification.Action.Builder(
    128                         Icon.createWithResource(mContext, R.drawable.ic_android_black_24dp),
    129                         "Reject",
    130                         PendingIntent.getBroadcast(mContext, 0, rejectIntent,
    131                                 PendingIntent.FLAG_UPDATE_CURRENT))
    132                         .build());
    133 
    134         NotificationManager notificationManager = mContext.getSystemService(
    135                 NotificationManager.class);
    136         notificationManager.notify(CALL_NOTIFICATION, mCallId, builder.build());
    137     }
    138 
    139     @Override
    140     public void onHold() {
    141         if (mMediaPlayer != null) {
    142             mMediaPlayer.pause();
    143         }
    144         setOnHold();
    145     }
    146 
    147     @Override
    148     public void onUnhold() {
    149         if (mMediaPlayer != null) {
    150             mMediaPlayer.start();
    151         }
    152         setActive();
    153     }
    154 
    155     @Override
    156     public void onAnswer(int videoState) {
    157         setConnectionActive();
    158     }
    159 
    160     @Override
    161     public void onAnswer() {
    162         onAnswer(VideoProfile.STATE_AUDIO_ONLY);
    163     }
    164 
    165     @Override
    166     public void onReject() {
    167         setConnectionDisconnected(DisconnectCause.REJECTED);
    168     }
    169 
    170     @Override
    171     public void onDisconnect() {
    172         setConnectionDisconnected(DisconnectCause.LOCAL);
    173     }
    174 
    175     public void setConnectionActive() {
    176         mMediaPlayer.start();
    177         setActive();
    178         if (mListener != null ) {
    179             mListener.onConnectionStateChanged(this);
    180         }
    181     }
    182 
    183     public void setConnectionHeld() {
    184         mMediaPlayer.pause();
    185         setOnHold();
    186         if (mListener != null ) {
    187             mListener.onConnectionStateChanged(this);
    188         }
    189     }
    190 
    191     public void setConnectionDisconnected(int cause) {
    192         NotificationManager notificationManager = mContext.getSystemService(
    193                 NotificationManager.class);
    194         notificationManager.cancel(CALL_NOTIFICATION, mCallId);
    195         mMediaPlayer.stop();
    196         setDisconnected(new DisconnectCause(cause));
    197         destroy();
    198         if (mListener != null ) {
    199             mListener.onConnectionRemoved(this);
    200         }
    201     }
    202 
    203     public void setIsIncomingCallUiShowing(boolean showing) {
    204         mIsIncomingCallUiShowing = showing;
    205     }
    206 
    207     public boolean isIncomingCallUiShowing() {
    208         return mIsIncomingCallUiShowing;
    209     }
    210 
    211     public boolean isIncomingCall() {
    212         return mIsIncomingCall;
    213     }
    214 
    215     public int getCallId() {
    216         return mCallId;
    217     }
    218 
    219     public void setIsHandover(boolean isHandover) {
    220         mIsHandover = isHandover;
    221     }
    222 
    223     public boolean isHandover() {
    224         return mIsHandover;
    225     }
    226 
    227     public boolean isHoldable() {
    228         return (getConnectionCapabilities() & Connection.CAPABILITY_HOLD) != 0;
    229     }
    230 
    231     private MediaPlayer createMediaPlayer(Context context) {
    232         int audioToPlay = (Math.random() > 0.5f) ? R.raw.sample_audio : R.raw.sample_audio2;
    233         MediaPlayer mediaPlayer = MediaPlayer.create(context, audioToPlay);
    234         mediaPlayer.setLooping(true);
    235         return mediaPlayer;
    236     }
    237 }
    238