Home | History | Annotate | Download | only in incallui
      1 /*
      2  * Copyright (C) 2014 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.ActivityNotFoundException;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.os.Looper;
     23 import android.telecom.InCallAdapter;
     24 import android.telecom.Phone;
     25 import android.telecom.PhoneAccountHandle;
     26 
     27 import com.google.common.base.Preconditions;
     28 
     29 import java.util.List;
     30 
     31 /** Wrapper around {@link InCallAdapter} that only forwards calls to the adapter when it's valid. */
     32 final class TelecomAdapter implements InCallPhoneListener {
     33     private static final String ADD_CALL_MODE_KEY = "add_call_mode";
     34 
     35     private static TelecomAdapter sInstance;
     36     private Context mContext;
     37     private Phone mPhone;
     38 
     39     static TelecomAdapter getInstance() {
     40         Preconditions.checkState(Looper.getMainLooper().getThread() == Thread.currentThread());
     41         if (sInstance == null) {
     42             sInstance = new TelecomAdapter();
     43         }
     44         return sInstance;
     45     }
     46 
     47     private TelecomAdapter() {
     48     }
     49 
     50     void setContext(Context context) {
     51         mContext = context;
     52     }
     53 
     54     @Override
     55     public void setPhone(Phone phone) {
     56         mPhone = phone;
     57     }
     58 
     59     @Override
     60     public void clearPhone() {
     61         mPhone = null;
     62     }
     63 
     64     private android.telecom.Call getTelecommCallById(String callId) {
     65         final Call call = CallList.getInstance().getCallById(callId);
     66         return call == null ? null : call.getTelecommCall();
     67     }
     68 
     69     void answerCall(String callId, int videoState) {
     70         if (mPhone != null) {
     71             final android.telecom.Call call = getTelecommCallById(callId);
     72             if (call != null) {
     73                 call.answer(videoState);
     74             } else {
     75                 Log.e(this, "error answerCall, call not in call list: " + callId);
     76             }
     77         } else {
     78             Log.e(this, "error answerCall, mPhone is null");
     79         }
     80     }
     81 
     82     void rejectCall(String callId, boolean rejectWithMessage, String message) {
     83         if (mPhone != null) {
     84             final android.telecom.Call call = getTelecommCallById(callId);
     85             if (call != null) {
     86                 call.reject(rejectWithMessage, message);
     87             } else {
     88                 Log.e(this, "error rejectCall, call not in call list: " + callId);
     89             }
     90         } else {
     91             Log.e(this, "error rejectCall, mPhone is null");
     92         }
     93     }
     94 
     95     void disconnectCall(String callId) {
     96         if (mPhone != null) {
     97             getTelecommCallById(callId).disconnect();
     98         } else {
     99             Log.e(this, "error disconnectCall, mPhone is null");
    100         }
    101     }
    102 
    103     void holdCall(String callId) {
    104         if (mPhone != null) {
    105             getTelecommCallById(callId).hold();
    106         } else {
    107             Log.e(this, "error holdCall, mPhone is null");
    108         }
    109     }
    110 
    111     void unholdCall(String callId) {
    112         if (mPhone != null) {
    113             getTelecommCallById(callId).unhold();
    114         } else {
    115             Log.e(this, "error unholdCall, mPhone is null");
    116         }
    117     }
    118 
    119     void mute(boolean shouldMute) {
    120         if (mPhone != null) {
    121             mPhone.setMuted(shouldMute);
    122         } else {
    123             Log.e(this, "error mute, mPhone is null");
    124         }
    125     }
    126 
    127     void setAudioRoute(int route) {
    128         if (mPhone != null) {
    129             mPhone.setAudioRoute(route);
    130         } else {
    131             Log.e(this, "error setAudioRoute, mPhone is null");
    132         }
    133     }
    134 
    135     void turnOnProximitySensor() {
    136         if (mPhone != null) {
    137             mPhone.setProximitySensorOn();
    138         } else {
    139             Log.e(this, "error setProximitySensorOn, mPhone is null");
    140         }
    141     }
    142 
    143     void turnOffProximitySensor(boolean screenOnImmediately) {
    144         if (mPhone != null) {
    145             mPhone.setProximitySensorOff(screenOnImmediately);
    146         } else {
    147             Log.e(this, "error setProximitySensorOff, mPhone is null");
    148         }
    149     }
    150 
    151     void separateCall(String callId) {
    152         if (mPhone != null) {
    153             getTelecommCallById(callId).splitFromConference();
    154         } else {
    155             Log.e(this, "error separateCall, mPhone is null.");
    156         }
    157     }
    158 
    159     void merge(String callId) {
    160         if (mPhone != null) {
    161             android.telecom.Call call = getTelecommCallById(callId);
    162             List<android.telecom.Call> conferenceable = call.getConferenceableCalls();
    163             if (!conferenceable.isEmpty()) {
    164                 call.conference(conferenceable.get(0));
    165             } else {
    166                 if (call.getDetails().can(
    167                         android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
    168                     call.mergeConference();
    169                 }
    170             }
    171         } else {
    172             Log.e(this, "error merge, mPhone is null.");
    173         }
    174     }
    175 
    176     void swap(String callId) {
    177         if (mPhone != null) {
    178             android.telecom.Call call = getTelecommCallById(callId);
    179             if (call.getDetails().can(
    180                     android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE)) {
    181                 call.swapConference();
    182             }
    183         } else {
    184             Log.e(this, "Error swap, mPhone is null.");
    185         }
    186     }
    187 
    188     void addCall() {
    189         if (mContext != null) {
    190             Intent intent = new Intent(Intent.ACTION_DIAL);
    191             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    192 
    193             // when we request the dialer come up, we also want to inform
    194             // it that we're going through the "add call" option from the
    195             // InCallScreen / PhoneUtils.
    196             intent.putExtra(ADD_CALL_MODE_KEY, true);
    197             try {
    198                 Log.d(this, "Sending the add Call intent");
    199                 mContext.startActivity(intent);
    200             } catch (ActivityNotFoundException e) {
    201                 // This is rather rare but possible.
    202                 // Note: this method is used even when the phone is encrypted. At that moment
    203                 // the system may not find any Activity which can accept this Intent.
    204                 Log.e(this, "Activity for adding calls isn't found.", e);
    205             }
    206         }
    207     }
    208 
    209     void playDtmfTone(String callId, char digit) {
    210         if (mPhone != null) {
    211             getTelecommCallById(callId).playDtmfTone(digit);
    212         } else {
    213             Log.e(this, "error playDtmfTone, mPhone is null");
    214         }
    215     }
    216 
    217     void stopDtmfTone(String callId) {
    218         if (mPhone != null) {
    219             getTelecommCallById(callId).stopDtmfTone();
    220         } else {
    221             Log.e(this, "error stopDtmfTone, mPhone is null");
    222         }
    223     }
    224 
    225     void postDialContinue(String callId, boolean proceed) {
    226         if (mPhone != null) {
    227             getTelecommCallById(callId).postDialContinue(proceed);
    228         } else {
    229             Log.e(this, "error postDialContinue, mPhone is null");
    230         }
    231     }
    232 
    233     void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, boolean setDefault) {
    234         if (mPhone != null) {
    235             getTelecommCallById(callId).phoneAccountSelected(accountHandle, setDefault);
    236         }  else {
    237             Log.e(this, "error phoneAccountSelected, mAdapter is null");
    238         }
    239 
    240         if (accountHandle == null) {
    241             Log.e(this, "error phoneAccountSelected, accountHandle is null");
    242         }
    243     }
    244 
    245     boolean canAddCall() {
    246         // Default to true if we are not connected to telecom.
    247         return mPhone == null ? true : mPhone.canAddCall();
    248     }
    249 }
    250