Home | History | Annotate | Download | only in call
      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.incallui.call;
     18 
     19 import android.content.ActivityNotFoundException;
     20 import android.content.Intent;
     21 import android.os.Looper;
     22 import android.support.annotation.MainThread;
     23 import android.support.annotation.VisibleForTesting;
     24 import android.telecom.InCallService;
     25 import com.android.dialer.common.LogUtil;
     26 import java.util.List;
     27 
     28 /** Wrapper around Telecom APIs. */
     29 public class TelecomAdapter implements InCallServiceListener {
     30 
     31   private static final String ADD_CALL_MODE_KEY = "add_call_mode";
     32 
     33   private static TelecomAdapter sInstance;
     34   private InCallService mInCallService;
     35 
     36   private TelecomAdapter() {}
     37 
     38   @MainThread
     39   public static TelecomAdapter getInstance() {
     40     if (!Looper.getMainLooper().isCurrentThread()) {
     41       throw new IllegalStateException();
     42     }
     43     if (sInstance == null) {
     44       sInstance = new TelecomAdapter();
     45     }
     46     return sInstance;
     47   }
     48 
     49   @VisibleForTesting(otherwise = VisibleForTesting.NONE)
     50   public static void setInstanceForTesting(TelecomAdapter telecomAdapter) {
     51     sInstance = telecomAdapter;
     52   }
     53 
     54   @Override
     55   public void setInCallService(InCallService inCallService) {
     56     mInCallService = inCallService;
     57   }
     58 
     59   @Override
     60   public void clearInCallService() {
     61     mInCallService = null;
     62   }
     63 
     64   private android.telecom.Call getTelecomCallById(String callId) {
     65     DialerCall call = CallList.getInstance().getCallById(callId);
     66     return call == null ? null : call.getTelecomCall();
     67   }
     68 
     69   public void mute(boolean shouldMute) {
     70     if (mInCallService != null) {
     71       mInCallService.setMuted(shouldMute);
     72     } else {
     73       LogUtil.e("TelecomAdapter.mute", "mInCallService is null");
     74     }
     75   }
     76 
     77   public void setAudioRoute(int route) {
     78     if (mInCallService != null) {
     79       mInCallService.setAudioRoute(route);
     80     } else {
     81       LogUtil.e("TelecomAdapter.setAudioRoute", "mInCallService is null");
     82     }
     83   }
     84 
     85   public void merge(String callId) {
     86     android.telecom.Call call = getTelecomCallById(callId);
     87     if (call != null) {
     88       List<android.telecom.Call> conferenceable = call.getConferenceableCalls();
     89       if (!conferenceable.isEmpty()) {
     90         call.conference(conferenceable.get(0));
     91         // It's safe to clear restrict count for merge action.
     92         DialerCall.clearRestrictedCount();
     93       } else {
     94         if (call.getDetails().can(android.telecom.Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
     95           call.mergeConference();
     96           // It's safe to clear restrict count for merge action.
     97           DialerCall.clearRestrictedCount();
     98         }
     99       }
    100     } else {
    101       LogUtil.e("TelecomAdapter.merge", "call not in call list " + callId);
    102     }
    103   }
    104 
    105   public void swap(String callId) {
    106     android.telecom.Call call = getTelecomCallById(callId);
    107     if (call != null) {
    108       if (call.getDetails().can(android.telecom.Call.Details.CAPABILITY_SWAP_CONFERENCE)) {
    109         call.swapConference();
    110       }
    111     } else {
    112       LogUtil.e("TelecomAdapter.swap", "call not in call list " + callId);
    113     }
    114   }
    115 
    116   public void addCall() {
    117     if (mInCallService != null) {
    118       Intent intent = new Intent(Intent.ACTION_DIAL);
    119       intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    120 
    121       // when we request the dialer come up, we also want to inform
    122       // it that we're going through the "add call" option from the
    123       // InCallScreen / PhoneUtils.
    124       intent.putExtra(ADD_CALL_MODE_KEY, true);
    125       try {
    126         LogUtil.d("TelecomAdapter.addCall", "Sending the add DialerCall intent");
    127         mInCallService.startActivity(intent);
    128       } catch (ActivityNotFoundException e) {
    129         // This is rather rare but possible.
    130         // Note: this method is used even when the phone is encrypted. At that moment
    131         // the system may not find any Activity which can accept this Intent.
    132         LogUtil.e("TelecomAdapter.addCall", "Activity for adding calls isn't found.", e);
    133       }
    134     }
    135   }
    136 
    137   public void playDtmfTone(String callId, char digit) {
    138     android.telecom.Call call = getTelecomCallById(callId);
    139     if (call != null) {
    140       call.playDtmfTone(digit);
    141     } else {
    142       LogUtil.e("TelecomAdapter.playDtmfTone", "call not in call list " + callId);
    143     }
    144   }
    145 
    146   public void stopDtmfTone(String callId) {
    147     android.telecom.Call call = getTelecomCallById(callId);
    148     if (call != null) {
    149       call.stopDtmfTone();
    150     } else {
    151       LogUtil.e("TelecomAdapter.stopDtmfTone", "call not in call list " + callId);
    152     }
    153   }
    154 
    155   public void postDialContinue(String callId, boolean proceed) {
    156     android.telecom.Call call = getTelecomCallById(callId);
    157     if (call != null) {
    158       call.postDialContinue(proceed);
    159     } else {
    160       LogUtil.e("TelecomAdapter.postDialContinue", "call not in call list " + callId);
    161     }
    162   }
    163 
    164   public boolean canAddCall() {
    165     if (mInCallService != null) {
    166       return mInCallService.canAddCall();
    167     }
    168     return false;
    169   }
    170 }
    171