OSDN Git Service

Moving Row inflation to the background too
authorSelim Cinek <cinek@google.com>
Sat, 29 Apr 2017 02:26:28 +0000 (19:26 -0700)
committerSelim Cinek <cinek@google.com>
Tue, 2 May 2017 23:30:52 +0000 (16:30 -0700)
Previously only the contentview inflation was on the
background, now the inflation of the row is too.

Test: runtest systemui
Bug: 34888292
Change-Id: I3adc6b3311217421c9de5c37794397b8a3fd665d

packages/SystemUI/Android.mk
packages/SystemUI/src/com/android/systemui/statusbar/Abortable.java [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInflater.java
packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java [new file with mode: 0644]
packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
packages/SystemUI/tests/Android.mk
packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationInflaterTest.java

index 5ee0c64..2fd7e87 100644 (file)
@@ -31,6 +31,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-Iaidl-files-unde
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     SystemUIPluginLib \
+    android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Abortable.java b/packages/SystemUI/src/com/android/systemui/statusbar/Abortable.java
new file mode 100644 (file)
index 0000000..d5ec4f6
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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
+ */
+
+package com.android.systemui.statusbar;
+
+/**
+ * An interface that allows aborting existing operations.
+ */
+public interface Abortable {
+    void abort();
+}
index 64f36c6..f9d939c 100644 (file)
@@ -33,7 +33,6 @@ import android.service.notification.NotificationListenerService.RankingMap;
 import android.service.notification.SnoozeCriterion;
 import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RemoteViews;
@@ -43,7 +42,6 @@ import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.util.NotificationColorUtil;
 import com.android.systemui.statusbar.notification.InflationException;
-import com.android.systemui.statusbar.notification.NotificationInflater;
 import com.android.systemui.statusbar.phone.NotificationGroupManager;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -86,7 +84,7 @@ public class NotificationData {
         public List<SnoozeCriterion> snoozeCriteria;
         private int mCachedContrastColor = COLOR_INVALID;
         private int mCachedContrastColorIsFor = COLOR_INVALID;
-        private NotificationInflater.AsyncInflationTask mRunningTask = null;
+        private Abortable mRunningTask = null;
 
         public Entry(StatusBarNotification n) {
             this.key = n.getKey();
@@ -218,17 +216,17 @@ public class NotificationData {
         /**
          * Abort all existing inflation tasks
          */
-        public void abortInflation() {
+        public void abortTask() {
             if (mRunningTask != null) {
                 mRunningTask.abort();
                 mRunningTask = null;
             }
         }
 
-        public void setInflationTask(NotificationInflater.AsyncInflationTask asyncInflationTask) {
+        public void setInflationTask(Abortable abortableTask) {
             // abort any existing inflation
-            abortInflation();
-            mRunningTask = asyncInflationTask;
+            abortTask();
+            mRunningTask = abortableTask;
         }
 
         public void onInflationTaskFinished() {
@@ -236,7 +234,7 @@ public class NotificationData {
         }
 
         @VisibleForTesting
-        public AsyncTask getRunningTask() {
+        public Abortable getRunningTask() {
             return mRunningTask;
         }
     }
index 4305bde..dc538da 100644 (file)
@@ -35,6 +35,7 @@ import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
+import android.os.Looper;
 import android.util.Log;
 import android.service.notification.StatusBarNotification;
 import android.view.LayoutInflater;
@@ -107,7 +108,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
         mHorizSpaceForIcon = res.getDimensionPixelSize(R.dimen.notification_menu_icon_size);
         mVertSpaceForIcons = res.getDimensionPixelSize(R.dimen.notification_min_height);
         mIconPadding = res.getDimensionPixelSize(R.dimen.notification_menu_icon_padding);
-        mHandler = new Handler();
+        mHandler = new Handler(Looper.getMainLooper());
         mMenuItems = new ArrayList<>();
         mSnoozeItem = createSnoozeItem(context);
         mInfoItem = createInfoItem(context);
index a7034c6..52f5e1c 100644 (file)
@@ -27,6 +27,7 @@ import android.view.View;
 import android.widget.RemoteViews;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.statusbar.Abortable;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.NotificationContentView;
 import com.android.systemui.statusbar.NotificationData;
@@ -475,7 +476,7 @@ public class NotificationInflater {
     }
 
     public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress>
-            implements InflationCallback {
+            implements InflationCallback, Abortable {
 
         private final StatusBarNotification mSbn;
         private final Context mContext;
@@ -556,6 +557,7 @@ public class NotificationInflater {
                     new InflationException("Couldn't inflate contentViews" + e));
         }
 
+        @Override
         public void abort() {
             cancel(true /* mayInterruptIfRunning */);
             if (mCancellationSignal != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RowInflaterTask.java
new file mode 100644 (file)
index 0000000..1bfc0cc
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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
+ */
+
+package com.android.systemui.statusbar.notification;
+
+import android.content.Context;
+import android.support.v4.view.AsyncLayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.Abortable;
+import com.android.systemui.statusbar.ExpandableNotificationRow;
+import com.android.systemui.statusbar.NotificationData;
+
+/**
+ * An inflater task that asynchronously inflates a ExpandableNotificationRow
+ */
+public class RowInflaterTask implements Abortable, AsyncLayoutInflater.OnInflateFinishedListener {
+    private RowInflationFinishedListener mListener;
+    private NotificationData.Entry mEntry;
+    private boolean mCancelled;
+
+    /**
+     * Inflates a new notificationView. This should not be called twice on this object
+     */
+    public void inflate(Context context, ViewGroup parent, NotificationData.Entry entry,
+            RowInflationFinishedListener listener) {
+        mListener = listener;
+        AsyncLayoutInflater inflater = new AsyncLayoutInflater(context);
+        mEntry = entry;
+        entry.setInflationTask(this);
+        inflater.inflate(R.layout.status_bar_notification_row, parent, this);
+    }
+
+    @Override
+    public void abort() {
+        mCancelled = true;
+    }
+
+    @Override
+    public void onInflateFinished(View view, int resid, ViewGroup parent) {
+        if (!mCancelled) {
+            mEntry.onInflationTaskFinished();
+            mListener.onInflationFinished((ExpandableNotificationRow) view);
+        }
+    }
+
+    public interface RowInflationFinishedListener {
+        void onInflationFinished(ExpandableNotificationRow row);
+    }
+}
index 2e6af75..6998c1f 100644 (file)
@@ -172,6 +172,7 @@ import com.android.systemui.statusbar.ScrimView;
 import com.android.systemui.statusbar.SignalClusterView;
 import com.android.systemui.statusbar.StatusBarState;
 import com.android.systemui.statusbar.notification.InflationException;
+import com.android.systemui.statusbar.notification.RowInflaterTask;
 import com.android.systemui.statusbar.notification.VisualStabilityManager;
 import com.android.systemui.statusbar.phone.StatusBarIconController.IconManager;
 import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener;
@@ -1588,12 +1589,12 @@ public class StatusBar extends SystemUI implements DemoMode,
     private void abortExistingInflation(String key) {
         if (mPendingNotifications.containsKey(key)) {
             Entry entry = mPendingNotifications.get(key);
-            entry.abortInflation();
+            entry.abortTask();
             mPendingNotifications.remove(key);
         }
         Entry addedEntry = mNotificationData.get(key);
         if (addedEntry != null) {
-            addedEntry.abortInflation();
+            addedEntry.abortTask();
         }
     }
 
@@ -6173,50 +6174,57 @@ public class StatusBar extends SystemUI implements DemoMode,
                 entry.notification.getUser().getIdentifier());
 
         final StatusBarNotification sbn = entry.notification;
-        ExpandableNotificationRow row;
         if (entry.row != null) {
-            row = entry.row;
             entry.reset();
+            updateNotification(entry, pmUser, sbn, entry.row);
         } else {
-            // create the row view
-            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
-                    Context.LAYOUT_INFLATER_SERVICE);
-            row = (ExpandableNotificationRow) inflater.inflate(R.layout.status_bar_notification_row,
-                    parent, false);
-            row.setExpansionLogger(this, entry.notification.getKey());
-            row.setGroupManager(mGroupManager);
-            row.setHeadsUpManager(mHeadsUpManager);
-            row.setRemoteInputController(mRemoteInputController);
-            row.setOnExpandClickListener(this);
-            row.setRemoteViewClickHandler(mOnClickHandler);
-            row.setInflationCallback(this);
-
-            // Get the app name.
-            // Note that Notification.Builder#bindHeaderAppName has similar logic
-            // but since this field is used in the guts, it must be accurate.
-            // Therefore we will only show the application label, or, failing that, the
-            // package name. No substitutions.
-            final String pkg = sbn.getPackageName();
-            String appname = pkg;
-            try {
-                final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
-                        PackageManager.MATCH_UNINSTALLED_PACKAGES
-                                | PackageManager.MATCH_DISABLED_COMPONENTS);
-                if (info != null) {
-                    appname = String.valueOf(pmUser.getApplicationLabel(info));
-                }
-            } catch (NameNotFoundException e) {
-                // Do nothing
-            }
-            row.setAppName(appname);
-            row.setOnDismissRunnable(() ->
-                    performRemoveNotification(row.getStatusBarNotification()));
-            row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
-            if (ENABLE_REMOTE_INPUT) {
-                row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+            new RowInflaterTask().inflate(mContext, parent, entry,
+                    row -> {
+                        bindRow(entry, pmUser, sbn, row);
+                        updateNotification(entry, pmUser, sbn, row);
+                    });
+        }
+
+    }
+
+    private void bindRow(Entry entry, PackageManager pmUser,
+            StatusBarNotification sbn, ExpandableNotificationRow row) {
+        row.setExpansionLogger(this, entry.notification.getKey());
+        row.setGroupManager(mGroupManager);
+        row.setHeadsUpManager(mHeadsUpManager);
+        row.setRemoteInputController(mRemoteInputController);
+        row.setOnExpandClickListener(this);
+        row.setRemoteViewClickHandler(mOnClickHandler);
+        row.setInflationCallback(this);
+
+        // Get the app name.
+        // Note that Notification.Builder#bindHeaderAppName has similar logic
+        // but since this field is used in the guts, it must be accurate.
+        // Therefore we will only show the application label, or, failing that, the
+        // package name. No substitutions.
+        final String pkg = sbn.getPackageName();
+        String appname = pkg;
+        try {
+            final ApplicationInfo info = pmUser.getApplicationInfo(pkg,
+                    PackageManager.MATCH_UNINSTALLED_PACKAGES
+                            | PackageManager.MATCH_DISABLED_COMPONENTS);
+            if (info != null) {
+                appname = String.valueOf(pmUser.getApplicationLabel(info));
             }
+        } catch (NameNotFoundException e) {
+            // Do nothing
+        }
+        row.setAppName(appname);
+        row.setOnDismissRunnable(() ->
+                performRemoveNotification(row.getStatusBarNotification()));
+        row.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+        if (ENABLE_REMOTE_INPUT) {
+            row.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
         }
+    }
 
+    private void updateNotification(Entry entry, PackageManager pmUser,
+            StatusBarNotification sbn, ExpandableNotificationRow row) {
         row.setNeedsRedaction(needsRedaction(entry));
         boolean isLowPriority = mNotificationData.isAmbient(sbn.getKey());
         row.setIsLowPriority(isLowPriority);
index 5e8b3f9..5e71dd4 100644 (file)
@@ -38,6 +38,7 @@ LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res \
 
 LOCAL_STATIC_ANDROID_LIBRARIES := \
     SystemUIPluginLib \
+    android-support-v4 \
     android-support-v7-recyclerview \
     android-support-v7-preference \
     android-support-v7-appcompat \
index 5e8ea9c..15381b7 100644 (file)
@@ -126,7 +126,7 @@ public class NotificationInflaterTest {
 
     @Test
     public void testAsyncTaskRemoved() throws Exception {
-        mRow.getEntry().abortInflation();
+        mRow.getEntry().abortTask();
         runThenWaitForInflation(() -> mNotificationInflater.inflateNotificationViews(),
                 mNotificationInflater);
         Assert.assertNull(mRow.getEntry().getRunningTask() );