Merge "Add SIM color picker" into qt-dev am: b747c5c270 am: c1c4a0858d
am: 3ccc01ca18

Change-Id: I0e2c4d96df27e71d11b8a092f2cf86733d29727b
diff --git a/res/layout/dialog_mobile_network_color_picker_item.xml b/res/layout/dialog_mobile_network_color_picker_item.xml
new file mode 100644
index 0000000..b6f4092
--- /dev/null
+++ b/res/layout/dialog_mobile_network_color_picker_item.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="horizontal"
+    android:background="?android:attr/selectableItemBackground" >
+
+    <ImageView
+        android:id="@+id/color_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="@dimen/sim_label_padding"
+        android:layout_gravity="center_vertical" />
+
+    <TextView
+        android:id="@+id/color_label"
+        android:gravity="center_vertical"
+        android:layout_height="wrap_content"
+        android:layout_width="0dp"
+        android:layout_weight="1"
+        android:paddingTop="@dimen/sim_label_padding"
+        android:paddingBottom="@dimen/sim_label_padding"
+        android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+        android:textColor="?android:attr/textColorPrimary"/>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/dialog_mobile_network_rename.xml b/res/layout/dialog_mobile_network_rename.xml
index d67f0dc..921ab86 100644
--- a/res/layout/dialog_mobile_network_rename.xml
+++ b/res/layout/dialog_mobile_network_rename.xml
@@ -21,44 +21,89 @@
     <LinearLayout
         android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:padding="@dimen/sim_content_padding">
+        android:layout_height="wrap_content">
 
-        <EditText
-            android:id="@+id/edittext"
+        <LinearLayout
+            android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:inputType="text"
-            android:maxLength="50"
-            android:singleLine="true">
-            <requestFocus/>
-        </EditText>
+            android:paddingEnd="@dimen/sim_content_padding"
+            android:paddingStart="@dimen/sim_content_padding">
 
-        <TextView
-            style="@style/device_info_dialog_label"
-            android:id="@+id/operator_name_label"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/status_operator"/>
-        <TextView
-            style="@style/device_info_dialog_value"
-            android:id="@+id/operator_name_value"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:text="@string/device_info_not_available"/>
+            <TextView
+                android:id="@+id/name_label"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="@dimen/sim_label_padding"
+                android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+                android:textColor="?android:attr/textColorPrimary"
+                android:text="@string/mobile_network_sim_name_label"/>
 
-        <TextView
-            style="@style/device_info_dialog_label"
-            android:id="@+id/number_label"
+            <EditText
+                android:id="@+id/name_edittext"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:inputType="text"
+                android:paddingTop="@dimen/sim_label_padding"
+                android:maxLength="50"
+                android:singleLine="true"/>
+
+            <TextView
+                android:id="@+id/color_label"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="@dimen/sim_label_padding"
+                android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+                android:textColor="?android:attr/textColorPrimary"
+                android:text="@string/mobile_network_sim_color_label"/>
+
+        </LinearLayout>
+
+        <Spinner
+            android:id="@+id/color_spinner"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/status_number_sim_status"/>
-        <TextView
-            style="@style/device_info_dialog_value"
-            android:id="@+id/number_value"
+            android:layout_marginStart="@dimen/sim_color_spinner_padding"
+            android:layout_marginEnd="@dimen/sim_color_spinner_padding"/>
+
+        <LinearLayout
+            android:orientation="vertical"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:text="@string/device_info_not_available"/>
+            android:paddingEnd="@dimen/sim_content_padding"
+            android:paddingStart="@dimen/sim_content_padding">
+
+            <TextView
+                android:id="@+id/operator_name_label"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="@dimen/sim_label_padding"
+                android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+                android:textColor="?android:attr/textColorPrimary"
+                android:text="@string/status_operator"/>
+
+            <TextView
+                android:id="@+id/operator_name_value"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/device_info_not_available"/>
+
+            <TextView
+                android:id="@+id/number_label"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:paddingTop="@dimen/sim_label_padding"
+                android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Subhead"
+                android:textColor="?android:attr/textColorPrimary"
+                android:text="@string/status_number_sim_status"/>
+
+            <TextView
+                android:id="@+id/number_value"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/device_info_not_available"/>
+
+        </LinearLayout>
 
     </LinearLayout>
 </ScrollView>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index e074fa9..54cd9dc 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -166,6 +166,7 @@
     <dimen name="sim_dialog_margin_bottom">16dip</dimen>
     <!-- SIM Dialog padding -->
     <dimen name="sim_dialog_padding">8dip</dimen>
