Redesign settings for tablets

1. Move AppCompatPreferenceActivity from Dialer to ContactsCommon
2. Move ContactsPreferenceActivity from Contacts to ContactsCommon,
   make it extend AppCompatPreferenceActivity and avoid building
   headers (by not overriding onBuildHeaders)
3. Move the "About" PreferenceScreen to preference_about.xml and
   add AboutPreferenceFragment so that we could switch between two
   fragments.
2. Add "back button" to LicenseActivity.

Here's how it looks:
https://docs.google.com/a/google.com/presentation/d/1A5n2o8epBCrizZvbOyelvjoHz-s5-IRlJd-KqWAMBao/edit?usp=sharing

Bug: 25629359
Bug: 26469731
Change-Id: If88722a62e41d1a2f4f70939b2d52d697e204628
diff --git a/src/com/android/contacts/common/activity/AppCompatPreferenceActivity.java b/src/com/android/contacts/common/activity/AppCompatPreferenceActivity.java
new file mode 100644
index 0000000..c3b7e94
--- /dev/null
+++ b/src/com/android/contacts/common/activity/AppCompatPreferenceActivity.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+package com.android.contacts.common.activity;
+
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatDelegate;
+import android.support.v7.widget.Toolbar;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
+ * to be used with AppCompat.
+ */
+public class AppCompatPreferenceActivity extends PreferenceActivity {
+    private AppCompatDelegate mDelegate;
+
+    private boolean mIsSafeToCommitTransactions;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        getDelegate().installViewFactory();
+        getDelegate().onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+        mIsSafeToCommitTransactions = true;
+    }
+
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        getDelegate().onPostCreate(savedInstanceState);
+    }
+
+    public ActionBar getSupportActionBar() {
+        return getDelegate().getSupportActionBar();
+    }
+
+    public void setSupportActionBar(Toolbar toolbar) {
+        getDelegate().setSupportActionBar(toolbar);
+    }
+
+    @Override
+    public MenuInflater getMenuInflater() {
+        return getDelegate().getMenuInflater();
+    }
+
+    @Override
+    public void setContentView(int layoutResID) {
+        getDelegate().setContentView(layoutResID);
+    }
+
+    @Override
+    public void setContentView(View view) {
+        getDelegate().setContentView(view);
+    }
+
+    @Override
+    public void setContentView(View view, ViewGroup.LayoutParams params) {
+        getDelegate().setContentView(view, params);
+    }
+
+    @Override
+    public void addContentView(View view, ViewGroup.LayoutParams params) {
+        getDelegate().addContentView(view, params);
+    }
+
+    @Override
+    protected void onPostResume() {
+        super.onPostResume();
+        getDelegate().onPostResume();
+    }
+
+    @Override
+    protected void onTitleChanged(CharSequence title, int color) {
+        super.onTitleChanged(title, color);
+        getDelegate().setTitle(title);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        getDelegate().onConfigurationChanged(newConfig);
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        getDelegate().onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        getDelegate().onDestroy();
+    }
+
+    @Override
+    public void invalidateOptionsMenu() {
+        getDelegate().invalidateOptionsMenu();
+    }
+
+    private AppCompatDelegate getDelegate() {
+        if (mDelegate == null) {
+            mDelegate = AppCompatDelegate.create(this, null);
+        }
+        return mDelegate;
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        mIsSafeToCommitTransactions = true;
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        mIsSafeToCommitTransactions = true;
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        mIsSafeToCommitTransactions = false;
+    }
+
+    /**
+     * Returns true if it is safe to commit {@link FragmentTransaction}s at this time, based on
+     * whether {@link Activity#onSaveInstanceState} has been called or not.
+     *
+     * Make sure that the current activity calls into
+     * {@link super.onSaveInstanceState(Bundle outState)} (if that method is overridden),
+     * so the flag is properly set.
+     */
+    public boolean isSafeToCommitTransactions() {
+        return mIsSafeToCommitTransactions;
+    }
+}
diff --git a/src/com/android/contacts/common/activity/LicenseActivity.java b/src/com/android/contacts/common/activity/LicenseActivity.java
index d72b305..9e86ee8 100644
--- a/src/com/android/contacts/common/activity/LicenseActivity.java
+++ b/src/com/android/contacts/common/activity/LicenseActivity.java
@@ -17,7 +17,8 @@
 
 import com.android.contacts.common.R;
 
-import android.app.Activity;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
 import android.os.Bundle;
 import android.view.MenuItem;
 import android.webkit.WebView;
@@ -25,7 +26,7 @@
 /**
  * Displays the licenses for all open source libraries.
  */
