summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNancy Chen <nancychen@google.com>2014-07-08 18:53:32 -0700
committerNancy Chen <nancychen@google.com>2014-07-17 10:17:43 -0700
commitaf9eefb9174cdb7a4824fc0a8ed6e85754acd0bd (patch)
treefbdda7d5391ed859d5a203b67d81b02aee708746
parent8ab0025de65b0af5027470ea63ae24445f0cb759 (diff)
Bring up dialog when an account is not set for the phone call
If an account default is not set, the incall ui will display a dialog to allow the user to select an account for that particular call. Bug: 16243703 Change-Id: Ic97c50d1116dd11ef900c4d20c6439683ed60e06
-rw-r--r--InCallUI/res/layout/select_account_list_item.xml36
-rw-r--r--InCallUI/res/values/strings.xml3
-rw-r--r--InCallUI/src/com/android/incallui/Call.java5
-rw-r--r--InCallUI/src/com/android/incallui/CallList.java7
-rw-r--r--InCallUI/src/com/android/incallui/InCallActivity.java14
-rw-r--r--InCallUI/src/com/android/incallui/InCallPresenter.java46
-rw-r--r--InCallUI/src/com/android/incallui/SelectPhoneAccountDialogFragment.java138
-rw-r--r--InCallUI/src/com/android/incallui/TelecommAdapter.java9
8 files changed, 251 insertions, 7 deletions
diff --git a/InCallUI/res/layout/select_account_list_item.xml b/InCallUI/res/layout/select_account_list_item.xml
new file mode 100644
index 000000000..0b24c9b9f
--- /dev/null
+++ b/InCallUI/res/layout/select_account_list_item.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<!-- Layout of a single item in the InCallUI Account Chooser Dialog. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="4dp" >
+
+ <ImageView android:id="@+id/icon"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:scaleType="center" />
+
+ <TextView android:id="@+id/text"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="start|center_vertical"
+ android:layout_marginLeft="8dp"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="match_parent" />
+</LinearLayout>
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index 19ba8a6c8..78fe885cd 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -537,6 +537,9 @@
<!-- This can be used in any application wanting to disable the text "Emergency number" -->
<string name="emergency_call_dialog_number_for_display">Emergency number</string>
+ <!-- Title for Select Account Dialog [CHAR LIMIT=30] -->
+ <string name="select_account_dialog_title">Select Account</string>
+
<!-- The digit to be displayed on the 0 key of the dialpad [CHAR LIMIT=1]-->
<string name="dialpad_0_number">0</string>
<!-- The digit to be displayed on the 1 key of the dialpad [CHAR LIMIT=1]-->
diff --git a/InCallUI/src/com/android/incallui/Call.java b/InCallUI/src/com/android/incallui/Call.java
index 6a4ee985d..f6c039138 100644
--- a/InCallUI/src/com/android/incallui/Call.java
+++ b/InCallUI/src/com/android/incallui/Call.java
@@ -45,6 +45,7 @@ public final class Call {
public static final int DISCONNECTING = 8; /* A call is being ended. */
public static final int DISCONNECTED = 9; /* State after a call disconnects */
public static final int CONFERENCED = 10; /* Call part of a conference call */
+ public static final int PRE_DIAL_WAIT = 11; /* Waiting for user before outgoing call */
public static boolean isConnected(int state) {
switch(state) {
@@ -89,6 +90,8 @@ public final class Call {
return "DISCONNECTED";
case CONFERENCED:
return "CONFERENCED";
+ case PRE_DIAL_WAIT:
+ return "PRE_DIAL_WAIT";
default:
return "UNKOWN";
}
@@ -214,6 +217,8 @@ public final class Call {
private static int translateState(int state) {
switch (state) {
+ case android.telecomm.Call.STATE_PRE_DIAL_WAIT:
+ return Call.State.PRE_DIAL_WAIT;
case android.telecomm.Call.STATE_DIALING:
case android.telecomm.Call.STATE_NEW:
return Call.State.DIALING;
diff --git a/InCallUI/src/com/android/incallui/CallList.java b/InCallUI/src/com/android/incallui/CallList.java
index f89d8aafe..e4085f610 100644
--- a/InCallUI/src/com/android/incallui/CallList.java
+++ b/InCallUI/src/com/android/incallui/CallList.java
@@ -197,6 +197,13 @@ public class CallList implements InCallPhoneListener {
return retval;
}
+ /**
+ * A call that is waiting for {@link PhoneAccount} selection
+ */
+ public Call getWaitingForAccountCall() {
+ return getFirstCallWithState(Call.State.PRE_DIAL_WAIT);
+ }
+
public Call getOutgoingCall() {
Call call = getFirstCallWithState(Call.State.DIALING);
if (call == null) {
diff --git a/InCallUI/src/com/android/incallui/InCallActivity.java b/InCallUI/src/com/android/incallui/InCallActivity.java
index 24e57625e..f609d28d2 100644
--- a/InCallUI/src/com/android/incallui/InCallActivity.java
+++ b/InCallUI/src/com/android/incallui/InCallActivity.java
@@ -192,6 +192,7 @@ public class InCallActivity extends Activity {
private boolean hasPendingErrorDialog() {
return mDialog != null;
}
+
/**
* Dismisses the in-call screen.
*
@@ -245,6 +246,10 @@ public class InCallActivity extends Activity {
// BACK is also used to exit out of any "special modes" of the
// in-call UI:
+ if (!mCallCardFragment.isVisible()) {
+ return;
+ }
+
if (mDialpadFragment.isVisible()) {
mCallButtonFragment.displayDialpad(false /* show */, true /* animate */);
return;
@@ -256,7 +261,7 @@ public class InCallActivity extends Activity {
// Always disable the Back key while an incoming call is ringing
final Call call = CallList.getInstance().getIncomingCall();
if (call != null) {
- Log.d(this, "Consume Back press for an inconing call");
+ Log.d(this, "Consume Back press for an incoming call");
return;
}
@@ -387,6 +392,13 @@ public class InCallActivity extends Activity {
mCallCardFragment.animateForNewOutgoingCall();
}
+ if (CallList.getInstance().getWaitingForAccountCall() != null) {
+ mCallCardFragment.setVisible(false);
+ SelectPhoneAccountDialogFragment.show(getFragmentManager());
+ } else {
+ mCallCardFragment.setVisible(true);
+ }
+
return;
}
}
diff --git a/InCallUI/src/com/android/incallui/InCallPresenter.java b/InCallUI/src/com/android/incallui/InCallPresenter.java
index 5c6283ea4..5965a950a 100644
--- a/InCallUI/src/com/android/incallui/InCallPresenter.java
+++ b/InCallUI/src/com/android/incallui/InCallPresenter.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.Intent;
import android.telecomm.CallCapabilities;
import android.telecomm.Phone;
+import android.telecomm.PhoneAccount;
import com.google.common.base.Preconditions;
import com.google.common.collect.Sets;
@@ -53,6 +54,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
private InCallState mInCallState = InCallState.NO_CALLS;
private ProximitySensor mProximitySensor;
private boolean mServiceConnected = false;
+ private boolean mAccountSelectionCancelled = false;
private final Phone.Listener mPhoneListener = new Phone.Listener() {
@Override
@@ -172,6 +174,12 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
if (doFinish) {
mInCallActivity.finish();
+
+ if (mAccountSelectionCancelled) {
+ // This finish is a result of account selection cancellation
+ // do not include activity ending transition
+ mInCallActivity.overridePendingTransition(0, 0);
+ }
}
}
@@ -327,6 +335,8 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
if (callList.getIncomingCall() != null) {
newState = InCallState.INCOMING;
+ } else if (callList.getWaitingForAccountCall() != null) {
+ newState = InCallState.WAITING_FOR_ACCOUNT;
} else if (callList.getOutgoingCall() != null) {
newState = InCallState.OUTGOING;
} else if (callList.getActiveCall() != null ||
@@ -363,6 +373,23 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
return mProximitySensor;
}
+ public void handleAccountSelection(PhoneAccount account) {
+ Call call = mCallList.getWaitingForAccountCall();
+ if (call != null) {
+ String callId = call.getId();
+ TelecommAdapter.getInstance().phoneAccountSelected(callId, account);
+ }
+ }
+
+ public void cancelAccountSelection() {
+ mAccountSelectionCancelled = true;
+ Call call = mCallList.getWaitingForAccountCall();
+ if (call != null) {
+ String callId = call.getId();
+ TelecommAdapter.getInstance().disconnectCall(callId);
+ }
+ }
+
/**
* Hangs up any active or outgoing calls.
*/
@@ -402,7 +429,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
Call call = mCallList.getIncomingCall();
if (call != null) {
TelecommAdapter.getInstance().answerCall(call.getId());
- showInCall(false, false/* newOutgoingCall */);
+ showInCall(false, false /* newOutgoingCall */);
}
}
@@ -431,7 +458,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
}
/**
- * Returns true of the activity has been created and is running.
+ * Returns true if the activity has been created and is running.
* Returns true as long as activity is not destroyed or finishing. This ensures that we return
* true even if the activity is paused (not in foreground).
*/
@@ -612,7 +639,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
// A new Incoming call means that the user needs to be notified of the the call (since
// it wasn't them who initiated it). We do this through full screen notifications and
- // happens indirectly through {@link StatusBarListener}.
+ // happens indirectly through {@link StatusBarNotifier}.
//
// The process for incoming calls is as follows:
//
@@ -636,12 +663,16 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
// we get an incoming call.
final boolean startStartupSequence = (InCallState.INCOMING == newState);
+ // A dialog to show on top of the InCallUI to select a PhoneAccount
+ final boolean showAccountPicker = (InCallState.WAITING_FOR_ACCOUNT == newState);
+
// A new outgoing call indicates that the user just now dialed a number and when that
- // happens we need to display the screen immediateley.
+ // happens we need to display the screen immediately or show an account picker dialog if
+ // no default is set.
//
// This is different from the incoming call sequence because we do not need to shock the
// user with a top-level notification. Just show the call UI normally.
- final boolean showCallUi = (InCallState.OUTGOING == newState);
+ final boolean showCallUi = (InCallState.OUTGOING == newState || showAccountPicker);
// TODO: Can we be suddenly in a call without it having been in the outgoing or incoming
// state? I havent seen that but if it can happen, the code below should be enabled.
@@ -659,7 +690,7 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
if (showCallUi) {
Log.i(this, "Start in call UI");
- showInCall(false /* showDialpad */, true /* newOutgoingCall */);
+ showInCall(false /* showDialpad */, !showAccountPicker /* newOutgoingCall */);
} else if (startStartupSequence) {
Log.i(this, "Start Full Screen in call UI");
@@ -783,6 +814,9 @@ public class InCallPresenter implements CallList.Listener, InCallPhoneListener {
// In-call experience is showing
INCALL,
+ // Waiting for user input before placing outgoing call
+ WAITING_FOR_ACCOUNT,
+
// User is dialing out
OUTGOING;
diff --git a/InCallUI/src/com/android/incallui/SelectPhoneAccountDialogFragment.java b/InCallUI/src/com/android/incallui/SelectPhoneAccountDialogFragment.java
new file mode 100644
index 000000000..eb61bba0a
--- /dev/null
+++ b/InCallUI/src/com/android/incallui/SelectPhoneAccountDialogFragment.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2014 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 com.google.android.collect.Lists;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.telecomm.PhoneAccount;
+import android.telecomm.PhoneAccountMetadata;
+import android.telecomm.TelecommManager;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.android.contacts.common.R;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Dialog that allows the user to switch between default SIM cards
+ */
+public class SelectPhoneAccountDialogFragment extends DialogFragment {
+ private List<PhoneAccount> mAccounts;
+ private boolean mIsSelected;
+ private TelecommManager mTelecommManager;
+
+ /* Preferred way to show this dialog */
+ public static void show(FragmentManager fragmentManager) {
+ SelectPhoneAccountDialogFragment fragment = new SelectPhoneAccountDialogFragment();
+ fragment.show(fragmentManager, "selectAccount");
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ mIsSelected = false;
+ mTelecommManager = TelecommManager.from(getActivity());
+ mAccounts = mTelecommManager.getEnabledPhoneAccounts();
+
+ final DialogInterface.OnClickListener selectionListener =
+ new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ mIsSelected = true;
+ PhoneAccount selectedAccount = mAccounts.get(which);
+ InCallPresenter.getInstance().handleAccountSelection(selectedAccount);
+ }
+ };
+
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+ ListAdapter selectAccountListAdapter = new SelectAccountListAdapter(
+ builder.getContext(),
+ R.layout.select_account_list_item,
+ mAccounts);
+
+ return builder.setTitle(R.string.select_account_dialog_title)
+ .setAdapter(selectAccountListAdapter, selectionListener)
+ .create();
+ }
+
+ private class SelectAccountListAdapter extends ArrayAdapter<PhoneAccount> {
+ private Context mContext;
+ private int mResId;
+
+ public SelectAccountListAdapter(Context context, int resource, List<PhoneAccount> objects) {
+ super(context, resource, objects);
+ mContext = context;
+ mResId = resource;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ LayoutInflater inflater = (LayoutInflater)
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ View rowView;
+ final ViewHolder holder;
+
+ if (convertView == null) {
+ // Cache views for faster scrolling
+ rowView = inflater.inflate(mResId, null);
+ holder = new ViewHolder();
+ holder.textView = (TextView) rowView.findViewById(R.id.text);
+ holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
+ rowView.setTag(holder);
+ }
+ else {
+ rowView = convertView;
+ holder = (ViewHolder) rowView.getTag();
+ }
+
+ PhoneAccount item = getItem(position);
+ PhoneAccountMetadata itemMetadata = mTelecommManager.getPhoneAccountMetadata(item);
+ holder.textView.setText(itemMetadata.getLabel());
+ holder.imageView.setImageDrawable(itemMetadata.getIcon(mContext));
+ return rowView;
+ }
+
+ private class ViewHolder {
+ TextView textView;
+ ImageView imageView;
+ }
+ }
+
+ @Override
+ public void onPause() {
+ if (!mIsSelected) {
+ InCallPresenter.getInstance().cancelAccountSelection();
+ }
+ super.onPause();
+ }
+} \ No newline at end of file
diff --git a/InCallUI/src/com/android/incallui/TelecommAdapter.java b/InCallUI/src/com/android/incallui/TelecommAdapter.java
index 6d0e0a62d..745931cfe 100644
--- a/InCallUI/src/com/android/incallui/TelecommAdapter.java
+++ b/InCallUI/src/com/android/incallui/TelecommAdapter.java
@@ -22,6 +22,7 @@ import android.content.Intent;
import android.os.Looper;
import android.telecomm.InCallAdapter;
import android.telecomm.Phone;
+import android.telecomm.PhoneAccount;
import com.google.common.base.Preconditions;
@@ -194,4 +195,12 @@ final class TelecommAdapter implements InCallPhoneListener {
Log.e(this, "error phoneAccountClicked, mPhone is null");
}
}
+
+ void phoneAccountSelected(String callId, PhoneAccount account) {
+ if (mPhone != null) {
+ getTelecommCallById(callId).phoneAccountSelected(account);
+ } else {
+ Log.e(this, "error phoneAccountSelected, mAdapter is null");
+ }
+ }
}