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

Commit f8a28911 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "LightsOut has its own controller"

parents 778380a1 ea2010c1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ import com.android.systemui.statusbar.phone.DozeServiceHost;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -306,6 +307,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
            RemoteInputUriController remoteInputUriController,
            Optional<Divider> dividerOptional,
            SuperStatusBarViewFactory superStatusBarViewFactory,
            LightsOutNotifController lightsOutNotifController,
            /* Car Settings injected components. */
            CarNavigationBarController carNavigationBarController) {
        super(
@@ -376,6 +378,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
                pluginManager,
                remoteInputUriController,
                dividerOptional,
                lightsOutNotifController,
                superStatusBarViewFactory);
        mScrimController = scrimController;
        mCarNavigationBarController = carNavigationBarController;
+3 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ import com.android.systemui.statusbar.phone.DozeServiceHost;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.LightsOutNotifController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -175,6 +176,7 @@ public class CarStatusBarModule {
            RemoteInputUriController remoteInputUriController,
            Optional<Divider> dividerOptional,
            SuperStatusBarViewFactory superStatusBarViewFactory,
            LightsOutNotifController lightsOutNotifController,
            CarNavigationBarController carNavigationBarController) {
        return new CarStatusBar(
                context,
@@ -244,6 +246,7 @@ public class CarStatusBarModule {
                remoteInputUriController,
                dividerOptional,
                superStatusBarViewFactory,
                lightsOutNotifController,
                carNavigationBarController);
    }
}
+179 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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.phone;

import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.view.View;
import android.view.WindowInsetsController;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.view.AppearanceRegion;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * Apps can request a low profile mode {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
 * where status bar and navigation icons dim. In this mode, a notification dot appears
 * where the notification icons would appear if they would be shown outside of this mode.
 *
 * This controller shows and hides the notification dot in the status bar to indicate
 * whether there are notifications when the device is in {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}.
 */
@Singleton
public class LightsOutNotifController {
    private final CommandQueue mCommandQueue;
    private final NotificationEntryManager mEntryManager;
    private final WindowManager mWindowManager;

    /** @see android.view.WindowInsetsController#setSystemBarsAppearance(int) */
    @VisibleForTesting @WindowInsetsController.Appearance int mAppearance;

    private int mDisplayId;
    private View mLightsOutNotifView;

    @Inject
    LightsOutNotifController(WindowManager windowManager,
            NotificationEntryManager entryManager,
            CommandQueue commandQueue) {
        mWindowManager = windowManager;
        mEntryManager = entryManager;
        mCommandQueue = commandQueue;
    }

    /**
     * Sets the notification dot view after it is created in the StatusBar.
     * This is the view this controller will show and hide depending on whether:
     * 1. there are active notifications
     * 2. an app has requested {@link View.SYSTEM_UI_FLAG_LOW_PROFILE}
     */
    void setLightsOutNotifView(View lightsOutNotifView) {
        destroy();
        mLightsOutNotifView = lightsOutNotifView;

        if (mLightsOutNotifView != null) {
            mLightsOutNotifView.setVisibility(View.GONE);
            mLightsOutNotifView.setAlpha(0f);
            init();
        }
    }

    private void destroy() {
        mEntryManager.removeNotificationEntryListener(mEntryListener);
        mCommandQueue.removeCallback(mCallback);
    }

    private void init() {
        mDisplayId = mWindowManager.getDefaultDisplay().getDisplayId();
        mEntryManager.addNotificationEntryListener(mEntryListener);
        mCommandQueue.addCallback(mCallback);

        updateLightsOutView();
    }

    private boolean hasActiveNotifications() {
        return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
    }

    @VisibleForTesting
    void updateLightsOutView() {
        if (mLightsOutNotifView == null) {
            return;
        }

        final boolean showDot = shouldShowDot();
        if (showDot != isShowingDot()) {
            if (showDot) {
                mLightsOutNotifView.setAlpha(0f);
                mLightsOutNotifView.setVisibility(View.VISIBLE);
            }

            mLightsOutNotifView.animate()
                    .alpha(showDot ? 1 : 0)
                    .setDuration(showDot ? 750 : 250)
                    .setInterpolator(new AccelerateInterpolator(2.0f))
                    .setListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationEnd(Animator a) {
                            mLightsOutNotifView.setAlpha(showDot ? 1 : 0);
                            mLightsOutNotifView.setVisibility(showDot ? View.VISIBLE : View.GONE);
                        }
                    })
                    .start();
        }
    }

    @VisibleForTesting
    boolean isShowingDot() {
        return mLightsOutNotifView.getVisibility() == View.VISIBLE
                && mLightsOutNotifView.getAlpha() == 1.0f;
    }

    @VisibleForTesting
    boolean shouldShowDot() {
        return hasActiveNotifications() && areLightsOut();
    }

    @VisibleForTesting
    boolean areLightsOut() {
        return 0 != (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
    }

    private final CommandQueue.Callbacks mCallback = new CommandQueue.Callbacks() {
        @Override
        public void onSystemBarAppearanceChanged(int displayId,
                @WindowInsetsController.Appearance int appearance,
                AppearanceRegion[] appearanceRegions,
                boolean navbarColorManagedByIme) {
            if (displayId != mDisplayId) {
                return;
            }
            mAppearance = appearance;
            updateLightsOutView();
        }
    };

    private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
        // Cares about notifications post-filtering
        @Override
        public void onNotificationAdded(NotificationEntry entry) {
            updateLightsOutView();
        }

        @Override
        public void onPostEntryUpdated(NotificationEntry entry) {
            updateLightsOutView();
        }

        @Override
        public void onEntryRemoved(@Nullable NotificationEntry entry,
                NotificationVisibility visibility, boolean removedByUser) {
            updateLightsOutView();
        }
    };
}
+0 −6
Original line number Diff line number Diff line
@@ -141,12 +141,6 @@ public interface ShadeController {
     */
    void onLaunchAnimationCancelled();

    /**
     * When notifications update, give the shade controller a chance to do thing in response to
     * the new data set
     */
    void updateAreThereNotifications();

    /**
     * Callback to notify the shade controller that a {@link ActivatableNotificationView} has become
     * inactive
+6 −48
Original line number Diff line number Diff line
@@ -47,8 +47,6 @@ import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARE
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_WARNING;
import static com.android.systemui.statusbar.phone.BarTransitions.TransitionMode;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -117,7 +115,6 @@ import android.view.WindowInsetsController.Appearance;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.AccelerateInterpolator;
import android.widget.DateTimeView;

import com.android.internal.annotations.VisibleForTesting;
@@ -399,6 +396,7 @@ public class StatusBar extends SystemUI implements DemoMode,
    private final RemoteInputUriController mRemoteInputUriController;
    private final Optional<Divider> mDividerOptional;
    private final SuperStatusBarViewFactory mSuperStatusBarViewFactory;
    private final LightsOutNotifController mLightsOutNotifController;

    // expanded notifications
    protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -704,6 +702,7 @@ public class StatusBar extends SystemUI implements DemoMode,
            PluginManager pluginManager,
            RemoteInputUriController remoteInputUriController,
            Optional<Divider> dividerOptional,
            LightsOutNotifController lightsOutNotifController,
            SuperStatusBarViewFactory superStatusBarViewFactory) {
        super(context);
        mFeatureFlags = featureFlags;
@@ -774,7 +773,7 @@ public class StatusBar extends SystemUI implements DemoMode,
        mDividerOptional = dividerOptional;

        mSuperStatusBarViewFactory = superStatusBarViewFactory;

        mLightsOutNotifController =  lightsOutNotifController;
        mBubbleExpandListener =
                (isExpanding, key) -> {
                    mEntryManager.updateNotifications("onBubbleExpandChanged");
@@ -928,7 +927,6 @@ public class StatusBar extends SystemUI implements DemoMode,
        mConfigurationController.addCallback(this);

        // set the initial view visibility
        Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
        int disabledFlags1 = result.mDisabledFlags1;
        int disabledFlags2 = result.mDisabledFlags2;
        Dependency.get(InitController.class).addPostInitTask(
@@ -1057,8 +1055,10 @@ public class StatusBar extends SystemUI implements DemoMode,
                            mStatusBarStateController, mKeyguardBypassController,
                            mKeyguardStateController, mWakeUpCoordinator, mCommandQueue);
                    mHeadsUpAppearanceController.readFrom(oldController);

                    mLightsOutNotifController.setLightsOutNotifView(
                            mStatusBarView.findViewById(R.id.notification_lights_out));
                    mStatusBarWindowViewController.setStatusBarView(mStatusBarView);
                    updateAreThereNotifications();
                    checkBarModes();
                }).getFragmentManager()
                .beginTransaction()
@@ -1546,38 +1546,6 @@ public class StatusBar extends SystemUI implements DemoMode,
        }
    }

    public void updateAreThereNotifications() {
        if (SPEW) {
            final boolean clearable = hasActiveNotifications() &&
                    mNotificationPanel.hasActiveClearableNotifications();
            Log.d(TAG, "updateAreThereNotifications: N=" +
                    mEntryManager.getNotificationData().getActiveNotifications().size() + " any=" +
                    hasActiveNotifications() + " clearable=" + clearable);
        }

        if (mStatusBarView != null) {
            final View nlo = mStatusBarView.findViewById(R.id.notification_lights_out);
            final boolean showDot = hasActiveNotifications() && !areLightsOn();
            if (showDot != (nlo.getAlpha() == 1.0f)) {
                if (showDot) {
                    nlo.setAlpha(0f);
                    nlo.setVisibility(View.VISIBLE);
                }
                nlo.animate()
                        .alpha(showDot ? 1 : 0)
                        .setDuration(showDot ? 750 : 250)
                        .setInterpolator(new AccelerateInterpolator(2.0f))
                        .setListener(showDot ? null : new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator _a) {
                                nlo.setVisibility(View.GONE);
                            }
                        })
                        .start();
            }
        }
    }

    private void updateReportRejectedTouchVisibility() {
        if (mReportRejectedTouch == null) {
            return;
@@ -2306,14 +2274,8 @@ public class StatusBar extends SystemUI implements DemoMode,
            return;
        }
        boolean barModeChanged = false;
        final int diff = mAppearance ^ appearance;
        if (mAppearance != appearance) {
            mAppearance = appearance;

            // update low profile
            if ((diff & APPEARANCE_LOW_PROFILE_BARS) != 0) {
                updateAreThereNotifications();
            }
            barModeChanged = updateBarMode(barMode(mTransientShown, appearance));
        }
        mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
@@ -2494,10 +2456,6 @@ public class StatusBar extends SystemUI implements DemoMode,
        return mAppImmersive;
    }

    private boolean areLightsOn() {
        return 0 == (mAppearance & APPEARANCE_LOW_PROFILE_BARS);
    }

    public static String viewInfo(View v) {
        return "[(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom()
                + ") " + v.getWidth() + "x" + v.getHeight() + "]";
Loading