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
This commit is contained in:
@@ -14,9 +14,9 @@
|
||||
~ limitations under the License
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
<com.android.systemui.qs.QSCarrier
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/linear_footer_carrier"
|
||||
android:id="@+id/linear_carrier"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
@@ -35,7 +35,7 @@
|
||||
android:layout_marginEnd="8dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<view class="com.android.systemui.qs.QSFooterImpl$QSCarrierText"
|
||||
<view class="com.android.systemui.qs.QSCarrier$QSCarrierText"
|
||||
android:id="@+id/qs_carrier_text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -46,4 +46,4 @@
|
||||
android:textDirection="locale"
|
||||
android:singleLine="true" />
|
||||
|
||||
</LinearLayout>
|
||||
</com.android.systemui.qs.QSCarrier>
|
||||
60
packages/SystemUI/res/layout/qs_carrier_group.xml
Normal file
60
packages/SystemUI/res/layout/qs_carrier_group.xml
Normal file
@@ -0,0 +1,60 @@
|
||||
<!--
|
||||
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
|
||||
-->
|
||||
|
||||
<!-- Extends LinearLayout -->
|
||||
<com.android.systemui.qs.QSCarrierGroup
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/qs_mobile"
|
||||
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">
|
||||
|
||||
<include
|
||||
layout="@layout/qs_carrier"
|
||||
android:id="@+id/carrier1" />
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_carrier_divider1"
|
||||
android:layout_width="2dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:background="?android:attr/dividerVertical"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/qs_carrier"
|
||||
android:id="@+id/carrier2"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_carrier_divider2"
|
||||
android:layout_width="2dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:background="?android:attr/dividerVertical"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/qs_carrier"
|
||||
android:id="@+id/carrier3"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</com.android.systemui.qs.QSCarrierGroup>
|
||||
@@ -41,34 +41,8 @@
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/qs_mobile"
|
||||
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">
|
||||
|
||||
<include
|
||||
layout="@layout/qs_footer_carrier"
|
||||
android:id="@+id/carrier1" />
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_carrier_divider"
|
||||
android:layout_width="2dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:background="?android:attr/dividerVertical"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/qs_footer_carrier"
|
||||
android:id="@+id/carrier2"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
<include layout="@layout/qs_carrier_group"
|
||||
android:id="@+id/carrier_group"/>
|
||||
|
||||
<com.android.systemui.qs.PageIndicator
|
||||
android:id="@+id/footer_page_indicator"
|
||||
|
||||
140
packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
Normal file
140
packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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 android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.graph.SignalDrawable;
|
||||
import com.android.systemui.R;
|
||||
|
||||
public class QSCarrier extends LinearLayout {
|
||||
|
||||
private View mMobileGroup;
|
||||
private TextView mCarrierText;
|
||||
private ImageView mMobileSignal;
|
||||
private ImageView mMobileRoaming;
|
||||
private ColorStateList mColorForegroundStateList;
|
||||
private float mColorForegroundIntensity;
|
||||
|
||||
public QSCarrier(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public QSCarrier(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public QSCarrier(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public QSCarrier(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
mMobileGroup = findViewById(R.id.mobile_combo);
|
||||
mMobileSignal = findViewById(R.id.mobile_signal);
|
||||
mMobileRoaming = findViewById(R.id.mobile_roaming);
|
||||
mCarrierText = findViewById(R.id.qs_carrier_text);
|
||||
|
||||
int colorForeground = Utils.getColorAttrDefaultColor(mContext,
|
||||
android.R.attr.colorForeground);
|
||||
mColorForegroundStateList = ColorStateList.valueOf(colorForeground);
|
||||
mColorForegroundIntensity = QuickStatusBarHeader.getColorIntensity(colorForeground);
|
||||
|
||||
}
|
||||
|
||||
public void updateState(QSCarrierGroup.CellSignalState state) {
|
||||
mMobileGroup.setVisibility(state.visible ? View.VISIBLE : View.GONE);
|
||||
if (state.visible) {
|
||||
mMobileRoaming.setVisibility(state.roaming ? View.VISIBLE : View.GONE);
|
||||
mMobileRoaming.setImageTintList(mColorForegroundStateList);
|
||||
SignalDrawable d = new SignalDrawable(mContext);
|
||||
d.setDarkIntensity(mColorForegroundIntensity);
|
||||
mMobileSignal.setImageDrawable(d);
|
||||
mMobileSignal.setImageLevel(state.mobileSignalIconId);
|
||||
|
||||
StringBuilder contentDescription = new StringBuilder();
|
||||
if (state.contentDescription != null) {
|
||||
contentDescription.append(state.contentDescription).append(", ");
|
||||
}
|
||||
if (state.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(state.typeContentDescription,
|
||||
mContext.getString(R.string.data_connection_no_internet))
|
||||
|| TextUtils.equals(state.typeContentDescription,
|
||||
mContext.getString(R.string.cell_data_off_content_description))) {
|
||||
contentDescription.append(state.typeContentDescription);
|
||||
}
|
||||
mMobileSignal.setContentDescription(contentDescription);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCarrierText(CharSequence text) {
|
||||
mCarrierText.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* 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 com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
|
||||
|
||||
import android.content.Context;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.keyguard.CarrierTextController;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* Displays Carrier name and network status in QS
|
||||
*/
|
||||
public class QSCarrierGroup extends LinearLayout implements
|
||||
CarrierTextController.CarrierTextCallback,
|
||||
NetworkController.SignalCallback {
|
||||
|
||||
private static final String TAG = "QSCarrierGroup";
|
||||
/**
|
||||
* Support up to 3 slots which is what's supported by {@link TelephonyManager#getPhoneCount}
|
||||
*/
|
||||
private static final int SIM_SLOTS = 3;
|
||||
private final NetworkController mNetworkController;
|
||||
|
||||
private View[] mCarrierDividers = new View[SIM_SLOTS - 1];
|
||||
private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS];
|
||||
private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS];
|
||||
private CarrierTextController mCarrierTextController;
|
||||
|
||||
private boolean mListening;
|
||||
|
||||
@Inject
|
||||
public QSCarrierGroup(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
|
||||
NetworkController networkController) {
|
||||
super(context, attrs);
|
||||
mNetworkController = networkController;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public QSCarrierGroup(Context context, AttributeSet attrs) {
|
||||
this(context, attrs,
|
||||
Dependency.get(NetworkController.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
mCarrierGroups[0] = findViewById(R.id.carrier1);
|
||||
mCarrierGroups[1] = findViewById(R.id.carrier2);
|
||||
mCarrierGroups[2] = findViewById(R.id.carrier3);
|
||||
|
||||
mCarrierDividers[0] = findViewById(R.id.qs_carrier_divider1);
|
||||
mCarrierDividers[1] = findViewById(R.id.qs_carrier_divider2);
|
||||
|
||||
for (int i = 0; i < SIM_SLOTS; i++) {
|
||||
mInfos[i] = new CellSignalState();
|
||||
}
|
||||
|
||||
CharSequence separator = mContext.getString(
|
||||
com.android.internal.R.string.kg_text_message_separator);
|
||||
mCarrierTextController = new CarrierTextController(mContext, separator, false, false);
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
}
|
||||
|
||||
public void setListening(boolean listening) {
|
||||
if (listening == mListening) {
|
||||
return;
|
||||
}
|
||||
mListening = listening;
|
||||
updateListeners();
|
||||
}
|
||||
|
||||
@Override
|
||||
@VisibleForTesting
|
||||
public void onDetachedFromWindow() {
|
||||
setListening(false);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
private void updateListeners() {
|
||||
if (mListening) {
|
||||
if (mNetworkController.hasVoiceCallingFeature()) {
|
||||
mNetworkController.addCallback(this);
|
||||
}
|
||||
mCarrierTextController.setListening(this);
|
||||
} else {
|
||||
mNetworkController.removeCallback(this);
|
||||
mCarrierTextController.setListening(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleUpdateState() {
|
||||
for (int i = 0; i < SIM_SLOTS; i++) {
|
||||
mCarrierGroups[i].updateState(mInfos[i]);
|
||||
}
|
||||
mCarrierDividers[0].setVisibility(
|
||||
mInfos[0].visible && mInfos[1].visible ? View.VISIBLE : View.GONE);
|
||||
// This tackles the case of slots 2 being available as well as at least one other.
|
||||
// In that case we show the second divider. Note that if both dividers are visible, it means
|
||||
// all three slots are in use, and that is correct.
|
||||
mCarrierDividers[1].setVisibility(
|
||||
(mInfos[1].visible && mInfos[2].visible)
|
||||
|| (mInfos[0].visible && mInfos[2].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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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<Integer>() {
|
||||
@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<Integer>() {
|
||||
@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);
|
||||
}
|
||||
}
|
||||
@@ -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<Integer>() {
|
||||
@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<Integer>() {
|
||||
@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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user