Merge "Update footer buttons depending on entry point" into qt-dev
diff --git a/res/layout/captioning_preview.xml b/res/layout/captioning_preview.xml
index b90c3a5..d8d2e4f 100644
--- a/res/layout/captioning_preview.xml
+++ b/res/layout/captioning_preview.xml
@@ -15,41 +15,32 @@
      limitations under the License.
 -->
 
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/preview_viewport"
+    android:clipToPadding="true"
+    android:clipChildren="true"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical" >
+    android:layout_height="wrap_content">
+
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/captioning_preview_height"
+        android:contentDescription="@null"
+        android:scaleType="centerCrop"
+        android:src="@drawable/caption_background"/>
 
     <FrameLayout
-        android:id="@+id/preview_viewport"
+        android:id="@+id/preview_window"
         android:layout_width="match_parent"
-        android:layout_height="@dimen/captioning_preview_height" >
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|start"
+        android:padding="16dp">
 
-        <ImageView
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:contentDescription="@null"
-            android:scaleType="centerCrop"
-            android:src="@drawable/caption_background" />
-
-        <FrameLayout
-            android:id="@+id/preview_window"
-            android:layout_width="match_parent"
+        <com.android.internal.widget.SubtitleView
+            android:id="@+id/preview_text"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_gravity="bottom|start"
-            android:padding="16dp" >
-
-            <com.android.internal.widget.SubtitleView
-                android:id="@+id/preview_text"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:text="@string/captioning_preview_text" />
-        </FrameLayout>
+            android:text="@string/captioning_preview_text"/>
     </FrameLayout>
-
-    <FrameLayout
-        android:id="@+id/properties_fragment"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent" />
-
-</LinearLayout>
+</FrameLayout>
diff --git a/res/layout/magnification_video_preference.xml b/res/layout/magnification_video_preference.xml
index fe7f26f..ff7089c 100644
--- a/res/layout/magnification_video_preference.xml
+++ b/res/layout/magnification_video_preference.xml
@@ -16,7 +16,9 @@
 <RelativeLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content">
+    android:layout_height="wrap_content"
+    android:clipChildren="true"
+    android:clipToPadding="true">
 
     <ImageView
         android:id="@+id/video_background"
diff --git a/res/raw/system_nav_3_button.mp4 b/res/raw/system_nav_3_button.mp4
index 1287f28..86fb236 100644
--- a/res/raw/system_nav_3_button.mp4
+++ b/res/raw/system_nav_3_button.mp4
Binary files differ
diff --git a/res/raw/system_nav_fully_gestural.mp4 b/res/raw/system_nav_fully_gestural.mp4
index 165ce33..ae9c6d7 100644
--- a/res/raw/system_nav_fully_gestural.mp4
+++ b/res/raw/system_nav_fully_gestural.mp4
Binary files differ
diff --git a/res/values/strings.xml b/res/values/strings.xml
index bea3c46..99c2958 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -890,6 +890,8 @@
     <string name="security_settings_face_preference_title">Face authentication</string>
     <!-- Introduction title shown in face enrollment education screen [CHAR LIMIT=40] -->
     <string name="security_settings_face_enroll_education_title">How to set up Face unlock</string>
+    <!-- Introduction title shown in face enrollment education screen for accessibility [CHAR LIMI=40]-->
+    <string name="security_settings_face_enroll_education_title_accessibility">Set up Face unlock</string>
     <!-- Introduction title shown in face enrollment education screen to show the face authentication feature, when face unlock is disabled by device admin [CHAR LIMIT=60] -->
     <string name="security_settings_face_enroll_education_title_unlock_disabled">Use your face to authenticate</string>
     <!-- Introduction detail message shown in face education [CHAR LIMIT=NONE] -->
diff --git a/res/xml/captioning_settings.xml b/res/xml/captioning_settings.xml
index 3129738..56e0e2d 100644
--- a/res/xml/captioning_settings.xml
+++ b/res/xml/captioning_settings.xml
@@ -21,6 +21,12 @@
     android:key="captioning_preference_screen"
     android:title="@string/accessibility_captioning_title" >
 
+    <com.android.settingslib.widget.LayoutPreference
+        android:key="caption_preview"
+        android:title="@string/summary_placeholder"
+        android:layout="@layout/captioning_preview"
+        settings:searchable="false"/>
+
     <PreferenceCategory
         android:key="standard"
         android:title="@string/captioning_standard_options_title" >
diff --git a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
index ae7e3fd..bddca9c 100644
--- a/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
+++ b/src/com/android/settings/accessibility/CaptionPropertiesFragment.java
@@ -22,13 +22,8 @@
 import android.content.res.Resources;
 import android.graphics.Color;
 import android.os.Bundle;
