[Wi-Fi] Add multiple networks request case for adding Wi-Fi for apps feature.

Handle adding multiple networks case, add UI components and process saving flow.

Bug: 136472483
Test: Add unit test cases to test filterSavedNetworks API.
Change-Id: I222e2f8294793796e293de49acdb96ecd6a57b0d
This commit is contained in:
govenliu
2019-12-02 15:22:12 +08:00
parent df1118d61c
commit c45672be54
5 changed files with 372 additions and 91 deletions

View File

@@ -3058,6 +3058,7 @@
android:theme="@style/Theme.Panel" android:theme="@style/Theme.Panel"
android:launchMode="singleInstance" android:launchMode="singleInstance"
android:excludeFromRecents="true" android:excludeFromRecents="true"
android:configChanges="orientation|keyboardHidden|screenSize"
android:permission="android.permission.CHANGE_WIFI_STATE"> android:permission="android.permission.CHANGE_WIFI_STATE">
<intent-filter> <intent-filter>
<action android:name="android.settings.WIFI_ADD_NETWORKS" /> <action android:name="android.settings.WIFI_ADD_NETWORKS" />

View File

@@ -118,6 +118,19 @@
android:textColor="?android:attr/textColorSecondary"/> android:textColor="?android:attr/textColorSecondary"/>
</LinearLayout> </LinearLayout>
<LinearLayout
android:id="@+id/multiple_networks"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ListView
android:id="@+id/config_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
android:scrollbarStyle="insideOverlay"/>
</LinearLayout>
<include layout="@layout/horizontal_divider"/> <include layout="@layout/horizontal_divider"/>
<LinearLayout <LinearLayout

View File

@@ -2345,7 +2345,15 @@
<!-- Summary for saved status when saving single network [CHAR LIMIT=30] --> <!-- Summary for saved status when saving single network [CHAR LIMIT=30] -->
<string name="wifi_add_app_single_network_saved_summary">Saved</string> <string name="wifi_add_app_single_network_saved_summary">Saved</string>
<!-- Summary for save failed status when saving single network [CHAR LIMIT=50] --> <!-- Summary for save failed status when saving single network [CHAR LIMIT=50] -->
<string name="wifi_add_app_single_network_save_failed_summary">Couldn\u2019t save. Try again.</string> <string name="wifi_add_app_network_save_failed_summary">Couldn\u2019t save. Try again.</string>
<!-- Title for the panel of add multiple Wi-Fi networks from APP [CHAR LIMIT=50] -->
<string name="wifi_add_app_networks_title">Save networks?</string>
<!-- Summary for the panel of add multiple Wi-Fi networks from APP [CHAR LIMIT=NONE] -->
<string name="wifi_add_app_networks_summary"><xliff:g id="appName" example="ThirdPartyAppName">%1$s</xliff:g> would like to save these networks to your phone</string>
<!-- Summary for the panel of add Wi-Fi networks from APP [CHAR LIMIT=NONE] -->
<string name="wifi_add_app_networks_saving_summary">Saving <xliff:g id="number" example="3">%d</xliff:g> networks\u2026</string>
<!-- Summary for saved status when saving multiple networks [CHAR LIMIT=NONE] -->
<string name="wifi_add_app_networks_saved_summary">Networks saved</string>
<!-- Do not translate. Used for diagnostic screens, precise translation is not necessary <!-- Do not translate. Used for diagnostic screens, precise translation is not necessary
Wi-Fi Testing on the diagnostic screen--> Wi-Fi Testing on the diagnostic screen-->

View File

