Settings: SoftAp: Add client manager
[jhonboy121]: adapted to A13
Signed-off-by: cjybyjk <cjybyjk@zjnu.edu.cn>
Change-Id: If9f0c1000ff4e7dd0b602a61299f1eb2c7608ac5
Signed-off-by: jhonboy121 <alfredmathew05@gmail.com>
diff --git a/res/values/leaf_plurals.xml b/res/values/leaf_plurals.xml
new file mode 100644
index 0000000..757ce30
--- /dev/null
+++ b/res/values/leaf_plurals.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <plurals name="wifi_hotspot_client_limit_summary">
+ <item quantity="other">Up to <xliff:g id="device_num">%1$d</xliff:g> devices can connect to this hotspot</item>
+ <item quantity="one">Up to <xliff:g id="device_num">%1$d</xliff:g> device can connect to this hotspot</item>
+ </plurals>
+</resources>
diff --git a/res/values/leaf_strings.xml b/res/values/leaf_strings.xml
index bc9d3e1..7e34ca1 100644
--- a/res/values/leaf_strings.xml
+++ b/res/values/leaf_strings.xml
@@ -101,4 +101,15 @@
<!-- Hotspot -->
<string name="wifi_hotspot_hidden_ssid_title">Hidden network</string>
<string name="wifi_hotspot_hidden_ssid_summary">Your mobile hotspot\'s name won\'t appear in the list of available WLAN networks.</string>
+ <string name="wifi_hotspot_client_manager_title">Connected devices</string>
+ <string name="wifi_hotspot_client_manager_summary">List and manage devices connected to the hotspot</string>
+ <string name="wifi_hotspot_client_manager_list_only_summary">List devices connected to the hotspot</string>
+ <string name="wifi_hotspot_client_limit_title">Limit of connected devices</string>
+ <string name="wifi_hotspot_blocked_clients_list_title">Blocked Devices</string>
+ <string name="wifi_hotspot_connected_clients_list_title">Connected Devices</string>
+ <string name="wifi_hotspot_block_client_dialog_title">Block device</string>
+ <string name="wifi_hotspot_block_client_dialog_text">This action will disconnect \"<xliff:g id="device_name">%1$s</xliff:g>\" from this device and add it to blocklist</string>
+ <string name="wifi_hotspot_unblock_client_dialog_title">Unblock device</string>
+ <string name="wifi_hotspot_unblock_client_dialog_text">The device \"<xliff:g id="device_name">%1$s</xliff:g>\" will be able to connect to this hotspot</string>
+ <string name="wifi_hotspot_client_manager_footer_text">No clients are currently available. Connected and blocked devices will be listed here when available.</string>
</resources>
diff --git a/res/xml/hotspot_client_manager.xml b/res/xml/hotspot_client_manager.xml
new file mode 100644
index 0000000..5e5a869
--- /dev/null
+++ b/res/xml/hotspot_client_manager.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 Project Kaleidoscope
+
+ 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.
+ -->
+
+<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <ink.kscope.settings.wifi.tether.preference.WifiTetherClientLimitPreference
+ android:key="client_limit"
+ android:title="@string/wifi_hotspot_client_limit_title" />
+
+ <PreferenceCategory
+ android:key="connected_client_list"
+ android:title="@string/wifi_hotspot_connected_clients_list_title" />
+
+ <PreferenceCategory
+ android:key="blocked_client_list"
+ android:title="@string/wifi_hotspot_blocked_clients_list_title" />
+
+ <com.android.settingslib.widget.FooterPreference
+ android:key="footer"
+ android:title="@string/wifi_hotspot_client_manager_footer_text"
+ android:selectable="false" />
+</PreferenceScreen>
diff --git a/res/xml/wifi_tether_settings.xml b/res/xml/wifi_tether_settings.xml
index a40480e..332cab0 100644
--- a/res/xml/wifi_tether_settings.xml
+++ b/res/xml/wifi_tether_settings.xml
@@ -69,5 +69,10 @@
<SwitchPreference
android:key="wifi_tether_hidden_ssid"
android:title="@string/wifi_hotspot_hidden_ssid_title"
- android:summary="@string/wifi_hotspot_hidden_ssid_summary"/>
+ android:summary="@string/wifi_hotspot_hidden_ssid_summary" />
+
+ <Preference
+ android:key="wifi_tether_client_manager"
+ android:title="@string/wifi_hotspot_client_manager_title"
+ android:fragment="ink.kscope.settings.wifi.tether.WifiTetherClientManager" />
</PreferenceScreen>
diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java
index d68f2c8..48c69eb 100644
--- a/src/com/android/settings/core/gateway/SettingsGateway.java
+++ b/src/com/android/settings/core/gateway/SettingsGateway.java
@@ -192,6 +192,8 @@
import com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2;
import com.android.settings.wifi.tether.WifiTetherSettings;
+import ink.kscope.settings.wifi.tether.WifiTetherClientManager;
+
public class SettingsGateway {
/**
@@ -372,6 +374,7 @@
BatteryInfoFragment.class.getName(),
UserAspectRatioDetails.class.getName(),
ScreenTimeoutSettings.class.getName(),
+ WifiTetherClientManager.class.getName()
};
public static final String[] SETTINGS_FOR_RESTRICTED = {
diff --git a/src/com/android/settings/wifi/tether/WifiTetherSettings.java b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
index 5264ce0..b5cb622 100644
--- a/src/com/android/settings/wifi/tether/WifiTetherSettings.java
+++ b/src/com/android/settings/wifi/tether/WifiTetherSettings.java
@@ -49,6 +49,7 @@
import com.android.settingslib.wifi.WifiEnterpriseRestrictionUtils;
import ink.kscope.settings.wifi.tether.WifiTetherHiddenSsidPreferenceController;
+import ink.kscope.settings.wifi.tether.WifiTetherClientManagerPreferenceController;
import java.util.ArrayList;
import java.util.List;
@@ -81,6 +82,9 @@
@VisibleForTesting
static final String KEY_WIFI_TETHER_HIDDEN_SSID =
WifiTetherHiddenSsidPreferenceController.PREF_KEY;
+ @VisibleForTesting
+ static final String KEY_WIFI_TETHER_CLIENT_MANAGER =
+ WifiTetherClientManagerPreferenceController.PREF_KEY;
@VisibleForTesting
SettingsMainSwitchBar mMainSwitchBar;
@@ -97,6 +101,8 @@
WifiTetherAutoOffPreferenceController mWifiTetherAutoOffPreferenceController;
@VisibleForTesting
WifiTetherHiddenSsidPreferenceController mHiddenSsidPrefController;
+ @VisibleForTesting
+ WifiTetherClientManagerPreferenceController mClientPrefController;
@VisibleForTesting
boolean mUnavailable;
@@ -207,6 +213,7 @@
use(WifiTetherMaximizeCompatibilityPreferenceController.class);
mWifiTetherAutoOffPreferenceController = use(WifiTetherAutoOffPreferenceController.class);
mHiddenSsidPrefController = use(WifiTetherHiddenSsidPreferenceController.class);
+ mClientPrefController = use(WifiTetherClientManagerPreferenceController.class);
}
@Override
@@ -292,6 +299,7 @@
new WifiTetherAutoOffPreferenceController(context, KEY_WIFI_TETHER_AUTO_OFF));
controllers.add(new WifiTetherMaximizeCompatibilityPreferenceController(context, listener));
controllers.add(new WifiTetherHiddenSsidPreferenceController(context, listener));
+ controllers.add(new WifiTetherClientManagerPreferenceController(context, listener));
return controllers;
}
@@ -339,6 +347,7 @@
configBuilder.setAutoShutdownEnabled(
mWifiTetherAutoOffPreferenceController.isEnabled());
configBuilder.setHiddenSsid(mHiddenSsidPrefController.isHiddenSsidEnabled());
+ mClientPrefController.updateConfig(configBuilder);
return configBuilder.build();
}
@@ -381,6 +390,7 @@
keys.add(KEY_WIFI_TETHER_AUTO_OFF);
keys.add(KEY_WIFI_TETHER_MAXIMIZE_COMPATIBILITY);
keys.add(KEY_WIFI_TETHER_HIDDEN_SSID);
+ keys.add(KEY_WIFI_TETHER_CLIENT_MANAGER);
}
// Remove duplicate
diff --git a/src/ink/kscope/settings/wifi/tether/WifiTetherClientManager.java b/src/ink/kscope/settings/wifi/tether/WifiTetherClientManager.java
new file mode 100644
index 0000000..a661f0e
--- /dev/null
+++ b/src/ink/kscope/settings/wifi/tether/WifiTetherClientManager.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2022 Project Kaleidoscope
+ *
+ * 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 ink.kscope.settings.wifi.tether;
+
+import android.annotation.NonNull;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.net.MacAddress;
+import android.net.TetheringManager;
+import android.net.TetheredClient;
+import android.net.wifi.SoftApCapability;
+import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.Bundle;
+import android.text.TextUtils;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+import com.android.settingslib.widget.FooterPreference;
+
+import ink.kscope.settings.wifi.tether.preference.WifiTetherClientLimitPreference;
+
+public class WifiTetherClientManager extends SettingsPreferenceFragment implements
+ Preference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener,
+ WifiManager.SoftApCallback, TetheringManager.TetheringEventCallback {
+
+ private static final String TAG = "WifiTetherClientManager";
+
+ private static final String PREF_KEY_CLIENT_LIMIT = "client_limit";
+ private static final String PREF_KEY_BLOCKED_CLIENT_LIST = "blocked_client_list";
+ private static final String PREF_KEY_CONNECTED_CLIENT_LIST = "connected_client_list";
+ private static final String PREF_KEY_FOOTER = "footer";
+
+ private WifiManager mWifiManager;
+ private TetheringManager mTetheringManager;
+
+ private WifiTetherClientLimitPreference mClientLimitPref;
+ private PreferenceCategory mConnectedClientsPref;
+ private PreferenceCategory mBlockedClientsPref;
+ private FooterPreference mFooterPref;
+
+ private boolean mSupportForceDisconnect;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mWifiManager = getSystemService(WifiManager.class);
+ mTetheringManager = getSystemService(TetheringManager.class);
+
+ mWifiManager.registerSoftApCallback(getActivity().getMainExecutor(), this);
+
+ addPreferencesFromResource(R.xml.hotspot_client_manager);
+
+ getActivity().setTitle(R.string.wifi_hotspot_client_manager_title);
+
+ mClientLimitPref = findPreference(PREF_KEY_CLIENT_LIMIT);
+ mConnectedClientsPref = findPreference(PREF_KEY_CONNECTED_CLIENT_LIST);
+ mBlockedClientsPref = findPreference(PREF_KEY_BLOCKED_CLIENT_LIST);
+ mFooterPref = findPreference(PREF_KEY_FOOTER);
+
+ mClientLimitPref.setOnPreferenceChangeListener(this);
+
+ updateBlockedClients();
+ updatePreferenceVisible();
+ }
+
+ @Override
+ public void onCapabilityChanged(@NonNull SoftApCapability softApCapability) {
+ mSupportForceDisconnect =
+ softApCapability.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT);
+ mWifiManager.unregisterSoftApCallback(this);
+
+ if (mSupportForceDisconnect) {
+ mClientLimitPref.setMin(1);
+ mClientLimitPref.setMax(softApCapability.getMaxSupportedClients());
+ final SoftApConfiguration softApConfiguration = mWifiManager.getSoftApConfiguration();
+ final int maxNumberOfClients = softApConfiguration.getMaxNumberOfClients();
+ mClientLimitPref.setValue(maxNumberOfClients, false);
+ }
+ updatePreferenceVisible();
+ }
+
+ private void updatePreferenceVisible() {
+ if (mBlockedClientsPref == null || mClientLimitPref == null ||
+ mConnectedClientsPref == null || mFooterPref == null) return;
+ boolean hasConnectedClient = mConnectedClientsPref.getPreferenceCount() > 0;
+ boolean hasBlockedClient = mBlockedClientsPref.getPreferenceCount() > 0;
+ mClientLimitPref.setVisible(mSupportForceDisconnect);
+ mBlockedClientsPref.setVisible(mSupportForceDisconnect && hasBlockedClient);
+ mConnectedClientsPref.setVisible(hasConnectedClient);
+ mFooterPref.setVisible(!hasBlockedClient && !hasConnectedClient);
+ }
+
+ private void updateBlockedClients() {
+ final SoftApConfiguration softApConfiguration = mWifiManager.getSoftApConfiguration();
+ final List<MacAddress> blockedClientList = softApConfiguration.getBlockedClientList();
+ mBlockedClientsPref.removeAll();
+ for (MacAddress mac : blockedClientList) {
+ BlockedClientPreference preference = new BlockedClientPreference(getActivity(), mac);
+ preference.setOnPreferenceClickListener(this);
+ mBlockedClientsPref.addPreference(preference);
+ }
+ updatePreferenceVisible();
+ }
+
+ @Override
+ public void onClientsChanged(Collection<TetheredClient> clients) {
+ mConnectedClientsPref.removeAll();
+ for (TetheredClient client : clients) {
+ if (client.getTetheringType() != TetheringManager.TETHERING_WIFI) {
+ continue;
+ }
+ ConnectedClientPreference preference =
+ new ConnectedClientPreference(getActivity(), client);
+ preference.setOnPreferenceClickListener(this);
+ mConnectedClientsPref.addPreference(preference);
+ }
+ updatePreferenceVisible();
+ }
+
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ if (mSupportForceDisconnect) {
+ if (preference instanceof ConnectedClientPreference) {
+ showBlockClientDialog(
+ ((ConnectedClientPreference)preference).getMacAddress(),
+ preference.getTitle());
+ return true;
+ } else if (preference instanceof BlockedClientPreference) {
+ showUnblockClientDialog(((BlockedClientPreference)preference).getMacAddress());
+ return true;
+ }
+ }
+ return super.onPreferenceTreeClick(preference);
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ if (preference == mClientLimitPref) {
+ int value = (int) newValue;
+ SoftApConfiguration softApConfiguration = mWifiManager.getSoftApConfiguration();
+ SoftApConfiguration newSoftApConfiguration =
+ new SoftApConfiguration.Builder(softApConfiguration)
+ .setMaxNumberOfClients(value)
+ .build();
+ return mWifiManager.setSoftApConfiguration(newSoftApConfiguration);
+ }
+ return false;
+ }
+
+ private void blockClient(MacAddress mac, boolean isBlock) {
+ final SoftApConfiguration softApConfiguration = mWifiManager.getSoftApConfiguration();
+ final List<MacAddress> blockedClientList = softApConfiguration.getBlockedClientList();
+ if (isBlock) {
+ if (blockedClientList.contains(mac)) return;
+ blockedClientList.add(mac);
+ } else {
+ if (!blockedClientList.contains(mac)) return;
+ blockedClientList.remove(mac);
+ }
+ SoftApConfiguration newSoftApConfiguration =
+ new SoftApConfiguration.Builder(softApConfiguration)
+ .setBlockedClientList(blockedClientList)
+ .build();
+ mWifiManager.setSoftApConfiguration(newSoftApConfiguration);
+ updateBlockedClients();
+ }
+
+ private void showBlockClientDialog(MacAddress mac, CharSequence deviceName) {
+ final Activity activity = getActivity();
+ new AlertDialog.Builder(activity)
+ .setTitle(R.string.wifi_hotspot_block_client_dialog_title)
+ .setMessage(activity.getString(
+ R.string.wifi_hotspot_block_client_dialog_text, deviceName))
+ .setPositiveButton(android.R.string.ok,
+ (dialog, which) -> {
+ blockClient(mac, true);
+ })
+ .setNegativeButton(android.R.string.cancel, null)
+ .create().show();
+ }
+
+ private void showUnblockClientDialog(MacAddress mac) {
+ final Activity activity = getActivity();
+ new AlertDialog.Builder(activity)
+ .setTitle(R.string.wifi_hotspot_unblock_client_dialog_title)
+ .setMessage(activity.getString(
+ R.string.wifi_hotspot_unblock_client_dialog_text, mac.toString()))
+ .setPositiveButton(android.R.string.ok,
+ (dialog, which) -> {
+ blockClient(mac, false);
+ })
+ .setNegativeButton(android.R.string.cancel, null)
+ .create().show();
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ mTetheringManager.registerTetheringEventCallback(getActivity().getMainExecutor(), this);
+ }
+
+ @Override
+ public void onStop() {
+ mTetheringManager.unregisterTetheringEventCallback(this);
+ super.onStop();
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.WIFI_TETHER_SETTINGS;
+ }
+
+ private class ConnectedClientPreference extends Preference {
+ private MacAddress mMacAddress;
+
+ public ConnectedClientPreference(Context context, TetheredClient client) {
+ super(context);
+ mMacAddress = client.getMacAddress();
+
+ String hostName = null;
+ String macAddress = client.getMacAddress().toString();
+
+ for (TetheredClient.AddressInfo addressInfo : client.getAddresses()) {
+ if (!TextUtils.isEmpty(addressInfo.getHostname())) {
+ hostName = addressInfo.getHostname();
+ break;
+ }
+ }
+
+ setKey(macAddress);
+ if (!TextUtils.isEmpty(hostName)) {
+ setTitle(hostName);
+ setSummary(macAddress);
+ } else {
+ setTitle(macAddress);
+ }
+ }
+
+ public MacAddress getMacAddress() {
+ return mMacAddress;
+ }
+ }
+
+ private class BlockedClientPreference extends Preference {
+ private MacAddress mMacAddress;
+
+ public BlockedClientPreference(Context context, MacAddress mac) {
+ super(context);
+ mMacAddress = mac;
+ setKey(mac.toString());
+ setTitle(mac.toString());
+ }
+
+ public MacAddress getMacAddress() {
+ return mMacAddress;
+ }
+ }
+}
diff --git a/src/ink/kscope/settings/wifi/tether/WifiTetherClientManagerPreferenceController.java b/src/ink/kscope/settings/wifi/tether/WifiTetherClientManagerPreferenceController.java
new file mode 100644
index 0000000..95572ce
--- /dev/null
+++ b/src/ink/kscope/settings/wifi/tether/WifiTetherClientManagerPreferenceController.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2022 Project Kaleidoscope
+ *
+ * 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 ink.kscope.settings.wifi.tether;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.net.MacAddress;
+import android.net.wifi.SoftApCapability;
+import android.net.wifi.SoftApConfiguration;
+import android.net.wifi.WifiManager;
+import android.util.FeatureFlagUtils;
+
+import androidx.preference.Preference;
+
+import com.android.settings.R;
+import com.android.settings.core.FeatureFlags;
+import com.android.settings.wifi.tether.WifiTetherBasePreferenceController;
+
+import java.util.List;
+
+public class WifiTetherClientManagerPreferenceController extends WifiTetherBasePreferenceController
+ implements WifiManager.SoftApCallback {
+
+ public static final String DEDUP_POSTFIX = "_2";
+ public static final String PREF_KEY = "wifi_tether_client_manager";
+
+ private boolean mSupportForceDisconnect;
+
+ public WifiTetherClientManagerPreferenceController(Context context,
+ WifiTetherBasePreferenceController.OnTetherConfigUpdateListener listener) {
+ super(context, listener);
+
+ mWifiManager.registerSoftApCallback(context.getMainExecutor(), this);
+ }
+
+ @Override
+ public String getPreferenceKey() {
+ return FeatureFlagUtils.isEnabled(mContext, FeatureFlags.TETHER_ALL_IN_ONE)
+ ? PREF_KEY + DEDUP_POSTFIX : PREF_KEY;
+ }
+
+ @Override
+ public void onCapabilityChanged(@NonNull SoftApCapability softApCapability) {
+ mSupportForceDisconnect =
+ softApCapability.areFeaturesSupported(
+ SoftApCapability.SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT);
+ mWifiManager.unregisterSoftApCallback(this);
+ updateDisplay();
+ }
+
+ @Override
+ public void updateDisplay() {
+ if (mPreference != null) {
+ if (mSupportForceDisconnect) {
+ mPreference.setSummary(R.string.wifi_hotspot_client_manager_summary);
+ } else {
+ mPreference.setSummary(R.string.wifi_hotspot_client_manager_list_only_summary);
+ }
+ }
+ }
+
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ return true;
+ }
+
+ public void updateConfig(SoftApConfiguration.Builder builder) {
+ if (builder == null || !mSupportForceDisconnect) return;
+ final SoftApConfiguration softApConfiguration = mWifiManager.getSoftApConfiguration();
+ final int maxNumberOfClients = softApConfiguration.getMaxNumberOfClients();
+ final List<MacAddress> blockedClientList = softApConfiguration.getBlockedClientList();
+ builder.setMaxNumberOfClients(maxNumberOfClients)
+ .setBlockedClientList(blockedClientList);
+ }
+}
diff --git a/src/ink/kscope/settings/wifi/tether/preference/WifiTetherClientLimitPreference.java b/src/ink/kscope/settings/wifi/tether/preference/WifiTetherClientLimitPreference.java
new file mode 100644
index 0000000..87d78b3
--- /dev/null
+++ b/src/ink/kscope/settings/wifi/tether/preference/WifiTetherClientLimitPreference.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 Project Kaleidoscope
+ *
+ * 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 ink.kscope.settings.wifi.tether.preference;
+
+import android.content.Context;
+import android.widget.SeekBar;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.settings.R;
+import com.android.settings.SeekBarDialogPreference;
+
+public class WifiTetherClientLimitPreference extends SeekBarDialogPreference implements
+ SeekBar.OnSeekBarChangeListener {
+
+ private Context mContext;
+ private SeekBar mSeekBar;
+ private int mValue;
+ private int mMin;
+ private int mMax;
+
+ public WifiTetherClientLimitPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mContext = context;
+ }
+
+ @Override
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
+ setText(getSummaryForValue(progress + mMin));
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+
+ mSeekBar = getSeekBar(view);
+ mSeekBar.setOnSeekBarChangeListener(this);
+ mSeekBar.setMax(mMax - mMin);
+ mSeekBar.setProgress(mValue - mMin);
+ }
+
+ @Override
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+ if (positiveResult) {
+ setValue(mSeekBar.getProgress() + mMin, true);
+ }
+ }
+
+ private String getSummaryForValue(int value) {
+ return mContext.getResources().getQuantityString(
+ R.plurals.wifi_hotspot_client_limit_summary, value, value);
+ }
+
+ public void setMin(int min) {
+ mMin = min;
+ }
+
+ public void setMax(int max) {
+ mMax = max;
+ }
+
+ public void setValue(int value, boolean callListener) {
+ if (value == 0) value = mMax;
+ mValue = value;
+ String summary = getSummaryForValue(value);
+ setSummary(summary);
+ setText(summary);
+ if (callListener) callChangeListener(value);
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+}