Skip to content

Commit be7f21c

Browse files
rmp22Joker-V2
authored andcommitted
[Feature] add network speed indicator
reverse-engineered from nothingOS - simplified/modernized Change-Id: Ia5ba8248107407db2c1b3c9a067b7bcd85e49aa9 Signed-off-by: rmp22 <[email protected]> Signed-off-by: Joker-V2 <[email protected]>
1 parent c9d8c8c commit be7f21c

File tree

14 files changed

+805
-4
lines changed

14 files changed

+805
-4
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:height="24dp"
4+
android:width="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24"
7+
android:tint="?android:attr/colorControlNormal">
8+
<path
9+
android:fillColor="#FFFFFFFF"
10+
android:pathData="M6.321,10H5.207V4.618L3.564,5.18V4.236L6.179,3.274H6.321V10ZM13.158,10H8.651V9.231L10.884,6.796C11.206,6.437 11.435,6.137 11.57,5.898C11.708,5.656 11.777,5.413 11.777,5.171C11.777,4.851 11.686,4.594 11.505,4.397C11.327,4.201 11.086,4.103 10.782,4.103C10.42,4.103 10.139,4.213 9.94,4.434C9.74,4.655 9.641,4.957 9.641,5.341H8.522C8.522,4.933 8.614,4.566 8.798,4.241C8.985,3.912 9.251,3.658 9.595,3.476C9.941,3.295 10.34,3.205 10.792,3.205C11.442,3.205 11.955,3.369 12.329,3.697C12.707,4.023 12.896,4.474 12.896,5.051C12.896,5.385 12.8,5.737 12.61,6.105C12.423,6.47 12.114,6.886 11.685,7.353L10.046,9.107H13.158V10ZM14.778,8.821C14.987,8.821 15.148,8.881 15.262,9.001C15.375,9.118 15.432,9.265 15.432,9.443C15.432,9.618 15.375,9.764 15.262,9.88C15.148,9.994 14.987,10.051 14.778,10.051C14.579,10.051 14.421,9.994 14.304,9.88C14.188,9.767 14.129,9.621 14.129,9.443C14.129,9.265 14.186,9.118 14.3,9.001C14.413,8.881 14.573,8.821 14.778,8.821ZM19.815,7.196C19.441,7.592 19.003,7.79 18.503,7.79C17.914,7.79 17.444,7.585 17.094,7.173C16.744,6.759 16.569,6.216 16.569,5.544C16.569,5.102 16.658,4.701 16.836,4.342C17.014,3.983 17.268,3.704 17.596,3.504C17.924,3.305 18.305,3.205 18.738,3.205C19.413,3.205 19.948,3.456 20.344,3.96C20.74,4.463 20.938,5.137 20.938,5.981V6.294C20.938,7.503 20.665,8.425 20.119,9.061C19.573,9.696 18.758,10.018 17.674,10.028H17.541V9.102H17.702C18.362,9.093 18.868,8.935 19.221,8.628C19.574,8.318 19.772,7.841 19.815,7.196ZM18.738,6.915C18.962,6.915 19.172,6.851 19.368,6.722C19.565,6.593 19.717,6.415 19.824,6.188V5.751C19.824,5.257 19.723,4.859 19.52,4.558C19.318,4.258 19.055,4.107 18.733,4.107C18.411,4.107 18.153,4.241 17.96,4.508C17.769,4.772 17.674,5.106 17.674,5.511C17.674,5.932 17.771,6.271 17.964,6.529C18.158,6.787 18.416,6.915 18.738,6.915Z"/>
11+
<path
12+
android:fillColor="#FFFFFFFF"
13+
android:pathData="M6.038,14.973L7.488,18.826L8.935,14.973H10.064V20H9.194V18.343L9.28,16.126L7.796,20H7.171L5.689,16.129L5.776,18.343V20H4.906V14.973H6.038ZM11.1,20V14.973H12.823C13.392,14.973 13.824,15.087 14.121,15.314C14.418,15.542 14.567,15.882 14.567,16.333C14.567,16.563 14.505,16.77 14.38,16.955C14.256,17.139 14.074,17.281 13.835,17.383C14.106,17.456 14.316,17.596 14.463,17.801C14.613,18.003 14.688,18.247 14.688,18.532C14.688,19.004 14.536,19.367 14.232,19.62C13.93,19.873 13.498,20 12.934,20H11.1ZM11.974,17.732V19.302H12.944C13.218,19.302 13.432,19.235 13.586,19.099C13.74,18.963 13.817,18.774 13.817,18.532C13.817,18.01 13.55,17.743 13.016,17.732H11.974ZM11.974,17.089H12.83C13.101,17.089 13.313,17.028 13.465,16.906C13.62,16.782 13.697,16.607 13.697,16.381C13.697,16.133 13.625,15.953 13.483,15.843C13.342,15.732 13.122,15.677 12.823,15.677H11.974V17.089ZM15.717,20.432H15.057L17.035,14.973H17.695L15.717,20.432ZM20.371,18.985C20.371,18.835 20.309,18.721 20.184,18.643C20.063,18.565 19.859,18.496 19.573,18.436C19.288,18.376 19.05,18.3 18.859,18.208C18.44,18.005 18.23,17.712 18.23,17.327C18.23,17.005 18.366,16.736 18.638,16.52C18.909,16.303 19.254,16.195 19.673,16.195C20.12,16.195 20.48,16.306 20.754,16.526C21.03,16.747 21.169,17.034 21.169,17.386H20.33C20.33,17.225 20.27,17.092 20.15,16.986C20.03,16.878 19.871,16.823 19.673,16.823C19.489,16.823 19.338,16.866 19.221,16.951C19.106,17.036 19.049,17.15 19.049,17.293C19.049,17.422 19.103,17.522 19.211,17.593C19.319,17.665 19.538,17.737 19.867,17.811C20.196,17.882 20.454,17.969 20.64,18.07C20.829,18.169 20.968,18.288 21.058,18.429C21.15,18.569 21.196,18.74 21.196,18.94C21.196,19.276 21.057,19.549 20.778,19.758C20.5,19.965 20.135,20.069 19.684,20.069C19.378,20.069 19.105,20.014 18.865,19.903C18.626,19.793 18.44,19.641 18.306,19.448C18.173,19.254 18.106,19.046 18.106,18.823H18.921C18.932,19.021 19.007,19.174 19.145,19.282C19.283,19.388 19.466,19.441 19.694,19.441C19.915,19.441 20.083,19.399 20.198,19.316C20.313,19.231 20.371,19.121 20.371,18.985Z"/>
14+
</vector>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<com.android.systemui.statusbar.policy.networkspeed.NetworkSpeedView xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_gravity="center_vertical"
4+
android:id="@+id/network_speed"
5+
android:layout_width="@dimen/network_speed_view_width"
6+
android:layout_height="match_parent"
7+
android:paddingEnd="@dimen/network_speed_view_padding_end">
8+
<TextView
9+
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
10+
android:textSize="@dimen/network_speed_text_size"
11+
android:gravity="end|center_vertical"
12+
android:layout_gravity="center_horizontal"
13+
android:id="@+id/number"
14+
android:layout_width="match_parent"
15+
android:layout_height="match_parent"
16+
android:layout_marginBottom="@dimen/network_speed_margin_bottom"
17+
android:maxLines="1"
18+
android:includeFontPadding="false"
19+
android:importantForAccessibility="no"
20+
android:textAlignment="viewEnd"/>
21+
<TextView
22+
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
23+
android:textSize="@dimen/network_speed_unit_text_size"
24+
android:gravity="end|center_vertical"
25+
android:layout_gravity="center_horizontal"
26+
android:id="@+id/unit"
27+
android:layout_width="match_parent"
28+
android:layout_height="match_parent"
29+
android:layout_marginTop="@dimen/network_speed_unit_margin_top"
30+
android:maxLines="1"
31+
android:includeFontPadding="false"
32+
android:importantForAccessibility="no"
33+
android:textAlignment="viewEnd"/>
34+
</com.android.systemui.statusbar.policy.networkspeed.NetworkSpeedView>

