OSDN Git Service

Fill UI polish
authorSvet Ganov <svetoslavganov@google.com>
Wed, 12 Apr 2017 06:10:43 +0000 (23:10 -0700)
committerSvet Ganov <svetoslavganov@google.com>
Wed, 12 Apr 2017 16:53:13 +0000 (09:53 -0700)
1. Avoid jank when the suggesting list scrolled

2. Remove hard-coded values from max popup height

3. UX requested tweaks

4. Remove dead code

Test: manual

bug:37245055
bug:37179467

Change-Id: I6a6760edb06230e3d4925e23863667cfd3ac0601

core/res/res/drawable/autofill_dataset_picker_background.xml [new file with mode: 0644]
core/res/res/layout/autofill_dataset_picker.xml
core/res/res/values/styles.xml
core/res/res/values/symbols.xml
services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
services/autofill/java/com/android/server/autofill/ui/FillUi.java

diff --git a/core/res/res/drawable/autofill_dataset_picker_background.xml b/core/res/res/drawable/autofill_dataset_picker_background.xml
new file mode 100644 (file)
index 0000000..b5617e1
--- /dev/null
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android">
+    <shape android:shape="rectangle">
+        <corners android:radius="2dp" />
+        <solid android:color="?attr/colorBackground" />
+    </shape>
+</inset>
index 133265b..5a835b7 100644 (file)
      limitations under the License.
 -->
 
-<ListView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_dataset_picker"
-    android:layout_width="wrap_content"
+<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
     android:layout_height="fill_parent"
-    android:divider="@null"
-    android:background="#ffffffff"
-    android:elevation="@dimen/floating_window_z">
-</ListView>
+    style="@style/AutofillDatasetPicker">
+
+    <ListView
+        android:id="@+id/autofill_dataset_list"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:divider="@null"
+        android:visibility="gone">
+    </ListView>
+
+</FrameLayout>
index 7dac18d..8bbb929 100644 (file)
@@ -1482,4 +1482,10 @@ please see styles_device_defaults.xml.
         <item name="successColor">@color/lock_pattern_view_success_color</item>
     </style>
 
+    <!-- @hide -->
+    <style name="AutofillDatasetPicker">
+        <item name="elevation">4dp</item>
+        <item name="background">@drawable/autofill_dataset_picker_background</item>
+    </style>
+
 </resources>
index 7cb9ba8..78f971f 100644 (file)
   <java-symbol type="dimen" name="item_touch_helper_swipe_escape_max_velocity"/>
 
   <!-- com.android.server.autofill -->
-  <!-- TODO: floating_window_z temporary exposed until Autofill UI uses a ContextThemeWrapper -->
-  <java-symbol type="dimen" name="floating_window_z" />
   <java-symbol type="layout" name="autofill_save"/>
   <java-symbol type="layout" name="autofill_dataset_picker"/>
+  <java-symbol type="id" name="autofill_dataset_list"/>
   <java-symbol type="id" name="autofill" />
   <java-symbol type="id" name="autofill_save_title" />
   <java-symbol type="id" name="autofill_save_subtitle" />
   <java-symbol type="string" name="autofill_save_type_credit_card" />
   <java-symbol type="string" name="autofill_save_type_username" />
   <java-symbol type="string" name="autofill_save_type_email_address" />
+  <java-symbol type="drawable" name="autofill_dataset_picker_background" />
+  <java-symbol type="style" name="AutofillDatasetPicker" />
 
   <!-- Accessibility fingerprint gestures -->
   <java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
index 64dee58..0f18c87 100644 (file)
@@ -28,7 +28,6 @@ import android.service.autofill.Dataset;
 import android.service.autofill.FillResponse;
 import android.service.autofill.SaveInfo;
 import android.text.TextUtils;
-import android.text.format.DateUtils;
 import android.util.Slog;
 import android.view.autofill.AutofillId;
 import android.view.autofill.IAutofillWindowPresenter;
