Fragmentize WifiSettings.

- Add button bar feature toward SettingsPreferenceFragment,
  which has existed in PreferenceActivity and has been used
  (probably) only by Settings app.
- super.onActivityCreated() is not called at the beggining of
  WifiSettings#onActivityCreated(), the parent method assumes
  the child should have prepared PreferenceScreen, while
  WifiSettings cannot do until the parent Activity is ready.
- Call SetHasOptionMenu() should be called AFTER the parent
  Activity is ready. It is not documented, so it would be better
  to file another bug.
- Add exception to proguard...

Change-Id: Iebd27f0cb0abdbee9b4b1cc9b00f4bf127f7815d
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 94e7329..9195d77 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -98,10 +98,11 @@
                 if (showFragment(intent.getComponent().getClassName(), intent.getExtras())) {
                     mMainPane.setVisibility(View.GONE);
                 }
-            }
-            Fragment topLevel = getFragmentManager().findFragmentById(R.id.top_level);
-            if (topLevel != null) {
-                ((TopLevelSettings) topLevel).selectFirst();
+            } else {
+                Fragment topLevel = getFragmentManager().findFragmentById(R.id.top_level);
+                if (topLevel != null) {
+                    ((TopLevelSettings) topLevel).selectFirst();
+                }
             }
         }
     }
@@ -165,13 +166,13 @@
     }
 
     public void onCreated(SettingsPreferenceFragment fragment) {
-        Log.d(TAG, "Fragment created " + fragment);
+        Log.d(TAG, "Fragment created " + fragment + " (name: " + fragment.getClass() + ")");
         addToBreadCrumbs(fragment);
     }
 
     public void onDestroyed(SettingsPreferenceFragment fragment) {
         removeFromBreadCrumbs(fragment);
-        Log.d(TAG, "Fragment destroyed " + fragment);
+        Log.d(TAG, "Fragment destroyed " + fragment + " (name: " + fragment.getClass() + ")");
     }
 
     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 83511c9..d10fda3 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -16,14 +16,21 @@
 
 package com.android.settings;
 
+import android.app.Activity;
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.content.ContentResolver;
+import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
+import android.preference.PreferenceActivity;
 import android.preference.PreferenceFragment;
