am 9c3c57f7: (-s ours) DO NOT MERGE: Fix bug #15161058 Stability: ISE in Settings:Fragment DashboardSummary{588de71} not attached to Activity

* commit '9c3c57f7aeced1dad6f7aca5552d01f696f8ea26':
  DO NOT MERGE: Fix bug #15161058 Stability: ISE in Settings:Fragment DashboardSummary{588de71} not attached to Activity
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index 7275c73..d0ae981 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -197,11 +197,6 @@
                         android:prompt="@string/proxy_settings_title"
                         android:entries="@array/wifi_proxy_settings" />
 
-                <TextView android:id="@+id/proxy_pac_info"
-                        style="@style/wifi_item_content"
-                        android:textStyle="bold"
-                        android:textAlignment="viewStart"
-                        android:visibility="gone"/>
             </LinearLayout>
 
             <LinearLayout android:id="@+id/proxy_warning_limited_support"
@@ -216,6 +211,21 @@
                         android:text="@string/proxy_warning_limited_support" />
             </LinearLayout>
 
+            <LinearLayout android:id="@+id/proxy_pac_field"
+                    style="@style/wifi_section"
+                    android:visibility="gone">
+                <LinearLayout style="@style/wifi_item">
+                    <TextView
+                            style="@style/wifi_item_label"
+                            android:text="@string/proxy_url_title" />
+
+                    <EditText android:id="@+id/proxy_pac"
+                            style="@style/wifi_item_content"
+                            android:hint="@string/proxy_url_hint"
+                            android:inputType="textNoSuggestions"
+                            android:singleLine="true"/>
+                </LinearLayout>
+            </LinearLayout>
             <LinearLayout android:id="@+id/proxy_fields"
                     style="@style/wifi_section"
                     android:visibility="gone">
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 5d1a9b6..8b8777c 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -469,6 +469,8 @@
         <item>None</item>
         <!-- Manual HTTP proxy settings are used for the current wifi network [CHAR LIMIT=25] -->
         <item>Manual</item>
+        <!-- Proxy Auto-Config URL that is used for the current wifi network [CHAR LIMIT=25] -->
+        <item>Proxy Auto-Config</item>
     </string-array>
 
     <!-- Sound settings for emergency tone. -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fd40524..5e90be5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -445,8 +445,10 @@
     <!-- HTTP proxy settings. Warning message about limited application support [CHAR LIMIT=100]-->
     <string name="proxy_warning_limited_support">The HTTP proxy is used by the browser but may not be used by the other apps.</string>
 
-    <!-- HTTP proxy settings. Title for Proxy-Auto Config URL.  [CHAR LIMIT=NONE]-->
-    <string name="proxy_url">"PAC URL: "</string>
+    <!-- HTTP proxy settings. Title for Proxy-Auto Config URL.  [CHAR LIMIT=25] -->
+    <string name="proxy_url_title">"PAC URL: "</string>
+    <!-- HTTP proxy settings. Hint for Proxy-Auto Config URL. -->
+    <string name="proxy_url_hint" translatable="false">https://www.example.com/proxy.pac</string>
 
     <!-- Radio Info screen. Label for a status item.  Used for diagnostic info screens, precise translation isn't needed -->
     <string name="radio_info_signal_location_label">Location:</string>
@@ -3151,10 +3153,12 @@
 
     <!-- Setting Checkbox title whether to show options for wireless display certification -->
     <string name="wifi_display_certification">Wireless display certification</string>
-    <!-- Setting Checkbox title whether to show options for WiFi Verbose Logging -->
+    <!-- Setting Checkbox title whether to enable WiFi Verbose Logging. [CHAR LIMIT=40] -->
     <string name="wifi_verbose_logging">Enable WiFi Verbose Logging</string>
     <!-- setting Checkbox summary whether to show options for wireless display certification  -->
     <string name="wifi_display_certification_summary">Show options for wireless display certification</string>
+    <!-- Setting Checkbox title whether to enable Wifi verbose Logging [CHAR LIMIT=80] -->
+    <string name="wifi_verbose_logging_summary">Increase Wifi logging level, show per SSID RSSI in WiFi Picker</string>
     <!-- Setting Checkbox title whether to allow mock locations -->
     <string name="allow_mock_location">Allow mock locations</string>
     <!-- setting Checkbox summary whether to allow mock locations  -->