-import android.preference.PreferenceFrameLayout;
 import android.provider.Settings;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.View.OnLayoutChangeListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
 import android.view.accessibility.CaptioningManager;
 import android.view.accessibility.CaptioningManager.CaptionStyle;
 
@@ -46,6 +41,7 @@
 import com.android.settings.widget.ToggleSwitch;
 import com.android.settings.widget.ToggleSwitch.OnBeforeCheckedChangeListener;
 import com.android.settingslib.accessibility.AccessibilityUtils;
+import com.android.settingslib.widget.LayoutPreference;
 
 import java.util.Locale;
 
@@ -54,6 +50,7 @@
  */
 public class CaptionPropertiesFragment extends SettingsPreferenceFragment
         implements OnPreferenceChangeListener, OnValueChangedListener {
+    private static final String PREF_CAPTION_PREVIEW = "caption_preview";
     private static final String PREF_BACKGROUND_COLOR = "captioning_background_color";
     private static final String PREF_BACKGROUND_OPACITY = "captioning_background_opacity";
     private static final String PREF_FOREGROUND_COLOR = "captioning_foreground_color";
@@ -116,43 +113,6 @@
     }
 
     @Override
-    public View onCreateView(
-            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        final View rootView = inflater.inflate(R.layout.captioning_preview, container, false);
-
-        // We have to do this now because PreferenceFrameLayout looks at it
-        // only when the view is added.
-        if (container instanceof PreferenceFrameLayout) {
-            ((PreferenceFrameLayout.LayoutParams) rootView.getLayoutParams()).removeBorders = true;
-        }
-
-        final View content = super.onCreateView(inflater, container, savedInstanceState);
-        ((ViewGroup) rootView.findViewById(R.id.properties_fragment)).addView(
-                content, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
-
-        return rootView;
-    }
-
-    @Override
-    public void onViewCreated(View view, Bundle savedInstanceState) {
-        super.onViewCreated(view, savedInstanceState);
-
-        final boolean enabled = mCaptioningManager.isEnabled();
-        mPreviewText = (SubtitleView) view.findViewById(R.id.preview_text);
-        mPreviewText.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
-
-        mPreviewWindow = view.findViewById(R.id.preview_window);
-        mPreviewViewport = view.findViewById(R.id.preview_viewport);
-        mPreviewViewport.addOnLayoutChangeListener(new OnLayoutChangeListener() {
-            @Override
-            public void onLayoutChange(View v, int left, int top, int right, int bottom,
-                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
-                refreshPreviewText();
-            }
-        });
-    }
-
-    @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
 
@@ -263,6 +223,19 @@
     }
 
     private void initializeAllPreferences() {
+        final LayoutPreference captionPreview = findPreference(PREF_CAPTION_PREVIEW);
+
+        final boolean enabled = mCaptioningManager.isEnabled();
+        mPreviewText = captionPreview.findViewById(R.id.preview_text);
+        mPreviewText.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
+
+        mPreviewWindow = captionPreview.findViewById(R.id.preview_window);
+
+        mPreviewViewport = captionPreview.findViewById(R.id.preview_viewport);
+        mPreviewViewport.addOnLayoutChangeListener(
+                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom)
+                        -> refreshPreviewText());
+
         mLocale = (LocalePreference) findPreference(PREF_LOCALE);
         mFontSize = (ListPreference) findPreference(PREF_FONT_SIZE);
 
@@ -370,9 +343,9 @@
     /**
      * Unpack the specified color value and update the preferences.
      *
-     * @param color color preference
+     * @param color   color preference
      * @param opacity opacity preference
-     * @param value packed value
+     * @param value   packed value
      */
     private void parseColorOpacity(ColorPreference color, ColorPreference opacity, int value) {
         final int colorValue;
diff --git a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
index bb26283..dcf1f1c 100644
--- a/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
+++ b/src/com/android/settings/accessibility/ShortcutServicePickerFragment.java
@@ -15,8 +15,6 @@
  */
 package com.android.settings.accessibility;
 
-import static android.content.DialogInterface.BUTTON_POSITIVE;
-
 import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME;
 import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME;
 
@@ -25,7 +23,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
@@ -191,6 +188,7 @@
                 ((ShortcutServicePickerFragment) fragment).onServiceConfirmed(
                         bundle.getString(EXTRA_KEY));
             }
+            dismiss();
         }
     }
 
diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java
index fae1785..956ba49 100644
--- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java
+++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java
@@ -33,6 +33,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.Button;
 import android.widget.CompoundButton;
+import android.widget.TextView;
 
 import com.android.settings.R;
 import com.android.settings.Utils;
@@ -59,19 +60,28 @@
     private View mIllustrationAccessibility;
     private Handler mHandler;
     private Intent mResultIntent;
