Home | History | Annotate | Download | only in incallui
      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.incallui;
     18 
     19 import android.telecom.PhoneCapabilities;
     20 import android.app.KeyguardManager;
     21 import android.content.Context;
     22 
     23 import java.util.List;
     24 
     25 /**
     26  * Presenter for the Incoming call widget.
     27  */
     28 public class AnswerPresenter extends Presenter<AnswerPresenter.AnswerUi>
     29         implements CallList.CallUpdateListener, CallList.Listener {
     30 
     31     private static final String TAG = AnswerPresenter.class.getSimpleName();
     32 
     33     private String mCallId;
     34     private Call mCall = null;
     35     private boolean mHasTextMessages = false;
     36 
     37     @Override
     38     public void onUiReady(AnswerUi ui) {
     39         super.onUiReady(ui);
     40 
     41         final CallList calls = CallList.getInstance();
     42         Call call;
     43         call = calls.getIncomingCall();
     44         if (call != null) {
     45             processIncomingCall(call);
     46         }
     47         call = calls.getVideoUpgradeRequestCall();
     48         if (call != null) {
     49             processVideoUpgradeRequestCall(call);
     50         }
     51 
     52         // Listen for incoming calls.
     53         calls.addListener(this);
     54     }
     55 
     56     @Override
     57     public void onUiUnready(AnswerUi ui) {
     58         super.onUiUnready(ui);
     59 
     60         CallList.getInstance().removeListener(this);
     61 
     62         // This is necessary because the activity can be destroyed while an incoming call exists.
     63         // This happens when back button is pressed while incoming call is still being shown.
     64         if (mCallId != null) {
     65             CallList.getInstance().removeCallUpdateListener(mCallId, this);
     66         }
     67     }
     68 
     69     @Override
     70     public void onCallListChange(CallList callList) {
     71         // no-op
     72     }
     73 
     74     @Override
     75     public void onDisconnect(Call call) {
     76         // no-op
     77     }
     78 
     79     @Override
     80     public void onIncomingCall(Call call) {
     81         // TODO: Ui is being destroyed when the fragment detaches.  Need clean up step to stop
     82         // getting updates here.
     83         Log.d(this, "onIncomingCall: " + this);
     84         if (getUi() != null) {
     85             if (!call.getId().equals(mCallId)) {
     86                 // A new call is coming in.
     87                 processIncomingCall(call);
     88             }
     89         }
     90     }
     91 
     92     private void processIncomingCall(Call call) {
     93         mCallId = call.getId();
     94         mCall = call;
     95 
     96         // Listen for call updates for the current call.
     97         CallList.getInstance().addCallUpdateListener(mCallId, this);
     98 
     99         Log.d(TAG, "Showing incoming for call id: " + mCallId + " " + this);
    100         final List<String> textMsgs = CallList.getInstance().getTextResponses(call.getId());
    101         getUi().showAnswerUi(true);
    102         configureAnswerTargetsForSms(call, textMsgs);
    103     }
    104 
    105     private void processVideoUpgradeRequestCall(Call call) {
    106         mCallId = call.getId();
    107         mCall = call;
    108 
    109         // Listen for call updates for the current call.
    110         CallList.getInstance().addCallUpdateListener(mCallId, this);
    111         getUi().showAnswerUi(true);
    112 
    113         getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_UPGRADE_REQUEST);
    114     }
    115 
    116     @Override
    117     public void onCallChanged(Call call) {
    118         Log.d(this, "onCallStateChange() " + call + " " + this);
    119         if (call.getState() != Call.State.INCOMING) {
    120             // Stop listening for updates.
    121             CallList.getInstance().removeCallUpdateListener(mCallId, this);
    122 
    123             getUi().showAnswerUi(false);
    124 
    125             // mCallId will hold the state of the call. We don't clear the mCall variable here as
    126             // it may be useful for sending text messages after phone disconnects.
    127             mCallId = null;
    128             mHasTextMessages = false;
    129         } else if (!mHasTextMessages) {
    130             final List<String> textMsgs = CallList.getInstance().getTextResponses(call.getId());
    131             if (textMsgs != null) {
    132                 configureAnswerTargetsForSms(call, textMsgs);
    133             }
    134         }
    135     }
    136 
    137     public void onAnswer(int videoState, Context context) {
    138         if (mCallId == null) {
    139             return;
    140         }
    141 
    142         Log.d(this, "onAnswer " + mCallId);
    143         if (mCall.getSessionModificationState()
    144                 == Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST) {
    145             InCallPresenter.getInstance().acceptUpgradeRequest(context);
    146         } else {
    147             TelecomAdapter.getInstance().answerCall(mCall.getId(), videoState);
    148         }
    149     }
    150 
    151     /**
    152      * TODO: We are using reject and decline interchangeably. We should settle on
    153      * reject since it seems to be more prevalent.
    154      */
    155     public void onDecline() {
    156         Log.d(this, "onDecline " + mCallId);
    157         TelecomAdapter.getInstance().rejectCall(mCall.getId(), false, null);
    158     }
    159 
    160     public void onText() {
    161         if (getUi() != null) {
    162             getUi().showMessageDialog();
    163         }
    164     }
    165 
    166     public void rejectCallWithMessage(String message) {
    167         Log.d(this, "sendTextToDefaultActivity()...");
    168         TelecomAdapter.getInstance().rejectCall(mCall.getId(), true, message);
    169 
    170         onDismissDialog();
    171     }
    172 
    173     public void onDismissDialog() {
    174         InCallPresenter.getInstance().onDismissDialog();
    175     }
    176 
    177     private void configureAnswerTargetsForSms(Call call, List<String> textMsgs) {
    178         final Context context = getUi().getContext();
    179 
    180         mHasTextMessages = textMsgs != null;
    181         boolean withSms = call.can(PhoneCapabilities.RESPOND_VIA_TEXT) && mHasTextMessages;
    182         if (call.isVideoCall(context)) {
    183             if (withSms) {
    184                 getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITH_SMS);
    185                 getUi().configureMessageDialog(textMsgs);
    186             } else {
    187                 getUi().showTargets(AnswerFragment.TARGET_SET_FOR_VIDEO_WITHOUT_SMS);
    188             }
    189         } else {
    190             if (withSms) {
    191                 getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITH_SMS);
    192                 getUi().configureMessageDialog(textMsgs);
    193             } else {
    194                 getUi().showTargets(AnswerFragment.TARGET_SET_FOR_AUDIO_WITHOUT_SMS);
    195             }
    196         }
    197     }
    198 
    199     interface AnswerUi extends Ui {
    200         public void showAnswerUi(boolean show);
    201         public void showTargets(int targetSet);
    202         public void showMessageDialog();
    203         public void configureMessageDialog(List<String> textResponses);
    204         public Context getContext();
    205     }
    206 }
    207