Added Wifi Assistant Card

+ Show Wi-Fi Assistant card above network list that scroll under the action bar with the rest of the list
+ Display a promo image and text
+ Clicking "Setup" should link to the selected Wi-Fi assistant app (must be open to 3rd parties)
+ Touching "No, Thanks" should snooze this card for 30 days / 2nd time 90 / 3rd time 180 days / then forever

Bug: 15703202

Change-Id: If74101bea630246c6bda2de3ed79fee72eca4c0c
This commit is contained in:
PauloftheWest
2014-07-05 06:28:56 -07:00
parent 6f877156e0
commit 060e01a93e
19 changed files with 276 additions and 59 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/wifi_assistant_card"
android:background="@android:color/transparent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="vertical"
android:padding="@dimen/wifi_assistant_padding">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/cardBackground"
android:background="@color/setup_add_wifi_network_text_color"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/wifi_assistant_card" />
<TextView
android:id="@+id/backgroundText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/wifi_assistant_text_padding"
android:gravity="start"
android:text="@string/wifi_assistant_intro_setup"
style="@style/WifiAssistantText" />
</RelativeLayout>
<TextView
android:id="@+id/wifi_assistant_text"
android:background="@android:color/transparent"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_marginBottom="@dimen/wifi_assistant_padding_top_bottom"
android:layout_marginTop="@dimen/wifi_assistant_padding_top_bottom"
android:layout_marginLeft="@dimen/wifi_assistant_padding_start_end"
android:layout_marginRight="@dimen/wifi_assistant_padding_start_end"
android:gravity="start"
android:text="@string/wifi_assistant_title_message"
android:textAppearance="?android:attr/textAppearanceMedium" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="@android:color/transparent"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:gravity="end"
android:orientation="horizontal">
<Button
android:id="@+id/no_thanks_button"
android:background="@android:color/white"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/wifi_assistant_no_thanks"
android:paddingLeft="@dimen/wifi_assistant_text_padding"
android:paddingRight="@dimen/wifi_assistant_text_padding" />
<Button
android:id="@+id/setup"
android:background="@android:color/white"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:paddingLeft="@dimen/wifi_assistant_text_padding"
android:paddingRight="@dimen/wifi_assistant_text_padding"
android:text="@string/wifi_assistant_setup"
style="@style/WifiAssistantButton" />
</LinearLayout>
</LinearLayout>

View File

@@ -16,4 +16,10 @@
<resources>
<dimen name="battery_history_chart_height">160dp</dimen>
<!-- Dimensions for Wifi Assistant Card -->
<dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
<dimen name="wifi_assistant_padding_start_end">16dp</dimen>
<dimen name="wifi_assistant_padding">25dp</dimen>
<dimen name="wifi_assistant_text_padding">16dp</dimen>
</resources>

View File

@@ -70,4 +70,9 @@
<dimen name="search_result_item_image_margin_start">24dp</dimen>
<dimen name="search_result_item_image_margin_end">32dp</dimen>
<!-- Dimensions for Wifi Assistant Card -->
<dimen name="wifi_assistant_padding_top_bottom">24dp</dimen>
<dimen name="wifi_assistant_padding_start_end">24dp</dimen>
<dimen name="wifi_assistant_padding">25dp</dimen>
<dimen name="wifi_assistant_text_padding">24dp</dimen>
</resources>

View File

@@ -50,4 +50,9 @@
<dimen name="switchbar_subsettings_margin_start">80dp</dimen>
<dimen name="switchbar_subsettings_margin_end">80dp</dimen>
<!-- Dimensions for Wifi Assistant Card -->
<dimen name="wifi_assistant_padding_top_bottom">24dp</dimen>
<dimen name="wifi_assistant_padding_start_end">24dp</dimen>
<dimen name="wifi_assistant_padding">25dp</dimen>
<dimen name="wifi_assistant_text_padding">24dp</dimen>
</resources>

View File

@@ -40,6 +40,7 @@
<color name="setup_divider_color_dark">#33ffffff</color>
<color name="setup_divider_color_light">#33000000</color>
<color name="setup_add_wifi_network_text_color">#ff009587</color>
<color name="setup_add_wifi_network_background_color">#ff009587</color>
<color name="circle_avatar_frame_color">#ffffffff</color>
<color name="circle_avatar_frame_shadow_color">#80000000</color>