packages/SystemUI/res/values/cm_strings.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,7 @@
135135

136136
<!-- Notify use that they are in Lock-to-app (for devices without navbar)-->
137137
<string name="screen_pinning_toast_no_navbar">To unpin this screen, touch &amp; hold Back button</string>
138+
139+
<!-- Internet -->
140+
<string name="status_bar_settings_network_speed">Internet speed</string>
138141
</resources>

packages/SystemUI/res/values/config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,7 @@
557557
<string-array name="config_statusBarIconsToExclude" translatable="false">
558558
<item>@*android:string/status_bar_rotate</item>
559559
<item>@*android:string/status_bar_headset</item>
560+
<item>network_speed</item>
560561
</string-array>
561562

562563

packages/SystemUI/res/values/lineage_dimens.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,12 @@
2121

2222
<!-- Largest size an avatar might need to be drawn in the power menu user picker -->
2323
<dimen name="global_actions_avatar_size">24dp</dimen>
24+
25+
<!-- Network Speed -->
26+
<dimen name="network_speed_margin_bottom">7dp</dimen>
27+
<dimen name="network_speed_text_size">8dp</dimen>
28+
<dimen name="network_speed_unit_margin_top">9dp</dimen>
29+
<dimen name="network_speed_unit_text_size">6dp</dimen>
30+
<dimen name="network_speed_view_padding_end">2dp</dimen>
31+
<dimen name="network_speed_view_width">22dp</dimen>
2432
</resources>

