Merge "Deprecate getTabLayout()" into rvc-qpr-dev
diff --git a/car-apps-common/res/drawable/control_bar_button_background.xml b/car-apps-common/res/drawable/control_bar_button_background.xml
index 2c6e1f2..09bd38a 100644
--- a/car-apps-common/res/drawable/control_bar_button_background.xml
+++ b/car-apps-common/res/drawable/control_bar_button_background.xml
@@ -17,6 +17,15 @@
   ~
  -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_pressed="true">
+        <shape android:shape="oval">
+            <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
+            <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
+                    android:color="@color/car_ui_rotary_focus_pressed_stroke_color" />
+            <size android:width="@dimen/control_bar_button_background_radius"
+                  android:height="@dimen/control_bar_button_background_radius"/>
+        </shape>
+    </item>
     <item android:state_focused="true">
         <shape android:shape="oval">
             <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
diff --git a/car-apps-common/res/drawable/hero_button_background.xml b/car-apps-common/res/drawable/hero_button_background.xml
index e036f4a..e5aeec5 100644
--- a/car-apps-common/res/drawable/hero_button_background.xml
+++ b/car-apps-common/res/drawable/hero_button_background.xml
@@ -14,6 +14,14 @@
 limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_pressed="true">
+        <shape android:shape="rectangle">
+            <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
+            <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
+                    android:color="@color/car_ui_rotary_focus_pressed_stroke_color" />
+            <corners android:radius="@dimen/hero_button_corner_radius"/>
+        </shape>
+    </item>
     <item android:state_focused="true">
         <shape android:shape="rectangle">
             <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
diff --git a/car-media-common/res/drawable/fab_empty_foreground.xml b/car-media-common/res/drawable/fab_empty_foreground.xml
deleted file mode 100644
index d9fb901..0000000
--- a/car-media-common/res/drawable/fab_empty_foreground.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-  Copyright 2018, 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.
--->
-<ripple
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:radius="0dp"
-    android:color="@color/car_dark_blue_grey_700" />
diff --git a/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml b/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml
index 38389b0..1d70c72 100644
--- a/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml
+++ b/car-media-common/res/layout/minimized_play_pause_stop_button_layout.xml
@@ -20,11 +20,9 @@
     android:focusable="false"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
-    <!-- The invisible foreground ripple stops Android O from drawing an ugly square over the play button -->
     <com.android.car.media.common.PlayPauseStopImageView
         android:id="@+id/play_pause_stop"
         style="@style/Widget.ActionButton"
-        android:foreground="@drawable/fab_empty_foreground"
         android:src="@drawable/ic_play_pause_stop_animated"/>
     <ProgressBar
         android:id="@+id/circular_progress_bar"
diff --git a/car-media-common/res/layout/play_pause_stop_button_layout.xml b/car-media-common/res/layout/play_pause_stop_button_layout.xml
index f7700fe..f61a821 100644
--- a/car-media-common/res/layout/play_pause_stop_button_layout.xml
+++ b/car-media-common/res/layout/play_pause_stop_button_layout.xml
@@ -20,11 +20,9 @@
     android:focusable="false"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content">
-    <!-- The invisible foreground ripple stops Android O from drawing an ugly square over the play button -->
     <com.android.car.media.common.PlayPauseStopImageView
         android:id="@+id/play_pause_stop"
         style="@style/Widget.ActionButton"
-        android:foreground="@drawable/fab_empty_foreground"
         android:src="@drawable/ic_play_pause_stop_animated"/>
     <ProgressBar
         android:id="@+id/circular_progress_bar"
diff --git a/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java b/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java
index dac0aa3..8ed7e73 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/InMemoryPhoneBook.java
@@ -25,8 +25,8 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.lifecycle.LiveData;
-import androidx.lifecycle.MutableLiveData;
 import androidx.lifecycle.Observer;