View File

@@ -165,4 +165,10 @@
<dimen name="search_suggestion_item_image_margin_start">32dp</dimen>
<dimen name="search_suggestion_item_image_margin_end">16dp</dimen>
<!-- Dimensions for Wifi Assistant Card -->
<dimen name="wifi_assistant_padding_top_bottom">16dp</dimen>
<dimen name="wifi_assistant_padding_start_end">16dp</dimen>
<dimen name="wifi_assistant_padding">25dp</dimen>
<dimen name="wifi_assistant_text_padding">16dp</dimen>
</resources>

View File

@@ -1288,6 +1288,8 @@
<!-- Bluetooth settings. Dock Setting Dialog - Remember setting and don't ask user again -->
<string name="bluetooth_dock_settings_remember">Remember settings</string>
<!-- Wifi Assistant title string. [CHAR LIMIT=20] -->
<string name="wifi_assistant_intro_setup">Introducing\nWi\u2011Fi Assistant</string>
<!-- Wifi Assistant title string. [CHAR LIMIT=40] -->
<string name="wifi_assistant_title">Wi\u2011Fi Assistant</string>
<!-- Wifi Assistant No, thanks string. Text to say no to wifi assistant. [CHAR LIMIT=20] -->

View File

@@ -262,6 +262,16 @@
<item name="android:textSize">18sp</item>
</style>
<style name="WifiAssistantText">
<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
<item name="android:textColor">@android:color/white</item>
</style>
<style name="WifiAssistantButton">
<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
<item name="android:textColor">@color/setup_add_wifi_network_text_color</item>
</style>
<!-- Scrollbar style OUTSIDE_OVERLAY -->
<integer name="preference_scrollbar_style">33554432</integer>

View File

