Merge changes Ib5ac6ee9,Ib127ad43,I37a423f3 into sc-qpr1-dev
* changes: [ProviderModel] Cherry-pick from master ag/15207286, ag/15216391 and ag/15205988 [Provider Model] Cherry-pick from master ag/15008434, ag/15023697 and ag/15023698 [ProviderModel] Add InternetDialogController for internet dialog
This commit is contained in:
26
packages/SystemUI/res/drawable/ic_arrow_forward.xml
Normal file
26
packages/SystemUI/res/drawable/ic_arrow_forward.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
~ Copyright (C) 2021 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:autoMirrored="true"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/black"
|
||||
android:pathData="M6.23,20.23l1.77,1.77l10,-10l-10,-10l-1.77,1.77l8.23,8.23z"/>
|
||||
</vector>
|
||||
26
packages/SystemUI/res/drawable/ic_friction_lock_closed.xml
Normal file
26
packages/SystemUI/res/drawable/ic_friction_lock_closed.xml
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2017 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M18,8h-1V6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2H6c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V10C20,8.9 19.1,8 18,8zM9,6c0,-1.66 1.34,-3 3,-3s3,1.34 3,3v2H9V6zM18,20H6V10h12V20zM12,17c1.1,0 2,-0.9 2,-2c0,-1.1 -0.9,-2 -2,-2c-1.1,0 -2,0.9 -2,2C10,16.1 10.9,17 12,17z"/>
|
||||
</vector>
|
||||
29
packages/SystemUI/res/drawable/ic_settings_24dp.xml
Normal file
29
packages/SystemUI/res/drawable/ic_settings_24dp.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<!--
|
||||
Copyright (C) 2015 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.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M13.85,22.25h-3.7c-0.74,0 -1.36,-0.54 -1.45,-1.27l-0.27,-1.89c-0.27,-0.14 -0.53,-0.29 -0.79,-0.46l-1.8,0.72c-0.7,0.26 -1.47,-0.03 -1.81,-0.65L2.2,15.53c-0.35,-0.66 -0.2,-1.44 0.36,-1.88l1.53,-1.19c-0.01,-0.15 -0.02,-0.3 -0.02,-0.46c0,-0.15 0.01,-0.31 0.02,-0.46l-1.52,-1.19C1.98,9.9 1.83,9.09 2.2,8.47l1.85,-3.19c0.34,-0.62 1.11,-0.9 1.79,-0.63l1.81,0.73c0.26,-0.17 0.52,-0.32 0.78,-0.46l0.27,-1.91c0.09,-0.7 0.71,-1.25 1.44,-1.25h3.7c0.74,0 1.36,0.54 1.45,1.27l0.27,1.89c0.27,0.14 0.53,0.29 0.79,0.46l1.8,-0.72c0.71,-0.26 1.48,0.03 1.82,0.65l1.84,3.18c0.36,0.66 0.2,1.44 -0.36,1.88l-1.52,1.19c0.01,0.15 0.02,0.3 0.02,0.46s-0.01,0.31 -0.02,0.46l1.52,1.19c0.56,0.45 0.72,1.23 0.37,1.86l-1.86,3.22c-0.34,0.62 -1.11,0.9 -1.8,0.63l-1.8,-0.72c-0.26,0.17 -0.52,0.32 -0.78,0.46l-0.27,1.91C15.21,21.71 14.59,22.25 13.85,22.25zM13.32,20.72c0,0.01 0,0.01 0,0.02L13.32,20.72zM10.68,20.7l0,0.02C10.69,20.72 10.69,20.71 10.68,20.7zM10.62,20.25h2.76l0.37,-2.55l0.53,-0.22c0.44,-0.18 0.88,-0.44 1.34,-0.78l0.45,-0.34l2.38,0.96l1.38,-2.4l-2.03,-1.58l0.07,-0.56c0.03,-0.26 0.06,-0.51 0.06,-0.78c0,-0.27 -0.03,-0.53 -0.06,-0.78l-0.07,-0.56l2.03,-1.58l-1.39,-2.4l-2.39,0.96l-0.45,-0.35c-0.42,-0.32 -0.87,-0.58 -1.33,-0.77L13.75,6.3l-0.37,-2.55h-2.76L10.25,6.3L9.72,6.51C9.28,6.7 8.84,6.95 8.38,7.3L7.93,7.63L5.55,6.68L4.16,9.07l2.03,1.58l-0.07,0.56C6.09,11.47 6.06,11.74 6.06,12c0,0.26 0.02,0.53 0.06,0.78l0.07,0.56l-2.03,1.58l1.38,2.4l2.39,-0.96l0.45,0.35c0.43,0.33 0.86,0.58 1.33,0.77l0.53,0.22L10.62,20.25zM18.22,17.72c0,0.01 -0.01,0.02 -0.01,0.03L18.22,17.72zM5.77,17.71l0.01,0.02C5.78,17.72 5.77,17.71 5.77,17.71zM3.93,9.47L3.93,9.47C3.93,9.47 3.93,9.47 3.93,9.47zM18.22,6.27c0,0.01 0.01,0.02 0.01,0.02L18.22,6.27zM5.79,6.25L5.78,6.27C5.78,6.27 5.79,6.26 5.79,6.25zM13.31,3.28c0,0.01 0,0.01 0,0.02L13.31,3.28zM10.69,3.26l0,0.02C10.69,3.27 10.69,3.27 10.69,3.26z"/>
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M12,12m-3.5,0a3.5,3.5 0,1 1,7 0a3.5,3.5 0,1 1,-7 0"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?android:attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M2,22l16,0l0,-2l-11,0l13,-13l0,1l2,0l0,-6z"
|
||||
android:strokeAlpha="0.3"
|
||||
android:fillAlpha="0.3"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,10h2v8h-2z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M20,20h2v2h-2z"/>
|
||||
</vector>
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="?android:attr/colorBackground" />
|
||||
</shape>
|
||||
</inset>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License
|
||||
-->
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:shape="rectangle">
|
||||
<stroke
|
||||
android:color="?androidprv:attr/colorAccentPrimaryVariant"
|
||||
android:width="1dp"/>
|
||||
<corners android:radius="20dp"/>
|
||||
<padding
|
||||
android:left="8dp"
|
||||
android:right="8dp"
|
||||
android:top="4dp"
|
||||
android:bottom="4dp" />
|
||||
<solid android:color="@android:color/transparent" />
|
||||
</shape>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 The Android Open Source Project
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shape android:shape="rectangle">
|
||||
<corners
|
||||
android:topLeftRadius="@dimen/internet_dialog_corner_radius"
|
||||
android:topRightRadius="@dimen/internet_dialog_corner_radius"
|
||||
android:bottomLeftRadius="@dimen/internet_dialog_corner_radius"
|
||||
android:bottomRightRadius="@dimen/internet_dialog_corner_radius"/>
|
||||
<solid android:color="?android:attr/colorBackground" />
|
||||
</shape>
|
||||
</inset>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/settingslib_state_off_color"/>
|
||||
<corners android:radius="@dimen/settingslib_switch_bar_radius"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="?android:attr/colorControlHighlight">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/settingslib_state_on_color"/>
|
||||
<corners android:radius="@dimen/settingslib_switch_bar_radius"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:top="@dimen/settingslib_switch_thumb_margin"
|
||||
android:left="@dimen/settingslib_switch_thumb_margin"
|
||||
android:right="@dimen/settingslib_switch_thumb_margin"
|
||||
android:bottom="@dimen/settingslib_switch_thumb_margin">
|
||||
<shape android:shape="oval">
|
||||
<size
|
||||
android:height="@dimen/settingslib_switch_thumb_size"
|
||||
android:width="@dimen/settingslib_switch_thumb_size"/>
|
||||
<solid
|
||||
android:color="@color/settingslib_thumb_off_color"
|
||||
android:alpha="?android:attr/disabledAlpha"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
31
packages/SystemUI/res/drawable/settingslib_thumb_off.xml
Normal file
31
packages/SystemUI/res/drawable/settingslib_thumb_off.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:top="@dimen/settingslib_switch_thumb_margin"
|
||||
android:left="@dimen/settingslib_switch_thumb_margin"
|
||||
android:right="@dimen/settingslib_switch_thumb_margin"
|
||||
android:bottom="@dimen/settingslib_switch_thumb_margin">
|
||||
<shape android:shape="oval">
|
||||
<size
|
||||
android:height="@dimen/settingslib_switch_thumb_size"
|
||||
android:width="@dimen/settingslib_switch_thumb_size"/>
|
||||
<solid android:color="@color/settingslib_thumb_off_color"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
31
packages/SystemUI/res/drawable/settingslib_thumb_on.xml
Normal file
31
packages/SystemUI/res/drawable/settingslib_thumb_on.xml
Normal file
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:top="@dimen/settingslib_switch_thumb_margin"
|
||||
android:left="@dimen/settingslib_switch_thumb_margin"
|
||||
android:right="@dimen/settingslib_switch_thumb_margin"
|
||||
android:bottom="@dimen/settingslib_switch_thumb_margin">
|
||||
<shape android:shape="oval">
|
||||
<size
|
||||
android:height="@dimen/settingslib_switch_thumb_size"
|
||||
android:width="@dimen/settingslib_switch_thumb_size"/>
|
||||
<solid android:color="@color/settingslib_state_on_color"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/settingslib_thumb_on" android:state_checked="true"/>
|
||||
<item android:drawable="@drawable/settingslib_thumb_off" android:state_checked="false"/>
|
||||
<item android:drawable="@drawable/settingslib_thumb_disabled" android:state_enabled="false"/>
|
||||
</selector>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2021 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
android:width="@dimen/settingslib_switch_track_width"
|
||||
android:height="@dimen/settingslib_switch_track_height">
|
||||
<solid
|
||||
android:color="@color/settingslib_track_off_color"
|
||||
android:alpha="?android:attr/disabledAlpha"/>
|
||||
<corners android:radius="@dimen/settingslib_switch_track_radius"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
android:width="@dimen/settingslib_switch_track_width"
|
||||
android:height="@dimen/settingslib_switch_track_height">
|
||||
<solid android:color="@color/settingslib_track_off_color"/>
|
||||
<corners android:radius="@dimen/settingslib_switch_track_radius"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle"
|
||||
android:width="@dimen/settingslib_switch_track_width"
|
||||
android:height="@dimen/settingslib_switch_track_height">
|
||||
<solid android:color="@color/settingslib_track_on_color"/>
|
||||
<corners android:radius="@dimen/settingslib_switch_track_radius"/>
|
||||
</shape>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/settingslib_track_on_background" android:state_checked="true"/>
|
||||
<item android:drawable="@drawable/settingslib_track_off_background" android:state_checked="false"/>
|
||||
<item android:drawable="@drawable/settingslib_track_disabled_background" android:state_enabled="false"/>
|
||||
</selector>
|
||||
366
packages/SystemUI/res/layout/internet_connectivity_dialog.xml
Normal file
366
packages/SystemUI/res/layout/internet_connectivity_dialog.xml
Normal file
@@ -0,0 +1,366 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/internet_connectivity_dialog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/internet_dialog_rounded_top_corner_background"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
style="@style/Widget.SliceView.Panel"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/internet_dialog_title"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="32dp"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="google-sans"
|
||||
android:textSize="24sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/internet_dialog_subtitle"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:fontFamily="google-sans"
|
||||
android:textSize="14sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/scroll_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<LinearLayout
|
||||
android:id="@+id/scroll_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
<LinearLayout
|
||||
android:id="@+id/internet_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/mobile_network_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="88dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginRight="@dimen/settingslib_switchbar_margin"
|
||||
android:layout_marginLeft="@dimen/settingslib_switchbar_margin"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:paddingStart="19dp"
|
||||
android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:clickable="false"
|
||||
android:layout_gravity="center_vertical|start">
|
||||
<ImageView
|
||||
android:id="@+id/signal_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/mobile_network_list"
|
||||
android:orientation="vertical"
|
||||
android:clickable="false"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start|center_vertical">
|
||||
<TextView
|
||||
android:id="@+id/mobile_title"
|
||||
android:layout_marginLeft="17dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
<TextView
|
||||
android:id="@+id/mobile_summary"
|
||||
android:layout_marginLeft="17dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="end|center_vertical">
|
||||
<Switch
|
||||
android:id="@+id/mobile_toggle"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:track="@drawable/settingslib_track_selector"
|
||||
android:thumb="@drawable/settingslib_thumb_selector"
|
||||
android:theme="@style/MainSwitch.Settingslib"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/wifi_searching_progress"
|
||||
android:indeterminate="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="1dp"
|
||||
android:maxHeight="1dp"
|
||||
style="@*android:style/Widget.Material.ProgressBar.Horizontal"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/turn_on_wifi_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginRight="@dimen/settingslib_switchbar_margin"
|
||||
android:layout_marginLeft="@dimen/settingslib_switchbar_margin"
|
||||
android:paddingStart="@dimen/settingslib_switchbar_padding_left"
|
||||
android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_weight="1"
|
||||
android:orientation="vertical"
|
||||
android:clickable="false"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent">
|
||||
<TextView
|
||||
android:text="@string/turn_on_wifi"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="16sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp">
|
||||
<Switch
|
||||
android:id="@+id/wifi_toggle"
|
||||
android:layout_gravity="center"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:track="@drawable/settingslib_track_selector"
|
||||
android:thumb="@drawable/settingslib_thumb_selector"
|
||||
android:theme="@style/MainSwitch.Settingslib"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/wifi_connected_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:visibility="gone"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginRight="@dimen/settingslib_switchbar_margin"
|
||||
android:layout_marginLeft="@dimen/settingslib_switchbar_margin"
|
||||
android:paddingStart="@dimen/settingslib_switchbar_padding_left"
|
||||
android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:clickable="false"
|
||||
android:layout_gravity="center_vertical|start">
|
||||
<ImageView
|
||||
android:id="@+id/wifi_connected_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_weight="3"
|
||||
android:id="@+id/wifi_connected_list"
|
||||
android:orientation="vertical"
|
||||
android:clickable="false"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="72dp"
|
||||
android:gravity="start|center_vertical">
|
||||
<TextView
|
||||
android:id="@+id/wifi_connected_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
<TextView
|
||||
android:id="@+id/wifi_connected_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorTertiary"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="5dp"
|
||||
android:clickable="false"
|
||||
android:gravity="center">
|
||||
<ImageView
|
||||
android:id="@+id/wifi_settings_icon"
|
||||
android:src="@drawable/ic_settings_24dp"
|
||||
android:layout_width="24dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/wifi_list_layout"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never"
|
||||
android:nestedScrollingEnabled="false"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/see_all_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="64dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:gravity="center_vertical|center_horizontal"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/settingslib_switchbar_padding_left"
|
||||
android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:clickable="false"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:layout_marginStart="16dp">
|
||||
<ImageView
|
||||
android:id="@+id/arrow_forward"
|
||||
android:src="@drawable/ic_arrow_forward"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:orientation="vertical"
|
||||
android:clickable="false"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginLeft="16dp">
|
||||
<TextView
|
||||
android:text="@string/see_all_networks"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start|center_vertical"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Space
|
||||
android:id="@+id/space"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="28dp"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginBottom="25dp"
|
||||
android:gravity="end"
|
||||
android:orientation="horizontal">
|
||||
<Button
|
||||
style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
|
||||
android:id="@+id/done"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginRight="24dp"
|
||||
android:layout_gravity="end"
|
||||
android:background="@drawable/internet_dialog_footer_background"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:text="@string/inline_done_button"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</androidx.core.widget.NestedScrollView>
|
||||
</LinearLayout>
|
||||
99
packages/SystemUI/res/layout/internet_list_item.xml
Normal file
99
packages/SystemUI/res/layout/internet_list_item.xml
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2021 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/internet_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/wifi_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="72dp"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="@dimen/settingslib_switchbar_padding_left"
|
||||
android:paddingEnd="@dimen/settingslib_switchbar_padding_right">
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:clickable="false"
|
||||
android:layout_gravity="center_vertical|start"
|
||||
android:layout_marginStart="16dp">
|
||||
<ImageView
|
||||
android:id="@+id/wifi_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"/>
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_weight="3"
|
||||
android:id="@+id/wifi_network_layout"
|
||||
android:orientation="vertical"
|
||||
android:clickable="false"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="72dp">
|
||||
<TextView
|
||||
android:id="@+id/wifi_title"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="start|center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
<TextView
|
||||
android:id="@+id/wifi_summary"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:gravity="start|center_vertical"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorSecondary"
|
||||
android:textSize="14sp"
|
||||
android:fontFamily="google-sans"/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginRight="@dimen/settingslib_switchbar_padding_right"
|
||||
android:clickable="false"
|
||||
android:gravity="center">
|
||||
<ImageView
|
||||
android:id="@+id/wifi_locked_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_height="wrap_content"/>
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -16,7 +16,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<resources>
|
||||
<resources xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
|
||||
<drawable name="notification_number_text_color">#ffffffff</drawable>
|
||||
<drawable name="ticker_background_color">#ff1d1d1d</drawable>
|
||||
<drawable name="system_bar_background">@color/system_bar_background_opaque</drawable>
|
||||
@@ -281,4 +281,16 @@
|
||||
<color name="wallet_card_border">#33FFFFFF</color>
|
||||
|
||||
<color name="people_tile_background">@android:color/system_accent2_50</color>
|
||||
|
||||
<!-- Internet Dialog -->
|
||||
<!-- Material next state on color-->
|
||||
<color name="settingslib_state_on_color">?androidprv:attr/colorAccentPrimary</color>
|
||||
<!-- Material next state off color-->
|
||||
<color name="settingslib_state_off_color">?androidprv:attr/colorAccentSecondary</color>
|
||||
<!-- Material next track on color-->
|
||||
<color name="settingslib_track_on_color">?androidprv:attr/colorAccentPrimaryVariant</color>
|
||||
<!-- Material next track off color-->
|
||||
<color name="settingslib_track_off_color">?androidprv:attr/colorAccentSecondaryVariant</color>
|
||||
<color name="connected_network_primary_color">#ff000000</color>
|
||||
<color name="connected_network_tertiary_color">#808080</color>
|
||||
</resources>
|
||||
|
||||
@@ -1590,4 +1590,35 @@
|
||||
<!-- The padding between the icon and the text. -->
|
||||
<dimen name="ongoing_call_chip_icon_text_padding">4dp</dimen>
|
||||
<dimen name="ongoing_call_chip_corner_radius">28dp</dimen>
|
||||
|
||||
<!-- Internet panel related dimensions -->
|
||||
<dimen name="internet_dialog_list_margin">12dp</dimen>
|
||||
<dimen name="internet_dialog_list_max_height">614dp</dimen>
|
||||
|
||||
<!-- Signal icon in internet dialog -->
|
||||
<dimen name="signal_strength_icon_size">24dp</dimen>
|
||||
|
||||
<!-- Internet dialog related dimensions -->
|
||||
<dimen name="internet_dialog_corner_radius">24dp</dimen>
|
||||
|
||||
<!-- Size of internet dialog -->
|
||||
<dimen name="settingslib_switchbar_margin">16dp</dimen>
|
||||
<!-- Minimum width of switch -->
|
||||
<dimen name="settingslib_min_switch_width">48dp</dimen>
|
||||
<!-- Size of layout margin left -->
|
||||
<dimen name="settingslib_switchbar_padding_left">20dp</dimen>
|
||||
<!-- Size of layout margin right -->
|
||||
<dimen name="settingslib_switchbar_padding_right">20dp</dimen>
|
||||
<!-- Radius of switch bar -->
|
||||
<dimen name="settingslib_switch_bar_radius">24dp</dimen>
|
||||
<!-- Margin of switch thumb -->
|
||||
<dimen name="settingslib_switch_thumb_margin">4dp</dimen>
|
||||
<!-- Size of switch thumb -->
|
||||
<dimen name="settingslib_switch_thumb_size">16dp</dimen>
|
||||
<!-- Width of switch track -->
|
||||
<dimen name="settingslib_switch_track_width">48dp</dimen>
|
||||
<!-- Height of switch track -->
|
||||
<dimen name="settingslib_switch_track_height">24dp</dimen>
|
||||
<!-- Radius of switch track -->
|
||||
<dimen name="settingslib_switch_track_radius">31dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -2994,4 +2994,37 @@
|
||||
<string name="global_actions_change_description" translatable="false"><xliff:g>%1$s</xliff:g></string>
|
||||
<!-- URL for more information about changes in global actions -->
|
||||
<string name="global_actions_change_url" translatable="false"></string>
|
||||
|
||||
<!-- Provider Model: Title of the airplane mode in the internet dialog. [CHAR LIMIT=50] -->
|
||||
<string name="airplane_mode">Airplane mode</string>
|
||||
<!-- Provider Model: Default title of the mobile network in the mobile layout. [CHAR LIMIT=50] -->
|
||||
<string name="mobile_data_settings_title">Mobile data</string>
|
||||
<!-- Provider Model: Summary text separator for preferences including a short description
|
||||
(eg. "Connected / 5G"). [CHAR LIMIT=50] -->
|
||||
<string name="preference_summary_default_combination"><xliff:g id="state" example="Connected">%1$s</xliff:g> / <xliff:g id="networkMode" example="LTE">%2$s</xliff:g></string>
|
||||
<!-- Provider Model:
|
||||
Summary indicating that a SIM has an active mobile data connection [CHAR LIMIT=50] -->
|
||||
<string name="mobile_data_connection_active">Connected</string>
|
||||
<!-- Provider Model:
|
||||
Summary indicating that a SIM has no mobile data connection [CHAR LIMIT=50] -->
|
||||
<string name="mobile_data_off_summary">Internet won\u0027t auto\u2011connect</string>
|
||||
<!-- Provider Model:
|
||||
Summary indicating that a active SIM and no network available [CHAR LIMIT=50] -->
|
||||
<string name="mobile_data_no_connection">No connection</string>
|
||||
<!-- Provider Model: Summary indicating that no other networks available [CHAR LIMIT=50] -->
|
||||
<string name="non_carrier_network_unavailable">No other networks available</string>
|
||||
<!-- Provider Model: Summary indicating that no networks available [CHAR LIMIT=50] -->
|
||||
<string name="all_network_unavailable">No networks available</string>
|
||||
<!-- Provider Model: Panel title text for turning on the Wi-Fi networks. [CHAR LIMIT=40] -->
|
||||
<string name="turn_on_wifi">Wi\u2011Fi</string>
|
||||
<!-- Provider Model: Title for detail page of wifi network [CHAR LIMIT=30] -->
|
||||
<string name="pref_title_network_details" msgid="7329759534269363308">"Network details"</string>
|
||||
<!-- Provider Model: Panel subtitle for tapping a network to connect to internet. [CHAR LIMIT=60] -->
|
||||
<string name="tap_a_network_to_connect">Tap a network to connect</string>
|
||||
<!-- Provider Model: Wi-Fi settings. text displayed when Wi-Fi is on and network list is empty [CHAR LIMIT=50]-->
|
||||
<string name="wifi_empty_list_wifi_on">Searching for networks\u2026</string>
|
||||
<!-- Provider Model: Failure notification for connect -->
|
||||
<string name="wifi_failed_connect_message">Failed to connect to network</string>
|
||||
<!-- Provider Model: Title to see all the networks [CHAR LIMIT=50] -->
|
||||
<string name="see_all_networks">See all</string>
|
||||
</resources>
|
||||
|
||||
@@ -903,4 +903,43 @@
|
||||
<!-- Setting a placeholder will avoid using the SystemUI icon on the splash screen. -->
|
||||
<item name="android:windowSplashScreenAnimatedIcon">@drawable/ic_blank</item>
|
||||
</style>
|
||||
|
||||
<style name="Animation.InternetDialog" parent="@android:style/Animation.InputMethod">
|
||||
</style>
|
||||
|
||||
<style name="Widget.SliceView.Panel">
|
||||
<item name="titleSize">16sp</item>
|
||||
<item name="rowStyle">@style/SliceRow</item>
|
||||
<item name="android:background">?android:attr/colorBackgroundFloating</item>
|
||||
</style>
|
||||
|
||||
<style name="SliceRow">
|
||||
<!-- 2dp start padding for the start icon -->
|
||||
<item name="titleItemStartPadding">2dp</item>
|
||||
<item name="titleItemEndPadding">0dp</item>
|
||||
|
||||
<!-- Padding between content and the start icon is 14dp -->
|
||||
<item name="contentStartPadding">14dp</item>
|
||||
<!-- Padding between content and end items is 16dp -->
|
||||
<item name="contentEndPadding">16dp</item>
|
||||
|
||||
<!-- Both side margins of end item are 16dp -->
|
||||
<item name="endItemStartPadding">16dp</item>
|
||||
<item name="endItemEndPadding">16dp</item>
|
||||
|
||||
<!-- Both side margins of bottom divider are 12dp -->
|
||||
<item name="bottomDividerStartPadding">12dp</item>
|
||||
<item name="bottomDividerEndPadding">12dp</item>
|
||||
|
||||
<item name="actionDividerHeight">32dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.SystemUI.Dialog.Internet">
|
||||
<item name="android:windowBackground">@drawable/internet_dialog_background</item>
|
||||
</style>
|
||||
|
||||
<style name="MainSwitch.Settingslib" parent="@android:style/Theme.DeviceDefault">
|
||||
<item name="android:switchMinWidth">@dimen/settingslib_min_switch_width</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -65,6 +65,7 @@ import com.android.systemui.power.EnhancedEstimates;
|
||||
import com.android.systemui.power.PowerUI;
|
||||
import com.android.systemui.privacy.PrivacyItemController;
|
||||
import com.android.systemui.qs.ReduceBrightColorsController;
|
||||
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
|
||||
import com.android.systemui.recents.OverviewProxyService;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.screenrecord.RecordingController;
|
||||
@@ -364,6 +365,7 @@ public class Dependency {
|
||||
@Inject Lazy<UiEventLogger> mUiEventLogger;
|
||||
@Inject Lazy<FeatureFlags> mFeatureFlagsLazy;
|
||||
@Inject Lazy<StatusBarContentInsetsProvider> mContentInsetsProviderLazy;
|
||||
@Inject Lazy<InternetDialogFactory> mInternetDialogFactory;
|
||||
|
||||
@Inject
|
||||
public Dependency() {
|
||||
@@ -578,6 +580,7 @@ public class Dependency {
|
||||
mProviders.put(PrivacyDotViewController.class, mPrivacyDotViewControllerLazy::get);
|
||||
mProviders.put(EdgeBackGestureHandler.Factory.class,
|
||||
mEdgeBackGestureHandlerFactoryLazy::get);
|
||||
mProviders.put(InternetDialogFactory.class, mInternetDialogFactory::get);
|
||||
mProviders.put(UiEventLogger.class, mUiEventLogger::get);
|
||||
mProviders.put(FeatureFlags.class, mFeatureFlagsLazy::get);
|
||||
mProviders.put(StatusBarContentInsetsProvider.class, mContentInsetsProviderLazy::get);
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.provider.Settings;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.FeatureFlagUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Switch;
|
||||
@@ -51,6 +52,7 @@ import com.android.systemui.qs.AlphaControlledSignalTileView;
|
||||
import com.android.systemui.qs.QSHost;
|
||||
import com.android.systemui.qs.logging.QSLogger;
|
||||
import com.android.systemui.qs.tileimpl.QSTileImpl;
|
||||
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.IconState;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.MobileDataIndicators;
|
||||
@@ -75,6 +77,8 @@ public class InternetTile extends QSTileImpl<SignalState> {
|
||||
private int mLastTileState = -1;
|
||||
|
||||
protected final InternetSignalCallback mSignalCallback = new InternetSignalCallback();
|
||||
private final InternetDialogFactory mInternetDialogFactory;
|
||||
final Handler mHandler;
|
||||
|
||||
@Inject
|
||||
public InternetTile(
|
||||
@@ -86,10 +90,13 @@ public class InternetTile extends QSTileImpl<SignalState> {
|
||||
StatusBarStateController statusBarStateController,
|
||||
ActivityStarter activityStarter,
|
||||
QSLogger qsLogger,
|
||||
NetworkController networkController
|
||||
NetworkController networkController,
|
||||
InternetDialogFactory internetDialogFactory
|
||||
) {
|
||||
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
|
||||
statusBarStateController, activityStarter, qsLogger);
|
||||
mInternetDialogFactory = internetDialogFactory;
|
||||
mHandler = mainHandler;
|
||||
mController = networkController;
|
||||
mDataController = mController.getMobileDataController();
|
||||
mController.observe(getLifecycle(), mSignalCallback);
|
||||
@@ -114,7 +121,13 @@ public class InternetTile extends QSTileImpl<SignalState> {
|
||||
|
||||
@Override
|
||||
protected void handleClick(@Nullable View view) {
|
||||
mActivityStarter.postStartActivityDismissingKeyguard(INTERNET_PANEL, 0);
|
||||
if (!FeatureFlagUtils.isEnabled(mContext, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL)) {
|
||||
mActivityStarter.postStartActivityDismissingKeyguard(INTERNET_PANEL, 0);
|
||||
} else {
|
||||
mHandler.post(() -> {
|
||||
mInternetDialogFactory.create(true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE;
|
||||
import static com.android.wifitrackerlib.WifiEntry.SECURITY_OWE;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.R;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Adapter for showing Wi-Fi networks.
|
||||
*/
|
||||
public class InternetAdapter extends RecyclerView.Adapter<InternetAdapter.InternetViewHolder> {
|
||||
|
||||
private static final String TAG = "InternetAdapter";
|
||||
private static final String ACTION_WIFI_DIALOG = "com.android.settings.WIFI_DIALOG";
|
||||
private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key";
|
||||
private static final String EXTRA_CONNECT_FOR_CALLER = "connect_for_caller";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final InternetDialogController mInternetDialogController;
|
||||
|
||||
protected View mHolderView;
|
||||
protected Context mContext;
|
||||
|
||||
public InternetAdapter(InternetDialogController controller) {
|
||||
mInternetDialogController = controller;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InternetViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
|
||||
int viewType) {
|
||||
mContext = viewGroup.getContext();
|
||||
mHolderView = LayoutInflater.from(mContext).inflate(R.layout.internet_list_item,
|
||||
viewGroup, false);
|
||||
return new InternetViewHolder(mHolderView, mInternetDialogController);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull InternetViewHolder viewHolder, int position) {
|
||||
List<WifiEntry> wifiList = getWifiEntryList();
|
||||
if (wifiList != null && wifiList.size() != 0) {
|
||||
int count = getItemCount();
|
||||
if (wifiList.size() > count) {
|
||||
wifiList = getWifiEntryList().subList(0, count - 1);
|
||||
}
|
||||
|
||||
if (position < wifiList.size()) {
|
||||
viewHolder.onBind(wifiList.get(position));
|
||||
}
|
||||
} else if (DEBUG) {
|
||||
Log.d(TAG, "onBindViewHolder, Wi-Fi entry list = null");
|
||||
}
|
||||
}
|
||||
|
||||
private List<WifiEntry> getWifiEntryList() {
|
||||
if (mInternetDialogController.getWifiEntryList() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return mInternetDialogController.getWifiEntryList().stream()
|
||||
.filter(wifiAp -> wifiAp.getConnectedState()
|
||||
!= WifiEntry.CONNECTED_STATE_CONNECTED)
|
||||
.limit(getItemCount())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of networks (mobile network and entries of Wi-Fi) should be four in
|
||||
* {@link InternetDialog}.
|
||||
*
|
||||
* Airplane mode is ON (mobile network is gone):
|
||||
* Return four Wi-Fi's entries if no connected Wi-Fi.
|
||||
* Return three Wi-Fi's entries if one connected Wi-Fi.
|
||||
* Airplane mode is OFF (mobile network is visible):
|
||||
* Return three Wi-Fi's entries if no connected Wi-Fi.
|
||||
* Return two Wi-Fi's entries if one connected Wi-Fi.
|
||||
*
|
||||
* @return The total number of networks.
|
||||
*/
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
boolean hasConnectedWifi = mInternetDialogController.getConnectedWifiEntry() != null;
|
||||
if (mInternetDialogController.isAirplaneModeEnabled()) {
|
||||
return hasConnectedWifi ? 3 : 4;
|
||||
} else {
|
||||
return hasConnectedWifi ? 2 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ViewHolder for binding Wi-Fi view.
|
||||
*/
|
||||
static class InternetViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
final LinearLayout mContainerLayout;
|
||||
final LinearLayout mWifiListLayout;
|
||||
final LinearLayout mWifiNetworkLayout;
|
||||
final ImageView mWifiIcon;
|
||||
final TextView mWifiTitleText;
|
||||
final TextView mWifiSummaryText;
|
||||
final ImageView mWifiLockedIcon;
|
||||
final Context mContext;
|
||||
final InternetDialogController mInternetDialogController;
|
||||
|
||||
InternetViewHolder(View view, InternetDialogController internetDialogController) {
|
||||
super(view);
|
||||
mContext = view.getContext();
|
||||
mInternetDialogController = internetDialogController;
|
||||
mContainerLayout = view.requireViewById(R.id.internet_container);
|
||||
mWifiListLayout = view.requireViewById(R.id.wifi_list);
|
||||
mWifiNetworkLayout = view.requireViewById(R.id.wifi_network_layout);
|
||||
mWifiIcon = view.requireViewById(R.id.wifi_icon);
|
||||
mWifiTitleText = view.requireViewById(R.id.wifi_title);
|
||||
mWifiSummaryText = view.requireViewById(R.id.wifi_summary);
|
||||
mWifiLockedIcon = view.requireViewById(R.id.wifi_locked_icon);
|
||||
}
|
||||
|
||||
void onBind(WifiEntry wifiEntry) {
|
||||
int security = wifiEntry.getSecurity();
|
||||
try {
|
||||
mWifiIcon.setImageDrawable(getWifiDrawable(wifiEntry));
|
||||
if (isOpenNetwork(security)) {
|
||||
mWifiLockedIcon.setVisibility(View.GONE);
|
||||
} else {
|
||||
mWifiLockedIcon.setVisibility(View.VISIBLE);
|
||||
mWifiLockedIcon.setImageDrawable(
|
||||
mContext.getDrawable(R.drawable.ic_friction_lock_closed));
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
|
||||
setWifiNetworkLayout(wifiEntry.getTitle(),
|
||||
Html.fromHtml(wifiEntry.getSummary(false), Html.FROM_HTML_MODE_LEGACY));
|
||||
|
||||
mWifiListLayout.setOnClickListener(v -> {
|
||||
if (wifiEntry.shouldEditBeforeConnect()) {
|
||||
final Intent intent = new Intent(ACTION_WIFI_DIALOG);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||
intent.putExtra(EXTRA_CHOSEN_WIFI_ENTRY_KEY, wifiEntry.getKey());
|
||||
intent.putExtra(EXTRA_CONNECT_FOR_CALLER, false);
|
||||
mContext.startActivity(intent);
|
||||
}
|
||||
mInternetDialogController.connect(wifiEntry);
|
||||
});
|
||||
}
|
||||
|
||||
/** Return true if this is an open network AccessPoint. */
|
||||
boolean isOpenNetwork(int security) {
|
||||
return security == SECURITY_NONE
|
||||
|| security == SECURITY_OWE;
|
||||
}
|
||||
|
||||
void setWifiNetworkLayout(CharSequence title, CharSequence summary) {
|
||||
mWifiNetworkLayout.setVisibility(View.VISIBLE);
|
||||
mWifiTitleText.setText(title);
|
||||
if (TextUtils.isEmpty(summary)) {
|
||||
mWifiTitleText.setGravity(Gravity.CENTER);
|
||||
mWifiSummaryText.setVisibility(View.GONE);
|
||||
return;
|
||||
} else {
|
||||
mWifiTitleText.setGravity(Gravity.BOTTOM);
|
||||
mWifiSummaryText.setGravity(Gravity.TOP);
|
||||
mWifiSummaryText.setVisibility(View.VISIBLE);
|
||||
}
|
||||
mWifiSummaryText.setText(summary);
|
||||
}
|
||||
|
||||
Drawable getWifiDrawable(WifiEntry wifiEntry) throws Throwable {
|
||||
Drawable drawable = mContext.getDrawable(
|
||||
com.android.internal.R.drawable.ic_wifi_signal_0);
|
||||
|
||||
AtomicReference<Drawable> shared = new AtomicReference<>();
|
||||
final @ColorInt int tint = Utils.getColorAttrDefaultColor(mContext,
|
||||
android.R.attr.colorControlNormal);
|
||||
Drawable signalDrawable = mContext.getDrawable(
|
||||
Utils.getWifiIconResource(wifiEntry.getLevel()));
|
||||
signalDrawable.setTint(tint);
|
||||
shared.set(signalDrawable);
|
||||
drawable = shared.get();
|
||||
return drawable;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,553 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
|
||||
|
||||
import static com.android.systemui.Prefs.Key.QS_HAS_TURNED_OFF_MOBILE_DATA;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyDisplayInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.Html;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Space;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.UiEvent;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.systemui.Prefs;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
/**
|
||||
* Dialog for showing mobile network, connected Wi-Fi network and Wi-Fi networks.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class InternetDialog extends SystemUIDialog implements
|
||||
InternetDialogController.InternetDialogCallback, Window.Callback {
|
||||
private static final String TAG = "InternetDialog";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
private final Handler mHandler;
|
||||
private final LinearLayoutManager mLayoutManager;
|
||||
private final Runnable mHideProgressBarRunnable = () -> {
|
||||
setProgressBarVisible(false);
|
||||
};
|
||||
|
||||
@VisibleForTesting
|
||||
protected InternetAdapter mAdapter;
|
||||
@VisibleForTesting
|
||||
protected WifiManager mWifiManager;
|
||||
@VisibleForTesting
|
||||
protected View mDialogView;
|
||||
|
||||
private InternetDialogFactory mInternetDialogFactory;
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private AlertDialog mAlertDialog;
|
||||
private UiEventLogger mUiEventLogger;
|
||||
private Context mContext;
|
||||
private InternetDialogController mInternetDialogController;
|
||||
private TextView mInternetDialogTitle;
|
||||
private TextView mInternetDialogSubTitle;
|
||||
private ProgressBar mProgressBar;
|
||||
private LinearLayout mInternetListLayout;
|
||||
private LinearLayout mConnectedWifListLayout;
|
||||
private LinearLayout mConnectedWifList;
|
||||
private LinearLayout mMobileNetworkLayout;
|
||||
private LinearLayout mMobileNetworkList;
|
||||
private LinearLayout mTurnWifiOnLayout;
|
||||
private LinearLayout mSeeAllLayout;
|
||||
private Space mSpace;
|
||||
private RecyclerView mWifiRecyclerView;
|
||||
private ImageView mConnectedWifiIcon;
|
||||
private ImageView mWifiSettingsIcon;
|
||||
private TextView mConnectedWifiTitleText;
|
||||
private TextView mConnectedWifiSummaryText;
|
||||
private ImageView mSignalIcon;
|
||||
private TextView mMobileTitleText;
|
||||
private TextView mMobileSummaryText;
|
||||
private Switch mMobileDataToggle;
|
||||
private Switch mWiFiToggle;
|
||||
private Button mDoneButton;
|
||||
private Drawable mBackgroundOn;
|
||||
private WifiEntry mConnectedWifiEntry;
|
||||
private int mListMaxHeight;
|
||||
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
private boolean mIsProgressBarVisible;
|
||||
|
||||
private final ViewTreeObserver.OnGlobalLayoutListener mInternetListLayoutListener = () -> {
|
||||
// Set max height for list
|
||||
if (mInternetListLayout.getHeight() > mListMaxHeight) {
|
||||
ViewGroup.LayoutParams params = mInternetListLayout.getLayoutParams();
|
||||
params.height = mListMaxHeight;
|
||||
mInternetListLayout.setLayoutParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
public InternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
||||
InternetDialogController internetDialogController,
|
||||
boolean aboveStatusBar, UiEventLogger uiEventLogger, @Main Handler handler) {
|
||||
super(context, R.style.Theme_SystemUI_Dialog_Internet);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Init InternetDialog");
|
||||
}
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
mInternetDialogFactory = internetDialogFactory;
|
||||
mInternetDialogController = internetDialogController;
|
||||
mSubscriptionManager = mInternetDialogController.getSubscriptionManager();
|
||||
mDefaultDataSubId = mInternetDialogController.getDefaultDataSubscriptionId();
|
||||
mTelephonyManager = mInternetDialogController.getTelephonyManager();
|
||||
mWifiManager = mInternetDialogController.getWifiManager();
|
||||
|
||||
mLayoutManager = new LinearLayoutManager(mContext) {
|
||||
@Override
|
||||
public boolean canScrollVertically() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
mListMaxHeight = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.internet_dialog_list_max_height);
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mAdapter = new InternetAdapter(mInternetDialogController);
|
||||
if (!aboveStatusBar) {
|
||||
getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onCreate");
|
||||
}
|
||||
mUiEventLogger.log(InternetDialogEvent.INTERNET_DIALOG_SHOW);
|
||||
mDialogView = LayoutInflater.from(mContext).inflate(R.layout.internet_connectivity_dialog,
|
||||
null);
|
||||
final Window window = getWindow();
|
||||
final WindowManager.LayoutParams layoutParams = window.getAttributes();
|
||||
layoutParams.gravity = Gravity.BOTTOM;
|
||||
// Move down the dialog to overlay the navigation bar.
|
||||
layoutParams.setFitInsetsTypes(
|
||||
layoutParams.getFitInsetsTypes() & ~WindowInsets.Type.navigationBars());
|
||||
layoutParams.setFitInsetsSides(WindowInsets.Side.all());
|
||||
layoutParams.setFitInsetsIgnoringVisibility(true);
|
||||
window.setAttributes(layoutParams);
|
||||
window.setContentView(mDialogView);
|
||||
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
window.setWindowAnimations(R.style.Animation_InternetDialog);
|
||||
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||
window.addFlags(FLAG_LAYOUT_NO_LIMITS);
|
||||
|
||||
mInternetDialogTitle = mDialogView.requireViewById(R.id.internet_dialog_title);
|
||||
mInternetDialogSubTitle = mDialogView.requireViewById(R.id.internet_dialog_subtitle);
|
||||
mProgressBar = mDialogView.requireViewById(R.id.wifi_searching_progress);
|
||||
mInternetListLayout = mDialogView.requireViewById(R.id.internet_list);
|
||||
mMobileNetworkLayout = mDialogView.requireViewById(R.id.mobile_network_layout);
|
||||
mMobileNetworkList = mDialogView.requireViewById(R.id.mobile_network_list);
|
||||
mTurnWifiOnLayout = mDialogView.requireViewById(R.id.turn_on_wifi_layout);
|
||||
mConnectedWifListLayout = mDialogView.requireViewById(R.id.wifi_connected_layout);
|
||||
mConnectedWifList = mDialogView.requireViewById(R.id.wifi_connected_list);
|
||||
mConnectedWifiIcon = mDialogView.requireViewById(R.id.wifi_connected_icon);
|
||||
mConnectedWifiTitleText = mDialogView.requireViewById(R.id.wifi_connected_title);
|
||||
mConnectedWifiSummaryText = mDialogView.requireViewById(R.id.wifi_connected_summary);
|
||||
mWifiSettingsIcon = mDialogView.requireViewById(R.id.wifi_settings_icon);
|
||||
mWifiRecyclerView = mDialogView.requireViewById(R.id.wifi_list_layout);
|
||||
mSeeAllLayout = mDialogView.requireViewById(R.id.see_all_layout);
|
||||
mSpace = mDialogView.requireViewById(R.id.space);
|
||||
mDoneButton = mDialogView.requireViewById(R.id.done);
|
||||
mSignalIcon = mDialogView.requireViewById(R.id.signal_icon);
|
||||
mMobileTitleText = mDialogView.requireViewById(R.id.mobile_title);
|
||||
mMobileSummaryText = mDialogView.requireViewById(R.id.mobile_summary);
|
||||
mMobileDataToggle = mDialogView.requireViewById(R.id.mobile_toggle);
|
||||
mWiFiToggle = mDialogView.requireViewById(R.id.wifi_toggle);
|
||||
mBackgroundOn = mContext.getDrawable(R.drawable.settingslib_switch_bar_bg_on);
|
||||
mInternetListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
mInternetListLayoutListener);
|
||||
mInternetDialogTitle.setText(getDialogTitleText());
|
||||
mInternetDialogTitle.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
||||
|
||||
setOnClickListener();
|
||||
mTurnWifiOnLayout.setBackground(null);
|
||||
mWifiRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mWifiRecyclerView.setAdapter(mAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onStart");
|
||||
}
|
||||
mInternetDialogController.onStart(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onStop");
|
||||
}
|
||||
mHandler.removeCallbacks(mHideProgressBarRunnable);
|
||||
mMobileNetworkLayout.setOnClickListener(null);
|
||||
mMobileDataToggle.setOnCheckedChangeListener(null);
|
||||
mConnectedWifListLayout.setOnClickListener(null);
|
||||
mSeeAllLayout.setOnClickListener(null);
|
||||
mWiFiToggle.setOnCheckedChangeListener(null);
|
||||
mDoneButton.setOnClickListener(null);
|
||||
mInternetDialogController.onStop();
|
||||
mInternetDialogFactory.destroyDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissDialog() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "dismissDialog");
|
||||
}
|
||||
mInternetDialogFactory.destroyDialog();
|
||||
dismiss();
|
||||
}
|
||||
|
||||
void updateDialog() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "updateDialog");
|
||||
}
|
||||
if (mInternetDialogController.isAirplaneModeEnabled()) {
|
||||
mInternetDialogSubTitle.setVisibility(View.GONE);
|
||||
} else {
|
||||
mInternetDialogSubTitle.setText(getSubtitleText());
|
||||
}
|
||||
showProgressBar();
|
||||
setMobileDataLayout(mInternetDialogController.activeNetworkIsCellular());
|
||||
setConnectedWifiLayout();
|
||||
boolean isWifiEnabled = mWifiManager.isWifiEnabled();
|
||||
mWiFiToggle.setChecked(isWifiEnabled);
|
||||
int visible = isWifiEnabled ? View.VISIBLE : View.GONE;
|
||||
mWifiRecyclerView.setVisibility(visible);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mSeeAllLayout.setVisibility(visible);
|
||||
mSpace.setVisibility(isWifiEnabled ? View.GONE : View.VISIBLE);
|
||||
}
|
||||
|
||||
private void setOnClickListener() {
|
||||
mMobileNetworkLayout.setOnClickListener(v -> {
|
||||
if (mInternetDialogController.isMobileDataEnabled()) {
|
||||
if (!mInternetDialogController.activeNetworkIsCellular()) {
|
||||
mInternetDialogController.connectCarrierNetwork();
|
||||
}
|
||||
}
|
||||
});
|
||||
mMobileDataToggle.setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
if (!isChecked && shouldShowMobileDialog()) {
|
||||
showTurnOffMobileDialog();
|
||||
} else if (!shouldShowMobileDialog()) {
|
||||
mInternetDialogController.setMobileDataEnabled(mContext, mDefaultDataSubId,
|
||||
isChecked, false);
|
||||
}
|
||||
});
|
||||
mConnectedWifListLayout.setOnClickListener(v -> {
|
||||
// TODO(b/191475923): Need to launch the detailed page of Wi-Fi entry.
|
||||
});
|
||||
mSeeAllLayout.setOnClickListener(v -> onClickSeeMoreButton());
|
||||
mWiFiToggle.setOnCheckedChangeListener(
|
||||
(buttonView, isChecked) -> {
|
||||
buttonView.setChecked(isChecked);
|
||||
mWifiManager.setWifiEnabled(isChecked);
|
||||
mSpace.setVisibility(isChecked ? View.GONE : View.VISIBLE);
|
||||
});
|
||||
mDoneButton.setOnClickListener(v -> dismiss());
|
||||
}
|
||||
|
||||
private void setMobileDataLayout(boolean isCellularNetwork) {
|
||||
if (mInternetDialogController.isAirplaneModeEnabled()
|
||||
|| !mInternetDialogController.hasCarrier()) {
|
||||
mMobileNetworkLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
mMobileDataToggle.setChecked(mInternetDialogController.isMobileDataEnabled());
|
||||
mMobileNetworkLayout.setVisibility(View.VISIBLE);
|
||||
mMobileTitleText.setText(getMobileNetworkTitle());
|
||||
mMobileSummaryText.setText(
|
||||
Html.fromHtml(getMobileNetworkSummary(), Html.FROM_HTML_MODE_LEGACY));
|
||||
mSignalIcon.setImageDrawable(getSignalStrengthDrawable());
|
||||
int titleColor = isCellularNetwork ? mContext.getColor(
|
||||
R.color.connected_network_primary_color) : Utils.getColorAttrDefaultColor(
|
||||
mContext, android.R.attr.textColorPrimary);
|
||||
int summaryColor = isCellularNetwork ? mContext.getColor(
|
||||
R.color.connected_network_tertiary_color) : Utils.getColorAttrDefaultColor(
|
||||
mContext, android.R.attr.textColorTertiary);
|
||||
mMobileTitleText.setTextColor(titleColor);
|
||||
mMobileSummaryText.setTextColor(summaryColor);
|
||||
mMobileNetworkLayout.setBackground(isCellularNetwork ? mBackgroundOn : null);
|
||||
}
|
||||
}
|
||||
|
||||
private void setConnectedWifiLayout() {
|
||||
if (!mWifiManager.isWifiEnabled()
|
||||
|| mInternetDialogController.getConnectedWifiEntry() == null) {
|
||||
mConnectedWifListLayout.setBackground(null);
|
||||
mConnectedWifListLayout.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
mConnectedWifListLayout.setVisibility(View.VISIBLE);
|
||||
mConnectedWifiTitleText.setText(getConnectedWifiTitle());
|
||||
mConnectedWifiSummaryText.setText(getConnectedWifiSummary());
|
||||
mConnectedWifiIcon.setImageDrawable(getConnectedWifiDrawable());
|
||||
mConnectedWifiTitleText.setTextColor(
|
||||
mContext.getColor(R.color.connected_network_primary_color));
|
||||
mConnectedWifiSummaryText.setTextColor(
|
||||
mContext.getColor(R.color.connected_network_tertiary_color));
|
||||
mWifiSettingsIcon.setColorFilter(
|
||||
mContext.getColor(R.color.connected_network_primary_color));
|
||||
mConnectedWifListLayout.setBackground(mBackgroundOn);
|
||||
}
|
||||
|
||||
void onClickSeeMoreButton() {
|
||||
mInternetDialogController.launchNetworkSetting();
|
||||
}
|
||||
|
||||
CharSequence getDialogTitleText() {
|
||||
return mInternetDialogController.getDialogTitleText();
|
||||
}
|
||||
|
||||
CharSequence getSubtitleText() {
|
||||
return mInternetDialogController.getSubtitleText(mIsProgressBarVisible);
|
||||
}
|
||||
|
||||
private Drawable getConnectedWifiDrawable() {
|
||||
try {
|
||||
return mInternetDialogController.getWifiConnectedDrawable(mConnectedWifiEntry);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Drawable getSignalStrengthDrawable() {
|
||||
return mInternetDialogController.getSignalStrengthDrawable();
|
||||
}
|
||||
|
||||
CharSequence getMobileNetworkTitle() {
|
||||
return mInternetDialogController.getMobileNetworkTitle();
|
||||
}
|
||||
|
||||
String getMobileNetworkSummary() {
|
||||
return mInternetDialogController.getMobileNetworkSummary();
|
||||
}
|
||||
|
||||
String getConnectedWifiTitle() {
|
||||
return mInternetDialogController.getConnectedWifiTitle();
|
||||
}
|
||||
|
||||
String getConnectedWifiSummary() {
|
||||
return mInternetDialogController.getConnectedWifiSummary();
|
||||
}
|
||||
|
||||
private void showProgressBar() {
|
||||
if (mWifiManager == null || !mWifiManager.isWifiEnabled()) {
|
||||
setProgressBarVisible(false);
|
||||
return;
|
||||
}
|
||||
setProgressBarVisible(true);
|
||||
List<ScanResult> wifiScanResults = mWifiManager.getScanResults();
|
||||
if (wifiScanResults != null && wifiScanResults.size() > 0) {
|
||||
mContext.getMainThreadHandler().postDelayed(mHideProgressBarRunnable,
|
||||
2000 /* delay millis */);
|
||||
}
|
||||
}
|
||||
|
||||
private void setProgressBarVisible(boolean visible) {
|
||||
if (mWifiManager.isWifiEnabled() && mAdapter.mHolderView != null
|
||||
&& mAdapter.mHolderView.isAttachedToWindow()) {
|
||||
mIsProgressBarVisible = true;
|
||||
}
|
||||
mIsProgressBarVisible = visible;
|
||||
mProgressBar.setVisibility(mIsProgressBarVisible ? View.VISIBLE : View.INVISIBLE);
|
||||
mInternetDialogSubTitle.setText(getSubtitleText());
|
||||
}
|
||||
|
||||
private boolean shouldShowMobileDialog() {
|
||||
boolean flag = Prefs.getBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA,
|
||||
false);
|
||||
if (mInternetDialogController.isMobileDataEnabled() && !flag) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void showTurnOffMobileDialog() {
|
||||
CharSequence carrierName =
|
||||
mSubscriptionManager.getDefaultDataSubscriptionInfo().getCarrierName();
|
||||
boolean isInService = mInternetDialogController.isVoiceStateInService();
|
||||
if (TextUtils.isEmpty(carrierName) || !isInService) {
|
||||
carrierName = mContext.getString(R.string.mobile_data_disable_message_default_carrier);
|
||||
}
|
||||
mAlertDialog = new Builder(mContext)
|
||||
.setTitle(R.string.mobile_data_disable_title)
|
||||
.setMessage(mContext.getString(R.string.mobile_data_disable_message, carrierName))
|
||||
.setNegativeButton(android.R.string.cancel, (d, w) -> {
|
||||
mMobileDataToggle.setChecked(true);
|
||||
})
|
||||
.setPositiveButton(
|
||||
com.android.internal.R.string.alert_windows_notification_turn_off_action,
|
||||
(d, w) -> {
|
||||
mInternetDialogController.setMobileDataEnabled(mContext,
|
||||
mDefaultDataSubId, false, false);
|
||||
mMobileDataToggle.setChecked(false);
|
||||
Prefs.putBoolean(mContext, QS_HAS_TURNED_OFF_MOBILE_DATA, true);
|
||||
})
|
||||
.create();
|
||||
mAlertDialog.setOnCancelListener(dialog -> mMobileDataToggle.setChecked(true));
|
||||
mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
|
||||
SystemUIDialog.setShowForAllUsers(mAlertDialog, true);
|
||||
SystemUIDialog.registerDismissListener(mAlertDialog);
|
||||
SystemUIDialog.setWindowOnTop(mAlertDialog);
|
||||
mAlertDialog.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRefreshCarrierInfo() {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSimStateChanged() {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscriptionsChanged(int defaultDataSubId) {
|
||||
mDefaultDataSubId = defaultDataSubId;
|
||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(ServiceState serviceState) {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataConnectionStateChanged(int state, int networkType) {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo) {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessPointsChanged(List<WifiEntry> wifiEntryList, WifiEntry connectedEntry) {
|
||||
mConnectedWifiEntry = connectedEntry;
|
||||
mAdapter.notifyDataSetChanged();
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
if (mAlertDialog != null && !mAlertDialog.isShowing()) {
|
||||
if (!hasFocus && isShowing()) {
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWifiStateReceived(Context context, Intent intent) {
|
||||
if (intent == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String action = intent.getAction();
|
||||
if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
|
||||
mInternetDialogController.scanWifiAccessPoints();
|
||||
showProgressBar();
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
mHandler.post(() -> updateDialog());
|
||||
}
|
||||
}
|
||||
|
||||
public enum InternetDialogEvent implements UiEventLogger.UiEventEnum {
|
||||
@UiEvent(doc = "The Internet dialog became visible on the screen.")
|
||||
INTERNET_DIALOG_SHOW(843);
|
||||
|
||||
private final int mId;
|
||||
|
||||
InternetDialogEvent(int id) {
|
||||
mId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return mId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,851 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import static com.android.settingslib.mobile.MobileMappings.getIconKey;
|
||||
import static com.android.settingslib.mobile.MobileMappings.mapIconSets;
|
||||
|
||||
import android.annotation.ColorInt;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.provider.Settings;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SignalStrength;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyCallback;
|
||||
import android.telephony.TelephonyDisplayInfo;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.keyguard.KeyguardUpdateMonitorCallback;
|
||||
import com.android.settingslib.DeviceInfoUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
import com.android.settingslib.graph.SignalDrawable;
|
||||
import com.android.settingslib.mobile.MobileMappings;
|
||||
import com.android.settingslib.net.SignalStrengthUtil;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
|
||||
import com.android.systemui.util.settings.GlobalSettings;
|
||||
import com.android.wifitrackerlib.MergedCarrierEntry;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
public class InternetDialogController implements WifiEntry.DisconnectCallback,
|
||||
NetworkController.AccessPointController.AccessPointCallback {
|
||||
|
||||
private static final String TAG = "InternetDialogController";
|
||||
private static final String ACTION_NETWORK_PROVIDER_SETTINGS =
|
||||
"android.settings.NETWORK_PROVIDER_SETTINGS";
|
||||
private static final String EXTRA_CHOSEN_WIFI_ENTRY_KEY = "key_chosen_wifientry_key";
|
||||
public static final Drawable EMPTY_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
|
||||
public static final int NO_CELL_DATA_TYPE_ICON = 0;
|
||||
private static final int SUBTITLE_TEXT_WIFI_IS_OFF = R.string.wifi_is_off;
|
||||
private static final int SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT =
|
||||
R.string.tap_a_network_to_connect;
|
||||
private static final int SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS =
|
||||
R.string.wifi_empty_list_wifi_on;
|
||||
private static final int SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE =
|
||||
R.string.non_carrier_network_unavailable;
|
||||
private static final int SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE =
|
||||
R.string.all_network_unavailable;
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private WifiManager mWifiManager;
|
||||
private Context mContext;
|
||||
private ActivityStarter mActivityStarter;
|
||||
private SubscriptionManager mSubscriptionManager;
|
||||
private TelephonyManager mTelephonyManager;
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
private TelephonyDisplayInfo mTelephonyDisplayInfo =
|
||||
new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_UNKNOWN,
|
||||
TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
|
||||
private Handler mHandler;
|
||||
private MobileMappings.Config mConfig = null;
|
||||
private Executor mExecutor;
|
||||
private AccessPointController mAccessPointController;
|
||||
private IntentFilter mWifiStateFilter;
|
||||
private InternetDialogCallback mCallback;
|
||||
private List<WifiEntry> mWifiEntry;
|
||||
private WifiEntry mConnectedEntry;
|
||||
private UiEventLogger mUiEventLogger;
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
private GlobalSettings mGlobalSettings;
|
||||
private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
||||
|
||||
@VisibleForTesting
|
||||
protected SubscriptionManager.OnSubscriptionsChangedListener mOnSubscriptionsChangedListener;
|
||||
@VisibleForTesting
|
||||
protected InternetTelephonyCallback mInternetTelephonyCallback;
|
||||
|
||||
private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
|
||||
new KeyguardUpdateMonitorCallback() {
|
||||
@Override
|
||||
public void onRefreshCarrierInfo() {
|
||||
mCallback.onRefreshCarrierInfo();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSimStateChanged(int subId, int slotId, int simState) {
|
||||
mCallback.onSimStateChanged();
|
||||
}
|
||||
};
|
||||
|
||||
protected List<SubscriptionInfo> getSubscriptionInfo() {
|
||||
return mKeyguardUpdateMonitor.getFilteredSubscriptionInfo(false);
|
||||
}
|
||||
|
||||
@Inject
|
||||
public InternetDialogController(@NonNull Context context, UiEventLogger uiEventLogger,
|
||||
ActivityStarter starter, AccessPointController accessPointController,
|
||||
SubscriptionManager subscriptionManager, TelephonyManager telephonyManager,
|
||||
@Nullable WifiManager wifiManager, ConnectivityManager connectivityManager,
|
||||
@Main Handler handler, @Main Executor mainExecutor,
|
||||
BroadcastDispatcher broadcastDispatcher, KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||
GlobalSettings globalSettings) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Init InternetDialogController");
|
||||
}
|
||||
mHandler = handler;
|
||||
mExecutor = mainExecutor;
|
||||
mContext = context;
|
||||
mGlobalSettings = globalSettings;
|
||||
mWifiManager = wifiManager;
|
||||
mTelephonyManager = telephonyManager;
|
||||
mConnectivityManager = connectivityManager;
|
||||
mSubscriptionManager = subscriptionManager;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
|
||||
mWifiStateFilter = new IntentFilter(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
mWifiStateFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mActivityStarter = starter;
|
||||
mAccessPointController = accessPointController;
|
||||
mConfig = MobileMappings.Config.readConfig(mContext);
|
||||
}
|
||||
|
||||
void onStart(@NonNull InternetDialogCallback callback) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onStart");
|
||||
}
|
||||
mCallback = callback;
|
||||
mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
|
||||
mAccessPointController.addAccessPointCallback(this);
|
||||
mBroadcastDispatcher.registerReceiver(mWifiStateReceiver, mWifiStateFilter, mExecutor);
|
||||
// Listen the subscription changes
|
||||
mOnSubscriptionsChangedListener = new InternetOnSubscriptionChangedListener();
|
||||
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
|
||||
mOnSubscriptionsChangedListener);
|
||||
mDefaultDataSubId = getDefaultDataSubscriptionId();
|
||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
||||
mInternetTelephonyCallback = new InternetTelephonyCallback();
|
||||
mTelephonyManager.registerTelephonyCallback(mExecutor, mInternetTelephonyCallback);
|
||||
// Listen the connectivity changes
|
||||
mConnectivityManager.registerNetworkCallback(new NetworkRequest.Builder()
|
||||
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
.build(), new DataConnectivityListener(), mHandler);
|
||||
scanWifiAccessPoints();
|
||||
}
|
||||
|
||||
void onStop() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onStop");
|
||||
}
|
||||
mBroadcastDispatcher.unregisterReceiver(mWifiStateReceiver);
|
||||
mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback);
|
||||
mSubscriptionManager.removeOnSubscriptionsChangedListener(
|
||||
mOnSubscriptionsChangedListener);
|
||||
mAccessPointController.removeAccessPointCallback(this);
|
||||
mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean isAirplaneModeEnabled() {
|
||||
return mGlobalSettings.getInt(Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected int getDefaultDataSubscriptionId() {
|
||||
return mSubscriptionManager.getDefaultDataSubscriptionId();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected Intent getSettingsIntent() {
|
||||
return new Intent(ACTION_NETWORK_PROVIDER_SETTINGS).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
|
||||
CharSequence getDialogTitleText() {
|
||||
if (isAirplaneModeEnabled()) {
|
||||
return mContext.getText(R.string.airplane_mode);
|
||||
}
|
||||
return mContext.getText(R.string.quick_settings_internet_label);
|
||||
}
|
||||
|
||||
CharSequence getSubtitleText(boolean isProgressBarVisible) {
|
||||
if (isAirplaneModeEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!mWifiManager.isWifiEnabled()) {
|
||||
// When the airplane mode is off and Wi-Fi is disabled.
|
||||
// Sub-Title: Wi-Fi is off
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Airplane mode off + Wi-Fi off.");
|
||||
}
|
||||
return mContext.getText(SUBTITLE_TEXT_WIFI_IS_OFF);
|
||||
}
|
||||
|
||||
if (isProgressBarVisible) {
|
||||
// When the Wi-Fi scan result callback is received
|
||||
// Sub-Title: Searching for networks...
|
||||
return mContext.getText(SUBTITLE_TEXT_SEARCHING_FOR_NETWORKS);
|
||||
}
|
||||
|
||||
final List<ScanResult> wifiList = mWifiManager.getScanResults();
|
||||
if (wifiList != null && wifiList.size() != 0) {
|
||||
return mContext.getText(SUBTITLE_TEXT_TAP_A_NETWORK_TO_CONNECT);
|
||||
}
|
||||
|
||||
// Sub-Title:
|
||||
// show non_carrier_network_unavailable
|
||||
// - while Wi-Fi on + no Wi-Fi item
|
||||
// - while Wi-Fi on + no Wi-Fi item + mobile data off
|
||||
// show all_network_unavailable:
|
||||
// - while Wi-Fi on + no Wi-Fi item + no carrier item
|
||||
// - while Wi-Fi on + no Wi-Fi item + service is out of service
|
||||
// - while Wi-Fi on + no Wi-Fi item + mobile data on + no carrier data.
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "No Wi-Fi item.");
|
||||
}
|
||||
if (!hasCarrier() || (!isVoiceStateInService() && !isDataStateInService())) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "No carrier or service is out of service.");
|
||||
}
|
||||
return mContext.getText(SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE);
|
||||
}
|
||||
|
||||
if (!isMobileDataEnabled()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Mobile data off");
|
||||
}
|
||||
return mContext.getText(SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE);
|
||||
}
|
||||
|
||||
if (!activeNetworkIsCellular()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "No carrier data.");
|
||||
}
|
||||
return mContext.getText(SUBTITLE_TEXT_ALL_CARRIER_NETWORK_UNAVAILABLE);
|
||||
}
|
||||
|
||||
return mContext.getText(SUBTITLE_TEXT_NON_CARRIER_NETWORK_UNAVAILABLE);
|
||||
}
|
||||
|
||||
Drawable getWifiConnectedDrawable(WifiEntry wifiEntry) throws Throwable {
|
||||
final @ColorInt int tint;
|
||||
tint = Utils.getColorAttrDefaultColor(mContext,
|
||||
com.android.internal.R.attr.colorAccentPrimaryVariant);
|
||||
final Drawable drawable = mContext.getDrawable(
|
||||
com.android.settingslib.Utils.getWifiIconResource(wifiEntry.getLevel()));
|
||||
drawable.setTint(tint);
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
Drawable getSignalStrengthDrawable() {
|
||||
Drawable drawable = mContext.getDrawable(
|
||||
R.drawable.ic_signal_strength_zero_bar_no_internet);
|
||||
try {
|
||||
if (mTelephonyManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "TelephonyManager is null");
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
|
||||
if (isDataStateInService() || isVoiceStateInService()) {
|
||||
AtomicReference<Drawable> shared = new AtomicReference<>();
|
||||
shared.set(getSignalStrengthDrawableWithLevel());
|
||||
drawable = shared.get();
|
||||
}
|
||||
|
||||
drawable.setTint(
|
||||
Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorControlNormal));
|
||||
if (activeNetworkIsCellular()) {
|
||||
drawable.setTint(Utils.getColorAttrDefaultColor(mContext,
|
||||
com.android.internal.R.attr.colorAccentPrimaryVariant));
|
||||
}
|
||||
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return drawable;
|
||||
}
|
||||
|
||||
/**
|
||||
* To get the signal bar icon with level.
|
||||
*
|
||||
* @return The Drawable which is a signal bar icon with level.
|
||||
*/
|
||||
Drawable getSignalStrengthDrawableWithLevel() {
|
||||
final SignalStrength strength = mTelephonyManager.getSignalStrength();
|
||||
int level = (strength == null) ? 0 : strength.getLevel();
|
||||
int numLevels = SignalStrength.NUM_SIGNAL_STRENGTH_BINS;
|
||||
if (mSubscriptionManager != null && shouldInflateSignalStrength(mDefaultDataSubId)) {
|
||||
level += 1;
|
||||
numLevels += 1;
|
||||
}
|
||||
return getSignalStrengthIcon(mContext, level, numLevels, NO_CELL_DATA_TYPE_ICON, false);
|
||||
}
|
||||
|
||||
Drawable getSignalStrengthIcon(Context context, int level, int numLevels,
|
||||
int iconType, boolean cutOut) {
|
||||
Log.d(TAG, "getSignalStrengthIcon");
|
||||
final SignalDrawable signalDrawable = new SignalDrawable(context);
|
||||
signalDrawable.setLevel(
|
||||
SignalDrawable.getState(level, numLevels, cutOut));
|
||||
|
||||
// Make the network type drawable
|
||||
final Drawable networkDrawable =
|
||||
iconType == NO_CELL_DATA_TYPE_ICON
|
||||
? EMPTY_DRAWABLE
|
||||
: context.getResources().getDrawable(iconType, context.getTheme());
|
||||
|
||||
// Overlay the two drawables
|
||||
final Drawable[] layers = {networkDrawable, signalDrawable};
|
||||
final int iconSize =
|
||||
context.getResources().getDimensionPixelSize(R.dimen.signal_strength_icon_size);
|
||||
|
||||
final LayerDrawable icons = new LayerDrawable(layers);
|
||||
// Set the network type icon at the top left
|
||||
icons.setLayerGravity(0 /* index of networkDrawable */, Gravity.TOP | Gravity.LEFT);
|
||||
// Set the signal strength icon at the bottom right
|
||||
icons.setLayerGravity(1 /* index of SignalDrawable */, Gravity.BOTTOM | Gravity.RIGHT);
|
||||
icons.setLayerSize(1 /* index of SignalDrawable */, iconSize, iconSize);
|
||||
icons.setTintList(Utils.getColorAttr(context, android.R.attr.colorControlNormal));
|
||||
return icons;
|
||||
}
|
||||
|
||||
private boolean shouldInflateSignalStrength(int subId) {
|
||||
return SignalStrengthUtil.shouldInflateSignalStrength(mContext, subId);
|
||||
}
|
||||
|
||||
private CharSequence getUniqueSubscriptionDisplayName(int subscriptionId, Context context) {
|
||||
final Map<Integer, CharSequence> displayNames = getUniqueSubscriptionDisplayNames(context);
|
||||
return displayNames.getOrDefault(subscriptionId, "");
|
||||
}
|
||||
|
||||
private Map<Integer, CharSequence> getUniqueSubscriptionDisplayNames(Context context) {
|
||||
class DisplayInfo {
|
||||
public SubscriptionInfo subscriptionInfo;
|
||||
public CharSequence originalName;
|
||||
public CharSequence uniqueName;
|
||||
}
|
||||
|
||||
// Map of SubscriptionId to DisplayName
|
||||
final Supplier<Stream<DisplayInfo>> originalInfos =
|
||||
() -> getSubscriptionInfo()
|
||||
.stream()
|
||||
.filter(i -> {
|
||||
// Filter out null values.
|
||||
return (i != null && i.getDisplayName() != null);
|
||||
})
|
||||
.map(i -> {
|
||||
DisplayInfo info = new DisplayInfo();
|
||||
info.subscriptionInfo = i;
|
||||
info.originalName = i.getDisplayName().toString().trim();
|
||||
return info;
|
||||
});
|
||||
|
||||
// A Unique set of display names
|
||||
Set<CharSequence> uniqueNames = new HashSet<>();
|
||||
// Return the set of duplicate names
|
||||
final Set<CharSequence> duplicateOriginalNames = originalInfos.get()
|
||||
.filter(info -> !uniqueNames.add(info.originalName))
|
||||
.map(info -> info.originalName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// If a display name is duplicate, append the final 4 digits of the phone number.
|
||||
// Creates a mapping of Subscription id to original display name + phone number display name
|
||||
final Supplier<Stream<DisplayInfo>> uniqueInfos = () -> originalInfos.get().map(info -> {
|
||||
if (duplicateOriginalNames.contains(info.originalName)) {
|
||||
// This may return null, if the user cannot view the phone number itself.
|
||||
final String phoneNumber = DeviceInfoUtils.getBidiFormattedPhoneNumber(context,
|
||||
info.subscriptionInfo);
|
||||
String lastFourDigits = "";
|
||||
if (phoneNumber != null) {
|
||||
lastFourDigits = (phoneNumber.length() > 4)
|
||||
? phoneNumber.substring(phoneNumber.length() - 4) : phoneNumber;
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(lastFourDigits)) {
|
||||
info.uniqueName = info.originalName;
|
||||
} else {
|
||||
info.uniqueName = info.originalName + " " + lastFourDigits;
|
||||
}
|
||||
|
||||
} else {
|
||||
info.uniqueName = info.originalName;
|
||||
}
|
||||
return info;
|
||||
});
|
||||
|
||||
// Check uniqueness a second time.
|
||||
// We might not have had permission to view the phone numbers.
|
||||
// There might also be multiple phone numbers whose last 4 digits the same.
|
||||
uniqueNames.clear();
|
||||
final Set<CharSequence> duplicatePhoneNames = uniqueInfos.get()
|
||||
.filter(info -> !uniqueNames.add(info.uniqueName))
|
||||
.map(info -> info.uniqueName)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return uniqueInfos.get().map(info -> {
|
||||
if (duplicatePhoneNames.contains(info.uniqueName)) {
|
||||
info.uniqueName = info.originalName + " "
|
||||
+ info.subscriptionInfo.getSubscriptionId();
|
||||
}
|
||||
return info;
|
||||
}).collect(Collectors.toMap(
|
||||
info -> info.subscriptionInfo.getSubscriptionId(),
|
||||
info -> info.uniqueName));
|
||||
}
|
||||
|
||||
CharSequence getMobileNetworkTitle() {
|
||||
return getUniqueSubscriptionDisplayName(mDefaultDataSubId, mContext);
|
||||
}
|
||||
|
||||
String getMobileNetworkSummary() {
|
||||
String description = getNetworkTypeDescription(mContext, mConfig,
|
||||
mTelephonyDisplayInfo, mDefaultDataSubId);
|
||||
return getMobileSummary(mContext, mTelephonyManager, description);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get currently description of mobile network type.
|
||||
*/
|
||||
private String getNetworkTypeDescription(Context context, MobileMappings.Config config,
|
||||
TelephonyDisplayInfo telephonyDisplayInfo, int subId) {
|
||||
String iconKey = getIconKey(telephonyDisplayInfo);
|
||||
|
||||
if (mapIconSets(config) == null || mapIconSets(config).get(iconKey) == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "The description of network type is empty.");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
int resId = mapIconSets(config).get(iconKey).dataContentDescription;
|
||||
return resId != 0
|
||||
? SubscriptionManager.getResourcesForSubId(context, subId).getString(resId) : "";
|
||||
}
|
||||
|
||||
private String getMobileSummary(Context context, TelephonyManager telephonyManager,
|
||||
String networkTypeDescription) {
|
||||
if (!isMobileDataEnabled()) {
|
||||
return context.getString(R.string.mobile_data_off_summary);
|
||||
}
|
||||
if (!isDataStateInService()) {
|
||||
return context.getString(R.string.mobile_data_no_connection);
|
||||
}
|
||||
String summary = networkTypeDescription;
|
||||
if (activeNetworkIsCellular()) {
|
||||
summary = context.getString(R.string.preference_summary_default_combination,
|
||||
context.getString(R.string.mobile_data_connection_active),
|
||||
networkTypeDescription);
|
||||
}
|
||||
return summary;
|
||||
}
|
||||
|
||||
String getConnectedWifiTitle() {
|
||||
if (getConnectedWifiEntry() == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "connected entry is null");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
return getConnectedWifiEntry().getTitle();
|
||||
}
|
||||
|
||||
String getConnectedWifiSummary() {
|
||||
if (getConnectedWifiEntry() == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "connected entry is null");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
return getConnectedWifiEntry().getSummary(false);
|
||||
}
|
||||
|
||||
void launchNetworkSetting() {
|
||||
mCallback.dismissDialog();
|
||||
mActivityStarter.postStartActivityDismissingKeyguard(getSettingsIntent(), 0);
|
||||
}
|
||||
|
||||
void connectCarrierNetwork() {
|
||||
final MergedCarrierEntry mergedCarrierEntry =
|
||||
mAccessPointController.getMergedCarrierEntry();
|
||||
if (mergedCarrierEntry != null && mergedCarrierEntry.canConnect()) {
|
||||
mergedCarrierEntry.connect(null /* ConnectCallback */);
|
||||
}
|
||||
}
|
||||
|
||||
List<WifiEntry> getWifiEntryList() {
|
||||
return mWifiEntry;
|
||||
}
|
||||
|
||||
WifiEntry getConnectedWifiEntry() {
|
||||
return mConnectedEntry;
|
||||
}
|
||||
|
||||
WifiManager getWifiManager() {
|
||||
return mWifiManager;
|
||||
}
|
||||
|
||||
TelephonyManager getTelephonyManager() {
|
||||
return mTelephonyManager;
|
||||
}
|
||||
|
||||
SubscriptionManager getSubscriptionManager() {
|
||||
return mSubscriptionManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether there is the carrier item in the slice.
|
||||
*/
|
||||
boolean hasCarrier() {
|
||||
if (mSubscriptionManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "SubscriptionManager is null, can not check carrier.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isAirplaneModeEnabled() || mTelephonyManager == null
|
||||
|| mSubscriptionManager.getActiveSubscriptionIdList().length <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if mobile data is enabled
|
||||
*/
|
||||
boolean isMobileDataEnabled() {
|
||||
if (mTelephonyManager == null || !mTelephonyManager.isDataEnabled()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether to enable data for {@code subId}, also whether to disable data for other
|
||||
* subscription
|
||||
*/
|
||||
void setMobileDataEnabled(Context context, int subId, boolean enabled,
|
||||
boolean disableOtherSubscriptions) {
|
||||
if (mTelephonyManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "TelephonyManager is null, can not set mobile data.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSubscriptionManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "SubscriptionManager is null, can not set mobile data.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mTelephonyManager.setDataEnabled(enabled);
|
||||
if (disableOtherSubscriptions) {
|
||||
final List<SubscriptionInfo> subInfoList =
|
||||
mSubscriptionManager.getActiveSubscriptionInfoList();
|
||||
if (subInfoList != null) {
|
||||
for (SubscriptionInfo subInfo : subInfoList) {
|
||||
// We never disable mobile data for opportunistic subscriptions.
|
||||
if (subInfo.getSubscriptionId() != subId && !subInfo.isOpportunistic()) {
|
||||
context.getSystemService(TelephonyManager.class).createForSubscriptionId(
|
||||
subInfo.getSubscriptionId()).setDataEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean isDataStateInService() {
|
||||
if (mTelephonyManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "TelephonyManager is null, can not detect mobile state.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return mTelephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED;
|
||||
}
|
||||
|
||||
boolean isVoiceStateInService() {
|
||||
if (mTelephonyManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "TelephonyManager is null, can not detect voice state.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final ServiceState serviceState = mTelephonyManager.getServiceState();
|
||||
return serviceState != null
|
||||
&& serviceState.getState() == serviceState.STATE_IN_SERVICE;
|
||||
}
|
||||
|
||||
boolean activeNetworkIsCellular() {
|
||||
if (mConnectivityManager == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "ConnectivityManager is null, can not check active network.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final Network activeNetwork = mConnectivityManager.getActiveNetwork();
|
||||
if (activeNetwork == null) {
|
||||
return false;
|
||||
}
|
||||
final NetworkCapabilities networkCapabilities =
|
||||
mConnectivityManager.getNetworkCapabilities(activeNetwork);
|
||||
if (networkCapabilities == null) {
|
||||
return false;
|
||||
}
|
||||
return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
|
||||
}
|
||||
|
||||
boolean connect(WifiEntry ap) {
|
||||
if (ap == null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "No Wi-Fi ap to connect.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ap.getWifiConfiguration() != null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "connect networkId=" + ap.getWifiConfiguration().networkId);
|
||||
}
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "connect to unsaved network " + ap.getTitle());
|
||||
}
|
||||
}
|
||||
ap.connect(new WifiEntryConnectCallback(mActivityStarter, mContext, ap));
|
||||
return false;
|
||||
}
|
||||
|
||||
static class WifiEntryConnectCallback implements WifiEntry.ConnectCallback {
|
||||
final ActivityStarter mActivityStarter;
|
||||
final Context mContext;
|
||||
final WifiEntry mWifiEntry;
|
||||
|
||||
WifiEntryConnectCallback(ActivityStarter activityStarter, Context context,
|
||||
WifiEntry connectWifiEntry) {
|
||||
mActivityStarter = activityStarter;
|
||||
mContext = context;
|
||||
mWifiEntry = connectWifiEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectResult(@ConnectStatus int status) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onConnectResult " + status);
|
||||
}
|
||||
|
||||
if (status == WifiEntry.ConnectCallback.CONNECT_STATUS_FAILURE_NO_CONFIG) {
|
||||
final Intent intent = new Intent("com.android.settings.WIFI_DIALOG")
|
||||
.putExtra(EXTRA_CHOSEN_WIFI_ENTRY_KEY, mWifiEntry.getKey());
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mActivityStarter.startActivity(intent, true);
|
||||
} else if (status == CONNECT_STATUS_FAILURE_UNKNOWN) {
|
||||
Toast.makeText(mContext, R.string.wifi_failed_connect_message,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "connect failure reason=" + status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void scanWifiAccessPoints() {
|
||||
mAccessPointController.scanForAccessPoints();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccessPointsChanged(List<WifiEntry> accessPoints) {
|
||||
if (accessPoints == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean hasConnectedWifi = false;
|
||||
mWifiEntry = accessPoints;
|
||||
for (WifiEntry wifiEntry : accessPoints) {
|
||||
if (wifiEntry.getConnectedState() == WifiEntry.CONNECTED_STATE_CONNECTED) {
|
||||
mConnectedEntry = wifiEntry;
|
||||
hasConnectedWifi = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasConnectedWifi) {
|
||||
mConnectedEntry = null;
|
||||
}
|
||||
|
||||
mCallback.onAccessPointsChanged(mWifiEntry, mConnectedEntry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSettingsActivityTriggered(Intent settingsIntent) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnectResult(int status) {
|
||||
}
|
||||
|
||||
private class InternetTelephonyCallback extends TelephonyCallback implements
|
||||
TelephonyCallback.DataConnectionStateListener,
|
||||
TelephonyCallback.DisplayInfoListener,
|
||||
TelephonyCallback.ServiceStateListener,
|
||||
TelephonyCallback.SignalStrengthsListener {
|
||||
|
||||
@Override
|
||||
public void onServiceStateChanged(@NonNull ServiceState serviceState) {
|
||||
mCallback.onServiceStateChanged(serviceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataConnectionStateChanged(int state, int networkType) {
|
||||
mCallback.onDataConnectionStateChanged(state, networkType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSignalStrengthsChanged(@NonNull SignalStrength signalStrength) {
|
||||
mCallback.onSignalStrengthsChanged(signalStrength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayInfoChanged(@NonNull TelephonyDisplayInfo telephonyDisplayInfo) {
|
||||
mTelephonyDisplayInfo = telephonyDisplayInfo;
|
||||
mCallback.onDisplayInfoChanged(telephonyDisplayInfo);
|
||||
}
|
||||
}
|
||||
|
||||
private class InternetOnSubscriptionChangedListener
|
||||
extends SubscriptionManager.OnSubscriptionsChangedListener {
|
||||
InternetOnSubscriptionChangedListener() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSubscriptionsChanged() {
|
||||
mDefaultDataSubId = getDefaultDataSubscriptionId();
|
||||
if (SubscriptionManager.isUsableSubscriptionId(mDefaultDataSubId)) {
|
||||
mTelephonyManager.unregisterTelephonyCallback(mInternetTelephonyCallback);
|
||||
|
||||
mTelephonyManager = mTelephonyManager.createForSubscriptionId(mDefaultDataSubId);
|
||||
mTelephonyManager.registerTelephonyCallback(mHandler::post,
|
||||
mInternetTelephonyCallback);
|
||||
mCallback.onSubscriptionsChanged(mDefaultDataSubId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class DataConnectivityListener extends ConnectivityManager.NetworkCallback {
|
||||
@Override
|
||||
public void onCapabilitiesChanged(@NonNull Network network,
|
||||
@NonNull NetworkCapabilities networkCapabilities) {
|
||||
final Network activeNetwork = mConnectivityManager.getActiveNetwork();
|
||||
if (activeNetwork != null && activeNetwork.equals(network)) {
|
||||
// update UI
|
||||
mCallback.onCapabilitiesChanged(network, networkCapabilities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mWifiStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
mCallback.onWifiStateReceived(context, intent);
|
||||
}
|
||||
};
|
||||
|
||||
interface InternetDialogCallback {
|
||||
|
||||
void onRefreshCarrierInfo();
|
||||
|
||||
void onSimStateChanged();
|
||||
|
||||
void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities);
|
||||
|
||||
void onSubscriptionsChanged(int defaultDataSubId);
|
||||
|
||||
void onServiceStateChanged(ServiceState serviceState);
|
||||
|
||||
void onDataConnectionStateChanged(int state, int networkType);
|
||||
|
||||
void onSignalStrengthsChanged(SignalStrength signalStrength);
|
||||
|
||||
void onDisplayInfoChanged(TelephonyDisplayInfo telephonyDisplayInfo);
|
||||
|
||||
void dismissDialog();
|
||||
|
||||
void onAccessPointsChanged(List<WifiEntry> wifiEntryList, WifiEntry connectedEntry);
|
||||
|
||||
void onWifiStateReceived(Context context, Intent intent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.systemui.qs.tiles.dialog
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Handler
|
||||
import android.util.Log
|
||||
import com.android.internal.logging.UiEventLogger
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val TAG = "InternetDialogFactory"
|
||||
private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
|
||||
|
||||
/**
|
||||
* Factory to create [InternetDialog] objects.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class InternetDialogFactory @Inject constructor(
|
||||
@Main private val handler: Handler,
|
||||
private val internetDialogController: InternetDialogController,
|
||||
private val context: Context,
|
||||
private val uiEventLogger: UiEventLogger
|
||||
) {
|
||||
companion object {
|
||||
var internetDialog: InternetDialog? = null
|
||||
}
|
||||
|
||||
/** Creates a [InternetDialog]. */
|
||||
fun create(aboveStatusBar: Boolean) {
|
||||
if (internetDialog != null) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "InternetDialog is showing, do not create it twice.")
|
||||
}
|
||||
return
|
||||
} else {
|
||||
internetDialog = InternetDialog(context, this, internetDialogController, aboveStatusBar,
|
||||
uiEventLogger, handler)
|
||||
internetDialog?.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun destroyDialog() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "destroyDialog")
|
||||
}
|
||||
internetDialog = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.FeatureFlagUtils;
|
||||
|
||||
public class InternetDialogUtil {
|
||||
|
||||
public static boolean isProviderModelEnabled(Context context) {
|
||||
if (context == null) {
|
||||
return false;
|
||||
}
|
||||
return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.SETTINGS_PROVIDER_MODEL);
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.wifitrackerlib.MergedCarrierEntry;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
import com.android.wifitrackerlib.WifiPickerTracker;
|
||||
|
||||
@@ -156,6 +157,15 @@ public class AccessPointControllerImpl
|
||||
fireAcccessPointsCallback(entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergedCarrierEntry getMergedCarrierEntry() {
|
||||
if (mWifiPickerTracker == null) {
|
||||
fireAcccessPointsCallback(Collections.emptyList());
|
||||
return null;
|
||||
}
|
||||
return mWifiPickerTracker.getMergedCarrierEntry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIcon(WifiEntry ap) {
|
||||
int level = ap.getLevel();
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.telephony.SubscriptionInfo;
|
||||
import com.android.settingslib.net.DataUsageController;
|
||||
import com.android.systemui.demomode.DemoMode;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;
|
||||
import com.android.wifitrackerlib.MergedCarrierEntry;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import java.util.List;
|
||||
@@ -223,6 +224,7 @@ public interface NetworkController extends CallbackController<SignalCallback>, D
|
||||
void addAccessPointCallback(AccessPointCallback callback);
|
||||
void removeAccessPointCallback(AccessPointCallback callback);
|
||||
void scanForAccessPoints();
|
||||
MergedCarrierEntry getMergedCarrierEntry();
|
||||
int getIcon(WifiEntry ap);
|
||||
boolean connect(WifiEntry ap);
|
||||
boolean canConfigWifi();
|
||||
|
||||
@@ -68,9 +68,12 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.demomode.DemoMode;
|
||||
import com.android.systemui.demomode.DemoModeController;
|
||||
import com.android.systemui.dump.DumpManager;
|
||||
import com.android.systemui.qs.tiles.dialog.InternetDialogFactory;
|
||||
import com.android.systemui.qs.tiles.dialog.InternetDialogUtil;
|
||||
import com.android.systemui.settings.CurrentUserTracker;
|
||||
import com.android.systemui.statusbar.FeatureFlags;
|
||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
|
||||
@@ -191,6 +194,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
private boolean mUserSetup;
|
||||
private boolean mSimDetected;
|
||||
private boolean mForceCellularValidated;
|
||||
private InternetDialogFactory mInternetDialogFactory;
|
||||
private Handler mMainHandler;
|
||||
|
||||
private ConfigurationController.ConfigurationListener mConfigurationListener =
|
||||
new ConfigurationController.ConfigurationListener() {
|
||||
@@ -221,7 +226,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
DemoModeController demoModeController,
|
||||
CarrierConfigTracker carrierConfigTracker,
|
||||
FeatureFlags featureFlags,
|
||||
DumpManager dumpManager) {
|
||||
DumpManager dumpManager,
|
||||
@Main Handler handler,
|
||||
InternetDialogFactory internetDialogFactory) {
|
||||
this(context, connectivityManager,
|
||||
telephonyManager,
|
||||
telephonyListenerManager,
|
||||
@@ -242,6 +249,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
featureFlags,
|
||||
dumpManager);
|
||||
mReceiverHandler.post(mRegisterListeners);
|
||||
mMainHandler = handler;
|
||||
mInternetDialogFactory = internetDialogFactory;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -480,6 +489,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
|
||||
if (InternetDialogUtil.isProviderModelEnabled(mContext)) {
|
||||
filter.addAction(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
|
||||
}
|
||||
mBroadcastDispatcher.registerReceiverWithHandler(this, filter, mReceiverHandler);
|
||||
mListening = true;
|
||||
|
||||
@@ -788,6 +800,9 @@ public class NetworkControllerImpl extends BroadcastReceiver
|
||||
mConfig = Config.readConfig(mContext);
|
||||
mReceiverHandler.post(this::handleConfigurationChanged);
|
||||
break;
|
||||
case Settings.Panel.ACTION_INTERNET_CONNECTIVITY:
|
||||
mMainHandler.post(() -> mInternetDialogFactory.create(true));
|
||||
break;
|
||||
default:
|
||||
int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
|
||||
SubscriptionManager.INVALID_SUBSCRIPTION_ID);
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class InternetAdapterTest extends SysuiTestCase {
|
||||
|
||||
private static final String WIFI_TITLE = "Wi-Fi Title";
|
||||
private static final String WIFI_SUMMARY = "Wi-Fi Summary";
|
||||
private InternetDialogController mInternetDialogController = mock(
|
||||
InternetDialogController.class);
|
||||
private InternetAdapter mInternetAdapter;
|
||||
private InternetAdapter.InternetViewHolder mViewHolder;
|
||||
@Mock
|
||||
private WifiEntry mWifiEntry = mock(WifiEntry.class);
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mInternetAdapter = new InternetAdapter(mInternetDialogController);
|
||||
mViewHolder = (InternetAdapter.InternetViewHolder) mInternetAdapter
|
||||
.onCreateViewHolder(new LinearLayout(mContext), 0);
|
||||
when(mWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
|
||||
when(mWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
|
||||
when(mInternetDialogController.getWifiEntryList()).thenReturn(Arrays.asList(mWifiEntry));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_withApmOnWifiOnNoConnectedWifi_returnFour() {
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
|
||||
|
||||
assertThat(mInternetAdapter.getItemCount()).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_withApmOnWifiOnHasConnectedWifi_returnThree() {
|
||||
when(mWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
|
||||
when(mInternetDialogController.getConnectedWifiEntry()).thenReturn(mWifiEntry);
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
|
||||
|
||||
assertThat(mInternetAdapter.getItemCount()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_withApmOffWifiOnNoConnectedWifi_returnThree() {
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
|
||||
|
||||
assertThat(mInternetAdapter.getItemCount()).isEqualTo(3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getItemCount_withApmOffWifiOnHasConnectedWifi_returnTwo() {
|
||||
when(mWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
|
||||
when(mInternetDialogController.getConnectedWifiEntry()).thenReturn(mWifiEntry);
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
|
||||
|
||||
assertThat(mInternetAdapter.getItemCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_bindWithOpenWifiNetwork_verifyView() {
|
||||
when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_NONE);
|
||||
mInternetAdapter.onBindViewHolder(mViewHolder, 0);
|
||||
|
||||
assertThat(mViewHolder.mWifiTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mWifiSummaryText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mWifiIcon.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mWifiLockedIcon.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onBindViewHolder_bindWithSecurityWifiNetwork_verifyView() {
|
||||
when(mWifiEntry.getSecurity()).thenReturn(WifiEntry.SECURITY_PSK);
|
||||
mInternetAdapter.onBindViewHolder(mViewHolder, 0);
|
||||
|
||||
assertThat(mViewHolder.mWifiTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mWifiSummaryText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mWifiIcon.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(mViewHolder.mWifiLockedIcon.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.telephony.ServiceState;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.keyguard.KeyguardUpdateMonitor;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.statusbar.policy.NetworkController;
|
||||
import com.android.systemui.statusbar.policy.NetworkController.AccessPointController;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.settings.GlobalSettings;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
public class InternetDialogControllerTest extends SysuiTestCase {
|
||||
|
||||
private static final int SUB_ID = 1;
|
||||
private static final String CONNECTED_TITLE = "Connected Wi-Fi Title";
|
||||
private static final String CONNECTED_SUMMARY = "Connected Wi-Fi Summary";
|
||||
|
||||
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
|
||||
private MockInternetDialogController mInternetDialogController;
|
||||
private InternetDialogController.InternetDialogCallback mCallback =
|
||||
mock(InternetDialogController.InternetDialogCallback.class);
|
||||
private ActivityStarter mStarter = mock(ActivityStarter.class);
|
||||
private WifiManager mWifiManager = mock(WifiManager.class);
|
||||
private ConnectivityManager mConnectivityManager = mock(ConnectivityManager.class);
|
||||
private TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
|
||||
private SubscriptionManager mSubscriptionManager = mock(SubscriptionManager.class);
|
||||
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
@Mock
|
||||
private Handler mHandler;
|
||||
@Mock
|
||||
private GlobalSettings mGlobalSettings;
|
||||
@Mock
|
||||
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@Mock
|
||||
private NetworkController.AccessPointController mAccessPointController;
|
||||
@Mock
|
||||
private WifiEntry mWifiEntryConnected = mock(WifiEntry.class);
|
||||
@Mock
|
||||
private WifiInfo mWifiInfo;
|
||||
@Mock
|
||||
private ServiceState mServiceState;
|
||||
@Mock
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
|
||||
when(mWifiManager.getConnectionInfo()).thenReturn(mWifiInfo);
|
||||
mInternetDialogController = new MockInternetDialogController(mContext, mUiEventLogger,
|
||||
mStarter, mAccessPointController, mSubscriptionManager, mTelephonyManager,
|
||||
mWifiManager, mConnectivityManager, mHandler, mExecutor, mBroadcastDispatcher,
|
||||
mKeyguardUpdateMonitor, mGlobalSettings);
|
||||
mSubscriptionManager.addOnSubscriptionsChangedListener(mExecutor,
|
||||
mInternetDialogController.mOnSubscriptionsChangedListener);
|
||||
mInternetDialogController.onStart(mCallback);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDialogTitleText_withAirplaneModeOn_returnAirplaneMode() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(true);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getDialogTitleText(),
|
||||
getResourcesString("airplane_mode")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getDialogTitleText_withAirplaneModeOff_returnInternet() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(false);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getDialogTitleText(),
|
||||
getResourcesString("quick_settings_internet_label")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtitleText_withAirplaneModeOn_returnNull() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(true);
|
||||
|
||||
assertThat(mInternetDialogController.getSubtitleText(false)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtitleText_withWifiOff_returnWifiIsOff() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(false);
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(false);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
|
||||
getResourcesString("wifi_is_off")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtitleText_withWifiOn_returnSearchWifi() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(false);
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(true),
|
||||
getResourcesString("wifi_empty_list_wifi_on")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtitleText_withWifiEntry_returnTapToConnect() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(false);
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
List<ScanResult> wifiScanResults = mock(ArrayList.class);
|
||||
doReturn(1).when(wifiScanResults).size();
|
||||
when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
|
||||
getResourcesString("tap_a_network_to_connect")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtitleText_withNoService_returnNoNetworksAvailable() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(false);
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
List<ScanResult> wifiScanResults = new ArrayList<>();
|
||||
doReturn(wifiScanResults).when(mWifiManager).getScanResults();
|
||||
when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
|
||||
when(mSubscriptionManager.getActiveSubscriptionIdList())
|
||||
.thenReturn(new int[] {SUB_ID});
|
||||
|
||||
doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getState();
|
||||
doReturn(mServiceState).when(mTelephonyManager).getServiceState();
|
||||
doReturn(TelephonyManager.DATA_DISCONNECTED).when(mTelephonyManager).getDataState();
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
|
||||
getResourcesString("all_network_unavailable")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSubtitleText_withMobileDataDisabled_returnNoOtherAvailable() {
|
||||
mInternetDialogController.setAirplaneModeEnabled(false);
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
List<ScanResult> wifiScanResults = new ArrayList<>();
|
||||
doReturn(wifiScanResults).when(mWifiManager).getScanResults();
|
||||
when(mWifiManager.getScanResults()).thenReturn(wifiScanResults);
|
||||
when(mSubscriptionManager.getActiveSubscriptionIdList())
|
||||
.thenReturn(new int[] {SUB_ID});
|
||||
|
||||
doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
|
||||
doReturn(mServiceState).when(mTelephonyManager).getServiceState();
|
||||
|
||||
when(mTelephonyManager.isDataEnabled()).thenReturn(false);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getSubtitleText(false),
|
||||
getResourcesString("non_carrier_network_unavailable")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedWifiTitle_withNoConnectedEntry_returnNull() {
|
||||
mInternetDialogController.setConnectedWifiEntry(null);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getConnectedWifiTitle(),
|
||||
""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedWifiTitle_withConnectedEntry_returnTitle() {
|
||||
mInternetDialogController.setConnectedWifiEntry(mWifiEntryConnected);
|
||||
when(mWifiEntryConnected.getTitle()).thenReturn(CONNECTED_TITLE);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getConnectedWifiTitle(),
|
||||
CONNECTED_TITLE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedWifiSummary_withNoConnectedEntry_returnNull() {
|
||||
mInternetDialogController.setConnectedWifiEntry(null);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getConnectedWifiSummary(),
|
||||
""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getConnectedWifiSummary_withConnectedEntry_returnSummary() {
|
||||
mInternetDialogController.setConnectedWifiEntry(mWifiEntryConnected);
|
||||
when(mWifiEntryConnected.getSummary(false)).thenReturn(CONNECTED_SUMMARY);
|
||||
|
||||
assertTrue(TextUtils.equals(mInternetDialogController.getConnectedWifiSummary(),
|
||||
CONNECTED_SUMMARY));
|
||||
}
|
||||
|
||||
private String getResourcesString(String name) {
|
||||
return mContext.getResources().getString(getResourcesId(name));
|
||||
}
|
||||
|
||||
private int getResourcesId(String name) {
|
||||
return mContext.getResources().getIdentifier(name, "string",
|
||||
mContext.getPackageName());
|
||||
}
|
||||
|
||||
private class MockInternetDialogController extends InternetDialogController {
|
||||
|
||||
private WifiEntry mConnectedEntry;
|
||||
private GlobalSettings mGlobalSettings;
|
||||
private boolean mIsAirplaneModeOn;
|
||||
|
||||
MockInternetDialogController(Context context, UiEventLogger uiEventLogger,
|
||||
ActivityStarter starter, AccessPointController accessPointController,
|
||||
SubscriptionManager subscriptionManager, TelephonyManager telephonyManager,
|
||||
@Nullable WifiManager wifiManager, ConnectivityManager connectivityManager,
|
||||
@Main Handler handler, @Main Executor mainExecutor,
|
||||
BroadcastDispatcher broadcastDispatcher,
|
||||
KeyguardUpdateMonitor keyguardUpdateMonitor, GlobalSettings globalSettings) {
|
||||
super(context, uiEventLogger, starter, accessPointController, subscriptionManager,
|
||||
telephonyManager, wifiManager, connectivityManager, handler, mainExecutor,
|
||||
broadcastDispatcher, keyguardUpdateMonitor, globalSettings);
|
||||
mGlobalSettings = globalSettings;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isAirplaneModeEnabled() {
|
||||
return mIsAirplaneModeOn;
|
||||
}
|
||||
|
||||
public void setAirplaneModeEnabled(boolean enabled) {
|
||||
mIsAirplaneModeOn = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
WifiEntry getConnectedWifiEntry() {
|
||||
return mConnectedEntry;
|
||||
}
|
||||
|
||||
public void setConnectedWifiEntry(WifiEntry connectedEntry) {
|
||||
mConnectedEntry = connectedEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
package com.android.systemui.qs.tiles.dialog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
public class InternetDialogTest extends SysuiTestCase {
|
||||
|
||||
private static final int SUB_ID = 1;
|
||||
private static final String MOBILE_NETWORK_TITLE = "Mobile Title";
|
||||
private static final String MOBILE_NETWORK_SUMMARY = "Mobile Summary";
|
||||
private static final String WIFI_TITLE = "Connected Wi-Fi Title";
|
||||
private static final String WIFI_SUMMARY = "Connected Wi-Fi Summary";
|
||||
|
||||
private final UiEventLogger mUiEventLogger = mock(UiEventLogger.class);
|
||||
|
||||
private InternetDialogFactory mInternetDialogFactory = mock(InternetDialogFactory.class);
|
||||
private InternetAdapter mInternetAdapter = mock(InternetAdapter.class);
|
||||
private InternetDialogController mInternetDialogController = mock(
|
||||
InternetDialogController.class);
|
||||
private InternetDialogController.InternetDialogCallback mCallback =
|
||||
mock(InternetDialogController.InternetDialogCallback.class);
|
||||
private MockInternetDialog mInternetDialog;
|
||||
private WifiReceiver mWifiReceiver = null;
|
||||
private WifiManager mMockWifiManager = mock(WifiManager.class);
|
||||
private TelephonyManager mTelephonyManager = mock(TelephonyManager.class);
|
||||
@Mock
|
||||
private WifiEntry mWifiEntry = mock(WifiEntry.class);
|
||||
@Mock
|
||||
private WifiInfo mWifiInfo;
|
||||
@Mock
|
||||
private Handler mHandler;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mInternetDialog = new MockInternetDialog(mContext, mInternetDialogFactory,
|
||||
mInternetDialogController, true, mUiEventLogger, mHandler);
|
||||
mInternetDialog.show();
|
||||
doReturn(mTelephonyManager).when(mTelephonyManager).createForSubscriptionId(SUB_ID);
|
||||
when(mMockWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
when(mMockWifiManager.getConnectionInfo()).thenReturn(mWifiInfo);
|
||||
mInternetDialog.setMobileNetworkTitle(MOBILE_NETWORK_TITLE);
|
||||
mInternetDialog.setMobileNetworkSummary(MOBILE_NETWORK_SUMMARY);
|
||||
mInternetDialog.setConnectedWifiTitle(WIFI_TITLE);
|
||||
mInternetDialog.setConnectedWifiSummary(WIFI_SUMMARY);
|
||||
mWifiReceiver = new WifiReceiver();
|
||||
IntentFilter mIntentFilter = new IntentFilter();
|
||||
mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
|
||||
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
mContext.registerReceiver(mWifiReceiver, mIntentFilter);
|
||||
when(mWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
|
||||
when(mWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
|
||||
when(mInternetDialogController.getWifiEntryList()).thenReturn(Arrays.asList(mWifiEntry));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mInternetDialog.dismissDialog();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDialog_withApmOn_internetDialogSubTitleGone() {
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
|
||||
mInternetDialog.updateDialog();
|
||||
final TextView view = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.internet_dialog_subtitle);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDialog_withApmOff_internetDialogSubTitleVisible() {
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(false);
|
||||
mInternetDialog.updateDialog();
|
||||
final TextView view = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.internet_dialog_subtitle);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDialog_withApmOn_mobileDataLayoutGone() {
|
||||
when(mInternetDialogController.isAirplaneModeEnabled()).thenReturn(true);
|
||||
mInternetDialog.updateDialog();
|
||||
final LinearLayout linearLayout = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.mobile_network_layout);
|
||||
|
||||
assertThat(linearLayout.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDialog_withWifiOnAndHasConnectedWifi_connectedWifiLayoutVisible() {
|
||||
doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
|
||||
when(mWifiEntry.getTitle()).thenReturn(WIFI_TITLE);
|
||||
when(mWifiEntry.getSummary(false)).thenReturn(WIFI_SUMMARY);
|
||||
when(mWifiEntry.getConnectedState()).thenReturn(WifiEntry.CONNECTED_STATE_CONNECTED);
|
||||
when(mInternetDialogController.getConnectedWifiEntry()).thenReturn(mWifiEntry);
|
||||
mInternetDialog.updateDialog();
|
||||
final LinearLayout linearLayout = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.wifi_connected_layout);
|
||||
|
||||
assertThat(linearLayout.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDialog_withWifiOnAndNoConnectedWifi_connectedWifiLayoutGone() {
|
||||
doReturn(false).when(mInternetDialogController).activeNetworkIsCellular();
|
||||
mInternetDialog.updateDialog();
|
||||
final LinearLayout linearLayout = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.wifi_connected_layout);
|
||||
|
||||
assertThat(linearLayout.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void updateDialog_withWifiOff_WifiRecycleViewGone() {
|
||||
when(mMockWifiManager.isWifiEnabled()).thenReturn(false);
|
||||
mInternetDialog.updateDialog();
|
||||
final RecyclerView view = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.wifi_list_layout);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClickSeeMoreButton_clickSeeMore_verifyLaunchNetworkSetting() {
|
||||
final LinearLayout seeAllLayout = mInternetDialog.mDialogView.requireViewById(
|
||||
R.id.see_all_layout);
|
||||
seeAllLayout.performClick();
|
||||
|
||||
verify(mInternetDialogController).launchNetworkSetting();
|
||||
}
|
||||
|
||||
private class MockInternetDialog extends InternetDialog {
|
||||
|
||||
private String mMobileNetworkTitle;
|
||||
private String mMobileNetworkSummary;
|
||||
private String mConnectedWifiTitle;
|
||||
private String mConnectedWifiSummary;
|
||||
|
||||
MockInternetDialog(Context context, InternetDialogFactory internetDialogFactory,
|
||||
InternetDialogController internetDialogController, boolean aboveStatusBar,
|
||||
UiEventLogger uiEventLogger, @Main Handler handler) {
|
||||
super(context, internetDialogFactory, internetDialogController, aboveStatusBar,
|
||||
uiEventLogger, handler);
|
||||
mAdapter = mInternetAdapter;
|
||||
mWifiManager = mMockWifiManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getMobileNetworkTitle() {
|
||||
return mMobileNetworkTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getMobileNetworkSummary() {
|
||||
return mMobileNetworkSummary;
|
||||
}
|
||||
|
||||
void setMobileNetworkTitle(String title) {
|
||||
mMobileNetworkTitle = title;
|
||||
}
|
||||
|
||||
void setMobileNetworkSummary(String summary) {
|
||||
mMobileNetworkSummary = summary;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getConnectedWifiTitle() {
|
||||
return mConnectedWifiTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getConnectedWifiSummary() {
|
||||
return mConnectedWifiSummary;
|
||||
}
|
||||
|
||||
void setConnectedWifiTitle(String title) {
|
||||
mConnectedWifiTitle = title;
|
||||
}
|
||||
|
||||
void setConnectedWifiSummary(String summary) {
|
||||
mConnectedWifiSummary = summary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWifiStateReceived(Context context, Intent intent) {
|
||||
setMobileNetworkTitle(MOBILE_NETWORK_TITLE);
|
||||
setMobileNetworkSummary(MOBILE_NETWORK_SUMMARY);
|
||||
}
|
||||
}
|
||||
|
||||
private class WifiReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String action = intent.getAction();
|
||||
if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
mInternetDialog.updateDialog();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user