-public class LicenseActivity extends Activity {
+public class LicenseActivity extends AppCompatActivity {
     private static final String LICENSE_FILE = "file:///android_asset/licenses.html";
     private WebView mWebView;
 
@@ -35,6 +36,10 @@
         setContentView(R.layout.licenses);
         mWebView = (WebView) findViewById(R.id.webview);
         mWebView.loadUrl(LICENSE_FILE);
+        final ActionBar actionBar = getSupportActionBar();
+        if (actionBar != null) {
+            actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
+        }
     }
 
     @Override
diff --git a/src/com/android/contacts/common/preference/AboutPreferenceFragment.java b/src/com/android/contacts/common/preference/AboutPreferenceFragment.java
new file mode 100644
index 0000000..3ab32d5
--- /dev/null
+++ b/src/com/android/contacts/common/preference/AboutPreferenceFragment.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+package com.android.contacts.common.preference;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.preference.Preference;
+import android.preference.PreferenceFragment;
+
+import com.android.contacts.common.R;
+import com.android.contacts.common.activity.LicenseActivity;
+
+/**
+ * This fragment shows the preferences for "about".
+ */
+public class AboutPreferenceFragment extends PreferenceFragment {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Load the preferences from an XML resource
+        addPreferencesFromResource(R.xml.preference_about);
+
+        // Set build version of Contacts App.
+        final PackageManager manager = getActivity().getPackageManager();
+        try {
+            final PackageInfo info = manager.getPackageInfo(getActivity().getPackageName(), 0);
+            final Preference versionPreference = findPreference(
+                    getString(R.string.pref_build_version_key));
+            versionPreference.setSummary(info.versionName);
+        } catch (PackageManager.NameNotFoundException e) {
+            // Nothing
+        }
+
+        final Preference licensePreference = findPreference(
+                getString(R.string.pref_open_source_licenses_key));
+        licensePreference.setIntent(new Intent(getActivity(), LicenseActivity.class));
+    }
+
+    @Override
+    public Context getContext() {
+        return getActivity();
+    }
+}
+
diff --git a/src/com/android/contacts/common/preference/ContactsPreferenceActivity.java b/src/com/android/contacts/common/preference/ContactsPreferenceActivity.java
new file mode 100644
index 0000000..3fd10d8
--- /dev/null
+++ b/src/com/android/contacts/common/preference/ContactsPreferenceActivity.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2009 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.
+ */
+
+package com.android.contacts.common.preference;
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.v7.app.ActionBar;
+import android.view.MenuItem;
+
+import com.android.contacts.common.activity.AppCompatPreferenceActivity;
+import com.android.contacts.common.R;
+
+/**
+ * Contacts settings.
+ */
+public final class ContactsPreferenceActivity extends AppCompatPreferenceActivity {
+
+    private static final String TAG_ABOUT_CONTACTS = "about_contacts";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final ActionBar actionBar = getSupportActionBar();
+        if (actionBar != null) {
+            actionBar.setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP, ActionBar.DISPLAY_HOME_AS_UP);
+        }
+
+        if (savedInstanceState == null) {
+            getFragmentManager().beginTransaction()
+                    .replace(android.R.id.content, new DisplayOptionsPreferenceFragment())
+                    .commit();
+            setActivityTitle(R.string.activity_title_settings);
+        } else {
+            final AboutPreferenceFragment fragment = (AboutPreferenceFragment) getFragmentManager()
+                    .findFragmentByTag(TAG_ABOUT_CONTACTS);
+            setActivityTitle(fragment == null ?
+                    R.string.activity_title_settings : R.string.setting_about);
+        }
+    }
+
+    public void showAboutFragment() {
+        getFragmentManager().beginTransaction()
+                .replace(android.R.id.content, new AboutPreferenceFragment(), TAG_ABOUT_CONTACTS)
+                .addToBackStack(null)
+                .commit();
+        setActivityTitle(R.string.setting_about);
+    }
+
+    /**
+     * Returns true if there are no preferences to display and therefore the
+     * corresponding menu item can be removed.
+     */
+    public static boolean isEmpty(Context context) {
+        return !context.getResources().getBoolean(R.bool.config_sort_order_user_changeable)
+                && !context.getResources().getBoolean(R.bool.config_display_order_user_changeable)
+                && !context.getResources().getBoolean(
+                        R.bool.config_default_account_user_changeable);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (item.getItemId() == android.R.id.home) {
+            onBackPressed();
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (getFragmentManager().getBackStackEntryCount() > 0) {
+            setActivityTitle(R.string.activity_title_settings);
+            getFragmentManager().popBackStack();
+        } else {
+            super.onBackPressed();
+        }
+    }
+
+    private void setActivityTitle(int res) {
+        final ActionBar actionBar = getSupportActionBar();
+        if (actionBar != null) {
+            actionBar.setTitle(res);
+        }
+    }
+}
diff --git a/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java b/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java
index a8bc234..6f91616 100644
--- a/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java
+++ b/src/com/android/contacts/common/preference/DisplayOptionsPreferenceFragment.java
@@ -17,18 +17,12 @@
 package com.android.contacts.common.preference;
 
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
-import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
-import android.preference.PreferenceScreen;
 
 import com.android.contacts.common.R;
-import com.android.contacts.common.activity.LicenseActivity;
 import com.android.contacts.common.compat.MetadataSyncEnabledCompat;
 import com.android.contacts.common.model.AccountTypeManager;
 import com.android.contacts.common.model.account.AccountWithDataSet;
@@ -37,7 +31,7 @@
 import java.util.List;
 
 /**
- * This fragment shows the preferences for the first header.
+ * This fragment shows the preferences for "display options"
  */
 public class DisplayOptionsPreferenceFragment extends PreferenceFragment {
 
@@ -50,20 +44,14 @@
 
         removeUnsupportedPreferences();
 
-        // Set build version of Contacts App.
-        final PackageManager manager = getActivity().getPackageManager();
-        try {
-            final PackageInfo info = manager.getPackageInfo(getActivity().getPackageName(), 0);
-            final Preference versionPreference = findPreference(
-                    getString(R.string.pref_build_version_key));
-            versionPreference.setSummary(info.versionName);
-        } catch (PackageManager.NameNotFoundException e) {
-            // Nothing
-        }
-
-        final Preference licensePreference = findPreference(
-                getString(R.string.pref_open_source_licenses_key));
-        licensePreference.setIntent(new Intent(getActivity(), LicenseActivity.class));
+        final Preference aboutPreference = findPreference("about");
+        aboutPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+            @Override
+            public boolean onPreferenceClick(Preference preference) {
+                ((ContactsPreferenceActivity) getActivity()).showAboutFragment();
+                return true;
+            }
+        });
     }
 
     private void removeUnsupportedPreferences() {