+    <dimen name="sim_color_spinner_padding">12dip</dimen>
     <dimen name="sim_label_padding">16dip</dimen>
     <dimen name="sim_content_padding">24dip</dimen>
     <!-- Sim Card Name length -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 79aad26..d441528 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -10959,10 +10959,14 @@
          subscription in various places in the Settings app. The default name is typically just the
          carrier name, but especially in multi-SIM configurations users may want to use a different
          name. [CHAR LIMIT=40] -->
-    <string name="mobile_network_sim_name">SIM name</string>
-    <!-- Label on the confirmation button of a dialog that lets a user set the display name of a
-         mobile network subscription [CHAR LIMIT=20] -->
-    <string name="mobile_network_sim_name_rename">Rename</string>
+    <string name="mobile_network_sim_name">SIM name &amp; color</string>
+    <!-- Label for an item listing the name of the SIM that the user has specified. [CHAR LIMIT=40] -->
+    <string name="mobile_network_sim_name_label">Name</string>
+    <!-- Label for an item listing the color of the SIM that the user has specified. [CHAR LIMIT=40] -->
+    <string name="mobile_network_sim_color_label">Color (used by compatible apps)</string>
+    <!-- Label on the confirmation button of a dialog that lets a user set the display name and
+         color of a mobile network subscription [CHAR LIMIT=20] -->
+    <string name="mobile_network_sim_name_rename">Save</string>
     <!-- Label for the on position of a switch on the mobile network details page which allows
          disabling/enabling a SIM. The SIM is enabled in this state. [CHAR LIMIT=40] -->
     <string name="mobile_network_use_sim_on">Use SIM</string>
diff --git a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
index 82554c2..a28fc91 100644
--- a/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
+++ b/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragment.java
@@ -19,6 +19,10 @@
 import android.app.Dialog;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Paint;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
 import android.os.Bundle;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
@@ -30,7 +34,12 @@
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
 import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.Spinner;
 import android.widget.TextView;
 
 import com.android.settings.R;
@@ -42,9 +51,12 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.appcompat.app.AlertDialog;
 