+    private TextView mDescriptionText;
 
     private CompoundButton.OnCheckedChangeListener mSwitchDiversityListener =
             new CompoundButton.OnCheckedChangeListener() {
                 @Override
                 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                    int titleRes = isChecked ?
+                            R.string.security_settings_face_enroll_education_title_accessibility
+                            : R.string.security_settings_face_enroll_education_title;
+                    getLayout().setHeaderText(titleRes);
+                    setTitle(titleRes);
+
                     if (isChecked) {
                         mIllustrationNormal.stop();
                         mIllustrationNormal.setVisibility(View.INVISIBLE);
                         mIllustrationAccessibility.setVisibility(View.VISIBLE);
+                        mDescriptionText.setVisibility(View.INVISIBLE);
                     } else {
                         mIllustrationNormal.setVisibility(View.VISIBLE);
                         mIllustrationNormal.start();
                         mIllustrationAccessibility.setVisibility(View.INVISIBLE);
+                        mDescriptionText.setVisibility(View.VISIBLE);
                     }
                 }
             };
@@ -88,6 +98,7 @@
 
         mIllustrationNormal = findViewById(R.id.illustration_normal);
         mIllustrationAccessibility = findViewById(R.id.illustration_accessibility);
+        mDescriptionText = findViewById(R.id.sud_layout_description);
 
         mFooterBarMixin = getLayout().getMixin(FooterBarMixin.class);
         mFooterBarMixin.setSecondaryButton(
diff --git a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
index 990e68d..d532a76 100644
--- a/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
+++ b/src/com/android/settings/biometrics/face/FaceSettingsRemoveButtonPreferenceController.java
@@ -94,6 +94,7 @@
             Log.e(TAG, "Unable to remove face: " + face.getBiometricId()
                     + " error: " + errMsgId + " " + errString);
             Toast.makeText(mContext, errString, Toast.LENGTH_SHORT).show();
+            mRemoving = false;
         }
 
         @Override
@@ -131,6 +132,7 @@
                 mFaceManager.remove(faces.get(0), mUserId, mRemovalCallback);
             } else {
                 mButton.setEnabled(true);
+                mRemoving = false;
             }
         }
     };
diff --git a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
index 1fe7e7d..d5e1723 100644
--- a/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
+++ b/src/com/android/settings/notification/RecentNotifyingAppsPreferenceController.java
@@ -79,7 +79,6 @@
     private final PackageManager mPm;
     private final NotificationBackend mNotificationBackend;
     private IUsageStatsManager mUsageStatsManager;
-    private final int mUserId;
     private final IconDrawableFactory mIconDrawableFactory;
 
     private Calendar mCal;
@@ -104,7 +103,6 @@
             ApplicationsState appState, Fragment host) {
         super(context);
         mIconDrawableFactory = IconDrawableFactory.newInstance(context);
-        mUserId = UserHandle.myUserId();
         mPm = context.getPackageManager();
         mHost = host;
         mApplicationsState = appState;
@@ -177,7 +175,6 @@
                 e.printStackTrace();
             }
             if (events != null) {
-
                 ArrayMap<String, NotifyingApp> aggregatedStats = new ArrayMap<>();
 
                 UsageEvents.Event event = new UsageEvents.Event();
@@ -205,7 +202,8 @@
         }
     }
 
-    private static String getKey(int userId, String pkg) {
+    @VisibleForTesting
+    static String getKey(int userId, String pkg) {
         return userId + "|" + pkg;
     }
 
@@ -252,12 +250,13 @@
             }
 
             boolean rebindPref = true;
-            NotificationAppPreference pref = appPreferences.remove(pkgName);
+            NotificationAppPreference pref = appPreferences.remove(getKey(app.getUserId(),
+                    pkgName));
             if (pref == null) {
                 pref = new NotificationAppPreference(prefContext);
                 rebindPref = false;
             }
-            pref.setKey(pkgName);
+            pref.setKey(getKey(app.getUserId(), pkgName));
             pref.setTitle(appEntry.label);
             pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
             pref.setIconSize(TwoTargetPreference.ICON_SIZE_SMALL);
@@ -267,11 +266,11 @@
             Bundle args = new Bundle();
             args.putString(AppInfoBase.ARG_PACKAGE_NAME, pkgName);
             args.putInt(AppInfoBase.ARG_PACKAGE_UID, appEntry.info.uid);
-
             pref.setIntent(new SubSettingLauncher(mHost.getActivity())
                     .setDestination(AppNotificationSettings.class.getName())
                     .setTitleRes(R.string.notifications_title)
                     .setArguments(args)
+                    .setUserHandle(new UserHandle(UserHandle.getUserId(appEntry.info.uid)))
                     .setSourceMetricsCategory(
                             SettingsEnums.MANAGE_APPLICATIONS_NOTIFICATIONS)
                     .toIntent());