+import android.text.TextUtils;
 import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
 
 /**
  * Base class for Settings fragments, with some helper functions and dialog management.
@@ -32,10 +39,18 @@
 
     private static final String TAG = "SettingsPreferenceFragment";
 
+    // Originally from PreferenceActivity.
+    private static final String EXTRA_PREFS_SHOW_BUTTON_BAR = "extra_prefs_show_button_bar";
+    private static final String EXTRA_PREFS_SHOW_SKIP = "extra_prefs_show_skip";
+    private static final String EXTRA_PREFS_SET_NEXT_TEXT = "extra_prefs_set_next_text";
+    private static final String EXTRA_PREFS_SET_BACK_TEXT = "extra_prefs_set_back_text";
+
     private SettingsDialogFragment mDialogFragment;
 
     private OnStateListener mOnStateListener;
 
+    private Button mNextButton;
+
     interface OnStateListener {
 
         void onCreated(SettingsPreferenceFragment fragment);
@@ -53,6 +68,8 @@
         if (mOnStateListener != null) {
             mOnStateListener.onCreated(this);
         }
+
+        setupButtonBar();
     }
 
     @Override
@@ -134,4 +151,101 @@
             return mDialogId;
         }
     }
+
+    protected boolean hasNextButton() {
+        return mNextButton != null;
+    }
+
+    protected Button getNextButton() {
+        return mNextButton;
+    }
+
+    /**
+     * Sets up Button Bar possibly required in the Fragment. Probably available only in
+     * phones.
+     *
+     * Previously {@link PreferenceActivity} had the capability as hidden functionality.
+     */
+    private void setupButtonBar() {
+        // Originally from PreferenceActivity, which has had button bar inside its layout.
+        final Activity activity = getActivity();
+        final Intent intent = activity.getIntent();
+        final View buttonBar = activity.findViewById(com.android.internal.R.id.button_bar);
+        if (!intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false) || buttonBar == null) {
+            return;
+        }
+
+        buttonBar.setVisibility(View.VISIBLE);
+        View tmpView = activity.findViewById(com.android.internal.R.id.back_button);
+        if (tmpView != null) {
+            // TODO: Assume this is pressed only in single pane, finishing current Activity.
+            try {
+                final Button backButton = (Button)tmpView;
+                backButton.setOnClickListener(new OnClickListener() {
+                    public void onClick(View v) {
+                        activity.setResult(Activity.RESULT_CANCELED);
+                        activity.finish();
+                    }
+                });
+                if (intent.hasExtra(EXTRA_PREFS_SET_BACK_TEXT)) {
+                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_BACK_TEXT);
+                    if (TextUtils.isEmpty(buttonText)) {
+                        backButton.setVisibility(View.GONE);
+                    }
+                    else {
+                        backButton.setText(buttonText);
+                    }
+                }
+            } catch (ClassCastException e) {
+                Log.w(TAG, "The view originally for back_button is used not as Button. " +
+                        "Ignored.");
+            }
+        }
+
+        tmpView = activity.findViewById(com.android.internal.R.id.skip_button);
+        if (tmpView != null) {
+            try {
+                final Button skipButton = (Button)tmpView;
+                skipButton.setOnClickListener(new OnClickListener() {
+                    public void onClick(View v) {
+                        activity.setResult(Activity.RESULT_OK);
+                        activity.finish();
+                    }
+                });
+                if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_SKIP, false)) {
+                    skipButton.setVisibility(View.VISIBLE);
+                }
+            } catch (ClassCastException e) {
+                Log.w(TAG, "The view originally for skip_button is used not as Button. " +
+                        "Ignored.");
+            }
+        }
+
+        tmpView = activity.findViewById(com.android.internal.R.id.next_button);
+        if (tmpView != null) {
+            try {
+                mNextButton = (Button)tmpView;
+                mNextButton.setOnClickListener(new OnClickListener() {
+                    public void onClick(View v) {
+                        activity.setResult(Activity.RESULT_OK);
+                        activity.finish();
+                    }
+                });
+                // set our various button parameters
+                if (intent.hasExtra(EXTRA_PREFS_SET_NEXT_TEXT)) {
+                    String buttonText = intent.getStringExtra(EXTRA_PREFS_SET_NEXT_TEXT);
+                    if (TextUtils.isEmpty(buttonText)) {
+                        mNextButton.setVisibility(View.GONE);
+                    }
+                    else {
+                        mNextButton.setText(buttonText);
+                    }
+                }
+            } catch (ClassCastException e) {
+                Log.w(TAG, "The view originally for next_button is used not as Button. " +
+                        "Ignored.");
+                mNextButton = null;
+            }
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 718b53e..5332fb3 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -16,9 +16,7 @@
 
 package com.android.settings.wifi;
 
-import com.android.settings.ProgressCategory;
-import com.android.settings.R;
-
+import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -31,7 +29,6 @@
 import android.net.wifi.SupplicantState;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
-import android.net.wifi.WifiConfiguration.Status;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
@@ -39,24 +36,29 @@
 import android.os.Message;
 import android.preference.CheckBoxPreference;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
 import android.provider.Settings.Secure;
 import android.security.Credentials;
 import android.security.KeyStore;
-import android.text.TextUtils;
+import android.util.Log;
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
 import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.Toast;
 
+import com.android.settings.ProgressCategory;
+import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
+
 import java.util.ArrayList;
 import java.util.List;
 
-public class WifiSettings extends PreferenceActivity implements DialogInterface.OnClickListener {
+public class WifiSettings extends SettingsPreferenceFragment
+        implements DialogInterface.OnClickListener {
     private static final int MENU_ID_SCAN = Menu.FIRST;
     private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
     private static final int MENU_ID_CONNECT = Menu.FIRST + 2;
@@ -108,28 +110,33 @@
     }
 
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
+    public void onActivityCreated(Bundle savedInstanceState) {
+        // We don't call super.onActivityCreated() here, since it assumes we already set up
+        // Preference (probably in onCreate()), while WifiSettings exceptionally set it up in
+        // this method.
 
         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
 
+        final Activity activity = getActivity();
+        final Intent intent = activity.getIntent();
+
         // if we're supposed to enable/disable the Next button based on our current connection
         // state, start it off in the right state
-        mEnableNextOnConnection = getIntent().getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);
+        mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false);
         if (mEnableNextOnConnection && hasNextButton()) {
             ConnectivityManager connectivity = (ConnectivityManager)
-                getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+                getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
             if (connectivity != null) {
                 NetworkInfo info = connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                 getNextButton().setEnabled(info.isConnected());
             }
         }
 
-        if (getIntent().getBooleanExtra("only_access_points", false)) {
+        if (intent.getBooleanExtra("only_access_points", false)) {
             addPreferencesFromResource(R.xml.wifi_access_points);
         } else {
             addPreferencesFromResource(R.xml.wifi_settings);
-            mWifiEnabler = new WifiEnabler(this,
+            mWifiEnabler = new WifiEnabler(activity,
                     (CheckBoxPreference) findPreference("enable_wifi"));
             mNotifyOpenNetworks =
                     (CheckBoxPreference) findPreference("notify_open_networks");
@@ -137,20 +144,25 @@
                     Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1);
         }
 
+        // After confirming PreferenceScreen is available, we call super.
+        super.onActivityCreated(savedInstanceState);
+
         mAccessPoints = (ProgressCategory) findPreference("access_points");
         mAccessPoints.setOrderingAsAdded(false);
         mAddNetwork = findPreference("add_network");
 
         registerForContextMenu(getListView());
+
+        setHasOptionsMenu(true);
     }
 
     @Override
-    protected void onResume() {
+    public void onResume() {
         super.onResume();
         if (mWifiEnabler != null) {
             mWifiEnabler.resume();
         }
-        registerReceiver(mReceiver, mFilter);
+        getActivity().registerReceiver(mReceiver, mFilter);
         if (mKeyStoreNetworkId != -1 && KeyStore.getInstance().test() == KeyStore.NO_ERROR) {
             mWifiManager.connectNetwork(mKeyStoreNetworkId);
         }
@@ -159,12 +171,12 @@
     }
 
     @Override
-    protected void onPause() {
+    public void onPause() {
         super.onPause();
         if (mWifiEnabler != null) {
             mWifiEnabler.pause();
         }
-        unregisterReceiver(mReceiver);
+        getActivity().unregisterReceiver(mReceiver);
         mScanner.pause();
         if (mDialog != null) {
             mDialog.dismiss();
@@ -173,12 +185,12 @@
     }
 
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan)
                 .setIcon(R.drawable.ic_menu_scan_network);
         menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced)
                 .setIcon(android.R.drawable.ic_menu_manage);
-        return super.onCreateOptionsMenu(menu);
+        super.onCreateOptionsMenu(menu, inflater);
     }
 
     @Override
@@ -190,7 +202,7 @@
                 }
                 return true;
             case MENU_ID_ADVANCED:
