Merge "Convert Dialer activities to AppCompat to support Snackbar."
diff --git a/Android.mk b/Android.mk
index 1440fcc..ba346d2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -19,12 +19,17 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
 LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs)) \
-    frameworks/support/v7/cardview/res frameworks/support/v7/recyclerview/res
+    frameworks/support/v7/appcompat/res \
+    frameworks/support/v7/cardview/res \
+    frameworks/support/v7/recyclerview/res \
+    frameworks/support/design/res
 
 LOCAL_AAPT_FLAGS := \
     --auto-add-overlay \
+    --extra-packages android.support.v7.appcompat \
     --extra-packages android.support.v7.cardview \
     --extra-packages android.support.v7.recyclerview \
+    --extra-packages android.support.design \
     --extra-packages com.android.incallui \
     --extra-packages com.android.contacts.common \
     --extra-packages com.android.phone.common
@@ -34,8 +39,10 @@
     android-common \
     android-support-v13 \
     android-support-v4 \
+    android-support-v7-appcompat \
     android-support-v7-cardview \
     android-support-v7-recyclerview \
+    android-support-design \
     com.android.services.telephony.common \
     com.android.vcard \
     guava \
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 2098b17..7a12386 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -24,7 +24,6 @@
         android:minSdkVersion="23"
         android:targetSdkVersion="23" />
 
-
     <uses-permission android:name="android.permission.CALL_PHONE" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e3a2f99..17b4a25 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -15,15 +15,21 @@
   ~ limitations under the License
   -->
 <resources>
-    <style name="DialtactsTheme"
-           parent="android:Theme.Material.Light">
+    <style name="DialtactsTheme" parent="Theme.AppCompat.Light">
         <item name="android:textColorPrimary">@color/dialtacts_primary_text_color</item>
         <item name="android:textColorSecondary">@color/dialtacts_secondary_text_color</item>
+
+        <!-- Styles that require AppCompat compatibility, remember to update both sets -->
         <item name="android:windowActionBarOverlay">true</item>
+        <item name="windowActionBarOverlay">true</item>
         <item name="android:windowActionModeOverlay">true</item>
+        <item name="windowActionModeOverlay">true</item>
         <item name="android:actionBarStyle">@style/DialtactsActionBarStyle</item>
+        <item name="actionBarStyle">@style/DialtactsActionBarStyle</item>
         <!-- Style for the overflow button in the actionbar. -->
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
+        <item name="actionOverflowButtonStyle">@style/DialtactsActionBarOverflow</item>
+
         <!--  Drawable for the back button -->
         <item name="android:homeAsUpIndicator">@drawable/ic_back_arrow</item>
         <item name="android:windowContentOverlay">@null</item>
@@ -96,13 +102,19 @@
     </style>
 
     <style name="DialtactsThemeWithoutActionBarOverlay" parent="DialtactsTheme">
+        <!-- Styles that require AppCompat compatibility, remember to update both sets -->
         <item name="android:windowActionBarOverlay">false</item>
+        <item name="windowActionBarOverlay">false</item>
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflowWhite</item>
+        <item name="actionOverflowButtonStyle">@style/DialtactsActionBarOverflowWhite</item>
     </style>
 
     <!-- Hide the actionbar title during the activity preview -->
     <style name="DialtactsActivityTheme" parent="DialtactsTheme">
+        <!-- Styles that require AppCompat compatibility, remember to update both sets -->
         <item name="android:actionBarStyle">@style/DialtactsActionBarWithoutTitleStyle</item>
+        <item name="actionBarStyle">@style/DialtactsActionBarWithoutTitleStyle</item>
+
         <item name="android:fastScrollThumbDrawable">@drawable/fastscroll_thumb</item>
         <item name="android:fastScrollTrackDrawable">@null</item>
     </style>
@@ -121,23 +133,36 @@
         <item name="android:actionOverflowButtonStyle">@style/DialtactsActionBarOverflowWhite</item>
     </style>
 
