Settings: Network setup UI changes for SUW
Author: Michael Bestas <mkbestas@lineageos.org>
Date: Tue Aug 24 01:18:55 2021 +0300
Settings: Network setup UI changes for SUW
Change-Id: Ic8e97b78f19e59fe108c7c3304dfe7e7f49020a9
Author: Erfan Abdi <erfangplus@gmail.com>
Date: Sun Mar 6 01:58:11 2022 -0700
Settings: Apply SUW button theming to WiFi page
Change-Id: Iab5723f4654d372948de372cfd62587e8932d72c
Author: Alexander Koskovich <akoskovich@pm.me>
Date: Fri Feb 2 07:09:07 2024 -0500
Handle mobile data on internet page during setup
Change-Id: Id00e9ef135cd2748376c69596979826e764e9185
Author: Michael Bestas <mkbestas@lineageos.org>
Date: Sat Feb 17 18:59:41 2024 +0200
Fix network SetupWizard theme issues
Change-Id: I7649ecacb5a2dd0cb15ed9b1d05c28b44257bb54
Change-Id: Ic8e97b78f19e59fe108c7c3304dfe7e7f49020a9
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index ef45b1e..253d196 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -475,6 +475,17 @@
</activity>
<activity
+ android:name=".network.NetworkSetupActivity"
+ android:exported="true">
+ <intent-filter android:priority="1">
+ <action android:name="android.settings.NETWORK_PROVIDER_SETUP" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+ android:value="true" />
+ </activity>
+
+ <activity
android:name=".wifi.WifiPickerActivity"
android:permission="android.permission.CHANGE_WIFI_STATE"
android:exported="true">
diff --git a/res/drawable/ic_network_setup.xml b/res/drawable/ic_network_setup.xml
new file mode 100644
index 0000000..4944cbc
--- /dev/null
+++ b/res/drawable/ic_network_setup.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 The LineageOS 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">
+
+ <path
+ android:fillColor="?android:attr/colorPrimary"
+ android:pathData="M12,2A8,8 0 0,0 4,10C4,14.03 7,17.42 11,17.93V19H10A1,1 0 0,0 9,20H2V22H9A1,1 0 0,0 10,23H14A1,1 0 0,0 15,22H22V20H15A1,1 0 0,0 14,19H13V17.93C17,17.43 20,14.03 20,10A8,8 0 0,0 12,2M12,4C12,4 12.74,5.28 13.26,7H10.74C11.26,5.28 12,4 12,4M9.77,4.43C9.5,4.93 9.09,5.84 8.74,7H6.81C7.5,5.84 8.5,4.93 9.77,4.43M14.23,4.44C15.5,4.94 16.5,5.84 17.19,7H15.26C14.91,5.84 14.5,4.93 14.23,4.44M6.09,9H8.32C8.28,9.33 8.25,9.66 8.25,10C8.25,10.34 8.28,10.67 8.32,11H6.09C6.03,10.67 6,10.34 6,10C6,9.66 6.03,9.33 6.09,9M10.32,9H13.68C13.72,9.33 13.75,9.66 13.75,10C13.75,10.34 13.72,10.67 13.68,11H10.32C10.28,10.67 10.25,10.34 10.25,10C10.25,9.66 10.28,9.33 10.32,9M15.68,9H17.91C17.97,9.33 18,9.66 18,10C18,10.34 17.97,10.67 17.91,11H15.68C15.72,10.67 15.75,10.34 15.75,10C15.75,9.66 15.72,9.33 15.68,9M6.81,13H8.74C9.09,14.16 9.5,15.07 9.77,15.56C8.5,15.06 7.5,14.16 6.81,13M10.74,13H13.26C12.74,14.72 12,16 12,16C12,16 11.26,14.72 10.74,13M15.26,13H17.19C16.5,14.16 15.5,15.07 14.23,15.57C14.5,15.07 14.91,14.16 15.26,13Z" />
+</vector>
diff --git a/src/com/android/settings/network/NetworkProviderSettings.java b/src/com/android/settings/network/NetworkProviderSettings.java
index f14c32c..acde54c 100644
--- a/src/com/android/settings/network/NetworkProviderSettings.java
+++ b/src/com/android/settings/network/NetworkProviderSettings.java
@@ -36,16 +36,19 @@
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
+import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -66,6 +69,7 @@
import com.android.settings.datausage.DataUsagePreference;
import com.android.settings.datausage.DataUsageUtils;
import com.android.settings.location.WifiScanningFragment;
+import com.android.settings.network.MobileDataEnabledListener;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.wifi.AddNetworkFragment;
import com.android.settings.wifi.AddWifiNetworkPreference;
@@ -93,6 +97,10 @@
import com.android.wifitrackerlib.WifiEntry.ConnectCallback;
import com.android.wifitrackerlib.WifiPickerTracker;
+import com.google.android.setupcompat.template.FooterButtonStyleUtils;
+import com.google.android.setupcompat.util.WizardManagerHelper;
+import com.google.android.setupdesign.GlifPreferenceLayout;
+
import java.util.List;
import java.util.Optional;
@@ -105,7 +113,8 @@
public class NetworkProviderSettings extends RestrictedSettingsFragment
implements Indexable, WifiPickerTracker.WifiPickerTrackerCallback,
WifiDialog2.WifiDialog2Listener, DialogInterface.OnDismissListener,
- AirplaneModeEnabler.OnAirplaneModeChangedListener, InternetUpdater.InternetChangeListener {
+ AirplaneModeEnabler.OnAirplaneModeChangedListener, InternetUpdater.InternetChangeListener,
+ MobileDataEnabledListener.Client {
public static final String ACTION_NETWORK_PROVIDER_SETTINGS =
"android.settings.NETWORK_PROVIDER_SETTINGS";
@@ -168,6 +177,8 @@
// Enable the Next button when a Wi-Fi network is connected.
private boolean mEnableNextOnConnection;
+ private boolean mIsInSetupWizard;
+
// This string extra specifies a network to open the connect dialog on, so the user can enter
// network credentials. This is used by quick settings for secured networks, among other
// things.
@@ -199,6 +210,9 @@
protected WifiManager mWifiManager;
private WifiManager.ActionListener mSaveListener;
+ int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+ MobileDataEnabledListener mDataStateListener;
+
protected InternetResetHelper mInternetResetHelper;
/**
@@ -262,6 +276,7 @@
public NetworkProviderSettings() {
super(DISALLOW_CONFIG_WIFI);
+ mSubId = SubscriptionManager.getActiveDataSubscriptionId();
}
@Override
@@ -272,6 +287,18 @@
return;
}
+ if (mIsInSetupWizard) {
+ GlifPreferenceLayout layout = (GlifPreferenceLayout) view;
+ layout.setDividerInsets(Integer.MAX_VALUE, 0);
+
+ layout.setIcon(getContext().getDrawable(R.drawable.ic_network_setup));
+ layout.setHeaderText(R.string.provider_internet_settings);
+ FooterButtonStyleUtils.applyPrimaryButtonPartnerResource(activity, getNextButton(),
+ true);
+
+ return;
+ }
+
setPinnedHeaderView(com.android.settingslib.widget.progressbar.R.layout.progress_header);
setProgressBarVisible(false);
@@ -295,6 +322,7 @@
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mAirplaneModeEnabler = new AirplaneModeEnabler(getContext(), this);
+ mDataStateListener = new MobileDataEnabledListener(getContext(), this);
// TODO(b/37429702): Add animations and preference comparator back after initial screen is
// loaded (ODR).
@@ -342,6 +370,8 @@
fixConnectivityItem.setVisible(!mIsGuest && (!isAirplaneModeOn || isWifiEnabled));
}
};
+ final Intent intent = this.getIntent();
+ mIsInSetupWizard = WizardManagerHelper.isAnySetupWizard(intent);
}
private void updateUserType() {
@@ -351,6 +381,17 @@
mIsGuest = userManager.isGuestUser();
}
+ @Override
+ public RecyclerView onCreateRecyclerView(LayoutInflater inflater, ViewGroup parent,
+ Bundle savedInstanceState) {
+ if (mIsInSetupWizard) {
+ GlifPreferenceLayout layout = (GlifPreferenceLayout) parent;
+ return layout.onCreateRecyclerView(inflater, parent, savedInstanceState);
+ } else {
+ return super.onCreateRecyclerView(inflater, parent, savedInstanceState);
+ }
+ }
+
private void addPreferences() {
addPreferencesFromResource(R.xml.network_provider_settings);
@@ -462,6 +503,11 @@
}
};
+ if (mIsInSetupWizard) {
+ mConfigureWifiSettingsPreference.setVisible(false);
+ mDataUsagePreference.setVisible(false);
+ }
+
if (savedInstanceState != null) {
mDialogMode = savedInstanceState.getInt(SAVE_DIALOG_MODE);
mDialogWifiEntryKey = savedInstanceState.getString(SAVE_DIALOG_WIFIENTRY_KEY);
@@ -501,6 +547,7 @@
return;
}
mAirplaneModeEnabler.start();
+ mDataStateListener.start(mSubId);
}
private void restrictUi() {
@@ -529,7 +576,8 @@
}
changeNextButtonState(mWifiPickerTracker != null
- && mWifiPickerTracker.getConnectedWifiEntry() != null);
+ && mWifiPickerTracker.getConnectedWifiEntry() != null
+ || getDataEnabled());
}
@Override
@@ -538,6 +586,7 @@
getView().removeCallbacks(mUpdateWifiEntryPreferencesRunnable);
getView().removeCallbacks(mHideProgressBarRunnable);
mAirplaneModeEnabler.stop();
+ mDataStateListener.stop();
super.onStop();
}
@@ -916,7 +965,8 @@
setProgressBarVisible(false);
}
changeNextButtonState(mWifiPickerTracker != null
- && mWifiPickerTracker.getConnectedWifiEntry() != null);
+ && mWifiPickerTracker.getConnectedWifiEntry() != null
+ || getDataEnabled());
// Edit the Wi-Fi network of specified SSID.
if (mOpenSsid != null && mWifiPickerTracker != null) {
@@ -991,7 +1041,9 @@
if (mClickedConnect) {
mClickedConnect = false;
- scrollToPreference(connectedWifiPreferenceCategory);
+ if (!mIsInSetupWizard) {
+ scrollToPreference(connectedWifiPreferenceCategory);
+ }
}
}
} else {
@@ -1112,10 +1164,12 @@
@VisibleForTesting
void setAdditionalSettingsSummaries() {
- mConfigureWifiSettingsPreference.setSummary(getString(
- isWifiWakeupEnabled()
- ? R.string.wifi_configure_settings_preference_summary_wakeup_on
- : R.string.wifi_configure_settings_preference_summary_wakeup_off));
+ if (!mIsInSetupWizard) {
+ mConfigureWifiSettingsPreference.setSummary(getString(
+ isWifiWakeupEnabled()
+ ? R.string.wifi_configure_settings_preference_summary_wakeup_on
+ : R.string.wifi_configure_settings_preference_summary_wakeup_off));
+ }
final int numSavedNetworks = mWifiPickerTracker == null ? 0 :
mWifiPickerTracker.getNumSavedNetworks();
@@ -1163,7 +1217,9 @@
}
protected void setProgressBarVisible(boolean visible) {
- showPinnedHeader(visible);
+ if (!mIsInSetupWizard) {
+ showPinnedHeader(visible);
+ }
}
@VisibleForTesting
@@ -1197,7 +1253,7 @@
* Renames/replaces "Next" button when appropriate. "Next" button usually exists in
* Wi-Fi setup screens, not in usual wifi settings screen.
*
- * @param enabled true when the device is connected to a wifi network.
+ * @param enabled true when the device is connected to a mobile or wifi network.
*/
@VisibleForTesting
void changeNextButtonState(boolean enabled) {
@@ -1467,6 +1523,17 @@
}
/**
+ * Implementation of {@code MobileDataEnabledListener.Client}
+ */
+ public void onMobileDataEnabledChange() {
+ changeNextButtonState(getDataEnabled());
+ }
+
+ boolean getDataEnabled() {
+ return getContext().getSystemService(TelephonyManager.class).getDataEnabled(mSubId);
+ }
+
+ /**
* A Wi-Fi preference for the connected Wi-Fi network without internet access.
*
* Override the icon color attribute by {@link ConnectedWifiEntryPreference#getIconColorAttr()}
diff --git a/src/com/android/settings/network/NetworkSetupActivity.java b/src/com/android/settings/network/NetworkSetupActivity.java
new file mode 100644
index 0000000..3b5fb82
--- /dev/null
+++ b/src/com/android/settings/network/NetworkSetupActivity.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ * Copyright (C) 2021-2024 The LineageOS 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.settings.network;
+
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.Bundle;
+
+import androidx.preference.PreferenceFragmentCompat;
+
+import com.android.settings.ButtonBarHandler;
+import com.android.settings.network.NetworkProviderSettings;
+import com.android.settings.R;
+import com.android.settings.SettingsActivity;
+import com.android.settings.SetupWizardUtils;
+import com.android.settings.wifi.p2p.WifiP2pSettings;
+import com.android.settings.wifi.savedaccesspoints2.SavedAccessPointsWifiSettings2;
+
+import com.google.android.setupdesign.util.ThemeHelper;
+
+public class NetworkSetupActivity extends SettingsActivity implements ButtonBarHandler {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTheme(SetupWizardUtils.getTheme(this, getIntent()));
+ setTheme(R.style.SettingsPreferenceTheme_SetupWizard);
+ ThemeHelper.trySetDynamicColor(this);
+ findViewById(R.id.content_parent).setFitsSystemWindows(false);
+ }
+
+ @Override
+ public Intent getIntent() {
+ Intent modIntent = new Intent(super.getIntent());
+ if (!modIntent.hasExtra(EXTRA_SHOW_FRAGMENT)) {
+ modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getNetworkProviderSettingsClass().getName());
+ modIntent.putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID,
+ R.string.provider_internet_settings);
+ }
+ return modIntent;
+ }
+
+ @Override
+ protected boolean isValidFragment(String fragmentName) {
+ final boolean isSavedAccessPointsWifiSettings =
+ SavedAccessPointsWifiSettings2.class.getName().equals(fragmentName);
+
+ if (NetworkProviderSettings.class.getName().equals(fragmentName)
+ || WifiP2pSettings.class.getName().equals(fragmentName)
+ || isSavedAccessPointsWifiSettings) {
+ return true;
+ }
+ return false;
+ }
+
+ /* package */ Class<? extends PreferenceFragmentCompat> getNetworkProviderSettingsClass() {
+ return NetworkProviderSettings.class;
+ }
+}
diff --git a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
index 06015d4..6d74a5c 100644
--- a/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
+++ b/src/com/android/settings/network/telephony/MobileDataPreferenceController.java
@@ -20,6 +20,7 @@
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import android.content.Context;
+import android.provider.Settings;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
@@ -40,6 +41,8 @@
import com.android.settingslib.mobile.dataservice.MobileNetworkInfoEntity;
import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity;
+import com.google.android.setupcompat.util.WizardManagerHelper;
+
import java.util.ArrayList;
import java.util.List;
@@ -121,6 +124,14 @@
public boolean setChecked(boolean isChecked) {
mNeedDialog = isDialogNeeded();
+ // If we are still provisioning we need to allow enabling mobile data first.
+ // By default it is not allowed to use mobile network during provisioning so
+ // we need to allow it.
+ if (!WizardManagerHelper.isDeviceProvisioned(mContext)) {
+ Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, isChecked ? 1 : 0);
+ }
+
if (!mNeedDialog) {
// Update data directly if we don't need dialog
MobileNetworkUtils.setMobileDataEnabled(mContext, mSubId, isChecked, false);