@@ -25,7 +25,6 @@ import com.android.settings.SettingsActivity;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
import com.android.settings.wifi.p2p.WifiP2pSettings;
import android.app.Activity;
import android.app.Dialog;
@@ -37,10 +36,12 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.SharedPreferences;
import android.location.LocationManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkScoreManager;
import android.net.wifi.ScanResult;
import android.net.wifi.SupplicantState;
import android.net.wifi.WifiConfiguration;
@@ -59,7 +60,9 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
@@ -82,6 +85,7 @@ public class WifiSettings extends RestrictedSettingsFragment
implements DialogInterface.OnClickListener, Indexable {
private static final String TAG = "WifiSettings";
/* package */ static final int MENU_ID_WPS_PBC = Menu.FIRST;
private static final int MENU_ID_WPS_PIN = Menu.FIRST + 1;
private static final int MENU_ID_SAVED_NETWORK = Menu.FIRST + 2;
@@ -93,6 +97,13 @@ public class WifiSettings extends RestrictedSettingsFragment
private static final int MENU_ID_MODIFY = Menu.FIRST + 8;
private static final int MENU_ID_WRITE_NFC = Menu.FIRST + 9;
private static final String KEY_ASSISTANT_DISMISS_TIME = "wifi_assistant_dismiss_time";
private static final String KEY_ASSISTANT_START_TIME = "wifi_assistant_start_time";
private static final long MILI_SECONDS_30_DAYS = 30L * 24L * 60L * 60L * 1000L;
private static final long MILI_SECONDS_90_DAYS = MILI_SECONDS_30_DAYS * 3L;
private static final long MILI_SECONDS_180_DAYS = MILI_SECONDS_90_DAYS * 2L;
public static final int WIFI_DIALOG_ID = 1;
/* package */ static final int WPS_PBC_DIALOG_ID = 2;
private static final int WPS_PIN_DIALOG_ID = 3;
@@ -142,6 +153,7 @@ public class WifiSettings extends RestrictedSettingsFragment
private boolean mDlgEdit;
private AccessPoint mDlgAccessPoint;
private Bundle mAccessPointSavedState;
private Preference mWifiAssistant;
/** verbose logging flag. this flag is set thru developer debugging options
* and used so as to assist with in-the-field WiFi connectivity debugging */
@@ -149,6 +161,105 @@ public class WifiSettings extends RestrictedSettingsFragment
/* End of "used in Wifi Setup context" */
/** Holds the Wifi Assistant Card. */
private static class WifiAssistantPreference extends Preference {
final WifiSettings mWifiSettings;
public WifiAssistantPreference(WifiSettings wifiSettings) {
super(wifiSettings.getActivity());
mWifiSettings = wifiSettings;
setLayoutResource(R.layout.wifi_assistant_card);
}
@Override
public void onBindView(View view) {
super.onBindView(view);
final Preference pref = this;
Button setup = (Button)view.findViewById(R.id.setup);
Button noThanks = (Button)view.findViewById(R.id.no_thanks_button);
if (setup != null && noThanks != null) {
setup.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(NetworkScoreManager.ACTION_CHANGE_ACTIVE);
intent.putExtra(NetworkScoreManager.EXTRA_PACKAGE_NAME, "wifi-assistant");
mWifiSettings.startActivity(intent);
mWifiSettings.setWifiAssistantTimeout();
mWifiSettings.getPreferenceScreen().removePreference(pref);
}
});
noThanks.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mWifiSettings.setWifiAssistantTimeout();
mWifiSettings.getPreferenceScreen().removePreference(pref);
}
});
}
}
}
/** A restricted multimap for use in constructAccessPoints */
private static class Multimap<K,V> {
private final HashMap<K,List<V>> store = new HashMap<K,List<V>>();
/** retrieve a non-null list of values with key K */
List<V> getAll(K key) {
List<V> values = store.get(key);
return values != null ? values : Collections.<V>emptyList();
}
void put(K key, V val) {
List<V> curVals = store.get(key);
if (curVals == null) {
curVals = new ArrayList<V>(3);
store.put(key, curVals);
}
curVals.add(val);
}
}
private static class Scanner extends Handler {
private int mRetry = 0;
private WifiSettings mWifiSettings = null;
Scanner(WifiSettings wifiSettings) {
mWifiSettings = wifiSettings;
}
void resume() {
if (!hasMessages(0)) {
sendEmptyMessage(0);
}
}
void forceScan() {
removeMessages(0);
sendEmptyMessage(0);
}
void pause() {
mRetry = 0;
removeMessages(0);
}
@Override
public void handleMessage(Message message) {
if (mWifiSettings.mWifiManager.startScan()) {
mRetry = 0;
} else if (++mRetry >= 3) {
mRetry = 0;
Activity activity = mWifiSettings.getActivity();
if (activity != null) {
Toast.makeText(activity, R.string.wifi_fail_to_scan, Toast.LENGTH_LONG).show();
}
return;
}
sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);
}
}
public WifiSettings() {
super(DISALLOW_CONFIG_WIFI);
mFilter = new IntentFilter();
@@ -168,7 +279,7 @@ public class WifiSettings extends RestrictedSettingsFragment
}
};
mScanner = new Scanner();
mScanner = new Scanner(this);
}
@Override
@@ -248,6 +359,8 @@ public class WifiSettings extends RestrictedSettingsFragment
addPreferencesFromResource(R.xml.wifi_settings);
mWifiAssistant = new WifiAssistantPreference(this);
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
getListView().setEmptyView(mEmptyView);
registerForContextMenu(getListView());
@@ -322,7 +435,7 @@ public class WifiSettings extends RestrictedSettingsFragment
.setIcon(ta.getDrawable(0))
.setEnabled(wifiIsEnabled)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
if (savedNetworksExist){
if (savedNetworksExist) {
menu.add(Menu.NONE, MENU_ID_SAVED_NETWORK, 0, R.string.wifi_saved_access_points_label)
.setIcon(ta.getDrawable(0))
.setEnabled(wifiIsEnabled)
@@ -483,7 +596,7 @@ public class WifiSettings extends RestrictedSettingsFragment
if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE &&
mSelectedAccessPoint.networkId == INVALID_NETWORK_ID) {
mSelectedAccessPoint.generateOpenNetworkConfig();
if (!savedNetworksExist){
if (!savedNetworksExist) {
savedNetworksExist = true;
getActivity().invalidateOptionsMenu();
}
@@ -566,9 +679,14 @@ public class WifiSettings extends RestrictedSettingsFragment
final Collection<AccessPoint> accessPoints =
constructAccessPoints(getActivity(), mWifiManager, mLastInfo, mLastState);
getPreferenceScreen().removeAll();
if(accessPoints.size() == 0) {
if (accessPoints.size() == 0) {
addMessagePreference(R.string.wifi_empty_list_wifi_on);
}
if (showWifiAssistantCard()) {
getPreferenceScreen().addPreference(mWifiAssistant);
}
for (AccessPoint accessPoint : accessPoints) {
getPreferenceScreen().addPreference(accessPoint);
}
@@ -588,6 +706,34 @@ public class WifiSettings extends RestrictedSettingsFragment
}
}
private boolean showWifiAssistantCard() {
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
long lastTimeoutEndTime = sharedPreferences.getLong(KEY_ASSISTANT_START_TIME, 0);
long dismissTime = sharedPreferences.getLong(KEY_ASSISTANT_DISMISS_TIME, 0);
return ((System.currentTimeMillis() - lastTimeoutEndTime) > dismissTime);
}
private void setWifiAssistantTimeout() {
SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
SharedPreferences.Editor editor = sharedPreferences.edit();
long dismissTime = sharedPreferences.getLong(KEY_ASSISTANT_DISMISS_TIME, 0);
if (dismissTime == 0) {
dismissTime = MILI_SECONDS_30_DAYS;
} else if (dismissTime == MILI_SECONDS_30_DAYS) {
dismissTime = MILI_SECONDS_90_DAYS;
} else if (dismissTime == MILI_SECONDS_90_DAYS) {
dismissTime = MILI_SECONDS_180_DAYS;
} else if (dismissTime == MILI_SECONDS_180_DAYS) {
dismissTime = java.lang.Long.MAX_VALUE;
}
editor.putLong(KEY_ASSISTANT_DISMISS_TIME, dismissTime);
editor.putLong(KEY_ASSISTANT_START_TIME, System.currentTimeMillis());
editor.apply();
}
private void setOffMessage() {
if (mEmptyView != null) {
mEmptyView.setCompoundDrawablesWithIntrinsicBounds(0,
@@ -663,25 +809,6 @@ public class WifiSettings extends RestrictedSettingsFragment
return accessPoints;
}
/** A restricted multimap for use in constructAccessPoints */
private static class Multimap<K,V> {
private final HashMap<K,List<V>> store = new HashMap<K,List<V>>();
/** retrieve a non-null list of values with key K */
List<V> getAll(K key) {
List<V> values = store.get(key);
return values != null ? values : Collections.<V>emptyList();
}
void put(K key, V val) {
List<V> curVals = store.get(key);
if (curVals == null) {
curVals = new ArrayList<V>(3);
store.put(key, curVals);
}
curVals.add(val);
}
}
private void handleEvent(Context context, Intent intent) {
String action = intent.getAction();
if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) {
@@ -773,41 +900,6 @@ public class WifiSettings extends RestrictedSettingsFragment
mScanner.pause();
}
private class Scanner extends Handler {
private int mRetry = 0;
void resume() {
if (!hasMessages(0)) {
sendEmptyMessage(0);
}
}
void forceScan() {
removeMessages(0);
sendEmptyMessage(0);
}
void pause() {
mRetry = 0;
removeMessages(0);
}
@Override
public void handleMessage(Message message) {
if (mWifiManager.startScan()) {
mRetry = 0;
} else if (++mRetry >= 3) {
mRetry = 0;
Activity activity = getActivity();
if (activity != null) {
Toast.makeText(activity, R.string.wifi_fail_to_scan, Toast.LENGTH_LONG).show();
}
return;
}
sendEmptyMessageDelayed(0, WIFI_RESCAN_INTERVAL_MS);
}
}
/**
* Renames/replaces "Next" button when appropriate. "Next" button usually exists in
* Wifi setup screens, not in usual wifi settings screen.