Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f674b60e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Extract NotificationClicker from NEM"

parents 2427aa5e 6e11ed6f
Loading
Loading
Loading
Loading
+104 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 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.
 */
package com.android.systemui.statusbar.notification;

import android.app.Notification;
import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.view.View;

import com.android.systemui.DejankUtils;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.ShadeController;

/**
 * Click handler for generic clicks on notifications. Clicks on specific areas (expansion caret,
 * app ops icon, etc) are handled elsewhere.
 */
public final class NotificationClicker implements View.OnClickListener {
    private static final String TAG = "NotificationClicker";

    private final ShadeController mShadeController;
    private final BubbleController mBubbleController;
    private final NotificationActivityStarter mNotificationActivityStarter;

    public NotificationClicker(ShadeController shadeController,
            BubbleController bubbleController,
            NotificationActivityStarter notificationActivityStarter) {
        mShadeController = shadeController;
        mBubbleController = bubbleController;
        mNotificationActivityStarter = notificationActivityStarter;
    }

    @Override
    public void onClick(final View v) {
        if (!(v instanceof ExpandableNotificationRow)) {
            Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
            return;
        }

        mShadeController.wakeUpIfDozing(SystemClock.uptimeMillis(), v);

        final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
        final StatusBarNotification sbn = row.getStatusBarNotification();
        if (sbn == null) {
            Log.e(TAG, "NotificationClicker called on an unclickable notification,");
            return;
        }

        // Check if the notification is displaying the menu, if so slide notification back
        if (isMenuVisible(row)) {
            row.animateTranslateNotification(0);
            return;
        } else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
            row.getNotificationParent().animateTranslateNotification(0);
            return;
        } else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
            // We never want to open the app directly if the user clicks in between
            // the notifications.
            return;
        }

        // Mark notification for one frame.
        row.setJustClicked(true);
        DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));

        // If it was a bubble we should close it
        if (row.getEntry().isBubble()) {
            mBubbleController.collapseStack();
        }

        mNotificationActivityStarter.onNotificationClicked(sbn, row);
    }

    private boolean isMenuVisible(ExpandableNotificationRow row) {
        return row.getProvider() != null && row.getProvider().isMenuVisible();
    }

    /**
     * Attaches the click listener to the row if appropriate.
     */
    public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
        Notification notification = sbn.getNotification();
        if (notification.contentIntent != null || notification.fullScreenIntent != null) {
            row.setOnClickListener(this);
        } else {
            row.setOnClickListener(null);
        }
    }
}
+7 −68
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */
package com.android.systemui.statusbar.notification;

import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.systemui.bubbles.BubbleController.DEBUG_DEMOTE_TO_NOTIF;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
@@ -36,7 +37,6 @@ import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.service.dreams.DreamService;
@@ -49,7 +49,6 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.android.internal.annotations.VisibleForTesting;
@@ -57,7 +56,6 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.EventLogTags;
@@ -115,7 +113,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
    private final NotificationMessagingUtil mMessagingUtil;
    protected final Context mContext;
    protected final HashMap<String, NotificationData.Entry> mPendingNotifications = new HashMap<>();
    private final NotificationClicker mNotificationClicker = new NotificationClicker();

    private final NotificationGroupManager mGroupManager =
            Dependency.get(NotificationGroupManager.class);
@@ -146,7 +143,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
    protected IStatusBarService mBarService;
    private NotificationPresenter mPresenter;
    private Callback mCallback;
    private NotificationActivityStarter mNotificationActivityStarter;
    protected PowerManager mPowerManager;
    private NotificationListenerService.RankingMap mLatestRankingMap;
    protected HeadsUpManager mHeadsUpManager;