-/** A dialog allowing the display name of a mobile network subscription to be changed */
+/**
+ * A dialog allowing the display name of a mobile network subscription to be changed
+ */
 public class RenameMobileNetworkDialogFragment extends InstrumentedDialogFragment {
-    public static final String TAG ="RenameMobileNetwork";
+
+    public static final String TAG = "RenameMobileNetwork";
 
     private static final String KEY_SUBSCRIPTION_ID = "subscription_id";
 
@@ -52,6 +64,8 @@
     private SubscriptionManager mSubscriptionManager;
     private int mSubId;
     private EditText mNameView;
+    private Spinner mColorSpinner;
+    private Color[] mColors;
 
     public static RenameMobileNetworkDialogFragment newInstance(int subscriptionId) {
         final Bundle args = new Bundle(1);
@@ -76,6 +90,11 @@
         return mNameView;
     }
 
+    @VisibleForTesting
+    protected Spinner getColorSpinnerView() {
+        return mColorSpinner;
+    }
+
     @Override
     public void onAttach(Context context) {
         super.onAttach(context);
@@ -87,6 +106,8 @@
     @NonNull
     @Override
     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
+        mColors = getColors();
+
         final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
         final LayoutInflater layoutInflater = builder.getContext().getSystemService(
                 LayoutInflater.class);
@@ -95,9 +116,11 @@
         builder.setTitle(R.string.mobile_network_sim_name)
                 .setView(view)
                 .setPositiveButton(R.string.mobile_network_sim_name_rename, (dialog, which) -> {
-                    String newName = mNameView.getText().toString();
-                    mSubscriptionManager.setDisplayName(newName, mSubId,
+                    mSubscriptionManager.setDisplayName(mNameView.getText().toString(), mSubId,
                             SubscriptionManager.NAME_SOURCE_USER_INPUT);
+                    mSubscriptionManager.setIconTint(
+                            mColors[mColorSpinner.getSelectedItemPosition()].getColor(),
+                            mSubId);
                 })
                 .setNegativeButton(android.R.string.cancel, null);
         return builder.create();
@@ -105,7 +128,7 @@
 
     @VisibleForTesting
     protected void populateView(View view) {
-        mNameView = view.findViewById(R.id.edittext);
+        mNameView = view.findViewById(R.id.name_edittext);
         final SubscriptionInfo info = mSubscriptionManager.getActiveSubscriptionInfo(mSubId);
         if (info == null) {
             Log.w(TAG, "got null SubscriptionInfo for mSubId:" + mSubId);
@@ -117,6 +140,17 @@
             mNameView.setSelection(displayName.length());
         }
 
+        mColorSpinner = view.findViewById(R.id.color_spinner);
+        final ColorAdapter adapter = new ColorAdapter(getContext(),
+                R.layout.dialog_mobile_network_color_picker_item, mColors);
+        mColorSpinner.setAdapter(adapter);
+        for (int i = 0; i < mColors.length; i++) {
+            if (mColors[i].getColor() == info.getIconTint()) {
+                mColorSpinner.setSelection(i);
+                break;
+            }
+        }
+
         final TextView operatorName = view.findViewById(R.id.operator_name_value);
         final ServiceState serviceState = mTelephonyManager.getServiceStateForSubscriber(mSubId);
         operatorName.setText(serviceState.getOperatorAlphaLong());
@@ -134,4 +168,80 @@
     public int getMetricsCategory() {
         return SettingsEnums.MOBILE_NETWORK_RENAME_DIALOG;
     }
+
+    private class ColorAdapter extends ArrayAdapter<Color> {
+
+        private Context mContext;
+        private int mItemResId;
+
+        public ColorAdapter(Context context, int resource, Color[] colors) {
+            super(context, resource, colors);
+            mContext = context;
+            mItemResId = resource;
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            final LayoutInflater inflater = (LayoutInflater)
+                    mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+            if (convertView == null) {
+                convertView = inflater.inflate(mItemResId, null);
+            }
+            ((ImageView) convertView.findViewById(R.id.color_icon))
+                    .setImageDrawable(getItem(position).getDrawable());
+            ((TextView) convertView.findViewById(R.id.color_label))
+                    .setText(getItem(position).getLabel());
+
+            return convertView;
+        }
+
+        @Override
+        public View getDropDownView(int position, View convertView, ViewGroup parent) {
+            return getView(position, convertView, parent);
+        }
+    }
+
+    private Color[] getColors() {
+        final Resources res = getContext().getResources();
+        final int[] colorInts = res.getIntArray(com.android.internal.R.array.sim_colors);
+        final String[] colorStrings = res.getStringArray(R.array.color_picker);
+        final int iconSize = res.getDimensionPixelSize(R.dimen.color_swatch_size);
+        final int strokeWidth = res.getDimensionPixelSize(R.dimen.color_swatch_stroke_width);
+        final Color[] colors = new Color[colorInts.length];
+        for (int i = 0; i < colors.length; i++) {
+            colors[i] = new Color(colorStrings[i], colorInts[i], iconSize, strokeWidth);
+        }
+        return colors;
+    }
+
+    private static class Color {
+
+        private String mLabel;
+        private int mColor;
+        private ShapeDrawable mDrawable;
+
+        private Color(String label, int color, int iconSize, int strokeWidth) {
+            mLabel = label;
+            mColor = color;
+            mDrawable = new ShapeDrawable(new OvalShape());
+            mDrawable.setIntrinsicHeight(iconSize);
+            mDrawable.setIntrinsicWidth(iconSize);
+            mDrawable.getPaint().setStrokeWidth(strokeWidth);
+            mDrawable.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
+            mDrawable.getPaint().setColor(color);
+        }
+
+        private String getLabel() {
+            return mLabel;
+        }
+
+        private int getColor() {
+            return mColor;
+        }
+
+        private ShapeDrawable getDrawable() {
+            return mDrawable;
+        }
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
index 5b008be..53b4f00 100644
--- a/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/network/telephony/RenameMobileNetworkDialogFragmentTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.Mockito.when;
 
 import android.content.DialogInterface;
+import android.graphics.Color;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
@@ -38,6 +39,7 @@
 import android.view.View;
 import android.widget.Button;
 import android.widget.EditText;
+import android.widget.Spinner;
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.FragmentActivity;
@@ -58,6 +60,7 @@
 @RunWith(RobolectricTestRunner.class)
 @Config(shadows = ShadowAlertDialogCompat.class)
 public class RenameMobileNetworkDialogFragmentTest {
+
     @Mock
     private TelephonyManager mTelephonyMgr;
     @Mock
@@ -95,7 +98,7 @@
     }
 
     @Test
-    public void dialog_cancelButtonClicked_setDisplayNameNotCalled() {
+    public void dialog_cancelButtonClicked_setDisplayNameAndIconTintNotCalled() {
         when(mSubscriptionMgr.getActiveSubscriptionInfo(mSubscriptionId)).thenReturn(
                 mSubscriptionInfo);
         final AlertDialog dialog = startDialog();
@@ -106,10 +109,11 @@
         negativeButton.performClick();
 
         verify(mSubscriptionMgr, never()).setDisplayName(anyString(), anyInt(), anyInt());
+        verify(mSubscriptionMgr, never()).setIconTint(anyInt(), anyInt());
     }
 
     @Test
-    public void dialog_renameButtonClicked_setDisplayNameCalled() {
+    public void dialog_saveButtonClicked_setDisplayNameAndIconTint() {
         when(mSubscriptionMgr.getActiveSubscriptionInfo(mSubscriptionId)).thenReturn(
                 mSubscriptionInfo);
 
@@ -117,6 +121,9 @@
         final EditText nameView = mFragment.getNameView();
         nameView.setText("test2");
 
+        final Spinner colorSpinnerView = mFragment.getColorSpinnerView();
+        colorSpinnerView.setSelection(0);
+
         final Button positiveButton = dialog.getButton(DialogInterface.BUTTON_POSITIVE);
         positiveButton.performClick();
 
@@ -124,6 +131,8 @@
         verify(mSubscriptionMgr).setDisplayName(captor.capture(), eq(mSubscriptionId),
                 eq(SubscriptionManager.NAME_SOURCE_USER_INPUT));
         assertThat(captor.getValue()).isEqualTo("test2");
+        verify(mSubscriptionMgr)
+                .setIconTint(eq(Color.parseColor("#ff00796b" /* teal */)), eq(mSubscriptionId));
     }
 
     @Test
@@ -140,7 +149,9 @@
         assertThat(view.findViewById(R.id.number_label).getVisibility()).isEqualTo(View.GONE);
     }
 
-    /** Helper method to start the dialog */
+    /**
+     * Helper method to start the dialog
+     */
     private AlertDialog startDialog() {
         mFragment.show(mActivity.getSupportFragmentManager(), null);
         return ShadowAlertDialogCompat.getLatestAlertDialog();