-    <style name="DialtactsActionBarStyle" parent="android:Widget.Material.ActionBar">
+    <style name="DialtactsActionBarStyle"
+           parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
+        <!-- Styles that require AppCompat compatibility, remember to update both sets -->
         <item name="android:background">@color/actionbar_background_color</item>
+        <item name="background">@color/actionbar_background_color</item>
         <item name="android:titleTextStyle">@style/DialtactsActionBarTitleText</item>
+        <item name="titleTextStyle">@style/DialtactsActionBarTitleText</item>
         <item name="android:height">@dimen/action_bar_height</item>
+        <item name="height">@dimen/action_bar_height</item>
         <item name="android:elevation">@dimen/action_bar_elevation</item>
+        <item name="elevation">@dimen/action_bar_elevation</item>
         <!-- Empty icon -->
         <item name="android:icon">@android:color/transparent</item>
+        <item name="icon">@android:color/transparent</item>
         <!-- Shift the title text to the right -->
         <item name="android:contentInsetStart">@dimen/actionbar_contentInsetStart</item>
+        <item name="contentInsetStart">@dimen/actionbar_contentInsetStart</item>
     </style>
 
     <style name="DialtactsActionBarWithoutTitleStyle" parent="DialtactsActionBarStyle">
+        <!-- Styles that require AppCompat compatibility, remember to update both sets -->
         <item name="android:displayOptions"></item>
+        <item name="displayOptions"></item>
         <item name="android:height">@dimen/action_bar_height_large</item>
+        <item name="height">@dimen/action_bar_height_large</item>
         <!-- Override ActionBar title offset to keep search box aligned left -->
         <item name="android:contentInsetStart">0dp</item>
+        <item name="contentInsetStart">0dp</item>
         <item name="android:contentInsetEnd">0dp</item>
+        <item name="contentInsetEnd">0dp</item>
     </style>
 
     <!-- Text in the action bar at the top of the screen -->
diff --git a/src/com/android/dialer/CallDetailActivity.java b/src/com/android/dialer/CallDetailActivity.java
index 56f2cb1..32eccc4 100644
--- a/src/com/android/dialer/CallDetailActivity.java
+++ b/src/com/android/dialer/CallDetailActivity.java
@@ -27,6 +27,8 @@
 import android.os.PowerManager;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.VoicemailContract.Voicemails;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
 import android.telecom.PhoneAccount;
 import android.telecom.PhoneAccountHandle;
 import android.telephony.TelephonyManager;
@@ -72,7 +74,7 @@
  * This activity can be either started with the URI of a single call log entry, or with the
  * {@link #EXTRA_CALL_LOG_IDS} extra to specify a group of call log entries.
  */
-public class CallDetailActivity extends Activity
+public class CallDetailActivity extends AppCompatActivity
         implements MenuItem.OnMenuItemClickListener {
     private static final String TAG = "CallDetail";
 
@@ -259,7 +261,7 @@
         });
 
         mContactInfoHelper = new ContactInfoHelper(this, GeoUtil.getCurrentCountryIso(this));
