Merge changes I5e5b5bf5,I44e6f917
* changes: Change visuals for expanded QS Extracts carrier information from QSFooterImpl
This commit is contained in:
committed by
Android (Google) Code Review
commit
d4ad9313d1
@@ -65,8 +65,8 @@
|
||||
android:layout_gravity="center_vertical">
|
||||
<com.android.systemui.statusbar.AnimatedImageView
|
||||
android:id="@+id/mobile_signal"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/qs_header_mobile_icon_size"
|
||||
android:layout_width="@dimen/qs_header_mobile_icon_size"
|
||||
systemui:hasOverlappingRendering="false"
|
||||
/>
|
||||
<ImageView
|
||||
|
||||
@@ -14,36 +14,33 @@
|
||||
~ 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:layout_width="0dp"
|
||||
android:id="@+id/linear_carrier"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:background="@android:color/transparent"
|
||||
android:clickable="false"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:paddingStart="16dp" >
|
||||
android:clipToPadding="false" >
|
||||
|
||||
<include
|
||||
layout="@layout/mobile_signal_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginEnd="@dimen/qs_carrier_margin_width"
|
||||
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_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:textAppearance="@style/TextAppearance.QS.CarrierInfo"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textAppearance="@style/TextAppearance.QS.Status"
|
||||
android:textDirection="locale"
|
||||
android:singleLine="true" />
|
||||
android:singleLine="true"
|
||||
android:maxEms="7"/>
|
||||
|
||||
</LinearLayout>
|
||||
</com.android.systemui.qs.QSCarrier>
|
||||
58
packages/SystemUI/res/layout/qs_carrier_group.xml
Normal file
58
packages/SystemUI/res/layout/qs_carrier_group.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<!--
|
||||
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="end|center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<include
|
||||
layout="@layout/qs_carrier"
|
||||
android:id="@+id/carrier1"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_carrier_divider1"
|
||||
android:layout_width="@dimen/qs_header_carrier_separator_width"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/qs_carrier"
|
||||
android:id="@+id/carrier2"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_carrier_divider2"
|
||||
android:layout_width="@dimen/qs_header_carrier_separator_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
layout="@layout/qs_carrier"
|
||||
android:id="@+id/carrier3"
|
||||
android:layout_weight="1"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</com.android.systemui.qs.QSCarrierGroup>
|
||||
@@ -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,34 +43,35 @@
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="end" >
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/qs_mobile"
|
||||
android:layout_width="0dp"
|
||||
<com.android.keyguard.AlphaOptimizedLinearLayout
|
||||
android:id="@+id/qs_footer_actions_edit_container"
|
||||
android:layout_width="@integer/qs_footer_actions_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical|start"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginEnd="32dp">
|
||||
android:layout_weight="@integer/qs_footer_actions_weight"
|
||||
android:gravity="center_vertical|start" >
|
||||
<com.android.systemui.statusbar.AlphaOptimizedImageView
|
||||
android:id="@android:id/edit"
|
||||
android:layout_width="@dimen/qs_footer_action_button_size"
|
||||
android:layout_height="@dimen/qs_footer_action_button_size"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:clipToPadding="false"
|
||||
android:contentDescription="@string/accessibility_quick_settings_edit"
|
||||
android:focusable="true"
|
||||
android:padding="@dimen/qs_footer_icon_padding"
|
||||
android:src="@*android:drawable/ic_mode_edit"
|
||||
android:tint="?android:attr/colorForeground"/>
|
||||
|
||||
<include
|
||||
layout="@layout/qs_footer_carrier"
|
||||
android:id="@+id/carrier1" />
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_carrier_divider"
|
||||
android:layout_width="2dp"
|
||||
<TextView
|
||||
android:id="@+id/build"
|
||||
android:layout_width="wrap_content"
|
||||
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:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:focusable="true"
|
||||
android:textAppearance="@style/TextAppearance.QS.Status"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
</com.android.keyguard.AlphaOptimizedLinearLayout>
|
||||
|
||||
<com.android.systemui.qs.PageIndicator
|
||||
android:id="@+id/footer_page_indicator"
|
||||
@@ -85,8 +88,8 @@
|
||||
android:gravity="center_vertical|end" >
|
||||
<com.android.systemui.statusbar.phone.MultiUserSwitch
|
||||
android:id="@+id/multi_user_switch"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_width="@dimen/qs_footer_action_button_size"
|
||||
android:layout_height="@dimen/qs_footer_action_button_size"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:background="@drawable/ripple_drawable"
|
||||
android:focusable="true">
|
||||
@@ -96,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"/>
|
||||
</com.android.systemui.statusbar.phone.MultiUserSwitch>
|
||||
|
||||
<com.android.systemui.statusbar.AlphaOptimizedImageView
|
||||
android:id="@android:id/edit"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:clickable="true"
|
||||
android:clipToPadding="false"
|
||||
android:contentDescription="@string/accessibility_quick_settings_edit"
|
||||
android:focusable="true"
|
||||
android:padding="15dp"
|
||||
android:src="@*android:drawable/ic_mode_edit"
|
||||
android:tint="?android:attr/colorForeground"/>
|
||||
|
||||
<com.android.systemui.statusbar.AlphaOptimizedFrameLayout
|
||||
android:id="@+id/settings_button_container"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_width="@dimen/qs_footer_action_button_size"
|
||||
android:layout_height="@dimen/qs_footer_action_button_size"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
|
||||
@@ -124,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"/>
|
||||
|
||||
<com.android.systemui.statusbar.AlphaOptimizedImageView
|
||||
@@ -143,7 +136,6 @@
|
||||
</com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
|
||||
</com.android.keyguard.AlphaOptimizedLinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/qs_drag_handle_view"
|
||||
android:layout_width="24dp"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
android:elevation="4dp"
|
||||
android:background="@android:color/transparent"
|
||||
android:focusable="true"
|
||||
android:accessibilityTraversalBefore="@id/qs_carrier_text"
|
||||
android:accessibilityTraversalBefore="@android:id/edit"
|
||||
/>
|
||||
|
||||
<include layout="@layout/quick_status_bar_expanded_header" />
|
||||
|
||||
@@ -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" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/status_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
android:gravity="center_vertical"
|
||||
android:alpha="0">
|
||||
android:layout_gravity="start|bottom"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/next_alarm_icon"
|
||||
android:layout_width="@dimen/qs_header_alarm_icon_size"
|
||||
android:layout_height="@dimen/qs_header_alarm_icon_size"
|
||||
android:src="@drawable/stat_sys_alarm"
|
||||
android:tint="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/next_alarm_text"
|
||||
<LinearLayout
|
||||
android:id="@+id/status_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
|
||||
android:textAppearance="@style/TextAppearance.QS.TileLabel"
|
||||
android:visibility="gone"/>
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center_vertical"
|
||||
android:alpha="0">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/next_alarm_icon"
|
||||
android:layout_width="@dimen/qs_header_alarm_icon_size"
|
||||
android:layout_height="@dimen/qs_header_alarm_icon_size"
|
||||
android:src="@drawable/stat_sys_alarm"
|
||||
android:tint="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/next_alarm_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
|
||||
android:textAppearance="@style/TextAppearance.QS.Status"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/status_separator"
|
||||
android:layout_width="@dimen/qs_header_separator_width"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ringer_mode_icon"
|
||||
android:layout_width="@dimen/qs_header_alarm_icon_size"
|
||||
android:layout_height="@dimen/qs_header_alarm_icon_size"
|
||||
android:tint="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ringer_mode_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
|
||||
android:textAppearance="@style/TextAppearance.QS.Status"
|
||||
android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/status_separator"
|
||||
android:layout_width="1dp"
|
||||
android:minWidth="@dimen/qs_status_separator"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:background="@android:color/white"
|
||||
android:backgroundTint="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/ringer_mode_icon"
|
||||
android:layout_width="@dimen/qs_header_alarm_icon_size"
|
||||
android:layout_height="@dimen/qs_header_alarm_icon_size"
|
||||
android:tint="?android:attr/textColorPrimary"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ringer_mode_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
|
||||
android:textAppearance="@style/TextAppearance.QS.TileLabel"
|
||||
android:visibility="gone"/>
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<include layout="@layout/qs_carrier_group"
|
||||
android:id="@+id/carrier_group"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android_layout_gravity="center vertical|end"/>
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018 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
|
||||
-->
|
||||
<resources>
|
||||
<!-- Action footer width is set to 0 to allow it to stretch (through a weight of 1) and center
|
||||
the page indicator in between the footer and the carrier text.-->
|
||||
<integer name="qs_footer_actions_width">0</integer>
|
||||
<integer name="qs_footer_actions_weight">1</integer>
|
||||
</resources>
|
||||
@@ -274,7 +274,16 @@
|
||||
|
||||
<!-- The height of the quick settings footer that holds the user switcher, settings icon,
|
||||
etc. -->
|
||||
<dimen name="qs_footer_height">56dp</dimen>
|
||||
<dimen name="qs_footer_height">48dp</dimen>
|
||||
|
||||
<!-- The size of each of the icon buttons in the QS footer -->
|
||||
<dimen name="qs_footer_action_button_size">@dimen/qs_footer_height</dimen>
|
||||
|
||||
<!-- Margins on each side of QS Footer -->
|
||||
<dimen name="qs_footer_margin">2dp</dimen>
|
||||
|
||||
<!-- Padding on each QS Footer Icon to make the icons 20dpx20dp -->
|
||||
<dimen name="qs_footer_icon_padding">14dp</dimen>
|
||||
|
||||
<!-- The padding between the notifications and the quick settings container -->
|
||||
<dimen name="qs_notification_padding">@dimen/notification_side_paddings</dimen>
|
||||
@@ -415,11 +424,16 @@
|
||||
<dimen name="qs_detail_item_icon_marginEnd">20dp</dimen>
|
||||
<dimen name="qs_header_tooltip_height">18dp</dimen>
|
||||
<dimen name="qs_header_alarm_icon_size">18dp</dimen>
|
||||
<dimen name="qs_header_mobile_icon_size">18dp</dimen>
|
||||
<dimen name="qs_header_alarm_text_margin_start">6dp</dimen>
|
||||
<dimen name="qs_header_separator_width">8dp</dimen>
|
||||
<dimen name="qs_header_carrier_separator_width">6dp</dimen>
|
||||
<dimen name="qs_status_separator">32dp</dimen>
|
||||
<dimen name="qs_carrier_margin_width">4dp</dimen>
|
||||
<dimen name="qs_footer_padding_start">16dp</dimen>
|
||||
<dimen name="qs_footer_padding_end">16dp</dimen>
|
||||
<dimen name="qs_footer_icon_size">16dp</dimen>
|
||||
<dimen name="qs_paged_tile_layout_padding_bottom">24dp</dimen>
|
||||
<dimen name="qs_paged_tile_layout_padding_bottom">16dp</dimen>
|
||||
|
||||
<dimen name="qs_notif_collapsed_space">64dp</dimen>
|
||||
|
||||
@@ -592,7 +606,7 @@
|
||||
<dimen name="multi_user_avatar_keyguard_size">22dp</dimen>
|
||||
|
||||
<!-- The width of user avatar when expanded -->
|
||||
<dimen name="multi_user_avatar_expanded_size">18dp</dimen>
|
||||
<dimen name="multi_user_avatar_expanded_size">20dp</dimen>
|
||||
|
||||
<!-- The font size of the time when collapsed in QS -->
|
||||
<dimen name="qs_time_collapsed_size">14sp</dimen>
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
<!-- Action footer width used for layout_width to indicate WRAP_CONTENT (along with a weight of
|
||||
0) as we can allow the carrier text to stretch as far as needed in the QS footer. -->
|
||||
<integer name="qs_footer_actions_width">-2</integer>
|
||||
<integer name="qs_footer_actions_weight">0</integer>
|
||||
<integer name="qs_footer_actions_width">0</integer>
|
||||
<integer name="qs_footer_actions_weight">1</integer>
|
||||
|
||||
<!-- Maximum number of bubbles to render and animate at one time. While the animations used are
|
||||
lightweight translation animations, this number can be reduced on lower end devices if any
|
||||
|
||||
@@ -227,6 +227,8 @@
|
||||
<item name="android:textSize">@dimen/qs_carrier_info_text_size</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.QS.Status" parent="TextAppearance.QS.TileLabel.Secondary" />
|
||||
|
||||
<style name="TextAppearance.AppOpsDialog" />
|
||||
|
||||
<style name="TextAppearance.AppOpsDialog.Title">
|
||||
|
||||
@@ -261,11 +261,9 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
|
||||
// Fade in the tiles/labels as we reach the final position.
|
||||
mFirstPageDelayedAnimator = new TouchAnimator.Builder()
|
||||
.setStartDelay(EXPANDED_TILE_DELAY)
|
||||
.addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1)
|
||||
.addFloat(tileLayout, "alpha", 0, 1)
|
||||
.addFloat(mQsPanel.getDivider(), "alpha", 0, 1)
|
||||
.addFloat(mQsPanel.getFooter().getView(), "alpha", 0, 1).build();
|
||||
mAllViews.add(mQsPanel.getPageIndicator());
|
||||
mAllViews.add(mQsPanel.getDivider());
|
||||
mAllViews.add(mQsPanel.getFooter().getView());
|
||||
float px = 0;
|
||||
@@ -283,7 +281,6 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
|
||||
}
|
||||
mNonfirstPageAnimator = new TouchAnimator.Builder()
|
||||
.addFloat(mQuickQsPanel, "alpha", 1, 0)
|
||||
.addFloat(mQsPanel.getPageIndicator(), "alpha", 0, 1)
|
||||
.addFloat(mQsPanel.getDivider(), "alpha", 0, 1)
|
||||
.setListener(mNonFirstPageListener)
|
||||
.setEndDelay(.5f)
|
||||
|
||||
141
packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
Normal file
141
packages/SystemUI/src/com/android/systemui/qs/QSCarrier.java
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* 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 QSCarrierText 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,224 @@
|
||||
/*
|
||||
* 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,24 +23,24 @@ 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.database.ContentObserver;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.text.TextUtils;
|
||||
import android.provider.Settings;
|
||||
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;
|
||||
|
||||
@@ -49,11 +49,10 @@ 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.development.DevelopmentSettingsEnabler;
|
||||
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 +61,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 +69,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 +87,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
|
||||
private boolean mListening;
|
||||
|
||||
private boolean mShowEmergencyCallsOnly;
|
||||
private View mDivider;
|
||||
protected MultiUserSwitch mMultiUserSwitch;
|
||||
private ImageView mMultiUserAvatar;
|
||||
@@ -103,35 +95,30 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
private float mExpansionAmount;
|
||||
|
||||
protected View mEdit;
|
||||
protected View mEditContainer;
|
||||
private TouchAnimator mSettingsCogAnimator;
|
||||
|
||||
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;
|
||||
|
||||
private final ContentObserver mDeveloperSettingsObserver = new ContentObserver(
|
||||
new Handler(mContext.getMainLooper())) {
|
||||
@Override
|
||||
public void onChange(boolean selfChange, Uri uri) {
|
||||
super.onChange(selfChange, uri);
|
||||
setBuildText();
|
||||
}
|
||||
};
|
||||
|
||||
@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 +127,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,26 +145,12 @@ 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);
|
||||
|
||||
mMultiUserSwitch = findViewById(R.id.multi_user_switch);
|
||||
mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
|
||||
|
||||
mDragHandle = findViewById(R.id.qs_drag_handle_view);
|
||||
mActionsContainer = findViewById(R.id.qs_footer_actions_container);
|
||||
mEditContainer = findViewById(R.id.qs_footer_actions_edit_container);
|
||||
|
||||
// RenderThread is doing more harm than good when touching the header (to expand quick
|
||||
// settings), so disable it for this view
|
||||
@@ -190,6 +162,21 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
oldBottom) -> updateAnimator(right - left));
|
||||
setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
|
||||
updateEverything();
|
||||
setBuildText();
|
||||
}
|
||||
|
||||
private void setBuildText() {
|
||||
TextView v = findViewById(R.id.build);
|
||||
if (v == null) return;
|
||||
if (DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)) {
|
||||
v.setText(mContext.getString(
|
||||
com.android.internal.R.string.bugreport_status,
|
||||
Build.VERSION.RELEASE,
|
||||
Build.ID));
|
||||
v.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
v.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateAnimator(int width) {
|
||||
@@ -222,14 +209,6 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
|
||||
private void updateResources() {
|
||||
updateFooterAnimator();
|
||||
|
||||
// Update the width and weight of the actions container as the page indicator can sometimes
|
||||
// show and the layout needs to center it between the carrier text and actions container.
|
||||
LinearLayout.LayoutParams params =
|
||||
(LinearLayout.LayoutParams) mActionsContainer.getLayoutParams();
|
||||
params.width = mContext.getResources().getInteger(R.integer.qs_footer_actions_width);
|
||||
params.weight = mContext.getResources().getInteger(R.integer.qs_footer_actions_weight);
|
||||
mActionsContainer.setLayoutParams(params);
|
||||
}
|
||||
|
||||
private void updateFooterAnimator() {
|
||||
@@ -240,9 +219,8 @@ 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(mActionsContainer, "alpha", 0, 1)
|
||||
.addFloat(mEditContainer, "alpha", 0, 1)
|
||||
.addFloat(mDragHandle, "alpha", 1, 0, 0)
|
||||
.addFloat(mPageIndicator, "alpha", 0, 1)
|
||||
.setStartDelay(0.15f)
|
||||
@@ -276,10 +254,19 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mContext.getContentResolver().registerContentObserver(
|
||||
Settings.Global.getUriFor(Settings.Global.DEVELOPMENT_SETTINGS_ENABLED), false,
|
||||
mDeveloperSettingsObserver, UserHandle.USER_ALL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@VisibleForTesting
|
||||
public void onDetachedFromWindow() {
|
||||
setListening(false);
|
||||
mContext.getContentResolver().unregisterContentObserver(mDeveloperSettingsObserver);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@@ -337,7 +324,7 @@ public class QSFooterImpl extends FrameLayout implements QSFooter,
|
||||
TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
|
||||
final boolean isDemo = UserManager.isDeviceInDemoMode(mContext);
|
||||
mMultiUserSwitch.setVisibility(showUserSwitcher(isDemo) ? View.VISIBLE : View.INVISIBLE);
|
||||
mEdit.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
|
||||
mEditContainer.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
|
||||
mSettingsButton.setVisibility(isDemo || !mExpanded ? View.INVISIBLE : View.VISIBLE);
|
||||
}
|
||||
|
||||
@@ -364,16 +351,8 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,17 +408,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 +420,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.systemui.qs;
|
||||
|
||||
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
|
||||
|
||||
import static com.android.systemui.qs.tileimpl.QSTileImpl.getColorForState;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
@@ -79,7 +77,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
protected QSTileHost mHost;
|
||||
|
||||
protected QSSecurityFooter mFooter;
|
||||
private PageIndicator mPanelPageIndicator;
|
||||
private PageIndicator mFooterPageIndicator;
|
||||
private boolean mGridContentVisible = true;
|
||||
|
||||
@@ -110,11 +107,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
mTileLayout.setListening(mListening);
|
||||
addView((View) mTileLayout);
|
||||
|
||||
mPanelPageIndicator = (PageIndicator) LayoutInflater.from(context).inflate(
|
||||
R.layout.qs_page_indicator, this, false);
|
||||
addView(mPanelPageIndicator);
|
||||
|
||||
((PagedTileLayout) mTileLayout).setPageIndicator(mPanelPageIndicator);
|
||||
mQsTileRevealController = new QSTileRevealController(mContext, this,
|
||||
(PagedTileLayout) mTileLayout);
|
||||
|
||||
@@ -141,10 +133,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
return mDivider;
|
||||
}
|
||||
|
||||
public View getPageIndicator() {
|
||||
return mPanelPageIndicator;
|
||||
}
|
||||
|
||||
public QSTileRevealController getQsTileRevealController() {
|
||||
return mQsTileRevealController;
|
||||
}
|
||||
@@ -265,21 +253,11 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne
|
||||
|
||||
private void updatePageIndicator() {
|
||||
if (mTileLayout instanceof PagedTileLayout) {
|
||||
// If we're in landscape, and we have the footer page indicator (which we should if the
|
||||
// footer has been initialized & linked), then we'll show the footer page indicator to
|
||||
// save space in the main QS tile area. Otherwise, we'll use the default one under the
|
||||
// tiles/above the footer.
|
||||
boolean shouldUseFooterPageIndicator =
|
||||
getResources().getConfiguration().orientation == ORIENTATION_LANDSCAPE
|
||||
&& mFooterPageIndicator != null;
|
||||
|
||||
mPanelPageIndicator.setVisibility(View.GONE);
|
||||
if (mFooterPageIndicator != null) {
|
||||
mFooterPageIndicator.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
((PagedTileLayout) mTileLayout).setPageIndicator(
|
||||
shouldUseFooterPageIndicator ? mFooterPageIndicator : mPanelPageIndicator);
|
||||
((PagedTileLayout) mTileLayout).setPageIndicator(mFooterPageIndicator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,6 +113,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
||||
private boolean mListening;
|
||||
private boolean mQsDisabled;
|
||||
|
||||
private QSCarrierGroup mCarrierGroup;
|
||||
protected QuickQSPanel mHeaderQsPanel;
|
||||
protected QSTileHost mHost;
|
||||
private TintedIconManager mIconManager;
|
||||
@@ -207,6 +208,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
||||
mRingerModeTextView = findViewById(R.id.ringer_mode_text);
|
||||
mPrivacyChip = findViewById(R.id.privacy_chip);
|
||||
mPrivacyChip.setOnClickListener(this);
|
||||
mCarrierGroup = findViewById(R.id.carrier_group);
|
||||
|
||||
updateResources();
|
||||
|
||||
@@ -519,6 +521,7 @@ public class QuickStatusBarHeader extends RelativeLayout implements
|
||||
}
|
||||
mHeaderQsPanel.setListening(listening);
|
||||
mListening = listening;
|
||||
mCarrierGroup.setListening(mListening);
|
||||
|
||||
if (listening) {
|
||||
mZenController.addCallback(this);
|
||||
|
||||
@@ -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