diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 006d7c25d3b..acbfa7e96e5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3370,7 +3370,7 @@ - - - - + - - - + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" /> + diff --git a/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java b/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java new file mode 100644 index 00000000000..f5c24068543 --- /dev/null +++ b/src/com/android/settings/sim/SelectSpecificDataSimDialogFragment.java @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2021 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.settings.sim; + +import android.app.Dialog; +import android.app.settings.SettingsEnums; +import android.content.DialogInterface; +import android.os.Bundle; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.text.TextUtils; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.appcompat.app.AlertDialog; + +import com.android.settings.R; +import com.android.settings.network.SubscriptionUtil; + +import java.util.List; + +/** + * Presents a dialog asking the user if they want to switch the data to another sim + */ +public class SelectSpecificDataSimDialogFragment extends SimDialogFragment implements + DialogInterface.OnClickListener { + private static final String TAG = "PreferredSimDialogFrag"; + + private SubscriptionInfo mSubscriptionInfo; + + /** + * @return the dialog fragment. + */ + public static SelectSpecificDataSimDialogFragment newInstance() { + final SelectSpecificDataSimDialogFragment + fragment = new SelectSpecificDataSimDialogFragment(); + final Bundle args = initArguments(SimDialogActivity.DATA_PICK, + R.string.select_specific_sim_for_data_title); + fragment.setArguments(args); + return fragment; + } + + @NonNull + @Override + public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) { + final AlertDialog dialog = new AlertDialog.Builder(getContext()) + .setNegativeButton(R.string.sim_action_no_thanks, null) + .create(); + updateDialog(dialog); + return dialog; + } + + @Override + public void onClick(DialogInterface dialog, int buttonClicked) { + if (buttonClicked != DialogInterface.BUTTON_POSITIVE) { + return; + } + final SimDialogActivity activity = (SimDialogActivity) getActivity(); + final SubscriptionInfo info = getTargetSubscriptionInfo(); + if (info != null) { + activity.onSubscriptionSelected(getDialogType(), info.getSubscriptionId()); + } + } + + private SubscriptionInfo getNonDefaultDataSubscriptionInfo(SubscriptionInfo dds) { + List subInfos = getSubscriptionManager().getActiveSubscriptionInfoList(); + if (subInfos == null || dds == null) { + return null; + } + return subInfos.stream().filter(subinfo -> subinfo != dds).findFirst().orElse(null); + } + + private SubscriptionInfo getDefaultDataSubId() { + return getSubscriptionManager().getDefaultDataSubscriptionInfo(); + } + + private void updateDialog(AlertDialog dialog) { + Log.d(TAG, "Dialog updated, dismiss status: " + mWasDismissed); + if (mWasDismissed) { + return; + } + + SubscriptionInfo activeSubInfo = getDefaultDataSubId(); + SubscriptionInfo newSubInfo = getNonDefaultDataSubscriptionInfo(activeSubInfo); + + if (newSubInfo == null || activeSubInfo == null) { + dismiss(); + return; + } + + setTargetSubscriptionInfo(newSubInfo); + + CharSequence newDataCarrierName = SubscriptionUtil.getUniqueSubscriptionDisplayName( + newSubInfo, getContext()); + CharSequence currentDataCarrierName = SubscriptionUtil.getUniqueSubscriptionDisplayName( + activeSubInfo, getContext()); + + String positive = getContext().getString( + R.string.select_specific_sim_for_data_button, newDataCarrierName); + String message = getContext().getString(R.string.select_specific_sim_for_data_msg, + newDataCarrierName, currentDataCarrierName); + + View content = LayoutInflater.from(getContext()).inflate( + R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null); + TextView dialogMessage = content.findViewById(R.id.msg); + if (!TextUtils.isEmpty(message) && dialogMessage != null) { + dialogMessage.setText(message); + } + + final ListView lvItems = content.findViewById(R.id.carrier_list); + if (lvItems != null) { + lvItems.setVisibility(View.GONE); + } + final LinearLayout infoOutline = content.findViewById(R.id.info_outline_layout); + if (infoOutline != null) { + infoOutline.setVisibility(View.GONE); + } + dialog.setView(content); + + View titleView = LayoutInflater.from(getContext()).inflate( + R.layout.sim_confirm_dialog_title_multiple_enabled_profiles_supported, null); + TextView titleTextView = titleView.findViewById(R.id.title); + titleTextView.setText(getContext().getString(getTitleResId(), newDataCarrierName)); + + dialog.setCustomTitle(titleTextView); + dialog.setButton(AlertDialog.BUTTON_POSITIVE, positive, this); + } + + private void setTargetSubscriptionInfo(SubscriptionInfo subInfo) { + mSubscriptionInfo = subInfo; + } + + private SubscriptionInfo getTargetSubscriptionInfo() { + return mSubscriptionInfo; + } + + @Override + public void updateDialog() { + updateDialog((AlertDialog) getDialog()); + } + + @VisibleForTesting + protected SubscriptionManager getSubscriptionManager() { + return getContext().getSystemService(SubscriptionManager.class); + } + + @Override + public int getMetricsCategory() { + return SettingsEnums.DIALOG_PREFERRED_SIM_PICKER; + } +} diff --git a/src/com/android/settings/sim/SimDialogActivity.java b/src/com/android/settings/sim/SimDialogActivity.java index f9aca77d20b..1125e1fe295 100644 --- a/src/com/android/settings/sim/SimDialogActivity.java +++ b/src/com/android/settings/sim/SimDialogActivity.java @@ -95,15 +95,16 @@ public class SimDialogActivity extends FragmentActivity { private SimDialogFragment createFragment(int dialogType) { switch (dialogType) { case DATA_PICK: - return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_data, - false /* includeAskEveryTime */); + return getDataPickDialogFramgent(); case CALLS_PICK: return CallsSimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_calls, - true /* includeAskEveryTime */); + true /* includeAskEveryTime */, + false /* isCancelItemShowed */); case SMS_PICK: return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms, - true /* includeAskEveryTime */); + true /* includeAskEveryTime */, + false /* isCancelItemShowed */); case PREFERRED_PICK: if (!getIntent().hasExtra(PREFERRED_SIM)) { throw new IllegalArgumentException("Missing required extra " + PREFERRED_SIM); @@ -111,12 +112,23 @@ public class SimDialogActivity extends FragmentActivity { return PreferredSimDialogFragment.newInstance(); case SMS_PICK_FOR_MESSAGE: return SimListDialogFragment.newInstance(dialogType, R.string.select_sim_for_sms, - false /* includeAskEveryTime */); + false /* includeAskEveryTime */, + false /* isCancelItemShowed */); default: throw new IllegalArgumentException("Invalid dialog type " + dialogType + " sent."); } } + private SimDialogFragment getDataPickDialogFramgent() { + if (SubscriptionManager.getDefaultDataSubscriptionId() + == SubscriptionManager.INVALID_SUBSCRIPTION_ID) { + return SimListDialogFragment.newInstance(DATA_PICK, R.string.select_sim_for_data, + false /* includeAskEveryTime */, + true /* isCancelItemShowed */); + } + return SelectSpecificDataSimDialogFragment.newInstance(); + } + public void onSubscriptionSelected(int dialogType, int subId) { if (getSupportFragmentManager().findFragmentByTag(Integer.toString(dialogType)) == null) { Log.w(TAG, "onSubscriptionSelected ignored because stored fragment was null"); diff --git a/src/com/android/settings/sim/SimListDialogFragment.java b/src/com/android/settings/sim/SimListDialogFragment.java index 2681d7b62bb..629a087b0eb 100644 --- a/src/com/android/settings/sim/SimListDialogFragment.java +++ b/src/com/android/settings/sim/SimListDialogFragment.java @@ -29,7 +29,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; -import android.widget.ImageView; +import android.widget.ListView; import android.widget.TextView; import androidx.annotation.NonNull; @@ -38,7 +38,6 @@ import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import com.android.settings.R; -import com.android.settings.Utils; import com.android.settings.network.SubscriptionUtil; import java.util.ArrayList; @@ -52,16 +51,19 @@ public class SimListDialogFragment extends SimDialogFragment implements DialogInterface.OnClickListener { private static final String TAG = "SimListDialogFragment"; protected static final String KEY_INCLUDE_ASK_EVERY_TIME = "include_ask_every_time"; + protected static final String KEY_SHOW_CANCEL_ITEM = "show_cancel_item"; + private static final int LIST_VIEW_DIVIDER_LINE_WEIGHT = 2; protected SelectSubscriptionAdapter mAdapter; @VisibleForTesting List mSubscriptions; public static SimListDialogFragment newInstance(int dialogType, int titleResId, - boolean includeAskEveryTime) { + boolean includeAskEveryTime, boolean isCancelItemShowed) { final SimListDialogFragment fragment = new SimListDialogFragment(); final Bundle args = initArguments(dialogType, titleResId); args.putBoolean(KEY_INCLUDE_ASK_EVERY_TIME, includeAskEveryTime); + args.putBoolean(KEY_SHOW_CANCEL_ITEM, isCancelItemShowed); fragment.setArguments(args); return fragment; } @@ -72,12 +74,20 @@ public class SimListDialogFragment extends SimDialogFragment implements mSubscriptions = new ArrayList<>(); final AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); - builder.setTitle(getTitleResId()); + View titleView = LayoutInflater.from(getContext()).inflate( + R.layout.sim_confirm_dialog_title_multiple_enabled_profiles_supported, null); + TextView titleTextView = titleView.findViewById(R.id.title); + titleTextView.setText(getContext().getString(getTitleResId())); + builder.setCustomTitle(titleTextView); mAdapter = new SelectSubscriptionAdapter(builder.getContext(), mSubscriptions); - setAdapter(builder); - final Dialog dialog = builder.create(); + + final AlertDialog dialog = builder.create(); + ListView listView = dialog.getListView(); + if (listView != null) { + listView.setDividerHeight(LIST_VIEW_DIVIDER_LINE_WEIGHT); + } updateDialog(); return dialog; } @@ -112,10 +122,22 @@ public class SimListDialogFragment extends SimDialogFragment implements } return; } - if (getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME)) { - final List tmp = new ArrayList<>(currentSubscriptions.size() + 1); - tmp.add(null); + boolean includeAskEveryTime = getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME); + boolean isCancelItemShowed = getArguments().getBoolean(KEY_SHOW_CANCEL_ITEM); + if (includeAskEveryTime || isCancelItemShowed) { + int arraySize = currentSubscriptions.size() + + (includeAskEveryTime ? 1 : 0) + + (isCancelItemShowed ? 1 : 0); + final List tmp = new ArrayList<>(arraySize); + if (includeAskEveryTime) { + // add the value of 'AskEveryTime' item + tmp.add(null); + } tmp.addAll(currentSubscriptions); + if (isCancelItemShowed) { + // add the value of 'Cancel' item + tmp.add(null); + } currentSubscriptions = tmp; } if (currentSubscriptions.equals(mSubscriptions)) { @@ -177,19 +199,23 @@ public class SimListDialogFragment extends SimDialogFragment implements final TextView title = convertView.findViewById(R.id.title); final TextView summary = convertView.findViewById(R.id.summary); - final ImageView icon = convertView.findViewById(R.id.icon); if (sub == null) { - title.setText(R.string.sim_calls_ask_first_prefs_title); - summary.setText(""); - icon.setImageDrawable(mContext.getDrawable(R.drawable.ic_feedback_24dp)); - icon.setImageTintList( - Utils.getColorAttr(mContext, android.R.attr.textColorSecondary)); + if (position == 0) { + title.setText(R.string.sim_calls_ask_first_prefs_title); + } else { + title.setText(R.string.sim_action_cancel); + } + summary.setVisibility(View.GONE); } else { title.setText(SubscriptionUtil.getUniqueSubscriptionDisplayName(sub, mContext)); - summary.setText(isMdnProvisioned(sub.getNumber()) ? sub.getNumber() : ""); - icon.setImageBitmap(sub.createIconBitmap(mContext)); - + String phoneNumber = isMdnProvisioned(sub.getNumber()) ? sub.getNumber() : ""; + if (!TextUtils.isEmpty(phoneNumber)) { + summary.setVisibility(View.VISIBLE); + summary.setText(phoneNumber); + } else { + summary.setVisibility(View.GONE); + } } return convertView; } diff --git a/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java index 0fefbe0ed49..070bcb1e74b 100644 --- a/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/sim/SimListDialogFragmentTest.java @@ -53,7 +53,8 @@ public class SimListDialogFragmentTest extends SimDialogFragmentTestBase