-        getActionBar().setDisplayHomeAsUpEnabled(true);
+        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
 
         if (getIntent().getBooleanExtra(EXTRA_FROM_NOTIFICATION, false)) {
             closeSystemDialogs();
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index 8fa56f0..ae1a160 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -16,7 +16,6 @@
 
 package com.android.dialer;
 
-import android.app.ActionBar;
 import android.app.Fragment;
 import android.app.FragmentTransaction;
 import android.content.ActivityNotFoundException;
@@ -32,6 +31,7 @@
 import android.provider.CallLog.Calls;
 import android.speech.RecognizerIntent;
 import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
 import android.telecom.PhoneAccount;
 import android.telecom.TelecomManager;
 import android.text.Editable;
@@ -58,7 +58,6 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
-import com.android.contacts.common.activity.TransactionSafeActivity;
 import com.android.contacts.common.dialog.ClearFrequentsDialog;
 import com.android.contacts.common.interactions.ImportExportDialogFragment;
 import com.android.contacts.common.interactions.TouchPointManager;
@@ -389,7 +388,7 @@
         getWindow().setBackgroundDrawable(null);
 
         Trace.beginSection(TAG + " setup Views");
-        final ActionBar actionBar = getActionBar();
+        final ActionBar actionBar = getSupportActionBar();
         actionBar.setCustomView(R.layout.search_edittext);
         actionBar.setDisplayShowCustomEnabled(true);
         actionBar.setBackgroundDrawable(null);
@@ -851,7 +850,7 @@
      * Sets the hint text for the contacts search box
      */
     private void setSearchBoxHint() {
-        SearchEditTextLayout searchEditTextLayout = (SearchEditTextLayout) getActionBar()
+        SearchEditTextLayout searchEditTextLayout = (SearchEditTextLayout) getSupportActionBar()
                 .getCustomView().findViewById(R.id.search_view_container);
         ((TextView) searchEditTextLayout.findViewById(R.id.search_box_start_search))
                 .setHint(getSearchBoxHint());
@@ -1342,12 +1341,12 @@
 
     @Override
     public int getActionBarHideOffset() {
-        return getActionBar().getHideOffset();
+        return getSupportActionBar().getHideOffset();
     }
 
     @Override
     public void setActionBarHideOffset(int offset) {
-        getActionBar().setHideOffset(offset);
+        getSupportActionBar().setHideOffset(offset);
     }
 
     @Override
diff --git a/src/com/android/dialer/TransactionSafeActivity.java b/src/com/android/dialer/TransactionSafeActivity.java
new file mode 100644
index 0000000..81e5012
--- /dev/null
+++ b/src/com/android/dialer/TransactionSafeActivity.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 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.dialer;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+/**
+ * A common superclass that keeps track of whether an {@link Activity} has saved its state yet or
+ * not.
+ */
+public abstract class TransactionSafeActivity extends AppCompatActivity {
+
+    private boolean mIsSafeToCommitTransactions;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mIsSafeToCommitTransactions = true;
+    }
+
+    @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/dialer/calllog/CallLogActivity.java b/src/com/android/dialer/calllog/CallLogActivity.java
index 16f48ad..ff0726d 100644
--- a/src/com/android/dialer/calllog/CallLogActivity.java
+++ b/src/com/android/dialer/calllog/CallLogActivity.java
@@ -15,7 +15,6 @@
  */
 package com.android.dialer.calllog;
 
-import android.app.ActionBar;
 import android.app.Activity;
 import android.app.Fragment;
 import android.app.FragmentManager;
@@ -27,6 +26,8 @@
 import android.provider.CallLog.Calls;
 import android.support.v13.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -40,7 +41,7 @@
 import com.android.dialer.DialtactsActivity;
 import com.android.dialer.R;
 
-public class CallLogActivity extends Activity implements ViewPager.OnPageChangeListener {
+public class CallLogActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
     private ViewPager mViewPager;
     private ViewPagerTabs mViewPagerTabs;
     private ViewPagerAdapter mViewPagerAdapter;
@@ -114,7 +115,7 @@
         setContentView(R.layout.call_log_activity);
         getWindow().setBackgroundDrawable(null);
 
-        final ActionBar actionBar = getActionBar();
+        final ActionBar actionBar = getSupportActionBar();
         actionBar.setDisplayShowHomeEnabled(true);
         actionBar.setDisplayHomeAsUpEnabled(true);
         actionBar.setDisplayShowTitleEnabled(true);
diff --git a/src/com/android/dialer/interactions/PhoneNumberInteraction.java b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
index 8455f24..6e218c0 100644
--- a/src/com/android/dialer/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
@@ -48,9 +48,9 @@
 import com.android.contacts.common.Collapser;
 import com.android.contacts.common.Collapser.Collapsible;
 import com.android.contacts.common.MoreContactUtils;
-import com.android.contacts.common.activity.TransactionSafeActivity;
 import com.android.contacts.common.util.ContactDisplayUtils;
 import com.android.dialer.R;
+import com.android.dialer.TransactionSafeActivity;
 import com.android.dialer.contact.ContactUpdateService;
 import com.android.dialer.util.IntentUtil;
 import com.android.dialer.util.DialerUtils;
diff --git a/src/com/android/dialer/list/ListsFragment.java b/src/com/android/dialer/list/ListsFragment.java
index 931b9bd..feab201 100644
--- a/src/com/android/dialer/list/ListsFragment.java
+++ b/src/com/android/dialer/list/ListsFragment.java
@@ -1,7 +1,21 @@
+/*
+ * Copyright (C) 2013 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.dialer.list;
 
 import android.animation.LayoutTransition;
-import android.app.ActionBar;
 import android.app.Fragment;
 import android.app.FragmentManager;
 import android.content.Context;
@@ -14,6 +28,8 @@
 import android.support.v13.app.FragmentPagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.support.v4.view.ViewPager.OnPageChangeListener;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -177,7 +193,7 @@
     public void onResume() {
         Trace.beginSection(TAG + " onResume");
         super.onResume();
-        mActionBar = getActivity().getActionBar();
+        mActionBar = ((AppCompatActivity) getActivity()).getSupportActionBar();
         if (getUserVisibleHint()) {
             sendScreenViewForCurrentPosition();
         }
diff --git a/src/com/android/dialer/settings/AppCompatPreferenceActivity.java b/src/com/android/dialer/settings/AppCompatPreferenceActivity.java
new file mode 100644
index 0000000..0708783
--- /dev/null
+++ b/src/com/android/dialer/settings/AppCompatPreferenceActivity.java
@@ -0,0 +1,136 @@
+/*
+ * 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.dialer.settings;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import android.preference.PreferenceActivity.Header;
+import android.provider.Settings;
+import android.support.v7.app.ActionBar;
+import android.support.v7.app.AppCompatActivity;
+import android.support.v7.app.AppCompatDelegate;
+import android.support.v7.widget.Toolbar;
+import android.telecom.TelecomManager;
+import android.telephony.TelephonyManager;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import java.util.List;
+
+/**
+ * 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;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        getDelegate().installViewFactory();
+        getDelegate().onCreate(savedInstanceState);
+        super.onCreate(savedInstanceState);
+    }
+
+    @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;
+    }
+}
diff --git a/src/com/android/dialer/settings/DialerSettingsActivity.java b/src/com/android/dialer/settings/DialerSettingsActivity.java
index c459d35..01a9fcf 100644
--- a/src/com/android/dialer/settings/DialerSettingsActivity.java
+++ b/src/com/android/dialer/settings/DialerSettingsActivity.java
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2013 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.dialer.settings;
 
 import android.app.AppOpsManager;
@@ -21,8 +36,7 @@
 
 import java.util.List;
 
-public class DialerSettingsActivity extends PreferenceActivity {
-
+public class DialerSettingsActivity extends AppCompatPreferenceActivity {
     protected SharedPreferences mPreferences;
 
     @Override
diff --git a/src/com/android/dialer/widget/ActionBarController.java b/src/com/android/dialer/widget/ActionBarController.java
index b9923d1..edf57b1 100644
--- a/src/com/android/dialer/widget/ActionBarController.java
+++ b/src/com/android/dialer/widget/ActionBarController.java
@@ -1,15 +1,28 @@
+/*
+ * Copyright (C) 2013 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.dialer.widget;
 
 import com.google.common.annotations.VisibleForTesting;
 
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.app.ActionBar;
 import android.os.Bundle;
 import android.util.Log;
 
 import com.android.dialer.DialtactsActivity;
-import com.android.phone.common.animation.AnimUtils;
 import com.android.phone.common.animation.AnimUtils.AnimationCallback;
 
 /**