summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamaljeet Maini <kmaini@cyngn.com>2016-04-22 14:40:17 -0700
committerKamaljeet Maini <kmaini@cyngn.com>2016-05-05 15:56:29 -0700
commit1179ffdd487b1aeb48aa562044508b4e50b65a00 (patch)
tree89347b27089f9c3647494884e80bae57a02358be
parent41b96a97cd4806b7076fa5b6a5353150efb18c7c (diff)
downloadandroid_packages_services_Telecomm-1179ffdd487b1aeb48aa562044508b4e50b65a00.tar.gz
android_packages_services_Telecomm-1179ffdd487b1aeb48aa562044508b4e50b65a00.tar.bz2
android_packages_services_Telecomm-1179ffdd487b1aeb48aa562044508b4e50b65a00.zip
Add new options for call waiting response in InCallUI
When an incoming call is received while there is already an active call, the user will be given four choices for the response: 1) Left button: hold the current call and answer incoming call 2) Bottom button: end the current call and answer the incoming call 3) Right button: decline the incoming call 4) Top button: Send a text message to the incoming caller if texting is enabled The changes in this component include removing the call reponse popup and handling the new hidden API. Change-Id: I920b16842a609f3350bfd5344a4b367da4580349
-rw-r--r--src/com/android/server/telecom/CallsManager.java193
-rw-r--r--src/com/android/server/telecom/InCallAdapter.java21
-rw-r--r--src/com/android/server/telecom/ui/CallWaitingDialog.java106
3 files changed, 108 insertions, 212 deletions
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 402ac054..ec65eb87 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -48,7 +48,6 @@ import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.util.BlacklistUtils;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.server.telecom.ui.CallWaitingDialog;
import java.util.Collection;
import java.util.Collections;
@@ -903,6 +902,19 @@ public class CallsManager extends Call.ListenerBase implements VideoProviderProx
* @param videoState The video state in which to answer the call.
*/
void answerCall(final Call call, final int videoState) {
+ answerCall(call, videoState, TelecomManager.CALL_WAITING_RESPONSE_NO_POPUP_END_CALL);
+ }
+
+ /**
+ * Instructs Telecom to answer the specified call. Intended to be invoked by the in-call
+ * app through {@link InCallAdapter} after Telecom notifies it of an incoming call followed by
+ * the user opting to answer said call.
+ *
+ * @param call The call to answer.
+ * @param videoState The video state in which to answer the call.
+ * @param callWaitingResponseType Response type for call waiting.
+ */
+ void answerCall(final Call call, final int videoState, final int callWaitingResponseType) {
if (!mCalls.contains(call)) {
Log.i(this, "Request to answer a non-existent call %s", call);
} else {
@@ -922,17 +934,17 @@ public class CallsManager extends Call.ListenerBase implements VideoProviderProx
activeCall.disconnect();
}
} else {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- CallWaitingListener listener = new CallWaitingListener(call,
+ switch (callWaitingResponseType) {
+ case TelecomManager.CALL_WAITING_RESPONSE_NO_POPUP_HOLD_CALL:
+ handleHoldCallAndAnswer(call,
activeCall, videoState, CallsManager.this);
- Dialog dialog =
- CallWaitingDialog.createCallWaitingDialog(mContext, call,
- listener, listener);
- dialog.show();
- }
- });
+ break;
+ case TelecomManager.CALL_WAITING_RESPONSE_NO_POPUP_END_CALL:
+ default:
+ handleEndCallAndAnswer(call,
+ activeCall, videoState, CallsManager.this);
+ break;
+ }
return;
}
}
@@ -2464,101 +2476,70 @@ public class CallsManager extends Call.ListenerBase implements VideoProviderProx
return false;
}
- private static class CallWaitingListener implements DialogInterface
- .OnClickListener {
-
- private final Call mNewCall;
- private final Call mActiveCall;
- private final CallsManager mLocalCallsManager;
- private final int mVideoState;
-
- /* package */ CallWaitingListener(Call newCall, Call activeCall, int videoState,
- CallsManager callsManager) {
- mNewCall = newCall;
- mActiveCall = activeCall;
- mLocalCallsManager = callsManager;
- mVideoState = videoState;
+ private void handleHoldCallAndAnswer(Call newCall, Call activeCall, int videoState,
+ CallsManager callsManager) {
+ // We only want one held call, so if we have a held call already we need to
+ // disconnect it
+ Call heldCall = callsManager.getHeldCall();
+ if (heldCall != null) {
+ Log.v(this,
+ "Disconnecting held call %s before holding active call ", heldCall);
+ heldCall.disconnect();
+ }
+
+ // TODO: This active call reference can be nullified and discarded from another thread,
+ // Fix this by reworking the state machine surrounding calls within telecomm.
+ if (activeCall != null) {
+ Log.v(this, "Holding active/dialing call %s before answering incoming call %s.",
+ callsManager.mForegroundCall, newCall);
+ activeCall.hold();
+ }
+ // TODO: Wait until we get confirmation of
+ // the active call being
+ // on-hold before answering the new call.
+ // TODO: Import logic from
+ // CallManager.acceptCall()
+ updateListeners(newCall, activeCall, videoState, callsManager, false);
+ }
+
+ private void handleEndCallAndAnswer(Call newCall, Call activeCall, int videoState,
+ CallsManager callsManager) {
+ // We don't want to hold, just disconnect
+
+ // TODO: This active call reference can be nullified and discarded from another thread,
+ // Fix this by reworking the state machine surrounding calls within telecomm.
+ if (activeCall != null) {
+ Log.v(this, "Holding active/dialing call %s for termination before answering incoming call %s.",
+ callsManager.mForegroundCall, newCall);
+ activeCall.hold();
+ }
+ // TODO: Wait until we get confirmation of
+ // the active call being
+ // on-hold before answering the new call.
+ // TODO: Import logic from
+ // CallManager.acceptCall()
+ updateListeners(newCall, activeCall, videoState, callsManager, true);
+ }
+
+ private void updateListeners(Call newCall, Call activeCall, int videoState,
+ CallsManager callsManager, boolean terminateActive) {
+ for (CallsManagerListener listener : callsManager.mListeners) {
+ listener.onIncomingCallAnswered(newCall);
+ }
+ callsManager.updateLchStatus(newCall.getTargetPhoneAccount().getId());
+ // We do not update the UI until we get
+ // confirmation of
+ // the answer() through
+ // {@link #markCallAsActive}.
+ newCall.answer(videoState);
+ if (terminateActive && activeCall != null) {
+ Log.v(this, "Terminating active call %s after answering incoming call %s.",
+ activeCall, newCall);
+ activeCall.disconnect();
+ }
+
+ if (callsManager.isSpeakerphoneAutoEnabled(videoState)) {
+ newCall.setStartWithSpeakerphoneOn(true);
}
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
- switch (which) {
- case DialogInterface.BUTTON_POSITIVE:
- // Hold call
- handleHoldCallAndAnswer();
- break;
- case DialogInterface.BUTTON_NEGATIVE:
- default:
- // End call
- handleEndCallAndAnswer();
- break;
- }
- }
-
- private void handleHoldCallAndAnswer() {
- // We only want one held call, so if we have a held call already we need to
- // disconnect it
- Call heldCall = mLocalCallsManager.getHeldCall();
- if (heldCall != null) {
- Log.v(this,
- "Disconnecting held call %s before holding active call ", heldCall);
- heldCall.disconnect();
- }
-
- // TODO: This active call reference can be nullified and discarded from another thread,
- // Fix this by reworking the state machine surrounding calls within telecomm.
- if (mActiveCall != null) {
- Log.v(this, "Holding active/dialing call %s before answering incoming call %s.",
- mLocalCallsManager.mForegroundCall, mNewCall);
- mActiveCall.hold();
- }
- // TODO: Wait until we get confirmation of
- // the active call being
- // on-hold before answering the new call.
- // TODO: Import logic from
- // CallManager.acceptCall()
- updateListeners(false);
- }
-
- private void handleEndCallAndAnswer() {
- // We don't want to hold, just disconnect
-
- // TODO: This active call reference can be nullified and discarded from another thread,
- // Fix this by reworking the state machine surrounding calls within telecomm.
- if (mActiveCall != null) {
- Log.v(this, "Holding active/dialing call %s for termination before answering incoming call %s.",
- mLocalCallsManager.mForegroundCall, mNewCall);
- mActiveCall.hold();
- }
- // TODO: Wait until we get confirmation of
- // the active call being
- // on-hold before answering the new call.
- // TODO: Import logic from
- // CallManager.acceptCall()
- updateListeners(true);
- }
-
- private void updateListeners(boolean terminateActive) {
- for (CallsManagerListener listener : mLocalCallsManager.mListeners) {
- listener.onIncomingCallAnswered(mNewCall);
- }
- mLocalCallsManager.updateLchStatus(mNewCall.getTargetPhoneAccount().getId());
- // We do not update the UI until we get
- // confirmation of
- // the answer() through
- // {@link #markCallAsActive}.
- mNewCall.answer(mVideoState);
- if (terminateActive && mActiveCall != null) {
- Log.v(this, "Terminating active call %s after answering incoming call %s.",
- mActiveCall, mNewCall);
- mActiveCall.disconnect();
- }
-
- if (mLocalCallsManager.isSpeakerphoneAutoEnabled(mVideoState)) {
- mNewCall.setStartWithSpeakerphoneOn(true);
- }
- }
-
}
-
}
diff --git a/src/com/android/server/telecom/InCallAdapter.java b/src/com/android/server/telecom/InCallAdapter.java
index 73212bd9..ba517280 100644
--- a/src/com/android/server/telecom/InCallAdapter.java
+++ b/src/com/android/server/telecom/InCallAdapter.java
@@ -60,6 +60,27 @@ class InCallAdapter extends IInCallAdapter.Stub {
}
@Override
+ public void answerCallWithCallWaitingResponse(String callId, int videoState, int
+ callWaitingResponseType) {
+ long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ Log.d(this, "answerCall(%s,%d)", callId, videoState);
+ if (mCallIdMapper.isValidCallId(callId)) {
+ Call call = mCallIdMapper.getCall(callId);
+ if (call != null) {
+ mCallsManager.answerCall(call, videoState, callWaitingResponseType);
+ } else {
+ Log.w(this, "answerCall, unknown call id: %s", callId);
+ }
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ @Override
public void rejectCall(String callId, boolean rejectWithMessage, String textMessage) {
long token = Binder.clearCallingIdentity();
try {
diff --git a/src/com/android/server/telecom/ui/CallWaitingDialog.java b/src/com/android/server/telecom/ui/CallWaitingDialog.java
deleted file mode 100644
index eea93e93..00000000
--- a/src/com/android/server/telecom/ui/CallWaitingDialog.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2016 The CyanogenMod 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.server.telecom.ui;
-
-import android.annotation.NonNull;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.text.TextUtils;
-import android.view.View;
-import android.view.WindowManager;
-import android.widget.AdapterView;
-import android.widget.ListView;
-import com.android.server.telecom.Call;
-import com.android.server.telecom.R;
-
-/**
- * <pre>
- * This dialog shows up when you answer another call while currently in a call
- * </pre>
- *
- * @see {@link Dialog}
- */
-public class CallWaitingDialog extends Dialog implements AdapterView.OnItemClickListener{
-
- // Members
- DialogInterface.OnClickListener mHoldListener;
- DialogInterface.OnClickListener mEndListener;
-
- // Views
- private ListView mButtonListView;
- private CallWaitingButtonAdapter mButtonAdapter;
- private Integer buttons[] = new Integer[] {
- CallWaitingDialogButton.BUTTON_HOLD,
- CallWaitingDialogButton.BUTTON_END
- };
-
- private CallWaitingDialog(@NonNull Context context,
- DialogInterface.OnClickListener holdListener,
- DialogInterface.OnClickListener endListener) {
- super(context, android.R.style.Theme_Material_Light_Dialog);
- setContentView(R.layout.call_waiting_dialog);
- mButtonListView = (ListView) findViewById(R.id.lv_buttons);
- mButtonAdapter = new CallWaitingButtonAdapter(context,
- R.layout.call_waiting_dialog_button, buttons);
- mButtonListView.setAdapter(mButtonAdapter);
- mHoldListener = holdListener;
- mEndListener = endListener;
- mButtonListView.setOnItemClickListener(this);
- }
-
- /**
- * Create a new call waiting choice dialog. This should be the entrypoint
- *
- * @param context {@link Context}
- * @param call {@link Call}
- * @param holdListener {@link android.content.DialogInterface.OnClickListener}
- * @param endListener {@link android.content.DialogInterface.OnClickListener}
- * @return {@link Dialog}
- */
- public static Dialog createCallWaitingDialog(Context context, final Call call,
- DialogInterface.OnClickListener holdListener,
- DialogInterface.OnClickListener endListener) {
- CallWaitingDialog dialog = new CallWaitingDialog(context, holdListener, endListener);
- String template = context.getResources().getString(R.string.call_waiting_dialog_title);
- String name = (TextUtils.isEmpty(call.getName()) ? call.getNumber() : call.getName());
- String title = String.format(template, name);
- dialog.setTitle(title);
- dialog.setCancelable(false);
- dialog.getWindow()
- .setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- return dialog;
- }
-
- @Override
- public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
- switch (position) {
- case CallWaitingDialogButton.BUTTON_HOLD:
- if (mHoldListener != null) {
- mHoldListener.onClick(this, DialogInterface.BUTTON_POSITIVE);
- }
- break;
- case CallWaitingDialogButton.BUTTON_END:
- default:
- if (mEndListener != null) {
- mEndListener.onClick(this, DialogInterface.BUTTON_NEGATIVE);
- }
- break;
- }
- this.dismiss();
- }
-
-}