blob: 314aa45d4a4984ca036163cc42fae2ed00d66f20 [file] [log] [blame]
/*
* Copyright (C) 2017 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.android.incallui;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.telecom.CallAudioState;
import com.android.dialer.common.LogUtil;
import com.android.dialer.configprovider.ConfigProviderBindings;
import com.android.dialer.telecom.TelecomUtil;
import com.android.dialershared.bubble.Bubble;
import com.android.dialershared.bubble.BubbleInfo;
import com.android.dialershared.bubble.BubbleInfo.Action;
import com.android.incallui.InCallPresenter.InCallUiListener;
import com.android.incallui.audiomode.AudioModeProvider;
import com.android.incallui.audiomode.AudioModeProvider.AudioModeListener;
import com.android.incallui.call.CallList;
import com.android.incallui.call.CallList.Listener;
import com.android.incallui.call.DialerCall;
import com.android.incallui.speakerbuttonlogic.SpeakerButtonInfo;
import com.android.incallui.speakerbuttonlogic.SpeakerButtonInfo.IconSize;
import java.util.ArrayList;
import java.util.List;
/**
* Listens for events relevant to the return-to-call bubble and updates the bubble's state as
* necessary
*/
public class ReturnToCallController implements InCallUiListener, Listener, AudioModeListener {
private final Context context;
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
Bubble bubble;
private CallAudioState audioState;
private final PendingIntent toggleSpeaker;
private final PendingIntent showSpeakerSelect;
private final PendingIntent toggleMute;
private final PendingIntent endCall;
public static boolean isEnabled(Context context) {
return !ConfigProviderBindings.get(context).getBoolean("disable_return_to_call_bubble", false);
}
public ReturnToCallController(Context context) {
this.context = context;
toggleSpeaker = createActionIntent(ReturnToCallActionReceiver.ACTION_TOGGLE_SPEAKER);
showSpeakerSelect =
createActionIntent(ReturnToCallActionReceiver.ACTION_SHOW_AUDIO_ROUTE_SELECTOR);
toggleMute = createActionIntent(ReturnToCallActionReceiver.ACTION_TOGGLE_MUTE);
endCall = createActionIntent(ReturnToCallActionReceiver.ACTION_END_CALL);
InCallPresenter.getInstance().addInCallUiListener(this);
CallList.getInstance().addListener(this);
AudioModeProvider.getInstance().addListener(this);
audioState = AudioModeProvider.getInstance().getAudioState();
}
public void tearDown() {
InCallPresenter.getInstance().removeInCallUiListener(this);
CallList.getInstance().removeListener(this);
AudioModeProvider.getInstance().removeListener(this);
}
@Override
public void onUiShowing(boolean showing) {
if (showing) {
hide();
} else {
if (TelecomUtil.isInCall(context)) {
show();
}
}
}
private void hide() {
if (bubble != null) {
bubble.hide();
} else {
LogUtil.i("ReturnToCallController.hide", "hide() called without calling show()");
}
}
private void show() {
if (bubble == null) {
bubble = startNewBubble();
} else {
bubble.show();
}
}
private Bubble startNewBubble() {
if (!Bubble.canShowBubbles(context)) {
LogUtil.i("ReturnToCallController.startNewBubble", "can't show bubble, no permission");
context.startActivity(Bubble.getRequestPermissionIntent(context));
return null;
}
Bubble returnToCallBubble = Bubble.createBubble(context, generateBubbleInfo());
returnToCallBubble.show();
return returnToCallBubble;
}
@Override
public void onIncomingCall(DialerCall call) {}
@Override
public void onUpgradeToVideo(DialerCall call) {}
@Override
public void onSessionModificationStateChange(DialerCall call) {}
@Override
public void onCallListChange(CallList callList) {}
@Override
public void onDisconnect(DialerCall call) {
if (bubble != null && bubble.isShowing()) {
bubble.showText(context.getText(R.string.incall_call_ended));
}
if (!TelecomUtil.isInCall(context)) {
hide();
}
}
@Override
public void onWiFiToLteHandover(DialerCall call) {}
@Override
public void onHandoverToWifiFailed(DialerCall call) {}
@Override
public void onInternationalCallOnWifi(@NonNull DialerCall call) {}
@Override
public void onAudioStateChanged(CallAudioState audioState) {
this.audioState = audioState;
if (bubble != null) {
bubble.updateActions(generateActions());
}
}
private BubbleInfo generateBubbleInfo() {
Intent activityIntent = InCallActivity.getIntent(context, false, false, false);
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
return BubbleInfo.builder()
.setPrimaryColor(context.getResources().getColor(R.color.dialer_theme_color, null))
.setPrimaryIcon(Icon.createWithResource(context, R.drawable.on_going_call))
.setStartingYPosition(
context.getResources().getDimensionPixelOffset(R.dimen.return_to_call_initial_offset_y))
.setPrimaryIntent(PendingIntent.getActivity(context, 0, activityIntent, 0))
.setActions(generateActions())
.build();
}
@NonNull
private List<Action> generateActions() {
List<Action> actions = new ArrayList<>();
SpeakerButtonInfo speakerButtonInfo = new SpeakerButtonInfo(audioState, IconSize.SIZE_24_DP);
actions.add(
Action.builder()
.setIcon(Icon.createWithResource(context, speakerButtonInfo.icon))
.setName(context.getText(speakerButtonInfo.label))
.setChecked(speakerButtonInfo.isChecked)
.setIntent(speakerButtonInfo.checkable ? toggleSpeaker : showSpeakerSelect)
.build());
actions.add(
Action.builder()
.setIcon(Icon.createWithResource(context, R.drawable.quantum_ic_mic_off_white_24))
.setName(context.getText(R.string.incall_label_mute))
.setChecked(audioState.isMuted())
.setIntent(toggleMute)
.build());
actions.add(
Action.builder()
.setIcon(Icon.createWithResource(context, R.drawable.quantum_ic_call_end_white_24))
.setName(context.getText(R.string.incall_label_end_call))
.setIntent(endCall)
.build());
return actions;
}
@NonNull
private PendingIntent createActionIntent(String action) {
Intent toggleSpeaker = new Intent(context, ReturnToCallActionReceiver.class);
toggleSpeaker.setAction(action);
return PendingIntent.getBroadcast(context, 0, toggleSpeaker, 0);
}
}