summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNancy Chen <nancychen@google.com>2014-07-17 17:22:16 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-07-16 23:30:53 +0000
commite933c08056c7f2c3afe1321ff867c75a8db97a66 (patch)
tree4a1fe107ec975671a4fb626524f39fd42fabdddf
parent9f9b49aa57a21acf08582b5247694f3e7f56c3cb (diff)
parentaf9eefb9174cdb7a4824fc0a8ed6e85754acd0bd (diff)
Merge "Bring up dialog when an account is not set for the phone call" into lmp-dev
-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");
+ }
+ }
}