@@ -161,63 +157,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
    private ExpandableNotificationRow.OnAppOpsClickListener mOnAppOpsClickListener;
    private NotificationViewHierarchyManager.StatusBarStateListener mStatusBarStateListener;
    @Nullable private AlertTransferListener mAlertTransferListener;

    private final class NotificationClicker implements View.OnClickListener {

        @Override
        public void onClick(final View v) {
            if (!(v instanceof ExpandableNotificationRow)) {
                Log.e(TAG, "NotificationClicker called on a view that is not a notification row.");
                return;
            }

            getShadeController().wakeUpIfDozing(SystemClock.uptimeMillis(), v);

            final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
            final StatusBarNotification sbn = row.getStatusBarNotification();
            if (sbn == null) {
                Log.e(TAG, "NotificationClicker called on an unclickable notification,");
                return;
            }

            // Check if the notification is displaying the menu, if so slide notification back
            if (isMenuVisible(row)) {
                row.animateTranslateNotification(0);
                return;
            } else if (row.isChildInGroup() && isMenuVisible(row.getNotificationParent())) {
                row.getNotificationParent().animateTranslateNotification(0);
                return;
            } else if (row.isSummaryWithChildren() && row.areChildrenExpanded()) {
                // We never want to open the app directly if the user clicks in between
                // the notifications.
                return;
            }

            // Mark notification for one frame.
            row.setJustClicked(true);
            DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));

            // If it was a bubble we should close it
            if (row.getEntry().isBubble()) {
                mBubbleController.collapseStack();
            }

            mNotificationActivityStarter.onNotificationClicked(sbn, row);
        }

        private boolean isMenuVisible(ExpandableNotificationRow row) {
            return row.getProvider() != null && row.getProvider().isMenuVisible();
        }

        public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
            Notification notification = sbn.getNotification();
            if (notification.contentIntent != null || notification.fullScreenIntent != null) {
                row.setOnClickListener(this);
            } else {
                row.setOnClickListener(null);
            }
        }
    }
    @Nullable private NotificationClicker mNotificationClicker;

    private final DeviceProvisionedController.DeviceProvisionedListener
            mDeviceProvisionedListener =
@@ -269,6 +209,10 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        mAlertTransferListener = listener;
    }

    public void setNotificationClicker(NotificationClicker clicker) {
        mNotificationClicker = clicker;
    }

    /**
     * Our dependencies can have cyclic references, so some need to be lazy
     */
@@ -355,11 +299,6 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        mOnAppOpsClickListener = mGutsManager::openGuts;
    }

    public void setNotificationActivityStarter(
            NotificationActivityStarter notificationActivityStarter) {
        mNotificationActivityStarter = notificationActivityStarter;
    }

    public NotificationData getNotificationData() {
        return mNotificationData;
    }
@@ -757,7 +696,7 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater.
        row.setIsLowPriority(isLowPriority);
        row.setLowPriorityStateUpdated(isUpdate && (wasLowPriority != isLowPriority));
        // bind the click event to the content area
        mNotificationClicker.register(row, sbn);
        checkNotNull(mNotificationClicker).register(row, sbn);

        // Extract target SDK version.
        try {
+6 −4
Original line number Diff line number Diff line
@@ -187,6 +187,7 @@ import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationClicker;
import com.android.systemui.statusbar.notification.NotificationData;
import com.android.systemui.statusbar.notification.NotificationData.Entry;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -630,8 +631,6 @@ public class StatusBar extends SystemUI implements DemoMode,
        mBubbleController = Dependency.get(BubbleController.class);
        mBubbleController.setExpandListener(mBubbleExpandListener);

        mGroupAlertTransferHelper.bind(mEntryManager, mGroupManager);

        mColorExtractor.addOnColorsChangedListener(this);
        mStatusBarStateController.addCallback(this, StatusBarStateController.RANK_STATUS_BAR);

@@ -1018,7 +1017,7 @@ public class StatusBar extends SystemUI implements DemoMode,
        return new QSFragment();
    }

    protected void setUpPresenter() {
    private void setUpPresenter() {
        // Set up the initial notification state.
        mActivityLaunchAnimator = new ActivityLaunchAnimator(
                mStatusBarWindow, this, mNotificationPanel,
@@ -1036,7 +1035,10 @@ public class StatusBar extends SystemUI implements DemoMode,
        mNotificationActivityStarter = new StatusBarNotificationActivityStarter(
                mContext, mNotificationPanel, mPresenter, mHeadsUpManager, mActivityLaunchAnimator);
        mGutsManager.setNotificationActivityStarter(mNotificationActivityStarter);
        mEntryManager.setNotificationActivityStarter(mNotificationActivityStarter);

        mGroupAlertTransferHelper.bind(mEntryManager, mGroupManager);
        mEntryManager.setNotificationClicker(new NotificationClicker(
                this, Dependency.get(BubbleController.class), mNotificationActivityStarter));
    }

    /**
+1 −0
Original line number Diff line number Diff line
@@ -231,6 +231,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
        mEntryManager = new TestableNotificationEntryManager(mContext, mBarService);
        Dependency.get(InitController.class).executePostInitTasks();
        mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mCallback, mHeadsUpManager);
        mEntryManager.setNotificationClicker(mock(NotificationClicker.class));

        setUserSentiment(mEntry.key, NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL);
    }