packages/SystemUI/res/xml/status_bar_prefs.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
android:key="rotate"
2424
android:title="@string/status_bar_settings_auto_rotation" />
2525

26+
<com.android.systemui.tuner.StatusBarSwitch
27+
android:icon="@drawable/nt_statusbar_icon_internet_speed"
28+
android:key="network_speed"
29+
android:title="@string/status_bar_settings_network_speed" />
30+
2631
<com.android.systemui.tuner.StatusBarSwitch
2732
android:icon="@drawable/ic_statusbar_headset"
2833
android:key="headset"
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (C) 2025 AxionOS Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.android.systemui.statusbar.phone
17+
18+
import com.android.systemui.statusbar.phone.StatusBarIconHolder
19+
import com.android.systemui.statusbar.policy.networkspeed.NetworkSpeedIconState
20+
21+
class NetworkSpeedIconHolder : StatusBarIconHolder() {
22+
23+
companion object {
24+
const val TYPE_NETWORK_SPEED = 6
25+
26+
fun fromNetworkIconState(state: NetworkSpeedIconState): NetworkSpeedIconHolder {
27+
val holder = NetworkSpeedIconHolder()
28+
holder.mNetworkSpeedIconState = state
29+
holder.type = TYPE_NETWORK_SPEED
30+
return holder
31+
}
32+
}
33+
34+
private var mNetworkSpeedIconState: NetworkSpeedIconState? = null
35+
36+
fun setNetworkSpeedIconState(state: NetworkSpeedIconState) {
37+
mNetworkSpeedIconState = state
38+
}
39+
40+
fun getNetworkSpeedIconState(): NetworkSpeedIconState? {
41+
return mNetworkSpeedIconState
42+
}
43+
44+
override var isVisible: Boolean
45+
get() = mNetworkSpeedIconState?.isVisible() ?: false
46+
set(value) {
47+
if (mNetworkSpeedIconState == null || isVisible == value) return
48+
mNetworkSpeedIconState?.setVisible(value)
49+
}
50+
51+
override fun toString(): String {
52+
return mNetworkSpeedIconState?.toString() ?: "null"
53+
}
54+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright (C) 2025 AxionOS Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.android.systemui.statusbar.phone
17+
18+
import android.content.Context
19+
import android.view.ViewGroup
20+
import android.widget.LinearLayout
21+
import com.android.systemui.res.R
22+
import com.android.systemui.statusbar.StatusIconDisplayable
23+
import com.android.systemui.statusbar.phone.ui.StatusBarIconControllerImpl
24+
import com.android.systemui.statusbar.phone.ui.StatusBarIconList
25+
import com.android.systemui.statusbar.policy.networkspeed.NetworkSpeedIconState
26+
import com.android.systemui.statusbar.policy.networkspeed.NetworkSpeedView
27+
28+
class StatusBarIconControllerImplEx private constructor(
29+
private val context: Context,
30+
private val iconController: StatusBarIconControllerImpl,
31+
private val iconList: StatusBarIconList
32+
) {
33+
34+
fun setNetworkSpeedIcon(slot: String, state: NetworkSpeedIconState?) {
35+
if (state == null || !state.isVisible()) {
36+
iconController.removeIcon(slot, 0)
37+
return
38+
}
39+
40+
val existingHolder = iconList.getIconHolder(slot, 0)
41+
42+
if (existingHolder == null) {
43+
val newHolder = NetworkSpeedIconHolder.fromNetworkIconState(state)
44+
iconController.setIcon(slot, newHolder)
45+
} else if (existingHolder is NetworkSpeedIconHolder) {
46+
existingHolder.setNetworkSpeedIconState(state)
47+
iconController.handleSet(slot, existingHolder)
48+
}
49+
}
50+
51+
fun addHolder(
52+
index: Int,
53+
slot: String,
54+
rootGroup: ViewGroup,
55+
holder: StatusBarIconHolder,
56+
blocked: Boolean
57+
): StatusIconDisplayable? {
58+
return if (holder.type == 6 && holder is NetworkSpeedIconHolder) {
59+
addNetworkSpeedIcon(index, slot, holder.getNetworkSpeedIconState(), rootGroup, blocked)
60+
} else {
61+
null
62+
}
63+
}
64+
65+
private fun addNetworkSpeedIcon(
66+
index: Int,
67+
slot: String,
68+
state: NetworkSpeedIconState?,
69+
rootGroup: ViewGroup,
70+
blocked: Boolean
71+
): NetworkSpeedView {
72+
val view = createNetworkSpeedView(slot, blocked)
73+
view.applyNetworkState(state)
74+
rootGroup.addView(view, index, createLayoutParams())
75+
return view
76+
}
77+
78+
private fun updateNetworkSpeedIcon(viewIndex: Int, state: NetworkSpeedIconState?, rootGroup: ViewGroup) {
79+
val view = rootGroup.getChildAt(viewIndex) as? NetworkSpeedView ?: return
80+
view.applyNetworkState(state)
81+
}
82+
83+
private fun createNetworkSpeedView(slot: String, blocked: Boolean): NetworkSpeedView {
84+
return NetworkSpeedView.fromContext(context, slot, blocked)
85+
}
86+
87+
private fun createLayoutParams(): LinearLayout.LayoutParams {
88+
val width = context.resources.getDimensionPixelSize(R.dimen.network_speed_view_width)
89+
return LinearLayout.LayoutParams(width, LinearLayout.LayoutParams.MATCH_PARENT)
90+
}
91+
92+
fun onSetIconHolder(viewIndex: Int, holder: StatusBarIconHolder, rootGroup: ViewGroup) {
93+
if (holder.type == 6 && holder is NetworkSpeedIconHolder) {
94+
updateNetworkSpeedIcon(viewIndex, holder.getNetworkSpeedIconState(), rootGroup)
95+
}
96+
}
97+
98+
companion object {
99+
@Volatile
100+
private var instance: StatusBarIconControllerImplEx? = null
101+
102+
fun init(
103+
context: Context,
104+
iconController: StatusBarIconControllerImpl,
105+
iconList: StatusBarIconList
106+
) {
107+
if (instance == null) {
108+
synchronized(this) {
109+
if (instance == null) {
110+
instance = StatusBarIconControllerImplEx(context, iconController, iconList)
111+
}
112+
}
113+
}
114+
}
115+
116+
fun get(): StatusBarIconControllerImplEx {
117+
return instance ?: throw IllegalStateException("init must be called first!!!")
118+
}
119+
}
120+
}

packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconHolder.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ import com.android.systemui.statusbar.phone.StatusBarSignalPolicy.CallIndicatorI
2424
import com.android.systemui.statusbar.pipeline.icons.shared.model.ModernStatusBarViewCreator
2525

2626
/** Wraps [com.android.internal.statusbar.StatusBarIcon] so we can still have a uniform list */
27-
open class StatusBarIconHolder private constructor() {
28-
@IntDef(TYPE_ICON, TYPE_MOBILE_NEW, TYPE_WIFI_NEW, TYPE_BINDABLE)
27+
open class StatusBarIconHolder protected constructor() {
28+
@IntDef(TYPE_ICON, TYPE_MOBILE_NEW, TYPE_WIFI_NEW, TYPE_BINDABLE, TYPE_NETWORK_SPEED)
2929
@Retention(AnnotationRetention.SOURCE)
3030
internal annotation class IconType
3131

@@ -46,6 +46,7 @@ open class StatusBarIconHolder private constructor() {
4646
// The new pipeline controls visibilities via the view model and
4747
// view binder, so
4848
// this is effectively an unused return value.
49+
TYPE_NETWORK_SPEED,
4950
TYPE_BINDABLE,
5051
TYPE_MOBILE_NEW,
5152
TYPE_WIFI_NEW -> true
@@ -57,6 +58,7 @@ open class StatusBarIconHolder private constructor() {
5758
}
5859
when (type) {
5960
TYPE_ICON -> icon!!.visible = visible
61+
TYPE_NETWORK_SPEED,
6062
TYPE_BINDABLE,
6163
TYPE_MOBILE_NEW,
6264
TYPE_WIFI_NEW -> {}
@@ -99,10 +101,13 @@ open class StatusBarIconHolder private constructor() {
99101

100102
/** Only applicable to [BindableIconHolder] */
101103
const val TYPE_BINDABLE = 5
104+
105+
const val TYPE_NETWORK_SPEED = 6
102106

103107
/** Returns a human-readable string representing the given type. */
104108
fun getTypeString(@IconType type: Int): String {
105109
return when (type) {
110+
TYPE_NETWORK_SPEED -> "NETWORK_SPEED"
106111
TYPE_ICON -> "ICON"
107112
TYPE_MOBILE_NEW -> "MOBILE_NEW"
108113
TYPE_WIFI_NEW -> "WIFI_NEW"

packages/SystemUI/src/com/android/systemui/statusbar/phone/ui/IconManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_ICON;
2121
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_MOBILE_NEW;
2222
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_WIFI_NEW;
23+
import static com.android.systemui.statusbar.phone.StatusBarIconHolder.TYPE_NETWORK_SPEED;
2324

2425
import android.annotation.Nullable;
2526
import android.content.Context;
@@ -47,6 +48,7 @@
4748
import com.android.systemui.statusbar.pipeline.wifi.ui.WifiUiAdapter;
4849
import com.android.systemui.statusbar.pipeline.wifi.ui.view.ModernStatusBarWifiView;
4950
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.LocationBasedWifiViewModel;
51+
import com.android.systemui.statusbar.policy.NetworkSpeedController;
5052
import com.android.systemui.util.Assert;
5153

5254
import java.util.ArrayList;
@@ -148,6 +150,8 @@ protected StatusIconDisplayable addHolder(int index, String slot, boolean blocke
148150
case TYPE_ICON -> addIcon(index, slot, blocked, holder.getIcon());
149151
case TYPE_WIFI_NEW -> addNewWifiIcon(index, slot);
150152
case TYPE_MOBILE_NEW -> addNewMobileIcon(index, slot, holder.getTag());
153+
case TYPE_NETWORK_SPEED ->
154+
NetworkSpeedController.Companion.get().addHolder(index, slot, mGroup, holder, blocked);
151155
case TYPE_BINDABLE ->
152156
// Safe cast, since only BindableIconHolders can set this tag on themselves
153157
addBindableIcon((BindableIconHolder) holder, index);
@@ -280,6 +284,9 @@ public void onSetIconHolder(int viewIndex, StatusBarIconHolder holder) {
280284
case TYPE_BINDABLE:
281285
// Nothing, the new icons update themselves
282286
return;
287+
case TYPE_NETWORK_SPEED:
288+
NetworkSpeedController.Companion.get().onSetIconHolder(viewIndex, holder, mGroup);
289+
return;
283290
default:
284291
break;
285292
}

0 commit comments

Comments
 (0)