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