diff --git a/res/xml/development_prefs.xml b/res/xml/development_prefs.xml
index 1d7d967..d435371 100644
--- a/res/xml/development_prefs.xml
+++ b/res/xml/development_prefs.xml
@@ -109,6 +109,7 @@
         <CheckBoxPreference
             android:key="wifi_verbose_logging"
             android:title="@string/wifi_verbose_logging" />
+            android:summary="@string/wifi_verbose_logging_summary"/>
 
     </PreferenceCategory>
 
diff --git a/res/xml/security_settings_picker.xml b/res/xml/security_settings_picker.xml
index 6ed7d5f..fda44e1 100644
--- a/res/xml/security_settings_picker.xml
+++ b/res/xml/security_settings_picker.xml
@@ -14,7 +14,9 @@
      limitations under the License.
 -->
 
-<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+        android:title="@string/lock_settings_picker_title"
+        android:key="lock_settings_picker">
 
     <PreferenceScreen
             android:key="unlock_set_off"
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 0081ad3..30a72ef 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -23,8 +23,6 @@
 import android.content.Intent;
 import android.content.pm.UserInfo;
 import android.os.Bundle;
-import android.os.Process;
-import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.Preference;
 import android.preference.PreferenceScreen;
diff --git a/src/com/android/settings/DataUsageSummary.java b/src/com/android/settings/DataUsageSummary.java
index 9f68023..86a73c2 100644
--- a/src/com/android/settings/DataUsageSummary.java
+++ b/src/com/android/settings/DataUsageSummary.java
@@ -192,7 +192,8 @@
     private INetworkManagementService mNetworkService;
     private INetworkStatsService mStatsService;
     private NetworkPolicyManager mPolicyManager;
-    private ConnectivityManager mConnService;
+    private TelephonyManager mTelephonyManager;
+
 
     private INetworkStatsSession mStatsSession;
 
@@ -274,7 +275,7 @@
         mStatsService = INetworkStatsService.Stub.asInterface(
                 ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
         mPolicyManager = NetworkPolicyManager.from(context);
-        mConnService = ConnectivityManager.from(context);
+        mTelephonyManager = TelephonyManager.from(context);
 
         mPrefs = getActivity().getSharedPreferences(PREF_FILE, Context.MODE_PRIVATE);
 
@@ -872,13 +873,13 @@
             // TODO: deprecate and remove this once enabled flag is on policy
             return mMobileDataEnabled;
         } else {
-            return mConnService.getMobileDataEnabled();
+            return mTelephonyManager.getDataEnabled();
         }
     }
 
     private void setMobileDataEnabled(boolean enabled) {
         if (LOGD) Log.d(TAG, "setMobileDataEnabled()");
-        mConnService.setMobileDataEnabled(enabled);
+        mTelephonyManager.setDataEnabled(enabled);
         mMobileDataEnabled = enabled;
         updatePolicy(false);
     }