@@ -36,13 +36,16 @@ import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.preference.internal.PreferenceImageView;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
@@ -67,10 +70,12 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
// Possible result values in each item of the returned result list, which is used // Possible result values in each item of the returned result list, which is used
// to inform the caller APP the processed result of each specified network. // to inform the caller APP the processed result of each specified network.
private static final int RESULT_NETWORK_INITIAL = -1; //initial value @VisibleForTesting
static final int RESULT_NETWORK_INITIAL = -1; //initial value
private static final int RESULT_NETWORK_SUCCESS = 0; private static final int RESULT_NETWORK_SUCCESS = 0;
private static final int RESULT_NETWORK_ADD_ERROR = 1; private static final int RESULT_NETWORK_ADD_ERROR = 1;
private static final int RESULT_NETWORK_ALREADY_EXISTS = 2; @VisibleForTesting
static final int RESULT_NETWORK_ALREADY_EXISTS = 2;
// Handler messages for controlling different state and delay showing the status message. // Handler messages for controlling different state and delay showing the status message.
private static final int MESSAGE_START_SAVING_NETWORK = 1; private static final int MESSAGE_START_SAVING_NETWORK = 1;
@@ -80,6 +85,8 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
// Signal level for the constant signal icon. // Signal level for the constant signal icon.
private static final int MAX_RSSI_SIGNAL_LEVEL = 4; private static final int MAX_RSSI_SIGNAL_LEVEL = 4;
// Max networks count within one request
private static final int MAX_SPECIFIC_NETWORKS_COUNT = 5;
// Duration for showing different status message. // Duration for showing different status message.
private static final long SHOW_SAVING_INTERVAL_MILLIS = 500L; private static final long SHOW_SAVING_INTERVAL_MILLIS = 500L;
@@ -95,51 +102,44 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
Button mSaveButton; Button mSaveButton;
@VisibleForTesting @VisibleForTesting
String mCallingPackageName; String mCallingPackageName;
@VisibleForTesting
List<WifiConfiguration> mAllSpecifiedNetworksList;
@VisibleForTesting
List<UiConfigurationItem> mUiToRequestedList;
@VisibleForTesting
List<Integer> mResultCodeArrayList;
private boolean mIsSingleNetwork;
private boolean mAnyNetworkSavedSuccess;
private TextView mSummaryView; private TextView mSummaryView;
private TextView mSingleNetworkProcessingStatusView; private TextView mSingleNetworkProcessingStatusView;
private int mSavingIndex; private int mSavingIndex;
private List<WifiConfiguration> mAllSpecifiedNetworksList; private UiConfigurationItemAdapter mUiConfigurationItemAdapter;
private ArrayList<Integer> mResultCodeArrayList;
private WifiManager.ActionListener mSaveListener; private WifiManager.ActionListener mSaveListener;
private WifiManager mWifiManager; private WifiManager mWifiManager;
private final Handler mHandler = new Handler() { private final Handler mHandler = new Handler() {
@Override @Override
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
showSaveStatusByState(msg.what);
switch (msg.what) { switch (msg.what) {
case MESSAGE_START_SAVING_NETWORK: case MESSAGE_START_SAVING_NETWORK:
mSaveButton.setEnabled(false); mSaveButton.setEnabled(false);
// Set the initial text color for status message. // Save the proposed networks, start from first one.
mSingleNetworkProcessingStatusView.setTextColor( saveNetwork(0);
com.android.settingslib.Utils.getColorAttr(mActivity,
android.R.attr.textColorSecondary));
mSingleNetworkProcessingStatusView.setText(
getString(R.string.wifi_add_app_single_network_saving_summary));
mSingleNetworkProcessingStatusView.setVisibility(View.VISIBLE);
// Save the proposed network.
saveNetworks();
break; break;
case MESSAGE_SHOW_SAVED_AND_CONNECT_NETWORK: case MESSAGE_SHOW_SAVED_AND_CONNECT_NETWORK:
mSingleNetworkProcessingStatusView.setText(
getString(R.string.wifi_add_app_single_network_saved_summary));
// For the single network case, we need to call connection after saved. // For the single network case, we need to call connection after saved.
connectNetwork(); if (mIsSingleNetwork) {
connectNetwork(0);
}
sendEmptyMessageDelayed(MESSAGE_FINISH, sendEmptyMessageDelayed(MESSAGE_FINISH,
SHOW_SAVED_INTERVAL_MILLIS); SHOW_SAVED_INTERVAL_MILLIS);
break; break;
case MESSAGE_SHOW_SAVE_FAILED: case MESSAGE_SHOW_SAVE_FAILED:
mSingleNetworkProcessingStatusView.setText(
getString(R.string.wifi_add_app_single_network_save_failed_summary));
// Error message need to use colorError attribute to show.
mSingleNetworkProcessingStatusView.setTextColor(
com.android.settingslib.Utils.getColorAttr(mActivity,
android.R.attr.colorError));
mSaveButton.setEnabled(true); mSaveButton.setEnabled(true);
break; break;
@@ -169,15 +169,15 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
public void onViewCreated(View view, Bundle savedInstanceState) { public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
// Initial UI variable. // Initial UI variables.
mLayoutView = view; mLayoutView = view;
mCancelButton = view.findViewById(R.id.cancel); mCancelButton = view.findViewById(R.id.cancel);
mSaveButton = view.findViewById(R.id.save); mSaveButton = view.findViewById(R.id.save);
mSummaryView = view.findViewById(R.id.app_summary); mSummaryView = view.findViewById(R.id.app_summary);
mSingleNetworkProcessingStatusView = view.findViewById(R.id.single_status); mSingleNetworkProcessingStatusView = view.findViewById(R.id.single_status);
// Assigns button listeners and network save listener. // Assigns button listeners and network save listener.
mCancelButton.setOnClickListener(getCancelListener()); mCancelButton.setOnClickListener(getCancelClickListener());
mSaveButton.setOnClickListener(getSaveListener()); mSaveButton.setOnClickListener(getSaveClickListener());
prepareSaveResultListener(); prepareSaveResultListener();
// Prepare the non-UI variables. // Prepare the non-UI variables.
@@ -189,25 +189,29 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
mAllSpecifiedNetworksList = mAllSpecifiedNetworksList =
bundle.getParcelableArrayList(Settings.EXTRA_WIFI_CONFIGURATION_LIST); bundle.getParcelableArrayList(Settings.EXTRA_WIFI_CONFIGURATION_LIST);
// If there is no networks in the request intent, then just finish activity. // If there is no network in the request intent or the requested networks exceed the
if (mAllSpecifiedNetworksList == null || mAllSpecifiedNetworksList.isEmpty()) { // maximum limit, then just finish activity.
if (mAllSpecifiedNetworksList == null || mAllSpecifiedNetworksList.isEmpty()
|| mAllSpecifiedNetworksList.size() > MAX_SPECIFIC_NETWORKS_COUNT) {
finishWithResult(RESULT_CANCELED, null /* resultArrayList */); finishWithResult(RESULT_CANCELED, null /* resultArrayList */);
return; return;
} }
// Initial the result arry. // Initial the result arry.
initializeResultCodeArray(); initializeResultCodeArray();
// Filter the saved networks, and prepare a not saved networks list for UI to present.
mUiToRequestedList = filterSavedNetworks(mWifiManager.getPrivilegedConfiguredNetworks());
// Filter out the saved networks, don't show saved networks to user. // If all the specific networks are all exist, we just need to finish with result.
checkSavedNetworks(); if (mUiToRequestedList.size() == 0) {
finishWithResult(RESULT_OK, mResultCodeArrayList);
return;
}
if (mAllSpecifiedNetworksList.size() == 1) { if (mAllSpecifiedNetworksList.size() == 1) {
// If the only one requested network is already saved, just return with existence. mIsSingleNetwork = true;
if (mResultCodeArrayList.get(0) == RESULT_NETWORK_ALREADY_EXISTS) { // Set the multiple networks related layout as GONE.
finishWithResult(RESULT_OK, mResultCodeArrayList); mLayoutView.findViewById(R.id.multiple_networks).setVisibility(View.GONE);
return;
}
// Show signal icon for single network case. // Show signal icon for single network case.
setSingleNetworkSignalIcon(); setSingleNetworkSignalIcon();
// Show the SSID of the proposed network. // Show the SSID of the proposed network.
@@ -216,7 +220,15 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
// Set the status view as gone when UI is initialized. // Set the status view as gone when UI is initialized.
mSingleNetworkProcessingStatusView.setVisibility(View.GONE); mSingleNetworkProcessingStatusView.setVisibility(View.GONE);
} else { } else {
// TODO: Add code for processing multiple networks case. // Multiple networks request case.
mIsSingleNetwork = false;
// Set the single network related layout as GONE.
mLayoutView.findViewById(R.id.single_network).setVisibility(View.GONE);
// Prepare a UI adapter and set to UI listview.
final ListView uiNetworkListView = mLayoutView.findViewById(R.id.config_list);
mUiConfigurationItemAdapter = new UiConfigurationItemAdapter(mActivity,
com.android.settingslib.R.layout.preference_access_point, mUiToRequestedList);
uiNetworkListView.setAdapter(mUiConfigurationItemAdapter);
} }
// Assigns caller app icon, title, and summary. // Assigns caller app icon, title, and summary.
@@ -257,23 +269,28 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
} }
/** /**
* For the APP specified networks, need to filter out those saved ones and mark them as existed. * For the APP specified networks, filter saved ones and mark those saved as existed. And
* finally return a new UiConfigurationItem list, which contains those new or need to be
* updated networks, back to caller for creating UI to user.
*/ */
private void checkSavedNetworks() { @VisibleForTesting
final List<WifiConfiguration> privilegedWifiConfigurations = ArrayList<UiConfigurationItem> filterSavedNetworks(
mWifiManager.getPrivilegedConfiguredNetworks(); List<WifiConfiguration> savedWifiConfigurations) {
ArrayList<UiConfigurationItem> uiToRequestedList = new ArrayList<>();
boolean foundInSavedList; boolean foundInSavedList;
int networkPositionInBundle = 0; int networkPositionInBundle = 0;
for (WifiConfiguration specifiecConfig : mAllSpecifiedNetworksList) { for (WifiConfiguration specifiecConfig : mAllSpecifiedNetworksList) {
foundInSavedList = false; foundInSavedList = false;
final String displayedSsid = removeDoubleQuotes(specifiecConfig.SSID);
final String ssidWithQuotation = addQuotationIfNeeded(specifiecConfig.SSID); final String ssidWithQuotation = addQuotationIfNeeded(specifiecConfig.SSID);
final String securityType = getSecurityType(specifiecConfig); final String securityType = getSecurityType(specifiecConfig);
for (WifiConfiguration privilegedWifiConfiguration : privilegedWifiConfigurations) { for (WifiConfiguration privilegedWifiConfiguration : savedWifiConfigurations) {
final String savedSecurityType = getSecurityType(privilegedWifiConfiguration); final String savedSecurityType = getSecurityType(privilegedWifiConfiguration);
// If SSID or security type is different, should be new network or need to updated // If SSID or security type is different, should be new network or need to be
// network. // updated network.
if (!ssidWithQuotation.equals(privilegedWifiConfiguration.SSID) if (!ssidWithQuotation.equals(privilegedWifiConfiguration.SSID)
|| !securityType.equals(savedSecurityType)) { || !securityType.equals(savedSecurityType)) {
continue; continue;
@@ -308,10 +325,15 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
// result code list as existed. // result code list as existed.
mResultCodeArrayList.set(networkPositionInBundle, RESULT_NETWORK_ALREADY_EXISTS); mResultCodeArrayList.set(networkPositionInBundle, RESULT_NETWORK_ALREADY_EXISTS);
} else { } else {
// TODO: for multiple networks case, need to add to adapter for present list to user // Prepare to add to UI list to show to user
UiConfigurationItem uiConfigurationIcon = new UiConfigurationItem(displayedSsid,
specifiecConfig, networkPositionInBundle);
uiToRequestedList.add(uiConfigurationIcon);
} }
networkPositionInBundle++; networkPositionInBundle++;
} }
return uiToRequestedList;
} }
private void setSingleNetworkSignalIcon() { private void setSingleNetworkSignalIcon() {
@@ -335,9 +357,22 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("\"").append(input).append("\""); sb.append("\"").append(input).append("\"");
return sb.toString(); return sb.toString();
} }
static String removeDoubleQuotes(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
int length = string.length();
if ((length > 1) && (string.charAt(0) == '"')
&& (string.charAt(length - 1) == '"')) {
return string.substring(1, length - 1);
}
return string;
}
private void assignAppIcon(Context context, String callingPackageName) { private void assignAppIcon(Context context, String callingPackageName) {
final Drawable drawable = loadPackageIconDrawable(context, callingPackageName); final Drawable drawable = loadPackageIconDrawable(context, callingPackageName);
((ImageView) mLayoutView.findViewById(R.id.app_icon)).setImageDrawable(drawable); ((ImageView) mLayoutView.findViewById(R.id.app_icon)).setImageDrawable(drawable);
@@ -364,21 +399,23 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
} }
private CharSequence getAddNetworkRequesterSummary(CharSequence appName) { private CharSequence getAddNetworkRequesterSummary(CharSequence appName) {
return getString(R.string.wifi_add_app_single_network_summary, appName); return getString(mIsSingleNetwork ? R.string.wifi_add_app_single_network_summary
: R.string.wifi_add_app_networks_summary, appName);
} }
private CharSequence getTitle() { private CharSequence getTitle() {
return getString(R.string.wifi_add_app_single_network_title); return getString(mIsSingleNetwork ? R.string.wifi_add_app_single_network_title
: R.string.wifi_add_app_networks_title);
} }
View.OnClickListener getCancelListener() { View.OnClickListener getCancelClickListener() {
return (v) -> { return (v) -> {
Log.d(TAG, "User rejected to add network"); Log.d(TAG, "User rejected to add network");
finishWithResult(RESULT_CANCELED, null /* resultArrayList */); finishWithResult(RESULT_CANCELED, null /* resultArrayList */);
}; };
} }
View.OnClickListener getSaveListener() { View.OnClickListener getSaveClickListener() {
return (v) -> { return (v) -> {
Log.d(TAG, "User agree to add networks"); Log.d(TAG, "User agree to add networks");
// Start to process saving networks. // Start to process saving networks.
@@ -387,44 +424,160 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
}; };
} }
/**
* This class used to show network items to user, each item contains one specific (@Code
* WifiConfiguration} and one index to mapping this UI item to the item in the APP request
* network list.
*/
@VisibleForTesting
static class UiConfigurationItem {
public final String mDisplayedSsid;
public final WifiConfiguration mWifiConfiguration;
public final int mIndex;
UiConfigurationItem(String displayedSsid, WifiConfiguration wifiConfiguration, int index) {
mDisplayedSsid = displayedSsid;
mWifiConfiguration = wifiConfiguration;
mIndex = index;
}
}
private class UiConfigurationItemAdapter extends ArrayAdapter<UiConfigurationItem> {
private final int mResourceId;
private final LayoutInflater mInflater;
UiConfigurationItemAdapter(Context context, int resourceId,
List<UiConfigurationItem> objects) {
super(context, resourceId, objects);
mResourceId = resourceId;
mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view == null) {
view = mInflater.inflate(mResourceId, parent, false /* attachToRoot */);
}
final View divider = view.findViewById(
com.android.settingslib.R.id.two_target_divider);
if (divider != null) {
divider.setVisibility(View.GONE);
}
final UiConfigurationItem uiConfigurationItem = getItem(position);
final TextView titleView = view.findViewById(android.R.id.title);
if (titleView != null) {
// Shows whole SSID for better UX.
titleView.setSingleLine(false);
titleView.setText(uiConfigurationItem.mDisplayedSsid);
}
final PreferenceImageView imageView = view.findViewById(android.R.id.icon);
if (imageView != null) {
final Drawable drawable = getContext().getDrawable(
com.android.settingslib.Utils.getWifiIconResource(MAX_RSSI_SIGNAL_LEVEL));
drawable.setTintList(
com.android.settingslib.Utils.getColorAttr(getContext(),
android.R.attr.colorControlNormal));
imageView.setImageDrawable(drawable);
}
final TextView summaryView = view.findViewById(android.R.id.summary);
if (summaryView != null) {
summaryView.setVisibility(View.GONE);
}
return view;
}
}
private void prepareSaveResultListener() { private void prepareSaveResultListener() {
mSaveListener = new WifiManager.ActionListener() { mSaveListener = new WifiManager.ActionListener() {
@Override @Override
public void onSuccess() { public void onSuccess() {
mResultCodeArrayList.set(mSavingIndex, RESULT_NETWORK_SUCCESS); // Set success into result list.
Message nextState_Message = mHandler.obtainMessage( mResultCodeArrayList.set(mUiToRequestedList.get(mSavingIndex).mIndex,
MESSAGE_SHOW_SAVED_AND_CONNECT_NETWORK); RESULT_NETWORK_SUCCESS);
// Delay to change to next state for showing saving mesage for a period. mAnyNetworkSavedSuccess = true;
mHandler.sendMessageDelayed(nextState_Message, SHOW_SAVING_INTERVAL_MILLIS);
if (saveNextNetwork()) {
return;
}
// Show saved or failed according to all results
showSavedOrFail();
} }
@Override @Override
public void onFailure(int reason) { public void onFailure(int reason) {
mResultCodeArrayList.set(mSavingIndex, RESULT_NETWORK_ADD_ERROR); // Set result code of this network to be failed in the return list.
Message nextState_Message = mHandler.obtainMessage(MESSAGE_SHOW_SAVE_FAILED); mResultCodeArrayList.set(mUiToRequestedList.get(mSavingIndex).mIndex,
// Delay to change to next state for showing saving mesage for a period. RESULT_NETWORK_ADD_ERROR);
mHandler.sendMessageDelayed(nextState_Message, SHOW_SAVING_INTERVAL_MILLIS);
if (saveNextNetwork()) {
return;
}
// Show saved or failed according to all results
showSavedOrFail();
} }
}; };
} }
private void saveNetworks() { /**
final WifiConfiguration wifiConfiguration = mAllSpecifiedNetworksList.get(0); * For multiple networks case, we need to check if there is other network need to save.
*/
private boolean saveNextNetwork() {
// Save the next network if have.
if (!mIsSingleNetwork && mSavingIndex < (mUiToRequestedList.size() - 1)) {
mSavingIndex++;
saveNetwork(mSavingIndex);
return true;
}
return false;
}
/**
* If any one of the specified networks is success, then we show saved and return all results
* list back to caller APP, otherwise we show failed to indicate all networks saved failed.
*/
private void showSavedOrFail() {
Message nextStateMessage;
if (mAnyNetworkSavedSuccess) {
// Enter next state after all networks are saved.
nextStateMessage = mHandler.obtainMessage(
MESSAGE_SHOW_SAVED_AND_CONNECT_NETWORK);
} else {
nextStateMessage = mHandler.obtainMessage(MESSAGE_SHOW_SAVE_FAILED);
}
// Delay to change to next state for showing saving mesage for a period.
mHandler.sendMessageDelayed(nextStateMessage, SHOW_SAVING_INTERVAL_MILLIS);
}
/**
* Call framework API to save single network.
*/
private void saveNetwork(int index) {
final WifiConfiguration wifiConfiguration = mUiToRequestedList.get(
index).mWifiConfiguration;
wifiConfiguration.SSID = addQuotationIfNeeded(wifiConfiguration.SSID); wifiConfiguration.SSID = addQuotationIfNeeded(wifiConfiguration.SSID);
mSavingIndex = index;
mWifiManager.save(wifiConfiguration, mSaveListener); mWifiManager.save(wifiConfiguration, mSaveListener);
} }
private void connectNetwork() { private void connectNetwork(int index) {
final WifiConfiguration wifiConfiguration = mAllSpecifiedNetworksList.get(0); final WifiConfiguration wifiConfiguration = mUiToRequestedList.get(
// Don't need to handle the connect result. index).mWifiConfiguration;
mWifiManager.connect(wifiConfiguration, null /* ActionListener */); mWifiManager.connect(wifiConfiguration, null /* ActionListener */);
} }
private void finishWithResult(int resultCode, ArrayList<Integer> resultArrayList) { private void finishWithResult(int resultCode, List<Integer> resultArrayList) {
if (resultArrayList != null) { if (resultArrayList != null) {
Intent intent = new Intent(); Intent intent = new Intent();
intent.putIntegerArrayListExtra(Settings.EXTRA_WIFI_CONFIGURATION_RESULT_LIST, intent.putIntegerArrayListExtra(Settings.EXTRA_WIFI_CONFIGURATION_RESULT_LIST,
resultArrayList); (ArrayList<Integer>) resultArrayList);
mActivity.setResult(resultCode, intent); mActivity.setResult(resultCode, intent);
} }
mActivity.finish(); mActivity.finish();
@@ -435,4 +588,59 @@ public class AddAppNetworksFragment extends InstrumentedFragment {
// TODO(b/144891278): Need to define a new metric for this page, use the WIFI item first. // TODO(b/144891278): Need to define a new metric for this page, use the WIFI item first.
return SettingsEnums.WIFI; return SettingsEnums.WIFI;
} }
private void showSaveStatusByState(int status) {
switch (status) {
case MESSAGE_START_SAVING_NETWORK:
if (mIsSingleNetwork) {
// Set the initial text color for status message.
mSingleNetworkProcessingStatusView.setTextColor(
com.android.settingslib.Utils.getColorAttr(mActivity,
android.R.attr.textColorSecondary));
mSingleNetworkProcessingStatusView.setText(
getString(R.string.wifi_add_app_single_network_saving_summary));
mSingleNetworkProcessingStatusView.setVisibility(View.VISIBLE);
} else {
mSummaryView.setTextColor(
com.android.settingslib.Utils.getColorAttr(mActivity,
android.R.attr.textColorSecondary));
mSummaryView.setText(
getString(R.string.wifi_add_app_networks_saving_summary,
mUiToRequestedList.size()));
}
break;
case MESSAGE_SHOW_SAVED_AND_CONNECT_NETWORK:
if (mIsSingleNetwork) {
mSingleNetworkProcessingStatusView.setText(
getString(R.string.wifi_add_app_single_network_saved_summary));
} else {
mSummaryView.setText(
getString(R.string.wifi_add_app_networks_saved_summary));
}
break;
case MESSAGE_SHOW_SAVE_FAILED:
if (mIsSingleNetwork) {
// Error message need to use colorError attribute to show.
mSingleNetworkProcessingStatusView.setTextColor(
com.android.settingslib.Utils.getColorAttr(mActivity,
android.R.attr.colorError));
mSingleNetworkProcessingStatusView.setText(
getString(R.string.wifi_add_app_network_save_failed_summary));
} else {
// Error message need to use colorError attribute to show.
mSummaryView.setTextColor(
com.android.settingslib.Utils.getColorAttr(mActivity,
android.R.attr.colorError));
mSummaryView.setText(
getString(R.string.wifi_add_app_network_save_failed_summary));
}
break;
default:
// Do nothing.
break;
}
}
} }

View File

@@ -21,13 +21,14 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import android.content.Context;
import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiConfiguration;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcelable; import android.os.Parcelable;
import android.provider.Settings; import android.provider.Settings;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import com.android.settings.R; import com.android.settings.R;
import org.junit.Before; import org.junit.Before;
@@ -42,18 +43,34 @@ import java.util.List;
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class AddAppNetworksFragmentTest { public class AddAppNetworksFragmentTest {
private static final String FAKE_APP_NAME = "fake_app_name"; private static final String FAKE_APP_NAME = "fake_app_name";
private static final String FAKE_SSID = "fake_ssid"; private static final String FAKE_NEW_WPA_SSID = "fake_new_wpa_ssid";
private static final String FAKE_NEW_OPEN_SSID = "fake_new_open_ssid";
private static final String FAKE_NEW_SAVED_WPA_SSID = "\"fake_new_wpa_ssid\"";
private AddAppNetworksFragment mAddAppNetworksFragment; private AddAppNetworksFragment mAddAppNetworksFragment;
private Context mContext; private List<WifiConfiguration> mFakedSpecifiedNetworksList;
private List<WifiConfiguration> mFakeSavedNetworksList;
private WifiConfiguration mNewWpaConfigEntry;
private WifiConfiguration mNewOpenConfigEntry;
private WifiConfiguration mSavedWpaConfigEntry;
private Bundle mBundle;
private ArrayList<Integer> mFakedResultArrayList = new ArrayList<>();
@Before @Before
public void setUp() { public void setUp() {
mAddAppNetworksFragment = spy(new AddAppNetworksFragment()); mAddAppNetworksFragment = spy(new AddAppNetworksFragment());
mNewWpaConfigEntry = generateWifiConfig(FAKE_NEW_WPA_SSID,
WifiConfiguration.KeyMgmt.WPA_PSK, "\"1234567890\"");
mNewOpenConfigEntry = generateWifiConfig(FAKE_NEW_OPEN_SSID,
WifiConfiguration.KeyMgmt.NONE, null);
mSavedWpaConfigEntry = generateWifiConfig(FAKE_NEW_SAVED_WPA_SSID,
WifiConfiguration.KeyMgmt.WPA_PSK, "\"1234567890\"");
} }
@Test @Test
public void callingPackageName_onCreateView_shouldBeCorrect() { public void callingPackageName_onCreateView_shouldBeCorrect() {
setUpOneNetworkBundle(); addOneSpecifiedNetworkConfig(mNewWpaConfigEntry);
setUpBundle(mFakedSpecifiedNetworksList);
setupFragment(); setupFragment();
assertThat(mAddAppNetworksFragment.mCallingPackageName).isEqualTo(FAKE_APP_NAME); assertThat(mAddAppNetworksFragment.mCallingPackageName).isEqualTo(FAKE_APP_NAME);
@@ -61,7 +78,8 @@ public class AddAppNetworksFragmentTest {
@Test @Test
public void launchFragment_shouldShowSaveButton() { public void launchFragment_shouldShowSaveButton() {
setUpOneNetworkBundle(); addOneSpecifiedNetworkConfig(mNewWpaConfigEntry);
setUpBundle(mFakedSpecifiedNetworksList);
setupFragment(); setupFragment();
assertThat(mAddAppNetworksFragment.mSaveButton).isNotNull(); assertThat(mAddAppNetworksFragment.mSaveButton).isNotNull();
@@ -69,7 +87,8 @@ public class AddAppNetworksFragmentTest {
@Test @Test
public void launchFragment_shouldShowCancelButton() { public void launchFragment_shouldShowCancelButton() {
setUpOneNetworkBundle(); addOneSpecifiedNetworkConfig(mNewWpaConfigEntry);
setUpBundle(mFakedSpecifiedNetworksList);
setupFragment(); setupFragment();
assertThat(mAddAppNetworksFragment.mCancelButton).isNotNull(); assertThat(mAddAppNetworksFragment.mCancelButton).isNotNull();
@@ -77,40 +96,72 @@ public class AddAppNetworksFragmentTest {
@Test @Test
public void requestOneNetwork_shouldShowCorrectSSID() { public void requestOneNetwork_shouldShowCorrectSSID() {
setUpOneNetworkBundle(); addOneSpecifiedNetworkConfig(mNewWpaConfigEntry);
setUpBundle(mFakedSpecifiedNetworksList);
setupFragment(); setupFragment();
TextView ssidView = (TextView) mAddAppNetworksFragment.mLayoutView.findViewById( TextView ssidView = (TextView) mAddAppNetworksFragment.mLayoutView.findViewById(
R.id.single_ssid); R.id.single_ssid);
assertThat(ssidView.getText()).isEqualTo(FAKE_SSID); assertThat(ssidView.getText()).isEqualTo(FAKE_NEW_WPA_SSID);
} }
@Test @Test
public void withNoExtra_requestNetwork_shouldFinished() { public void withNoExtra_requestNetwork_shouldFinished() {
setUpNoNetworkBundle(); addOneSpecifiedNetworkConfig(null);
setUpBundle(mFakedSpecifiedNetworksList);
setupFragment(); setupFragment();
assertThat(mAddAppNetworksFragment.mActivity.isFinishing()).isTrue(); assertThat(mAddAppNetworksFragment.mActivity.isFinishing()).isTrue();
} }
private void setUpOneNetworkBundle() { @Test
// Setup one network. public void withOneHalfSavedNetworks_uiListAndResultListShouldBeCorrect() {
List<WifiConfiguration> wifiConfigurationList = new ArrayList<>(); // Arrange
wifiConfigurationList.add( // Setup a fake saved network list and assign to fragment.
generateWifiConfig(FAKE_SSID, WifiConfiguration.KeyMgmt.WPA_PSK, "\"1234567890\"")); addOneSavedNetworkConfig(mSavedWpaConfigEntry);
// Setup two specified networks and their results and assign to fragment.
addOneSpecifiedNetworkConfig(mNewWpaConfigEntry);
addOneSpecifiedNetworkConfig(mNewOpenConfigEntry);
mAddAppNetworksFragment.mAllSpecifiedNetworksList = mFakedSpecifiedNetworksList;
mFakedResultArrayList.add(mAddAppNetworksFragment.RESULT_NETWORK_INITIAL);
mFakedResultArrayList.add(mAddAppNetworksFragment.RESULT_NETWORK_INITIAL);
mAddAppNetworksFragment.mResultCodeArrayList = mFakedResultArrayList;
// Act
mAddAppNetworksFragment.mUiToRequestedList = mAddAppNetworksFragment.filterSavedNetworks(
mFakeSavedNetworksList);
// Assert
assertThat(mAddAppNetworksFragment.mUiToRequestedList).hasSize(1);
assertThat(mAddAppNetworksFragment.mResultCodeArrayList.get(0)).isEqualTo(
mAddAppNetworksFragment.RESULT_NETWORK_ALREADY_EXISTS);
assertThat(mAddAppNetworksFragment.mUiToRequestedList.get(
0).mWifiConfiguration.SSID).isEqualTo(FAKE_NEW_OPEN_SSID);
}
private void addOneSavedNetworkConfig(@NonNull WifiConfiguration wifiConfiguration) {
if (mFakeSavedNetworksList == null) {
mFakeSavedNetworksList = new ArrayList<>();
}
mFakeSavedNetworksList.add(wifiConfiguration);
}
private void addOneSpecifiedNetworkConfig(@NonNull WifiConfiguration wifiConfiguration) {
if (wifiConfiguration != null) {
if (mFakedSpecifiedNetworksList == null) {
mFakedSpecifiedNetworksList = new ArrayList<>();
}
mFakedSpecifiedNetworksList.add(wifiConfiguration);
}
}
private void setUpBundle(List<WifiConfiguration> allFakedNetworksList) {
// Set up bundle. // Set up bundle.
final Bundle bundle = new Bundle(); final Bundle bundle = new Bundle();
bundle.putString(AddAppNetworksActivity.KEY_CALLING_PACKAGE_NAME, FAKE_APP_NAME); bundle.putString(AddAppNetworksActivity.KEY_CALLING_PACKAGE_NAME, FAKE_APP_NAME);
bundle.putParcelableArrayList(Settings.EXTRA_WIFI_CONFIGURATION_LIST, bundle.putParcelableArrayList(Settings.EXTRA_WIFI_CONFIGURATION_LIST,
(ArrayList<? extends Parcelable>) wifiConfigurationList); (ArrayList<? extends Parcelable>) allFakedNetworksList);
doReturn(bundle).when(mAddAppNetworksFragment).getArguments();
}
private void setUpNoNetworkBundle() {
// Set up bundle.
final Bundle bundle = new Bundle();
bundle.putString(AddAppNetworksActivity.KEY_CALLING_PACKAGE_NAME, FAKE_APP_NAME);
bundle.putParcelableArrayList(Settings.EXTRA_WIFI_CONFIGURATION_LIST, null);
doReturn(bundle).when(mAddAppNetworksFragment).getArguments(); doReturn(bundle).when(mAddAppNetworksFragment).getArguments();
} }