@@ -301,11 +300,11 @@
         int count = 0;
         for (NotifyingApp app : mApps) {
             final ApplicationsState.AppEntry appEntry = mApplicationsState.getEntry(
-                    app.getPackage(), mUserId);
+                    app.getPackage(), app.getUserId());
             if (appEntry == null) {
                 continue;
             }
-            if (!shouldIncludePkgInRecents(app.getPackage())) {
+            if (!shouldIncludePkgInRecents(app.getPackage(), app.getUserId())) {
                 continue;
             }
             displayableApps.add(app);
@@ -321,14 +320,14 @@
     /**
      * Whether or not the app should be included in recent list.
      */
-    private boolean shouldIncludePkgInRecents(String pkgName) {
+    private boolean shouldIncludePkgInRecents(String pkgName, int userId) {
         final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER)
                 .setPackage(pkgName);
 
         if (mPm.resolveActivity(launchIntent, 0) == null) {
             // Not visible on launcher -> likely not a user visible app, skip if non-instant.
             final ApplicationsState.AppEntry appEntry =
-                    mApplicationsState.getEntry(pkgName, mUserId);
+                    mApplicationsState.getEntry(pkgName, userId);
             if (appEntry == null || appEntry.info == null || !AppUtils.isInstant(appEntry.info)) {
                 Log.d(TAG, "Not a user visible or instant app, skipping " + pkgName);
                 return false;
diff --git a/src/com/android/settings/widget/UsageGraph.java b/src/com/android/settings/widget/UsageGraph.java
index 7cef66f..505dc58 100644
--- a/src/com/android/settings/widget/UsageGraph.java
+++ b/src/com/android/settings/widget/UsageGraph.java
@@ -288,7 +288,11 @@
         canvas.drawPath(mPath, paint);
     }
 
-    private void drawFilledPath(Canvas canvas, SparseIntArray localPaths, Paint paint) {
+    @VisibleForTesting
+    void drawFilledPath(Canvas canvas, SparseIntArray localPaths, Paint paint) {
+        if (localPaths.size() == 0) {
+            return;
+        }
         mPath.reset();
         float lastStartX = localPaths.keyAt(0);
         mPath.moveTo(localPaths.keyAt(0), localPaths.valueAt(0));
diff --git a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
index d47d125..93bd8dc 100644
--- a/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/RecentNotifyingAppsPreferenceControllerTest.java
@@ -168,7 +168,6 @@
 
     @Test
     public void display_showRecents() throws Exception {
-
         List<Event> events = new ArrayList<>();
         Event app = new Event();
         app.mEventType = Event.NOTIFICATION_INTERRUPTION;
@@ -262,8 +261,12 @@
         ArgumentCaptor<Preference> prefCaptor = ArgumentCaptor.forClass(Preference.class);
         verify(mCategory, times(2)).addPreference(prefCaptor.capture());
         List<Preference> prefs = prefCaptor.getAllValues();
-        assertThat(prefs.get(1).getKey()).isEqualTo(app.getPackageName());
-        assertThat(prefs.get(0).getKey()).isEqualTo(app1.getPackageName());
+        assertThat(prefs.get(1).getKey()).isEqualTo(
+                RecentNotifyingAppsPreferenceController.getKey(UserHandle.myUserId(),
+                        app.getPackageName()));
+        assertThat(prefs.get(0).getKey()).isEqualTo(
+                RecentNotifyingAppsPreferenceController.getKey(UserHandle.myUserId(),
+                        app1.getPackageName()));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/widget/UsageGraphTest.java b/tests/robotests/src/com/android/settings/widget/UsageGraphTest.java
index 7f09c3b..ebb496c 100644
--- a/tests/robotests/src/com/android/settings/widget/UsageGraphTest.java
+++ b/tests/robotests/src/com/android/settings/widget/UsageGraphTest.java
@@ -24,6 +24,8 @@
 
 import android.content.Context;
 import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
 import android.util.SparseIntArray;
 
 import com.android.settingslib.R;
@@ -177,4 +179,14 @@
         assertThat(localPaths.keyAt(5)).isEqualTo(1001);
         assertThat(localPaths.valueAt(5)).isEqualTo(-1);
     }
+
+    @Test
+    public void drawFilledPath_emptyPath_shouldNotCrash() {
+        final Canvas canvas = new Canvas();
+        final SparseIntArray localPaths = new SparseIntArray();
+        final Paint paint = new Paint();
+
+        // Should not crash
+        mGraph.drawFilledPath(canvas, localPaths, paint);
+    }
 }