From a48d2d09d5ba7fe6a76b07c986ada781cbc9358d Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Wed, 27 Feb 2019 11:36:02 -0500 Subject: [PATCH 1/2] Extracts carrier information from QSFooterImpl QSCarrierGroup performs the same logic and visuals that were inside QSFooterImpl Extracted to QSCarrier Supports up to 3 sims Test: atest QSFooterImpl Test: atest QSCarrierGroup Test: manual Change-Id: I44e6f917e176af7f305a1de235e1a5be52da579c --- .../{qs_footer_carrier.xml => qs_carrier.xml} | 8 +- .../SystemUI/res/layout/qs_carrier_group.xml | 60 +++++ .../SystemUI/res/layout/qs_footer_impl.xml | 30 +-- .../com/android/systemui/qs/QSCarrier.java | 140 +++++++++++ .../android/systemui/qs/QSCarrierGroup.java | 223 +++++++++++++++++ .../com/android/systemui/qs/QSFooterImpl.java | 230 +----------------- .../util/InjectionInflationController.java | 6 + .../systemui/qs/QSCarrierGroupTest.java | 177 ++++++++++++++ .../android/systemui/qs/QSFooterImplTest.java | 121 --------- 9 files changed, 617 insertions(+), 378 deletions(-) rename packages/SystemUI/res/layout/{qs_footer_carrier.xml => qs_carrier.xml} (90%) create mode 100644 packages/SystemUI/res/layout/qs_carrier_group.xml create mode 100644 packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java create mode 100644 packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java create mode 100644 packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java diff --git a/packages/SystemUI/res/layout/qs_footer_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml similarity index 90% rename from packages/SystemUI/res/layout/qs_footer_carrier.xml rename to packages/SystemUI/res/layout/qs_carrier.xml index bd492b022e367..089a7e701e31a 100644 --- a/packages/SystemUI/res/layout/qs_footer_carrier.xml +++ b/packages/SystemUI/res/layout/qs_carrier.xml @@ -14,9 +14,9 @@ ~ limitations under the License --> - - - \ No newline at end of file + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/qs_carrier_group.xml new file mode 100644 index 0000000000000..13035620bc7f7 --- /dev/null +++ b/packages/SystemUI/res/layout/qs_carrier_group.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index 67e31ac7f9dab..fb2a343c4937b 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -41,34 +41,8 @@ android:layout_gravity="center_vertical" android:gravity="end" > - - - - - - - - - + = SIM_SLOTS) { + Log.w(TAG, "updateInfoCarrier - slot: " + slot); + continue; + } + if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + Log.e(TAG, + "Invalid SIM slot index for subscription: " + + info.subscriptionIds[i]); + continue; + } + mInfos[slot].visible = true; + slotSeen[slot] = true; + mCarrierGroups[slot].setCarrierText(info.listOfCarriers[i].toString().trim()); + mCarrierGroups[slot].setVisibility(View.VISIBLE); + } + for (int i = 0; i < SIM_SLOTS; i++) { + if (!slotSeen[i]) { + mInfos[i].visible = false; + mCarrierGroups[i].setVisibility(View.GONE); + } + } + } else { + Log.e(TAG, "Carrier information arrays not of same length"); + } + } else { + mInfos[0].visible = false; + mCarrierGroups[0].setCarrierText(info.carrierText); + mCarrierGroups[0].setVisibility(View.VISIBLE); + for (int i = 1; i < SIM_SLOTS; i++) { + mInfos[i].visible = false; + mCarrierGroups[i].setCarrierText(""); + mCarrierGroups[i].setVisibility(View.GONE); + } + } + handleUpdateState(); + } + + @Override + public void setMobileDataIndicators(NetworkController.IconState statusIcon, + NetworkController.IconState qsIcon, int statusType, + int qsType, boolean activityIn, boolean activityOut, + String typeContentDescription, + String description, boolean isWide, int subId, boolean roaming) { + int slotIndex = getSlotIndex(subId); + if (slotIndex >= SIM_SLOTS) { + Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex); + return; + } + if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { + Log.e(TAG, "Invalid SIM slot index for subscription: " + subId); + return; + } + mInfos[slotIndex].visible = statusIcon.visible; + mInfos[slotIndex].mobileSignalIconId = statusIcon.icon; + mInfos[slotIndex].contentDescription = statusIcon.contentDescription; + mInfos[slotIndex].typeContentDescription = typeContentDescription; + mInfos[slotIndex].roaming = roaming; + handleUpdateState(); + } + + @Override + public void setNoSims(boolean hasNoSims, boolean simDetected) { + if (hasNoSims) { + for (int i = 0; i < SIM_SLOTS; i++) { + mInfos[i].visible = false; + } + } + handleUpdateState(); + } + + static final class CellSignalState { + boolean visible; + int mobileSignalIconId; + String contentDescription; + String typeContentDescription; + boolean roaming; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java index bbd8de333d793..dcb33e4a5c336 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java @@ -23,25 +23,19 @@ import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEX import android.content.Context; import android.content.Intent; import android.content.pm.UserInfo; -import android.content.res.ColorStateList; import android.content.res.Configuration; import android.graphics.PorterDuff.Mode; import android.graphics.drawable.Drawable; import android.graphics.drawable.RippleDrawable; import android.os.Bundle; import android.os.UserManager; -import android.telephony.SubscriptionManager; -import android.text.TextUtils; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.View.OnClickListener; -import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; @@ -49,11 +43,9 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto; -import com.android.keyguard.CarrierTextController; import com.android.keyguard.KeyguardUpdateMonitor; import com.android.settingslib.Utils; import com.android.settingslib.drawable.UserIconDrawable; -import com.android.settingslib.graph.SignalDrawable; import com.android.systemui.Dependency; import com.android.systemui.R; import com.android.systemui.R.dimen; @@ -62,9 +54,6 @@ import com.android.systemui.qs.TouchAnimator.Builder; import com.android.systemui.statusbar.phone.MultiUserSwitch; import com.android.systemui.statusbar.phone.SettingsButton; import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.systemui.statusbar.policy.NetworkController; -import com.android.systemui.statusbar.policy.NetworkController.EmergencyListener; -import com.android.systemui.statusbar.policy.NetworkController.SignalCallback; import com.android.systemui.statusbar.policy.UserInfoController; import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener; import com.android.systemui.tuner.TunerService; @@ -73,15 +62,12 @@ import javax.inject.Inject; import javax.inject.Named; public class QSFooterImpl extends FrameLayout implements QSFooter, - OnClickListener, OnUserInfoChangedListener, EmergencyListener, SignalCallback, - CarrierTextController.CarrierTextCallback { + OnClickListener, OnUserInfoChangedListener { - private static final int SIM_SLOTS = 2; private static final String TAG = "QSFooterImpl"; private final ActivityStarter mActivityStarter; private final UserInfoController mUserInfoController; - private final NetworkController mNetworkController; private final DeviceProvisionedController mDeviceProvisionedController; private SettingsButton mSettingsButton; protected View mSettingsContainer; @@ -94,7 +80,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private boolean mListening; - private boolean mShowEmergencyCallsOnly; + private QSCarrierGroup mCarrierGroup; private View mDivider; protected MultiUserSwitch mMultiUserSwitch; private ImageView mMultiUserAvatar; @@ -108,30 +94,15 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private View mActionsContainer; private View mDragHandle; - private View mCarrierDivider; - private ViewGroup mMobileFooter; - private View[] mMobileGroups = new View[SIM_SLOTS]; - private ViewGroup[] mCarrierGroups = new ViewGroup[SIM_SLOTS]; - private TextView[] mCarrierTexts = new TextView[SIM_SLOTS]; - private ImageView[] mMobileSignals = new ImageView[SIM_SLOTS]; - private ImageView[] mMobileRoamings = new ImageView[SIM_SLOTS]; - private final CellSignalState[] mInfos = - new CellSignalState[]{new CellSignalState(), new CellSignalState()}; - - private final int mColorForeground; private OnClickListener mExpandClickListener; - private CarrierTextController mCarrierTextController; @Inject public QSFooterImpl(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs, ActivityStarter activityStarter, UserInfoController userInfoController, - NetworkController networkController, DeviceProvisionedController deviceProvisionedController) { super(context, attrs); - mColorForeground = Utils.getColorAttrDefaultColor(context, android.R.attr.colorForeground); mActivityStarter = activityStarter; mUserInfoController = userInfoController; - mNetworkController = networkController; mDeviceProvisionedController = deviceProvisionedController; } @@ -140,7 +111,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, this(context, attrs, Dependency.get(ActivityStarter.class), Dependency.get(UserInfoController.class), - Dependency.get(NetworkController.class), Dependency.get(DeviceProvisionedController.class)); } @@ -159,20 +129,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, mSettingsContainer = findViewById(R.id.settings_button_container); mSettingsButton.setOnClickListener(this); - mMobileFooter = findViewById(R.id.qs_mobile); - mCarrierGroups[0] = findViewById(R.id.carrier1); - mCarrierGroups[1] = findViewById(R.id.carrier2); - - for (int i = 0; i < SIM_SLOTS; i++) { - mMobileGroups[i] = mCarrierGroups[i].findViewById(R.id.mobile_combo); - mMobileSignals[i] = mCarrierGroups[i].findViewById(R.id.mobile_signal); - mMobileRoamings[i] = mCarrierGroups[i].findViewById(R.id.mobile_roaming); - mCarrierTexts[i] = mCarrierGroups[i].findViewById(R.id.qs_carrier_text); - } - mCarrierDivider = findViewById(R.id.qs_carrier_divider); - CharSequence separator = mContext.getString( - com.android.internal.R.string.kg_text_message_separator); - mCarrierTextController = new CarrierTextController(mContext, separator, false, false); + mCarrierGroup = findViewById(R.id.carrier_group); mMultiUserSwitch = findViewById(R.id.multi_user_switch); mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar); @@ -240,8 +197,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private TouchAnimator createFooterAnimator() { return new TouchAnimator.Builder() .addFloat(mDivider, "alpha", 0, 1) - .addFloat(mMobileFooter, "alpha", 0, 0, 1) - .addFloat(mCarrierDivider, "alpha", 0, 1) + .addFloat(mCarrierGroup, "alpha", 0, 0, 1) .addFloat(mActionsContainer, "alpha", 0, 1) .addFloat(mDragHandle, "alpha", 1, 0, 0) .addFloat(mPageIndicator, "alpha", 0, 1) @@ -364,17 +320,10 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, private void updateListeners() { if (mListening) { mUserInfoController.addCallback(this); - if (mNetworkController.hasVoiceCallingFeature()) { - mNetworkController.addEmergencyListener(this); - mNetworkController.addCallback(this); - } - mCarrierTextController.setListening(this); } else { mUserInfoController.removeCallback(this); - mNetworkController.removeEmergencyListener(this); - mNetworkController.removeCallback(this); - mCarrierTextController.setListening(null); } + mCarrierGroup.setListening(mListening); } @Override @@ -429,17 +378,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, true /* dismissShade */); } - @Override - public void setEmergencyCallsOnly(boolean show) { - boolean changed = show != mShowEmergencyCallsOnly; - if (changed) { - mShowEmergencyCallsOnly = show; - if (mExpanded) { - updateEverything(); - } - } - } - @Override public void onUserInfoChanged(String name, Drawable picture, String userAccount) { if (picture != null && @@ -452,162 +390,4 @@ public class QSFooterImpl extends FrameLayout implements QSFooter, } mMultiUserAvatar.setImageDrawable(picture); } - - private void handleUpdateState() { - for (int i = 0; i < SIM_SLOTS; i++) { - mMobileGroups[i].setVisibility(mInfos[i].visible ? View.VISIBLE : View.GONE); - if (mInfos[i].visible) { - mMobileRoamings[i].setVisibility(mInfos[i].roaming ? View.VISIBLE : View.GONE); - mMobileRoamings[i].setImageTintList(ColorStateList.valueOf(mColorForeground)); - SignalDrawable d = new SignalDrawable(mContext); - d.setDarkIntensity(QuickStatusBarHeader.getColorIntensity(mColorForeground)); - mMobileSignals[i].setImageDrawable(d); - mMobileSignals[i].setImageLevel(mInfos[i].mobileSignalIconId); - - StringBuilder contentDescription = new StringBuilder(); - if (mInfos[i].contentDescription != null) { - contentDescription.append(mInfos[i].contentDescription).append(", "); - } - if (mInfos[i].roaming) { - contentDescription - .append(mContext.getString(R.string.data_connection_roaming)) - .append(", "); - } - // TODO: show mobile data off/no internet text for 5 seconds before carrier text - if (TextUtils.equals(mInfos[i].typeContentDescription, - mContext.getString(R.string.data_connection_no_internet)) - || TextUtils.equals(mInfos[i].typeContentDescription, - mContext.getString(R.string.cell_data_off_content_description))) { - contentDescription.append(mInfos[i].typeContentDescription); - } - mMobileSignals[i].setContentDescription(contentDescription); - } - } - mCarrierDivider.setVisibility( - mInfos[0].visible && mInfos[1].visible ? View.VISIBLE : View.GONE); - } - - @VisibleForTesting - protected int getSlotIndex(int subscriptionId) { - return SubscriptionManager.getSlotIndex(subscriptionId); - } - - @Override - public void updateCarrierInfo(CarrierTextController.CarrierTextCallbackInfo info) { - if (info.anySimReady) { - boolean[] slotSeen = new boolean[SIM_SLOTS]; - if (info.listOfCarriers.length == info.subscriptionIds.length) { - for (int i = 0; i < SIM_SLOTS && i < info.listOfCarriers.length; i++) { - int slot = getSlotIndex(info.subscriptionIds[i]); - if (slot >= SIM_SLOTS) { - Log.w(TAG, "updateInfoCarrier - slot: " + slot); - continue; - } - if (slot == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { - Log.e(TAG, - "Invalid SIM slot index for subscription: " - + info.subscriptionIds[i]); - continue; - } - mInfos[slot].visible = true; - slotSeen[slot] = true; - mCarrierTexts[slot].setText(info.listOfCarriers[i].toString().trim()); - mCarrierGroups[slot].setVisibility(View.VISIBLE); - } - for (int i = 0; i < SIM_SLOTS; i++) { - if (!slotSeen[i]) { - mInfos[i].visible = false; - mCarrierGroups[i].setVisibility(View.GONE); - } - } - } else { - Log.e(TAG, "Carrier information arrays not of same length"); - } - } else { - mInfos[0].visible = false; - mCarrierTexts[0].setText(info.carrierText); - mCarrierGroups[0].setVisibility(View.VISIBLE); - for (int i = 1; i < SIM_SLOTS; i++) { - mInfos[i].visible = false; - mCarrierTexts[i].setText(""); - mCarrierGroups[i].setVisibility(View.GONE); - } - } - handleUpdateState(); - } - - @Override - public void setMobileDataIndicators(NetworkController.IconState statusIcon, - NetworkController.IconState qsIcon, int statusType, - int qsType, boolean activityIn, boolean activityOut, - String typeContentDescription, - String description, boolean isWide, int subId, boolean roaming) { - int slotIndex = getSlotIndex(subId); - if (slotIndex >= SIM_SLOTS) { - Log.w(TAG, "setMobileDataIndicators - slot: " + slotIndex); - return; - } - if (slotIndex == SubscriptionManager.INVALID_SIM_SLOT_INDEX) { - Log.e(TAG, "Invalid SIM slot index for subscription: " + subId); - return; - } - mInfos[slotIndex].visible = statusIcon.visible; - mInfos[slotIndex].mobileSignalIconId = statusIcon.icon; - mInfos[slotIndex].contentDescription = statusIcon.contentDescription; - mInfos[slotIndex].typeContentDescription = typeContentDescription; - mInfos[slotIndex].roaming = roaming; - handleUpdateState(); - } - - @Override - public void setNoSims(boolean hasNoSims, boolean simDetected) { - if (hasNoSims) { - mInfos[0].visible = false; - mInfos[1].visible = false; - } - handleUpdateState(); - } - - private final class CellSignalState { - boolean visible; - int mobileSignalIconId; - public String contentDescription; - String typeContentDescription; - boolean roaming; - } - - /** - * TextView that changes its ellipsize value with its visibility. - */ - public static class QSCarrierText extends TextView { - public QSCarrierText(Context context) { - super(context); - } - - public QSCarrierText(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public QSCarrierText(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } - - public QSCarrierText(Context context, AttributeSet attrs, int defStyleAttr, - int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - } - - @Override - protected void onVisibilityChanged(View changedView, int visibility) { - super.onVisibilityChanged(changedView, visibility); - // Only show marquee when visible - if (visibility == VISIBLE) { - setEllipsize(TextUtils.TruncateAt.MARQUEE); - setSelected(true); - } else { - setEllipsize(TextUtils.TruncateAt.END); - setSelected(false); - } - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java index c6636b480bfac..e6b6672d35448 100644 --- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java +++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java @@ -24,6 +24,7 @@ import android.view.LayoutInflater; import android.view.View; import com.android.systemui.SystemUIFactory; +import com.android.systemui.qs.QSCarrierGroup; import com.android.systemui.qs.QSFooterImpl; import com.android.systemui.qs.QuickStatusBarHeader; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; @@ -124,6 +125,11 @@ public class InjectionInflationController { * Creates the NotificationPanelView. */ NotificationPanelView createPanelView(); + + /** + * Creates the QSCarrierGroup + */ + QSCarrierGroup createQSCarrierGroup(); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java new file mode 100644 index 0000000000000..f29392b2c5d6b --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSCarrierGroupTest.java @@ -0,0 +1,177 @@ +/* + * 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. + */ + +package com.android.systemui.qs; + +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import android.telephony.SubscriptionManager; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.view.LayoutInflater; + +import androidx.test.filters.SmallTest; + +import com.android.keyguard.CarrierTextController; +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.NetworkController; +import com.android.systemui.utils.leaks.LeakCheckedTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class QSCarrierGroupTest extends LeakCheckedTest { + + private QSCarrierGroup mCarrierGroup; + + @Before + public void setup() throws Exception { + injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES); + TestableLooper.get(this).runWithLooper( + () -> mCarrierGroup = (QSCarrierGroup) LayoutInflater.from(mContext).inflate( + R.layout.qs_carrier_group, null)); + } + + @Test // throws no Exception + public void testUpdateCarrierText_sameLengths() { + QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup); + when(spiedCarrierGroup.getSlotIndex(anyInt())).thenAnswer( + new Answer() { + @Override + public Integer answer(InvocationOnMock invocationOnMock) throws Throwable { + return invocationOnMock.getArgument(0); + } + }); + + // listOfCarriers length 1, subscriptionIds length 1, anySims false + CarrierTextController.CarrierTextCallbackInfo + c1 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{""}, + false, + new int[]{0}); + spiedCarrierGroup.updateCarrierInfo(c1); + + // listOfCarriers length 1, subscriptionIds length 1, anySims true + CarrierTextController.CarrierTextCallbackInfo + c2 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{""}, + true, + new int[]{0}); + spiedCarrierGroup.updateCarrierInfo(c2); + + // listOfCarriers length 2, subscriptionIds length 2, anySims false + CarrierTextController.CarrierTextCallbackInfo + c3 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{"", ""}, + false, + new int[]{0, 1}); + spiedCarrierGroup.updateCarrierInfo(c3); + + // listOfCarriers length 2, subscriptionIds length 2, anySims true + CarrierTextController.CarrierTextCallbackInfo + c4 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{"", ""}, + true, + new int[]{0, 1}); + spiedCarrierGroup.updateCarrierInfo(c4); + } + + @Test // throws no Exception + public void testUpdateCarrierText_differentLength() { + QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup); + when(spiedCarrierGroup.getSlotIndex(anyInt())).thenAnswer( + new Answer() { + @Override + public Integer answer(InvocationOnMock invocationOnMock) throws Throwable { + return invocationOnMock.getArgument(0); + } + }); + + // listOfCarriers length 2, subscriptionIds length 1, anySims false + CarrierTextController.CarrierTextCallbackInfo + c1 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{"", ""}, + false, + new int[]{0}); + spiedCarrierGroup.updateCarrierInfo(c1); + + // listOfCarriers length 2, subscriptionIds length 1, anySims true + CarrierTextController.CarrierTextCallbackInfo + c2 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{"", ""}, + true, + new int[]{0}); + spiedCarrierGroup.updateCarrierInfo(c2); + + // listOfCarriers length 1, subscriptionIds length 2, anySims false + CarrierTextController.CarrierTextCallbackInfo + c3 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{""}, + false, + new int[]{0, 1}); + spiedCarrierGroup.updateCarrierInfo(c3); + + // listOfCarriers length 1, subscriptionIds length 2, anySims true + CarrierTextController.CarrierTextCallbackInfo + c4 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{""}, + true, + new int[]{0, 1}); + spiedCarrierGroup.updateCarrierInfo(c4); + } + + @Test // throws no Exception + public void testUpdateCarrierText_invalidSim() { + QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup); + when(spiedCarrierGroup.getSlotIndex(anyInt())).thenReturn( + SubscriptionManager.INVALID_SIM_SLOT_INDEX); + CarrierTextController.CarrierTextCallbackInfo + c4 = new CarrierTextController.CarrierTextCallbackInfo( + "", + new CharSequence[]{"", ""}, + true, + new int[]{0, 1}); + spiedCarrierGroup.updateCarrierInfo(c4); + } + + @Test // throws no Exception + public void testSetMobileDataIndicators_invalidSim() { + QSCarrierGroup spiedCarrierGroup = Mockito.spy(mCarrierGroup); + when(spiedCarrierGroup.getSlotIndex(anyInt())).thenReturn( + SubscriptionManager.INVALID_SIM_SLOT_INDEX); + spiedCarrierGroup.setMobileDataIndicators( + mock(NetworkController.IconState.class), + mock(NetworkController.IconState.class), + 0, 0, true, true, "", "", true, 0, true); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java index a8b169cc63d2b..d4688d77a840e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterImplTest.java @@ -16,13 +16,10 @@ package com.android.systemui.qs; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import android.telephony.SubscriptionManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; @@ -31,21 +28,16 @@ import android.view.View; import androidx.test.filters.SmallTest; -import com.android.keyguard.CarrierTextController.CarrierTextCallbackInfo; import com.android.systemui.R; import com.android.systemui.R.id; import com.android.systemui.plugins.ActivityStarter; import com.android.systemui.statusbar.policy.DeviceProvisionedController; -import com.android.systemui.statusbar.policy.NetworkController; import com.android.systemui.utils.leaks.LeakCheckedTest; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mockito; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; @RunWith(AndroidTestingRunner.class) @RunWithLooper @@ -77,117 +69,4 @@ public class QSFooterImplTest extends LeakCheckedTest { // Verify Settings wasn't launched. verify(mActivityStarter, never()).startActivity(any(), anyBoolean()); } - - @Test // throws no Exception - public void testUpdateCarrierText_sameLengts() { - QSFooterImpl spiedFooter = Mockito.spy(mFooter); - when(spiedFooter.getSlotIndex(anyInt())).thenAnswer( - new Answer() { - @Override - public Integer answer(InvocationOnMock invocationOnMock) throws Throwable { - return invocationOnMock.getArgument(0); - } - }); - - // listOfCarriers length 1, subscriptionIds length 1, anySims false - CarrierTextCallbackInfo c1 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{""}, - false, - new int[]{0}); - spiedFooter.updateCarrierInfo(c1); - - // listOfCarriers length 1, subscriptionIds length 1, anySims true - CarrierTextCallbackInfo c2 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{""}, - true, - new int[]{0}); - spiedFooter.updateCarrierInfo(c2); - - // listOfCarriers length 2, subscriptionIds length 2, anySims false - CarrierTextCallbackInfo c3 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{"", ""}, - false, - new int[]{0, 1}); - spiedFooter.updateCarrierInfo(c3); - - // listOfCarriers length 2, subscriptionIds length 2, anySims true - CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{"", ""}, - true, - new int[]{0, 1}); - spiedFooter.updateCarrierInfo(c4); - } - - @Test // throws no Exception - public void testUpdateCarrierText_differentLength() { - QSFooterImpl spiedFooter = Mockito.spy(mFooter); - when(spiedFooter.getSlotIndex(anyInt())).thenAnswer( - new Answer() { - @Override - public Integer answer(InvocationOnMock invocationOnMock) throws Throwable { - return invocationOnMock.getArgument(0); - } - }); - - // listOfCarriers length 2, subscriptionIds length 1, anySims false - CarrierTextCallbackInfo c1 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{"", ""}, - false, - new int[]{0}); - spiedFooter.updateCarrierInfo(c1); - - // listOfCarriers length 2, subscriptionIds length 1, anySims true - CarrierTextCallbackInfo c2 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{"", ""}, - true, - new int[]{0}); - spiedFooter.updateCarrierInfo(c2); - - // listOfCarriers length 1, subscriptionIds length 2, anySims false - CarrierTextCallbackInfo c3 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{""}, - false, - new int[]{0, 1}); - spiedFooter.updateCarrierInfo(c3); - - // listOfCarriers length 1, subscriptionIds length 2, anySims true - CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{""}, - true, - new int[]{0, 1}); - spiedFooter.updateCarrierInfo(c4); - } - - @Test // throws no Exception - public void testUpdateCarrierText_invalidSim() { - QSFooterImpl spiedFooter = Mockito.spy(mFooter); - when(spiedFooter.getSlotIndex(anyInt())).thenReturn( - SubscriptionManager.INVALID_SIM_SLOT_INDEX); - CarrierTextCallbackInfo c4 = new CarrierTextCallbackInfo( - "", - new CharSequence[]{"", ""}, - true, - new int[]{0, 1}); - spiedFooter.updateCarrierInfo(c4); - } - - @Test // throws no Exception - public void testSetMobileDataIndicators_invalidSim() { - QSFooterImpl spiedFooter = Mockito.spy(mFooter); - when(spiedFooter.getSlotIndex(anyInt())).thenReturn( - SubscriptionManager.INVALID_SIM_SLOT_INDEX); - spiedFooter.setMobileDataIndicators( - mock(NetworkController.IconState.class), - mock(NetworkController.IconState.class), - 0, 0, true, true, "", "", true, 0, true); - } - } From 4e76d1f32beaa7f6b32a51b030c6b9575ae6d1f1 Mon Sep 17 00:00:00 2001 From: Fabian Kozynski Date: Mon, 25 Feb 2019 16:30:04 -0500 Subject: [PATCH 2/2] Change visuals for expanded QS * Moved status icons to the left * Moved carriers to top right of QS * Moved edit button to left of QSFooter * Moved PageIndicator to always be in Footer * Added build number to footer. Test: manual using landscape and RTL Bug: 124464727 Bug: 124466547 Bug: 126759381 Change-Id: I5e5b5bf559d75a8520e772e96b8c4e77ffb72d84 --- .../res/layout/mobile_signal_group.xml | 4 +- packages/SystemUI/res/layout/qs_carrier.xml | 17 ++-- .../SystemUI/res/layout/qs_carrier_group.xml | 22 ++--- .../SystemUI/res/layout/qs_footer_impl.xml | 62 +++++++----- packages/SystemUI/res/layout/qs_panel.xml | 2 +- .../res/layout/quick_settings_header_info.xml | 95 +++++++++++-------- .../SystemUI/res/values-land/integers.xml | 22 ----- packages/SystemUI/res/values/dimens.xml | 20 +++- packages/SystemUI/res/values/integers.xml | 4 +- packages/SystemUI/res/values/styles.xml | 2 + .../com/android/systemui/qs/QSAnimator.java | 3 - .../com/android/systemui/qs/QSCarrier.java | 3 +- .../android/systemui/qs/QSCarrierGroup.java | 1 + .../com/android/systemui/qs/QSFooterImpl.java | 60 +++++++++--- .../src/com/android/systemui/qs/QSPanel.java | 26 +---- .../systemui/qs/QuickStatusBarHeader.java | 3 + 16 files changed, 189 insertions(+), 157 deletions(-) delete mode 100644 packages/SystemUI/res/values-land/integers.xml diff --git a/packages/SystemUI/res/layout/mobile_signal_group.xml b/packages/SystemUI/res/layout/mobile_signal_group.xml index 5ecd380c69500..bfd079b59054a 100644 --- a/packages/SystemUI/res/layout/mobile_signal_group.xml +++ b/packages/SystemUI/res/layout/mobile_signal_group.xml @@ -65,8 +65,8 @@ android:layout_gravity="center_vertical"> + android:clipToPadding="false" > + android:singleLine="true" + android:maxEms="7"/> \ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_carrier_group.xml b/packages/SystemUI/res/layout/qs_carrier_group.xml index 13035620bc7f7..20190b7fff0d4 100644 --- a/packages/SystemUI/res/layout/qs_carrier_group.xml +++ b/packages/SystemUI/res/layout/qs_carrier_group.xml @@ -21,40 +21,38 @@ android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" - android:gravity="center_vertical|start" - android:orientation="horizontal" - android:layout_marginEnd="32dp"> + android:gravity="end|center_vertical" + android:orientation="horizontal"> + + android:id="@+id/carrier1" + android:layout_weight="1"/> \ No newline at end of file diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml index fb2a343c4937b..669d53bfdc60e 100644 --- a/packages/SystemUI/res/layout/qs_footer_impl.xml +++ b/packages/SystemUI/res/layout/qs_footer_impl.xml @@ -21,6 +21,8 @@ android:id="@+id/qs_footer" android:layout_width="match_parent" android:layout_height="@dimen/qs_footer_height" + android:layout_marginStart="@dimen/qs_footer_margin" + android:layout_marginEnd="@dimen/qs_footer_margin" android:elevation="4dp" android:background="@android:color/transparent" android:baselineAligned="false" @@ -41,8 +43,35 @@ android:layout_gravity="center_vertical" android:gravity="end" > - + + + + + @@ -70,26 +99,14 @@ android:layout_width="@dimen/multi_user_avatar_expanded_size" android:layout_height="@dimen/multi_user_avatar_expanded_size" android:layout_gravity="center" + android:tint="?android:attr/colorAccent" android:scaleType="centerInside"/> - - @@ -98,10 +115,12 @@ style="@android:style/Widget.Material.Button.Borderless" android:layout_width="match_parent" android:layout_height="match_parent" + android:layout_gravity="center" + android:padding="@dimen/qs_footer_icon_padding" android:background="@drawable/ripple_drawable" android:contentDescription="@string/accessibility_quick_settings_settings" - android:padding="15dp" - android:src="@drawable/ic_settings_16dp" + android:src="@drawable/ic_settings" + android:scaleType="centerInside" android:tint="?android:attr/colorForeground"/> - diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml index 967e13f05cfb4..075f51d2e17ac 100644 --- a/packages/SystemUI/res/layout/quick_settings_header_info.xml +++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml @@ -25,7 +25,7 @@ android:id="@+id/long_press_tooltip" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_gravity="center_horizontal|bottom" + android:layout_gravity="start|bottom" android:alpha="0" android:text="@string/quick_settings_header_onboarding_text" android:textAppearance="@style/TextAppearance.QS.TileLabel" @@ -33,54 +33,69 @@ android:visibility="invisible" /> + android:layout_gravity="start|bottom" + android:gravity="center_vertical"> - - - + android:layout_gravity="start|center_vertical" + android:layout_weight="1" + android:gravity="center_vertical" + android:alpha="0"> + + + + + + + + + + + - - - - + android:layout_weight="1"/> + diff --git a/packages/SystemUI/res/values-land/integers.xml b/packages/SystemUI/res/values-land/integers.xml deleted file mode 100644 index fb226659dae77..0000000000000 --- a/packages/SystemUI/res/values-land/integers.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - 0 - 1 - \ No newline at end of file diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index a40a14a477447..9a2eb940bbfea 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -274,7 +274,16 @@ - 56dp + 48dp + + + @dimen/qs_footer_height + + + 2dp + + + 14dp @dimen/notification_side_paddings @@ -415,11 +424,16 @@ 20dp 18dp 18dp + 18dp 6dp + 8dp + 6dp + 32dp + 4dp 16dp 16dp 16dp - 24dp + 16dp 64dp @@ -592,7 +606,7 @@ 22dp - 18dp + 20dp 14sp diff --git a/packages/SystemUI/res/values/integers.xml b/packages/SystemUI/res/values/integers.xml index e8fabf5a07f10..a6dae45f4b537 100644 --- a/packages/SystemUI/res/values/integers.xml +++ b/packages/SystemUI/res/values/integers.xml @@ -19,8 +19,8 @@ - -2 - 0 + 0 + 1