-                startActivity(new Intent(this, AdvancedSettings.class));
+                startActivity(new Intent(getActivity(), AdvancedSettings.class));
                 return true;
         }
         return super.onOptionsItemSelected(item);
@@ -295,7 +307,7 @@
         if (mDialog != null) {
             mDialog.dismiss();
         }
-        mDialog = new WifiDialog(this, this, accessPoint, edit);
+        mDialog = new WifiDialog(getActivity(), this, accessPoint, edit);
         mDialog.show();
     }
 
@@ -303,7 +315,7 @@
         if (WifiDialog.requireKeyStore(config) &&
                 KeyStore.getInstance().test() != KeyStore.NO_ERROR) {
             mKeyStoreNetworkId = config.networkId;
-            Credentials.getInstance().unlock(this);
+            Credentials.getInstance().unlock(getActivity());
             return true;
         }
         return false;
@@ -315,7 +327,7 @@
         List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
         if (configs != null) {
             for (WifiConfiguration config : configs) {
-                AccessPoint accessPoint = new AccessPoint(this, config);
+                AccessPoint accessPoint = new AccessPoint(getActivity(), config);
                 accessPoint.update(mLastInfo, mLastState);
                 accessPoints.add(accessPoint);
             }
@@ -337,7 +349,7 @@
                     }
                 }
                 if (!found) {
-                    accessPoints.add(new AccessPoint(this, result));
+                    accessPoints.add(new AccessPoint(getActivity(), result));
                 }
             }
         }
@@ -424,7 +436,7 @@
                 mRetry = 0;
             } else if (++mRetry >= 3) {
                 mRetry = 0;
-                Toast.makeText(WifiSettings.this, R.string.wifi_fail_to_scan,
+                Toast.makeText(getActivity(), R.string.wifi_fail_to_scan,
                         Toast.LENGTH_LONG).show();
                 return;
             }