diff --git a/src/com/android/settings/RadioInfo.java b/src/com/android/settings/RadioInfo.java
index 4c86144..b0a4a53 100644
--- a/src/com/android/settings/RadioInfo.java
+++ b/src/com/android/settings/RadioInfo.java
@@ -22,7 +22,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
-import android.net.ConnectivityManager;
 import android.net.TrafficStats;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -917,15 +916,13 @@
 
     private MenuItem.OnMenuItemClickListener mToggleData = new MenuItem.OnMenuItemClickListener() {
         public boolean onMenuItemClick(MenuItem item) {
-            ConnectivityManager cm =
-                    (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
             int state = mTelephonyManager.getDataState();
             switch (state) {
                 case TelephonyManager.DATA_CONNECTED:
-                    cm.setMobileDataEnabled(false);
+                    phone.setDataEnabled(false);
                     break;
                 case TelephonyManager.DATA_DISCONNECTED:
-                    cm.setMobileDataEnabled(true);
+                    phone.setDataEnabled(true);
                     break;
                 default:
                     // do nothing
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 0c8616d..7ba6371 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -18,6 +18,7 @@
 
 import android.provider.SearchIndexableResource;
 
+import com.android.settings.ChooseLockGeneric;
 import com.android.settings.DataUsageSummary;
 import com.android.settings.DateTimeSettings;
 import com.android.settings.DevelopmentSettings;
@@ -187,6 +188,12 @@
                         SecuritySettings.class.getName(),
                         R.drawable.ic_settings_security));
 
+        sResMap.put(ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
+                new SearchIndexableResource(RANK_SECURITY,
+                        R.xml.security_settings_picker,
+                        ChooseLockGeneric.ChooseLockGenericFragment.class.getName(),
+                        R.drawable.ic_settings_security));
+
         sResMap.put(InputMethodAndLanguageSettings.class.getName(),
                 new SearchIndexableResource(RANK_IME,
                         NO_DATA_RES_ID,
diff --git a/src/com/android/settings/wifi/AccessPoint.java b/src/com/android/settings/wifi/AccessPoint.java
index 688fc63..4ac9112 100644
--- a/src/com/android/settings/wifi/AccessPoint.java
+++ b/src/com/android/settings/wifi/AccessPoint.java
@@ -28,9 +28,13 @@
 import android.os.Bundle;
 import android.preference.Preference;
 import android.util.Log;
+import android.util.LruCache;
 import android.view.View;
 import android.widget.ImageView;
 
+import java.util.Map;
+
+
 class AccessPoint extends Preference {
     static final String TAG = "Settings.AccessPoint";
 
@@ -74,6 +78,21 @@
     private WifiInfo mInfo;
     private DetailedState mState;
 
+    private static final int VISIBILITY_MAX_AGE_IN_MILLI = 1000000;
+    private static final int VISIBILITY_OUTDATED_AGE_IN_MILLI = 20000;
+    private static final int LOWER_FREQ_24GHZ = 2400;
+    private static final int HIGHER_FREQ_24GHZ = 2500;
+    private static final int LOWER_FREQ_5GHZ = 4900;
+    private static final int HIGHER_FREQ_5GHZ = 5900;
+    private static final int SECOND_TO_MILLI = 1000;
+
+    /** Experiemental: we should be able to show the user the list of BSSIDs and bands
+     *  for that SSID.
+     *  For now this data is used only with Verbose Logging so as to show the band and number
+     *  of BSSIDs on which that network is seen.
+     */
+    public LruCache<String, ScanResult> scanResultCache;
+
     static int getSecurity(WifiConfiguration config) {
         if (config.allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
             return SECURITY_PSK;
@@ -201,6 +220,9 @@
             pskType = getPskType(result);
         mRssi = result.level;
         mScanResult = result;
+        if (result.seen > mSeen) {
+            mSeen = result.seen;
+        }
     }
 
     @Override
@@ -267,6 +289,13 @@
         if (result.seen > mSeen) {
             mSeen = result.seen;
         }
+        if (WifiSettings.mVerboseLogging > 0) {
+            if (scanResultCache == null) {
+                scanResultCache = new LruCache<String, ScanResult>(32);
+            }
+            scanResultCache.put(result.BSSID, result);
+        }
+
         if (ssid.equals(result.SSID) && security == getSecurity(result)) {
             if (WifiManager.compareSignalLevel(result.level, mRssi) > 0) {
                 int oldLevel = getLevel();
@@ -340,25 +369,84 @@
 
     /** visibility status of the WifiConfiguration
      * @return RSSI and update indicator
-     * TODO: indicate both 2.4 and 5GHz RSSI as well as number of results
+     * TODO: use a string formatter
      * ["rssi 5Ghz", "num results on 5GHz" / "rssi 5Ghz", "num results on 5GHz"]
      * For instance [-40,5/-30,2]
      */
     private String getVisibilityStatus() {
-        String visibility ;
+        StringBuilder visibility = new StringBuilder();
+
         long now = System.currentTimeMillis();
         long age = (now - mSeen);
-        if (age < 1000000) {
+        if (age < VISIBILITY_MAX_AGE_IN_MILLI) {
             //show age in seconds, in the form xx
-            visibility = Long.toString((age / 1000) % 1000);
+            visibility.append(Long.toString((age / SECOND_TO_MILLI) % SECOND_TO_MILLI));
         } else {
             //not seen for more than 1000 seconds
-            visibility = "!";
+            visibility.append("!");
         }
-        if (mRssi != Integer.MAX_VALUE) {
-            visibility = visibility + ", " + Integer.toString(mRssi);
+
+        if (scanResultCache != null) {
+            int rssi5 = WifiConfiguration.INVALID_RSSI;
+            int rssi24 = WifiConfiguration.INVALID_RSSI;
+            int num5 = 0;
+            int num24 = 0;
+            Map<String, ScanResult> list = scanResultCache.snapshot();
+            for (ScanResult result : list.values()) {
+                if (result.seen == 0)
+                    continue;
+
+                if (result.frequency > LOWER_FREQ_5GHZ
+                        && result.frequency < HIGHER_FREQ_5GHZ) {
+                    //strictly speaking: [4915, 5825]
+                    //number of known BSSID on 5GHz band
+                    num5 = num5 + 1;
+                } else if (result.frequency > LOWER_FREQ_24GHZ
+                        && result.frequency < HIGHER_FREQ_24GHZ) {
+                    //strictly speaking: [2412, 2482]
+                    //number of known BSSID on 2.4Ghz band
+                    num24 = num24 + 1;
+                }
+
+                //ignore results seen, older than 20 seconds
+                if (now - result.seen > VISIBILITY_OUTDATED_AGE_IN_MILLI) continue;
+
+                if (result.frequency > LOWER_FREQ_5GHZ
+                        &&result.frequency < HIGHER_FREQ_5GHZ) {
+                    if (result.level > rssi5) {
+                        rssi5 = result.level;
+                    }
+                } else if (result.frequency > LOWER_FREQ_24GHZ
+                        && result.frequency < HIGHER_FREQ_24GHZ) {
+                    if (result.level > rssi24) {
+                        rssi24 = result.level;
+                    }
+                }
+            }
+            visibility.append(" [");
+            if (num24 > 0 || rssi24 > WifiConfiguration.INVALID_RSSI) {
+                visibility.append(Integer.toString(rssi24));
+                visibility.append(",");
+                visibility.append(Integer.toString(num24));
+            }
+            visibility.append(";");
+            if (num5 > 0 || rssi5 > WifiConfiguration.INVALID_RSSI) {
+                visibility.append(Integer.toString(rssi5));
+                visibility.append(",");
+                visibility.append(Integer.toString(num5));
+            }
+            visibility.append("]");
+        } else {
+            if (mRssi != Integer.MAX_VALUE) {
+                visibility.append(", ");
+                visibility.append(Integer.toString(mRssi));
+                if (mScanResult != null) {
+                    visibility.append(", ");
+                    visibility.append(Integer.toString(mScanResult.frequency));
+                }
+            }
         }
-        return visibility;
+        return visibility.toString();
     }
 
     /** Updates the title and summary; may indirectly call notifyChanged()  */
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 7ccfc6b..8779798 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -29,6 +29,7 @@
 import android.net.NetworkUtils;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
+import android.net.Uri;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
@@ -105,6 +106,7 @@
     /* These values come from "wifi_proxy_settings" resource array */
     public static final int PROXY_NONE = 0;
     public static final int PROXY_STATIC = 1;
+    public static final int PROXY_PAC = 2;
 
     /* These values come from "wifi_eap_method" resource array */
     public static final int WIFI_EAP_METHOD_PEAP = 0;
@@ -130,6 +132,7 @@
     private TextView mProxyHostView;
     private TextView mProxyPortView;
     private TextView mProxyExclusionListView;
+    private TextView mProxyPacView;
 
     private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED;
     private ProxySettings mProxySettings = ProxySettings.UNASSIGNED;
@@ -257,11 +260,7 @@
                     mProxySettingsSpinner.setSelection(PROXY_STATIC);
                     showAdvancedFields = true;
                 } else if (config.getProxySettings() == ProxySettings.PAC) {
-                    mProxySettingsSpinner.setVisibility(View.GONE);
-                    TextView textView = (TextView)mView.findViewById(R.id.proxy_pac_info);
-                    textView.setVisibility(View.VISIBLE);
-                    textView.setText(context.getString(R.string.proxy_url) +
-                            config.getLinkProperties().getHttpProxy().getPacFileUrl());
+                    mProxySettingsSpinner.setSelection(PROXY_PAC);
                     showAdvancedFields = true;
                 } else {
                     mProxySettingsSpinner.setSelection(PROXY_NONE);
@@ -466,11 +465,10 @@
             }
         }
 
-        mProxySettings = (mProxySettingsSpinner != null &&
-                mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) ?
-                ProxySettings.STATIC : ProxySettings.NONE;
-
-        if (mProxySettings == ProxySettings.STATIC && mProxyHostView != null) {
+        final int selectedPosition = mProxySettingsSpinner.getSelectedItemPosition();
+        mProxySettings = ProxySettings.NONE;
+        if (selectedPosition == PROXY_STATIC && mProxyHostView != null) {
+            mProxySettings = ProxySettings.STATIC;
             String host = mProxyHostView.getText().toString();
             String portStr = mProxyPortView.getText().toString();
             String exclusionList = mProxyExclusionListView.getText().toString();
@@ -488,6 +486,18 @@
             } else {
                 return false;
             }
+        } else if (selectedPosition == PROXY_PAC && mProxyPacView != null) {
+            mProxySettings = ProxySettings.PAC;
+            CharSequence uriSequence = mProxyPacView.getText();
+            if (TextUtils.isEmpty(uriSequence)) {
+                return false;
+            }
+            Uri uri = Uri.parse(uriSequence.toString());
+            if (uri == null) {
+                return false;
+            }
+            ProxyInfo proxyInfo = new ProxyInfo(uri);
+            mLinkProperties.setHttpProxy(proxyInfo);
         }
         return true;
     }
@@ -811,8 +821,9 @@
         }
 
         if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_STATIC) {
-            mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.VISIBLE);
-            mView.findViewById(R.id.proxy_fields).setVisibility(View.VISIBLE);
+            setVisibility(R.id.proxy_warning_limited_support, View.VISIBLE);
+            setVisibility(R.id.proxy_fields, View.VISIBLE);
+            setVisibility(R.id.proxy_pac_field, View.GONE);
             if (mProxyHostView == null) {
                 mProxyHostView = (TextView) mView.findViewById(R.id.proxy_hostname);
                 mProxyHostView.addTextChangedListener(this);
@@ -829,13 +840,34 @@
                     mProxyExclusionListView.setText(proxyProperties.getExclusionListAsString());
                 }
             }
+        } else if (mProxySettingsSpinner.getSelectedItemPosition() == PROXY_PAC) {
+            setVisibility(R.id.proxy_warning_limited_support, View.GONE);
+            setVisibility(R.id.proxy_fields, View.GONE);
+            setVisibility(R.id.proxy_pac_field, View.VISIBLE);
+
+            if (mProxyPacView == null) {
+                mProxyPacView = (TextView) mView.findViewById(R.id.proxy_pac);
+                mProxyPacView.addTextChangedListener(this);
+            }
+            if (config != null) {
+                ProxyInfo proxyInfo = config.getLinkProperties().getHttpProxy();
+                if (proxyInfo != null) {
+                    mProxyPacView.setText(proxyInfo.getPacFileUrl().toString());
+                }
+            }
         } else {
-            mView.findViewById(R.id.proxy_warning_limited_support).setVisibility(View.GONE);
-            mView.findViewById(R.id.proxy_fields).setVisibility(View.GONE);
+            setVisibility(R.id.proxy_warning_limited_support, View.GONE);
+            setVisibility(R.id.proxy_fields, View.GONE);
+            setVisibility(R.id.proxy_pac_field, View.GONE);
         }
     }
 
-
+    private void setVisibility(int id, int visibility) {
+        final View v = mView.findViewById(id);
+        if (v != null) {
+            v.setVisibility(visibility);
+        }
+    }
 
     private void loadCertificates(Spinner spinner, String prefix) {
         final Context context = mConfigUi.getContext();
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 604275a..a653910 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -178,6 +178,10 @@
 
     private SwitchBar mSwitchBar;
 
+    /** verbose logging flag. this flag is set thru developer debugging options
+     * and used so as to assist with in-the-field WiFi connectivity debugging  */
+    public static int mVerboseLogging = 0;
+
     /* End of "used in Wifi Setup context" */
 
     public WifiSettings() {
@@ -712,8 +716,6 @@
         return super.onCreateDialog(dialogId);
     }
 
-    /** verbose logging flag is set only thru developer debugging options */
-    public static int mVerboseLogging = 0;
     /**
      * Shows the latest access points available with supplimental information like
      * the strength of network and the security for it.
@@ -728,7 +730,7 @@
         }
         final int wifiState = mWifiManager.getWifiState();
 
-        //check if verbose logging has been turned on or off
+        //when we update the screen, check if verbose logging has been turned on or off
         mVerboseLogging = mWifiManager.getVerboseLoggingLevel();
 
         switch (wifiState) {