+import androidx.lifecycle.Transformations;
 
 import com.android.car.apps.common.log.L;
 
@@ -59,10 +59,9 @@
     private final Map<String, Map<String, Contact>> mLookupKeyContactMap = new HashMap<>();
 
     /**
-     * A map which divides contacts LiveData by account.
+     * A map which divides contacts by account.
      */
-    private final Map<String, MutableLiveData<List<Contact>>> mAccountContactsLiveDataMap =
-            new ArrayMap<>();
+    private final Map<String, List<Contact>> mAccountContactsMap = new ArrayMap<>();
     private boolean mIsLoaded = false;
 
     /**
@@ -160,10 +159,8 @@
      *                    Bluetooth address.
      */
     public LiveData<List<Contact>> getContactsLiveDataByAccount(String accountName) {
-        if (!mAccountContactsLiveDataMap.containsKey(accountName)) {
-            mAccountContactsLiveDataMap.put(accountName, new MutableLiveData<>());
-        }
-        return mAccountContactsLiveDataMap.get(accountName);
+        return Transformations.map(mContactListAsyncQueryLiveData,
+                contacts -> contacts == null ? null : mAccountContactsMap.get(accountName));
     }
 
     /**
@@ -252,12 +249,13 @@
             subMap.put(lookupKey, Contact.fromCursor(mContext, cursor, subMap.get(lookupKey)));
         }
 
+        mAccountContactsMap.clear();
         for (String accountName : contactMap.keySet()) {
             Map<String, Contact> subMap = contactMap.get(accountName);
             contactList.addAll(subMap.values());
-            MutableLiveData<List<Contact>> accountContactsLiveData =
-                    (MutableLiveData<List<Contact>>) getContactsLiveDataByAccount(accountName);
-            accountContactsLiveData.postValue(new ArrayList<>(subMap.values()));
+            List<Contact> accountContacts = new ArrayList<>();
+            accountContacts.addAll(subMap.values());
+            mAccountContactsMap.put(accountName, accountContacts);
         }
 
         mLookupKeyContactMap.clear();
diff --git a/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java b/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java
index b3c1fb1..394b6d4 100644
--- a/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java
+++ b/car-telephony-common/src/com/android/car/telephony/common/ObservableAsyncQuery.java
@@ -50,9 +50,9 @@
 
     private AsyncQueryHandler mAsyncQueryHandler;
     private QueryParam.Provider mQueryParamProvider;
-    private Cursor mCurrentCursor;
     private OnQueryFinishedListener mOnQueryFinishedListener;
     private ContentObserver mContentObserver;
+    private ContentResolver mContentResolver;
     private boolean mIsActive = false;
     private int mToken;
 
@@ -65,6 +65,7 @@
             @NonNull ContentResolver cr,
             @NonNull OnQueryFinishedListener listener) {
         mAsyncQueryHandler = new AsyncQueryHandlerImpl(this, cr);
+        mContentResolver = cr;
         mContentObserver = new ContentObserver(mAsyncQueryHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -83,6 +84,7 @@
     public void startQuery() {
         L.d(TAG, "startQuery");
         mAsyncQueryHandler.cancelOperation(mToken); // Cancel the query task.
+        mContentResolver.unregisterContentObserver(mContentObserver);
 
         mToken++;
         QueryParam queryParam = mQueryParamProvider.getQueryParam();
@@ -95,6 +97,7 @@
                     queryParam.mSelection,
                     queryParam.mSelectionArgs,
                     queryParam.mOrderBy);
+            mContentResolver.registerContentObserver(queryParam.mUri, false, mContentObserver);
         } else {
             mOnQueryFinishedListener.onQueryFinished(null);
         }
@@ -109,7 +112,7 @@
     public void stopQuery() {
         L.d(TAG, "stopQuery");
         mIsActive = false;
-        cleanupCursorIfNecessary();
+        mContentResolver.unregisterContentObserver(mContentObserver);
         mAsyncQueryHandler.cancelOperation(mToken); // Cancel the query task.
     }
 
@@ -118,23 +121,11 @@
             return;
         }
         L.d(TAG, "onQueryComplete");
-        cleanupCursorIfNecessary();
-        if (cursor != null) {
-            cursor.registerContentObserver(mContentObserver);
-            mCurrentCursor = cursor;
-        }
         if (mOnQueryFinishedListener != null) {
             mOnQueryFinishedListener.onQueryFinished(cursor);
         }
     }
 
-    protected void cleanupCursorIfNecessary() {
-        if (mCurrentCursor != null) {
-            mCurrentCursor.unregisterContentObserver(mContentObserver);
-        }
-        mCurrentCursor = null;
-    }
-
     private static class AsyncQueryHandlerImpl extends AsyncQueryHandler {
         private ObservableAsyncQuery mQuery;
 
diff --git a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
index f5c6c1d..b71b3ab 100644
--- a/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
+++ b/car-ui-lib/car-ui-lib/src/main/java/com/android/car/ui/FocusArea.java
@@ -282,10 +282,11 @@
 
     /**
      * Updates {@link #mPreviousFocusArea} when the focus has moved from another FocusArea to this
-     * FocusArea.
+     * FocusArea, and sets it to {@code null} in any other cases.
      */
     private void maybeUpdatePreviousFocusArea(boolean hasFocus, View oldFocus) {
-        if (mHasFocus || !hasFocus || oldFocus == null) {
+        if (mHasFocus || !hasFocus || oldFocus == null || oldFocus instanceof FocusParkingView) {
+            mPreviousFocusArea = null;
             return;
         }
         mPreviousFocusArea = getAncestorFocusArea(oldFocus);
diff --git a/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml b/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
index e9b706d..91e2cf4 100644
--- a/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res-overlayable/values/overlayable.xml
@@ -94,6 +94,8 @@
       <item type="color" name="car_ui_ripple_color"/>
       <item type="color" name="car_ui_rotary_focus_fill_color"/>
       <item type="color" name="car_ui_rotary_focus_fill_secondary_color"/>
+      <item type="color" name="car_ui_rotary_focus_pressed_fill_color"/>
+      <item type="color" name="car_ui_rotary_focus_pressed_stroke_color"/>
       <item type="color" name="car_ui_rotary_focus_stroke_color"/>
       <item type="color" name="car_ui_rotary_focus_stroke_secondary_color"/>
       <item type="color" name="car_ui_scrollbar_thumb"/>
@@ -173,6 +175,7 @@
       <item type="dimen" name="car_ui_recyclerview_divider_height"/>
       <item type="dimen" name="car_ui_recyclerview_divider_start_margin"/>
       <item type="dimen" name="car_ui_recyclerview_divider_top_margin"/>
+      <item type="dimen" name="car_ui_rotary_focus_pressed_stroke_width"/>
       <item type="dimen" name="car_ui_rotary_focus_stroke_width"/>
       <item type="dimen" name="car_ui_scrollbar_button_size"/>
       <item type="dimen" name="car_ui_scrollbar_container_width"/>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml
index f10416e..4d33475 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/drawable/car_ui_list_item_background.xml
@@ -13,22 +13,20 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_pressed="true">
+        <shape android:shape="rectangle">
+            <solid android:color="@color/car_ui_rotary_focus_pressed_fill_color"/>
+            <stroke android:width="@dimen/car_ui_rotary_focus_pressed_stroke_width"
+                    android:color="@color/car_ui_rotary_focus_pressed_stroke_color"/>
+        </shape>
+    </item>
     <item android:state_focused="true">
-        <layer-list>
-            <item>
-                <shape android:shape="rectangle">
-                    <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
-                </shape>
-            </item>
-            <item>
-                <shape android:shape="rectangle">
-                    <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
-                            android:color="@color/car_ui_rotary_focus_stroke_color"/>
-                </shape>
-            </item>
-        </layer-list>
+        <shape android:shape="rectangle">
+            <solid android:color="@color/car_ui_rotary_focus_fill_color"/>
+            <stroke android:width="@dimen/car_ui_rotary_focus_stroke_width"
+                    android:color="@color/car_ui_rotary_focus_stroke_color"/>
+        </shape>
     </item>
     <item>
         <ripple android:color="?android:attr/colorControlHighlight">
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml b/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml
index d943920..326dcfb 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/values/colors.xml
@@ -48,6 +48,8 @@
 
     <color name="car_ui_rotary_focus_stroke_color">#94CBFF</color>
     <color name="car_ui_rotary_focus_fill_color">#3D94CBFF</color>
+    <color name="car_ui_rotary_focus_pressed_stroke_color">#94CBFF</color>
+    <color name="car_ui_rotary_focus_pressed_fill_color">#8A94CBFF</color>
     <color name="car_ui_rotary_focus_stroke_secondary_color">#0059B3</color>
     <color name="car_ui_rotary_focus_fill_secondary_color">#3D0059B3</color>
 </resources>
diff --git a/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml b/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml
index f0c2a8b..b2eaadc 100644
--- a/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml
+++ b/car-ui-lib/car-ui-lib/src/main/res/values/dimens.xml
@@ -210,5 +210,6 @@
     <!-- Rotary focus highlight  -->
 
     <dimen name="car_ui_rotary_focus_stroke_width">8dp</dimen>
+    <dimen name="car_ui_rotary_focus_pressed_stroke_width">4dp</dimen>
 
 </resources>
diff --git a/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml b/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
index 1f89ff2..14f6cd0 100644
--- a/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
+++ b/car-ui-lib/referencedesign/res/drawable/car_ui_toolbar_menu_item_icon_ripple.xml
@@ -17,6 +17,15 @@
   ~
  -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:state_pressed="true">
+        <shape android:shape="oval">
+            <solid android:color="#8A94CBFF"/>
+            <stroke android:width="4dp"
+                    android:color="#94CBFF"/>
+            <size android:width="48dp"
+                  android:height="48dp"/>
+        </shape>
+    </item>
     <item android:state_focused="true">
         <shape android:shape="oval">
             <solid android:color="#3D94CBFF"/>
diff --git a/car-ui-lib/tests/apitest/current.xml b/car-ui-lib/tests/apitest/current.xml
index 76eb5a2..2c6553e 100644
--- a/car-ui-lib/tests/apitest/current.xml
+++ b/car-ui-lib/tests/apitest/current.xml
@@ -29,6 +29,8 @@
   <public type="color" name="car_ui_ripple_color"/>
   <public type="color" name="car_ui_rotary_focus_fill_color"/>
   <public type="color" name="car_ui_rotary_focus_fill_secondary_color"/>
+  <public type="color" name="car_ui_rotary_focus_pressed_fill_color"/>
+  <public type="color" name="car_ui_rotary_focus_pressed_stroke_color"/>
   <public type="color" name="car_ui_rotary_focus_stroke_color"/>
   <public type="color" name="car_ui_rotary_focus_stroke_secondary_color"/>
   <public type="color" name="car_ui_scrollbar_thumb"/>
@@ -108,6 +110,7 @@
   <public type="dimen" name="car_ui_recyclerview_divider_height"/>
   <public type="dimen" name="car_ui_recyclerview_divider_start_margin"/>
   <public type="dimen" name="car_ui_recyclerview_divider_top_margin"/>
+  <public type="dimen" name="car_ui_rotary_focus_pressed_stroke_width"/>
   <public type="dimen" name="car_ui_rotary_focus_stroke_width"/>
   <public type="dimen" name="car_ui_scrollbar_button_size"/>
   <public type="dimen" name="car_ui_scrollbar_container_width"/>