@@ -50,8 +49,6 @@ import java.io.PrintWriter;
 public final class AutoFillUI {
     private static final String TAG = "AutoFillUI";
 
-    private static final int MAX_SAVE_TIMEOUT_MS = (int) (30 * DateUtils.SECOND_IN_MILLIS);
-
     private final Handler mHandler = UiThread.getHandler();
     private final @NonNull Context mContext;
 
@@ -60,7 +57,6 @@ public final class AutoFillUI {
 
     private @Nullable AutoFillUiCallback mCallback;
 
-    private int mSaveTimeoutMs = (int) (5 * DateUtils.SECOND_IN_MILLIS);
     private final MetricsLogger mMetricsLogger = new MetricsLogger();
 
     public interface AutoFillUiCallback {
@@ -273,22 +269,11 @@ public final class AutoFillUI {
         mHandler.post(this::hideAllUiThread);
     }
 
-    public void setSaveTimeout(int timeout) {
-        if (timeout > MAX_SAVE_TIMEOUT_MS) {
-            throw new IllegalArgumentException("Maximum value is " + MAX_SAVE_TIMEOUT_MS + "ms");
-        }
-        if (timeout <= 0) {
-            throw new IllegalArgumentException("Must be a positive value");
-        }
-        mSaveTimeoutMs = timeout;
-    }
-
     public void dump(PrintWriter pw) {
         pw.println("Autofill UI");
         final String prefix = "  ";
         final String prefix2 = "    ";
         pw.print(prefix); pw.print("showsSaveUi: "); pw.println(mSaveUi != null);
-        pw.print(prefix); pw.print("save timeout: "); pw.println(mSaveTimeoutMs);
         if (mFillUi != null) {
             pw.print(prefix); pw.println("showsFillUi: true");
             mFillUi.dump(pw, prefix2);
index b69d1dc..a89df92 100644 (file)
@@ -69,7 +69,6 @@ final class FillUi {
     private final @Nullable ArrayAdapter<ViewItem> mAdapter;
 
     private @Nullable String mFilterText;
-    private final String mAccessibilityTitle;
 
     private int mContentWidth;
     private int mContentHeight;
@@ -81,7 +80,9 @@ final class FillUi {
             @NonNull Callback callback) {
         mCallback = callback;
 
-        mAccessibilityTitle = context.getString(R.string.autofill_picker_accessibility_title);
+        final LayoutInflater inflater = LayoutInflater.from(context);
+        final ViewGroup decor = (ViewGroup) inflater.inflate(
+                R.layout.autofill_dataset_picker, null);
 
         if (response.getAuthentication() != null) {
             mListView = null;
@@ -89,23 +90,23 @@ final class FillUi {
 
             final View content;
             try {
-                content = response.getPresentation().apply(context, null);
+                content = response.getPresentation().apply(context, decor);
+                decor.addView(content);
             } catch (RuntimeException e) {
                 callback.onCanceled();
                 Slog.e(TAG, "Error inflating remote views", e);
                 mWindow = null;
                 return;
             }
-            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
-            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(MeasureSpec.UNSPECIFIED, 0);
+            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
             content.measure(widthMeasureSpec, heightMeasureSpec);
             content.setOnClickListener(v -> mCallback.onResponsePicked(response));
-            content.setElevation(context.getResources().getDimension(R.dimen.floating_window_z));
             // TODO(b/33197203 , b/36660292): temporary limiting maximum height and minimum width
             mContentWidth = Math.max(content.getMeasuredWidth(), 1000);
             mContentHeight = Math.min(content.getMeasuredHeight(), 500);
 
-            mWindow = new AnchoredWindow(content);
+            mWindow = new AnchoredWindow(decor);
             mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
         } else {
             final int datasetCount = response.getDatasets().size();
@@ -139,9 +140,9 @@ final class FillUi {
                 }
             };
 
-            final LayoutInflater inflater = LayoutInflater.from(context);
-            mListView = (ListView) inflater.inflate(R.layout.autofill_dataset_picker, null);
+            mListView = decor.findViewById(R.id.autofill_dataset_list);
             mListView.setAdapter(mAdapter);
+            mListView.setVisibility(View.VISIBLE);
             mListView.setOnItemClickListener((adapter, view, position, id) -> {
                 final ViewItem vi = mAdapter.getItem(position);
                 mCallback.onDatasetPicked(vi.getDataset());
@@ -154,11 +155,12 @@ final class FillUi {
             }
 
             applyNewFilterText();
-            mWindow = new AnchoredWindow(mListView);
+            mWindow = new AnchoredWindow(decor);
         }
     }
 
     private void applyNewFilterText() {
+        final int oldCount = mAdapter.getCount();
         mAdapter.getFilter().filter(mFilterText, (count) -> {
             if (mDestroyed) {
                 return;
@@ -175,6 +177,9 @@ final class FillUi {
                 } else {
                     mListView.setVerticalScrollBarEnabled(false);
                 }
+                if (mAdapter.getCount() != oldCount) {
+                    mListView.requestLayout();
+                }
             }
         });
     }
@@ -312,7 +317,8 @@ final class FillUi {
         public void show(WindowManager.LayoutParams params) {
             try {
                 if (!mShowing) {
-                    params.accessibilityTitle = mAccessibilityTitle;
+                    params.accessibilityTitle = mContentView.getContext()
+                            .getString(R.string.autofill_picker_accessibility_title);
                     mWm.addView(mContentView, params);
                     mContentView.setOnTouchListener(this);
                     mShowing = true;
@@ -352,7 +358,6 @@ final class FillUi {
         pw.print(prefix); pw.print("mListView: "); pw.println(mListView);
         pw.print(prefix); pw.print("mAdapter: "); pw.println(mAdapter != null);
         pw.print(prefix); pw.print("mFilterText: "); pw.println(mFilterText);
-        pw.print(prefix); pw.print("mAccessibilityTitle: "); pw.println(mAccessibilityTitle);
         pw.print(prefix); pw.print("mContentWidth: "); pw.println(mContentWidth);
         pw.print(prefix); pw.print("mContentHeight: "); pw.println(mContentHeight);
         pw.print(prefix); pw.print("mDestroyed: "); pw.println(mDestroyed);