/*
 * 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.car;

import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarUxRestrictionsManager;
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
import android.car.media.CarAudioManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.media.AudioManager;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.WindowManager;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.android.car.notification.CarHeadsUpNotificationManager;
import com.android.car.notification.CarNotificationListener;
import com.android.car.notification.CarNotificationView;
import com.android.car.notification.CarUxRestrictionManagerWrapper;
import com.android.car.notification.HeadsUpEntry;
import com.android.car.notification.NotificationClickHandlerFactory;
import com.android.car.notification.NotificationDataManager;
import com.android.car.notification.NotificationViewController;
import com.android.car.notification.PreprocessingManager;
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.CarSystemUIFactory;
import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.car.SUWProgressController;
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.car.CarQSFragment;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.car.hvac.HvacController;
import com.android.systemui.statusbar.car.hvac.TemperatureView;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.phone.AutoHideElement;
import com.android.systemui.statusbar.phone.BarTransitions;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.LightBarController;
import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.volume.VolumeUI;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;

/**
 * A status bar (and navigation bar) tailored for the automotive use case.
 */
public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler {
    private static final String TAG = "CarStatusBar";
    private static final int MODE_INVALID = -1;
    // used to calculate how fast to open or close the window
    private static final float DEFAULT_FLING_VELOCITY = 0;
    // max time a fling animation takes
    private static final float FLING_ANIMATION_MAX_TIME = 0.5f;
    // acceleration rate for the fling animation
    private static final float FLING_SPEED_UP_FACTOR = 0.6f;

    private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
    private float mClosingVelocity = DEFAULT_FLING_VELOCITY;

    private float mBackgroundAlphaDiff;
    private float mInitialBackgroundAlpha;

    private TaskStackListenerImpl mTaskStackListener;

    private FullscreenUserSwitcher mFullscreenUserSwitcher;

    private CarBatteryController mCarBatteryController;
    private BatteryMeterView mBatteryMeterView;
    private Drawable mNotificationPanelBackground;

    private ViewGroup mTopNavigationBarContainer;
    private ViewGroup mNavigationBarWindow;
    private ViewGroup mLeftNavigationBarWindow;
    private ViewGroup mRightNavigationBarWindow;
    private CarNavigationBarView mTopNavigationBarView;
    private CarNavigationBarView mNavigationBarView;
    private CarNavigationBarView mLeftNavigationBarView;
    private CarNavigationBarView mRightNavigationBarView;

    private final Object mQueueLock = new Object();
    private boolean mShowLeft;
    private boolean mShowRight;
    private boolean mShowBottom;
    private CarFacetButtonController mCarFacetButtonController;
    private ActivityManagerWrapper mActivityManagerWrapper;
    private DeviceProvisionedController mDeviceProvisionedController;
    private SUWProgressController mSUWProgressController;
    private boolean mDeviceIsSetUpForUser = true;
    private boolean mIsUserSetupInProgress = false;
    private HvacController mHvacController;
    private DrivingStateHelper mDrivingStateHelper;
    private PowerManagerHelper mPowerManagerHelper;
    private FlingAnimationUtils mFlingAnimationUtils;
    private SwitchToGuestTimer mSwitchToGuestTimer;
    private NotificationDataManager mNotificationDataManager;
    private CarNotificationListener mCarNotificationListener;
    private NotificationClickHandlerFactory mNotificationClickHandlerFactory;
    private ScreenLifecycle mScreenLifecycle;
    private CarAudioManager mCarAudioManager;
    private VolumeUI mVolumeUI;

    // The container for the notifications.
    private CarNotificationView mNotificationView;
    private RecyclerView mNotificationList;
    // The handler bar view at the bottom of notification shade.
    private View mHandleBar;
    // The controller for the notification view.
    private NotificationViewController mNotificationViewController;
    // The state of if the notification list is currently showing the bottom.
    private boolean mNotificationListAtBottom;
    // Was the notification list at the bottom when the user first touched the screen
    private boolean mNotificationListAtBottomAtTimeOfTouch;
    // To be attached to the top navigation bar (i.e. status bar) to pull down the notification
    // panel.
    private View.OnTouchListener mTopNavBarNotificationTouchListener;
    // To be attached to the navigation bars such that they can close the notification panel if
    // it's open.
    private View.OnTouchListener mNavBarNotificationTouchListener;

    // Percentage from top of the screen after which the notification shade will open. This value
    // will be used while opening the notification shade.
    private int mSettleOpenPercentage;
    // Percentage from top of the screen below which the notification shade will close. This
    // value will be used while closing the notification shade.
    private int mSettleClosePercentage;
    // Percentage of notification shade open from top of the screen.
    private int mPercentageFromBottom;
    // If notification shade is animation to close or to open.
    private boolean mIsNotificationAnimating;

    // Tracks when the notification shade is being scrolled. This refers to the glass pane being
    // scrolled not the recycler view.
    private boolean mIsTracking;
    private float mFirstTouchDownOnGlassPane;

    // If the notification card inside the recycler view is being swiped.
    private boolean mIsNotificationCardSwiping;
    // If notification shade is being swiped vertically to close.
    private boolean mIsSwipingVerticallyToClose;
    // Whether heads-up notifications should be shown when shade is open.
    private boolean mEnableHeadsUpNotificationWhenNotificationShadeOpen;
    // If the nav bar should be hidden when the soft keyboard is visible.
    private boolean mHideNavBarForKeyboard;
    private boolean mBottomNavBarVisible;

    private CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper;

    private final CarPowerStateListener mCarPowerStateListener =
            (int state) -> {
                // When the car powers on, clear all notifications and mute/unread states.
                Log.d(TAG, "New car power state: " + state);
                if (state == CarPowerStateListener.ON) {
                    if (mNotificationClickHandlerFactory != null) {
                        mNotificationClickHandlerFactory.clearAllNotifications();
                    }
                    if (mNotificationDataManager != null) {
                        mNotificationDataManager.clearAll();
                    }
                }
            };

    private final CarAudioManager.CarVolumeCallback mVolumeChangeCallback =
            new CarAudioManager.CarVolumeCallback() {
                @Override
                public void onGroupVolumeChanged(int zoneId, int groupId, int flags) {
                    if (mVolumeUI == null && (flags & AudioManager.FLAG_SHOW_UI) != 0) {
                        new Handler(Looper.getMainLooper()).post(() -> {
                            // Initialize Volume UI
                            mVolumeUI = new VolumeUI();
                            mVolumeUI.mComponents = mComponents;
                            mVolumeUI.mContext = mContext;
                            mVolumeUI.start();
                        });
                        mCarAudioManager.unregisterCarVolumeCallback(mVolumeChangeCallback);
                    }
                }

                @Override
                public void onMasterMuteChanged(int zoneId, int flags) {
                    // ignored
                }
            };

    private boolean mBootCompleted = false;
    private final BroadcastReceiver mBootCompletedReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            mBootCompleted = true;
            String action = intent.getAction();
            if (action != null && action.equals(Intent.ACTION_BOOT_COMPLETED)) {
                initHvac();
            }
        }
    };

    private int mNavigationBarMode;
    private BarTransitions mNavBarTransitions;

    @Override
    public void start() {
        // Non blocking call to connect to car service. Call this early so that we'll be connected
        // asap.
        ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext);

        // Defer some actions for CarStatusBar initialization until after boot complete event
        registerBootCompletedReceiver();

        // get the provisioned state before calling the parent class since it's that flow that
        // builds the nav bar
        mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
        mSUWProgressController = new SUWProgressController(mContext);
        mDeviceIsSetUpForUser = mDeviceProvisionedController.isCurrentUserSetup();
        mIsUserSetupInProgress = mSUWProgressController.isCurrentUserSetupInProgress();

        // Keyboard related setup, before nav bars are created.
        mHideNavBarForKeyboard = mContext.getResources().getBoolean(
                com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
        mBottomNavBarVisible = false;

        // Need to initialize screen lifecycle before calling super.start - before switcher is
        // created.
        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
        mScreenLifecycle.addObserver(mScreenObserver);

        // Need to initialize HVAC controller before calling super.start - before system bars are
        // created.
        mHvacController = new HvacController(mContext);

      	// Notification bar related setup.
        mInitialBackgroundAlpha = (float) mContext.getResources().getInteger(
            R.integer.config_initialNotificationBackgroundAlpha) / 100;
        if (mInitialBackgroundAlpha < 0 || mInitialBackgroundAlpha > 100) {
            throw new RuntimeException(
              "Unable to setup notification bar due to incorrect initial background alpha"
                      + " percentage");
        }
        float finalBackgroundAlpha = Math.max(
            mInitialBackgroundAlpha,
            (float) mContext.getResources().getInteger(
                R.integer.config_finalNotificationBackgroundAlpha) / 100);
        if (finalBackgroundAlpha < 0 || finalBackgroundAlpha > 100) {
            throw new RuntimeException(
              "Unable to setup notification bar due to incorrect final background alpha"
                      + " percentage");
        }
        mBackgroundAlphaDiff = finalBackgroundAlpha - mInitialBackgroundAlpha;

        super.start();
        mTaskStackListener = new TaskStackListenerImpl();
        mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
        mActivityManagerWrapper.registerTaskStackListener(mTaskStackListener);

        mNotificationPanel.setScrollingEnabled(true);
        mSettleOpenPercentage = mContext.getResources().getInteger(
                R.integer.notification_settle_open_percentage);
        mSettleClosePercentage = mContext.getResources().getInteger(
                R.integer.notification_settle_close_percentage);
        mFlingAnimationUtils = new FlingAnimationUtils(mContext,
                FLING_ANIMATION_MAX_TIME, FLING_SPEED_UP_FACTOR);

        createBatteryController();
        mCarBatteryController.startListening();

        mHvacController.connectToCarService();

        mSUWProgressController.addCallback(
                new SUWProgressController.SUWProgressListener() {
                    @Override
                    public void onUserSetupInProgressChanged() {
                        mHandler.post(() -> restartNavBarsIfNecessary());
                    }
                });
        mDeviceProvisionedController.addCallback(
                new DeviceProvisionedController.DeviceProvisionedListener() {
                    @Override
                    public void onUserSetupChanged() {
                        mHandler.post(() -> restartNavBarsIfNecessary());
                    }

                    @Override
                    public void onUserSwitched() {
                        mSUWProgressController.onUserSwitched();
                        mHandler.post(() -> restartNavBarsIfNecessary());
                    }
                });

        // Used by onDrivingStateChanged and it can be called inside
        // DrivingStateHelper.connectToCarService()
        mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);

        // Register a listener for driving state changes.
        mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
        mDrivingStateHelper.connectToCarService();

        mPowerManagerHelper = new PowerManagerHelper(mContext, mCarPowerStateListener);
        mPowerManagerHelper.connectToCarService();

        ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext)
                .addListener((car, ready) -> {
                    if (!ready || mCarAudioManager != null) {
                        return;
                    }
                    try {
                        mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
                        Log.d(TAG, "Registering mVolumeChangeCallback.");
                        // This volume call back is never unregistered because CarStatusBar is
                        // never destroyed.
                        mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
                    } catch (CarNotConnectedException e) {
                        Log.wtf(TAG, " mVolumeChangeCallback failed to connect to car ", e);
                    }
                });

        mAutoHideController.setNavigationBar(new AutoHideElement() {
            @Override
            public void synchronizeState() {
                checkNavBarModes();
            }

            @Override
            public boolean isSemiTransparent() {
                return mNavigationBarMode == MODE_SEMI_TRANSPARENT;
            }
        });
    }

    @Override
    protected void getDependencies() {
        // Keyguard
        mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
        mWakefulnessLifecycle = Dependency.get(WakefulnessLifecycle.class);
        mScreenLifecycle = Dependency.get(ScreenLifecycle.class);

        // Policy
        mZenController = Dependency.get(ZenModeController.class);
        if (Build.IS_USERDEBUG) {
            mNetworkController = Dependency.get(NetworkController.class);
        }

        // Icon
        mIconController = Dependency.get(StatusBarIconController.class);
        mLightBarController = Dependency.get(LightBarController.class);

        // Notifications
        mEntryManager = Dependency.get(NotificationEntryManager.class);
        mForegroundServiceController = Dependency.get(ForegroundServiceController.class);
        mGroupAlertTransferHelper = Dependency.get(NotificationGroupAlertTransferHelper.class);
        mGroupManager = Dependency.get(NotificationGroupManager.class);
        mGutsManager = Dependency.get(NotificationGutsManager.class);
        mLockscreenUserManager = Dependency.get(NotificationLockscreenUserManager.class);
        mMediaManager = Dependency.get(NotificationMediaManager.class);
        mNotificationListener = Dependency.get(NotificationListener.class);
        mNotificationLogger = Dependency.get(NotificationLogger.class);
        mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
        mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
        mVisualStabilityManager = Dependency.get(VisualStabilityManager.class);

        // Others
        mColorExtractor = Dependency.get(SysuiColorExtractor.class);
        mNavigationBarController = Dependency.get(NavigationBarController.class);
        mUserSwitcherController = Dependency.get(UserSwitcherController.class);
    }

    @Override
    public void setSystemUiVisibility(int displayId, int vis, int fullscreenStackVis,
            int dockedStackVis, int mask, Rect fullscreenStackBounds, Rect dockedStackBounds,
            boolean navbarColorManagedByIme) {
        // Ensure we store the systemUiVisibility flags before the super call overwrites it.
        int oldVal = getSystemUiVisibility();

        super.setSystemUiVisibility(displayId, vis, fullscreenStackVis, dockedStackVis, mask,
                fullscreenStackBounds, dockedStackBounds, navbarColorManagedByIme);

        if (displayId != getDisplayId()) {
            return;
        }

        int newVal = (oldVal & ~mask) | (vis & mask);

        // update navigation bar mode
        int nbMode = mNavigationBarWindow == null ? MODE_INVALID : computeNavBarMode(oldVal,
                newVal);
        boolean nbModeChanged = nbMode != MODE_INVALID;
        if (nbModeChanged) {
            if (mNavigationBarMode != nbMode) {
                mNavigationBarMode = nbMode;
                checkNavBarModes();
            }
            mAutoHideController.touchAutoHide();
        }

        mLightBarController.onNavigationVisibilityChanged(
                vis, mask, nbModeChanged, mNavigationBarMode, navbarColorManagedByIme);
    }

    @BarTransitions.TransitionMode
    private int computeNavBarMode(int oldVis, int newVis) {
        int oldMode = navBarMode(oldVis);
        int newMode = navBarMode(newVis);
        if (oldMode == newMode) {
            return -1; // no mode change
        }
        return newMode;
    }

    @BarTransitions.TransitionMode
    private int navBarMode(int vis) {
        if ((vis & View.NAVIGATION_BAR_TRANSIENT) != 0) {
            return MODE_SEMI_TRANSPARENT;
        } else {
            return MODE_OPAQUE;
        }
    }

    /**
     * Checks current navigation bar mode and make transitions.
     */
    private void checkNavBarModes() {
        boolean anim = isDeviceInteractive() && mBottomNavBarVisible;
        mNavBarTransitions.transitionTo(mNavigationBarMode, anim);
    }

    @Override
    protected void setUpQuickSettingsTilePanel() {
        // ignore.
    }

    private void registerBootCompletedReceiver() {
        IntentFilter bootCompletedFilter = new IntentFilter(Intent.ACTION_BOOT_COMPLETED);
        bootCompletedFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        mContext.registerReceiver(mBootCompletedReceiver, bootCompletedFilter);
    }

    private void unregisterBootCompletedListener() {
        mContext.unregisterReceiver(mBootCompletedReceiver);
    }

    private void restartNavBarsIfNecessary() {
        boolean currentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
        boolean currentUserSetupInProgress = mSUWProgressController.isCurrentUserSetupInProgress();
        if (mIsUserSetupInProgress != currentUserSetupInProgress
                || mDeviceIsSetUpForUser != currentUserSetup) {
            mDeviceIsSetUpForUser = currentUserSetup;
            mIsUserSetupInProgress = currentUserSetupInProgress;
            restartNavBars();
        }
    }

    /**
     * Remove all content from navbars and rebuild them. Used to allow for different nav bars
     * before and after the device is provisioned. . Also for change of density and font size.
     */
    private void restartNavBars() {
        // remove and reattach all hvac components such that we don't keep a reference to unused
        // ui elements
        if (mHvacController != null) {
            mHvacController.removeAllComponents();
        }
        mCarFacetButtonController.removeAll();

        if (mNavigationBarWindow != null) {
            mNavigationBarWindow.removeAllViews();
            mNavigationBarView = null;
        }

        if (mLeftNavigationBarWindow != null) {
            mLeftNavigationBarWindow.removeAllViews();
            mLeftNavigationBarView = null;
        }

        if (mRightNavigationBarWindow != null) {
            mRightNavigationBarWindow.removeAllViews();
            mRightNavigationBarView = null;
        }

        buildNavBarContent();
        if (mBootCompleted) {
            initHvac();
        }
        // If the UI was rebuilt (day/night change) while the keyguard was up we need to
        // correctly respect that state.
        if (mIsKeyguard) {
            updateNavBarForKeyguardContent();
        }
        // CarFacetButtonController was reset therefore we need to re-add the status bar elements
        // to the controller.
        mCarFacetButtonController.addAllFacetButtons(mStatusBarWindow);

        // Upon restarting the Navigation Bar, CarFacetButtonController should immediately apply the
        // selection state that reflects the current task stack.
        try {
            mCarFacetButtonController.taskChanged(
                    ActivityTaskManager.getService().getAllStackInfos());
        } catch (Exception e) {
            Log.e(TAG, "Getting StackInfo from activity manager failed", e);
        }
    }

    private void addTemperatureViewToController(View v) {
        if (v == null) return;

        if (v instanceof TemperatureView) {
            mHvacController.addHvacTextView((TemperatureView) v);
        } else if (v instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) v;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                addTemperatureViewToController(viewGroup.getChildAt(i));
            }
        }
    }
    /**
     * Allows for showing or hiding just the navigation bars. This is indented to be used when
     * the full screen user selector is shown.
     */
    void setNavBarVisibility(@View.Visibility int visibility) {
        if (mNavigationBarWindow != null) {
            mNavigationBarWindow.setVisibility(visibility);
        }
        if (mLeftNavigationBarWindow != null) {
            mLeftNavigationBarWindow.setVisibility(visibility);
        }
        if (mRightNavigationBarWindow != null) {
            mRightNavigationBarWindow.setVisibility(visibility);
        }
    }


    @Override
    public boolean hideKeyguard() {
        boolean result = super.hideKeyguard();
        if (mNavigationBarView != null) {
            mNavigationBarView.hideKeyguardButtons();
        }
        if (mLeftNavigationBarView != null) {
            mLeftNavigationBarView.hideKeyguardButtons();
        }
        if (mRightNavigationBarView != null) {
            mRightNavigationBarView.hideKeyguardButtons();
        }
        return result;
    }

    @Override
    public void showKeyguard() {
        super.showKeyguard();
        updateNavBarForKeyguardContent();
    }

    /**
     * Switch to the keyguard applicable content contained in the nav bars
     */
    private void updateNavBarForKeyguardContent() {
        if (mNavigationBarView != null) {
            mNavigationBarView.showKeyguardButtons();
        }
        if (mLeftNavigationBarView != null) {
            mLeftNavigationBarView.showKeyguardButtons();
        }
        if (mRightNavigationBarView != null) {
            mRightNavigationBarView.showKeyguardButtons();
        }
    }

    @Override
    protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
        super.makeStatusBarView(result);

        CarSystemUIFactory factory = SystemUIFactory.getInstance();
        mCarFacetButtonController = factory.getCarDependencyComponent()
                .getCarFacetButtonController();
        mNotificationPanelBackground = getDefaultWallpaper();
        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);

        FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
        manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
            mBatteryMeterView = fragment.getView().findViewById(R.id.battery);

            // By default, the BatteryMeterView should not be visible. It will be toggled
            // when a device has connected by bluetooth.
            mBatteryMeterView.setVisibility(View.GONE);
        });

        connectNotificationsUI();
    }

    /**
     * Attach the notification listeners and controllers to the UI as well as build all the
     * touch listeners needed for opening and closing the notification panel
     */
    private void connectNotificationsUI() {
        // Attached to the top navigation bar (i.e. status bar) to detect pull down of the
        // notification shade.
        GestureDetector openGestureDetector = new GestureDetector(mContext,
                new OpenNotificationGestureListener() {
                    @Override
                    protected void openNotification() {
                        animateExpandNotificationsPanel();
                    }
                });
        // Attached to the notification ui to detect close request of the notification shade.
        GestureDetector closeGestureDetector = new GestureDetector(mContext,
                new CloseNotificationGestureListener() {
                    @Override
                    protected void close() {
                        if (mPanelExpanded) {
                            animateCollapsePanels();
                        }
                    }
                });
        // Attached to the NavBars to close the notification shade
        GestureDetector navBarCloseNotificationGestureDetector = new GestureDetector(mContext,
                new NavBarCloseNotificationGestureListener() {
                    @Override
                    protected void close() {
                        if (mPanelExpanded) {
                            animateCollapsePanels();
                        }
                    }
                });

        // Attached to the Handle bar to close the notification shade
        GestureDetector handleBarCloseNotificationGestureDetector = new GestureDetector(mContext,
                new HandleBarCloseNotificationGestureListener());

        mTopNavBarNotificationTouchListener = (v, event) -> {
            if (!mDeviceIsSetUpForUser || mIsUserSetupInProgress) {
                return true;
            }
            boolean consumed = openGestureDetector.onTouchEvent(event);
            if (consumed) {
                return true;
            }
            maybeCompleteAnimation(event);
            return true;
        };

        mNavBarNotificationTouchListener =
                (v, event) -> {
                    boolean consumed = navBarCloseNotificationGestureDetector.onTouchEvent(event);
                    if (consumed) {
                        return true;
                    }
                    maybeCompleteAnimation(event);
                    return true;
                };

        mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(
                mBarService,
                launchResult -> {
                    if (launchResult == ActivityManager.START_TASK_TO_FRONT
                            || launchResult == ActivityManager.START_SUCCESS) {
                        animateCollapsePanels();
                    }
                });

        mCarUxRestrictionManagerWrapper = new CarUxRestrictionManagerWrapper();

        if (mCarNotificationListener == null) {
            // Only make and register a listener if we don't already have one since
            // #connectNotificationsUI can be called multiple times on locale change.
            mCarNotificationListener = new CarNotificationListener();
            mNotificationDataManager = new NotificationDataManager();

            CarHeadsUpNotificationManager carHeadsUpNotificationManager =
                    new CarSystemUIHeadsUpNotificationManager(mContext,
                            mNotificationClickHandlerFactory, mNotificationDataManager);
            mCarNotificationListener.registerAsSystemService(mContext,
                    mCarUxRestrictionManagerWrapper,
                    carHeadsUpNotificationManager, mNotificationDataManager);
        }

        mNotificationDataManager.setOnUnseenCountUpdateListener(() -> {
            if (mNavigationBarView != null && mNotificationDataManager != null) {
                onUseenCountUpdate(mNotificationDataManager.getUnseenNotificationCount());
            }
        });

        mEnableHeadsUpNotificationWhenNotificationShadeOpen = mContext.getResources().getBoolean(
                R.bool.config_enableHeadsUpNotificationWhenNotificationShadeOpen);

        mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager);

        mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view);
        View glassPane = mStatusBarWindow.findViewById(R.id.glass_pane);
        mHandleBar = mStatusBarWindow.findViewById(R.id.handle_bar);
        mNotificationView.setClickHandlerFactory(mNotificationClickHandlerFactory);
        mNotificationView.setNotificationDataManager(mNotificationDataManager);

        // The glass pane is used to view touch events before passed to the notification list.
        // This allows us to initialize gesture listeners and detect when to close the notifications
        glassPane.setOnTouchListener((v, event) -> {
            if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                mNotificationListAtBottomAtTimeOfTouch = false;
            }
            if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
                mFirstTouchDownOnGlassPane = event.getRawX();
                mNotificationListAtBottomAtTimeOfTouch = mNotificationListAtBottom;
                // Reset the tracker when there is a touch down on the glass pane.
                mIsTracking = false;
                // Pass the down event to gesture detector so that it knows where the touch event
                // started.
                closeGestureDetector.onTouchEvent(event);
            }
            return false;
        });

        mHandleBar.setOnTouchListener((v, event) -> {
            handleBarCloseNotificationGestureDetector.onTouchEvent(event);
            maybeCompleteAnimation(event);
            return true;
        });

        mNotificationList = mNotificationView.findViewById(R.id.notifications);
        mNotificationList.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (!mNotificationList.canScrollVertically(1)) {
                    mNotificationListAtBottom = true;
                    return;
                }
                mNotificationListAtBottom = false;
                mIsSwipingVerticallyToClose = false;
                mNotificationListAtBottomAtTimeOfTouch = false;
            }
        });
        mNotificationList.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                mIsNotificationCardSwiping = Math.abs(mFirstTouchDownOnGlassPane - event.getRawX())
                        > SWIPE_MAX_OFF_PATH;
                if (mNotificationListAtBottomAtTimeOfTouch && mNotificationListAtBottom) {
                    // We need to save the state here as if notification card is swiping we will
                    // change the mNotificationListAtBottomAtTimeOfTouch. This is to protect
                    // closing the notification shade while the notification card is being swiped.
                    mIsSwipingVerticallyToClose = true;
                }

                // If the card is swiping we should not allow the notification shade to close.
                // Hence setting mNotificationListAtBottomAtTimeOfTouch to false will stop that
                // for us. We are also checking for mIsTracking because while swiping the
                // notification shade to close if the user goes a bit horizontal while swiping
                // upwards then also this should close.
                if (mIsNotificationCardSwiping && !mIsTracking) {
                    mNotificationListAtBottomAtTimeOfTouch = false;
                }

                boolean handled = closeGestureDetector.onTouchEvent(event);
                boolean isTracking = mIsTracking;
                Rect rect = mNotificationView.getClipBounds();
                float clippedHeight = 0;
                if (rect != null) {
                    clippedHeight = rect.bottom;
                }
                if (!handled && event.getActionMasked() == MotionEvent.ACTION_UP
                        && mIsSwipingVerticallyToClose) {
                    if (mSettleClosePercentage < mPercentageFromBottom && isTracking) {
                        animateNotificationPanel(DEFAULT_FLING_VELOCITY, false);
                    } else if (clippedHeight != mNotificationView.getHeight() && isTracking) {
                        // this can be caused when user is at the end of the list and trying to
                        // fling to top of the list by scrolling down.
                        animateNotificationPanel(DEFAULT_FLING_VELOCITY, true);
                    }
                }

                // Updating the mNotificationListAtBottomAtTimeOfTouch state has to be done after
                // the event has been passed to the closeGestureDetector above, such that the
                // closeGestureDetector sees the up event before the state has changed.
                if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                    mNotificationListAtBottomAtTimeOfTouch = false;
                }
                return handled || isTracking;
            }
        });
        ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext)
                .addListener((car, ready) -> {
                    if (!ready) {
                        return;
                    }
                    CarUxRestrictionsManager carUxRestrictionsManager =
                            (CarUxRestrictionsManager)
                                    car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
                    mCarUxRestrictionManagerWrapper.setCarUxRestrictionsManager(
                            carUxRestrictionsManager);

                    mNotificationViewController = new NotificationViewController(
                            mNotificationView,
                            PreprocessingManager.getInstance(mContext),
                            mCarNotificationListener,
                            mCarUxRestrictionManagerWrapper,
                            mNotificationDataManager);
                    mNotificationViewController.enable();
                });
    }

    /**
     * This method is automatically called whenever there is an update to the number of unseen
     * notifications. This method can be extended by OEMs to customize the desired logic.
     */
    protected void onUseenCountUpdate(int unseenNotificationCount) {
        boolean hasUnseen = unseenNotificationCount > 0;

        if (mNavigationBarView != null) {
            mNavigationBarView.toggleNotificationUnseenIndicator(hasUnseen);
        }

        if (mLeftNavigationBarView != null) {
            mLeftNavigationBarView.toggleNotificationUnseenIndicator(hasUnseen);
        }

        if (mRightNavigationBarView != null) {
            mRightNavigationBarView.toggleNotificationUnseenIndicator(hasUnseen);
        }
    }

    /**
     * @return true if the notification panel is currently visible
     */
    boolean isNotificationPanelOpen() {
        return mPanelExpanded;
    }

    @Override
    public void animateExpandNotificationsPanel() {
        if (!mCommandQueue.panelsEnabled() || !mUserSetup) {
            return;
        }
        // scroll to top
        mNotificationList.scrollToPosition(0);
        mStatusBarWindowController.setPanelVisible(true);
        mNotificationView.setVisibility(View.VISIBLE);
        animateNotificationPanel(mOpeningVelocity, false);

        setPanelExpanded(true);
    }

    @Override
    public void animateCollapsePanels(int flags, boolean force, boolean delayed,
            float speedUpFactor) {
        super.animateCollapsePanels(flags, force, delayed, speedUpFactor);
        if (!mPanelExpanded || mNotificationView.getVisibility() == View.INVISIBLE) {
            return;
        }
        mStatusBarWindowController.setStatusBarFocusable(false);
        mStatusBarWindow.cancelExpandHelper();
        mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);

        animateNotificationPanel(mClosingVelocity, true);

        if (!mIsTracking) {
            mStatusBarWindowController.setPanelVisible(false);
            mNotificationView.setVisibility(View.INVISIBLE);
        }

        setPanelExpanded(false);
    }

    private void maybeCompleteAnimation(MotionEvent event) {
        if (event.getActionMasked() == MotionEvent.ACTION_UP
                && mNotificationView.getVisibility() == View.VISIBLE) {
            if (mSettleClosePercentage < mPercentageFromBottom) {
                animateNotificationPanel(DEFAULT_FLING_VELOCITY, false);
            } else {
                animateNotificationPanel(DEFAULT_FLING_VELOCITY, true);
            }
        }
    }

    /**
     * Animates the notification shade from one position to other. This is used to either open or
     * close the notification shade completely with a velocity. If the animation is to close the
     * notification shade this method also makes the view invisible after animation ends.
     */
    private void animateNotificationPanel(float velocity, boolean isClosing) {
        float to = 0;
        if (!isClosing) {
            to = mNotificationView.getHeight();
        }

        Rect rect = mNotificationView.getClipBounds();
        if (rect != null) {
            float from = rect.bottom;
            animate(from, to, velocity, isClosing);
            return;
        }

        // We will only be here if the shade is being opened programmatically.
        ViewTreeObserver notificationTreeObserver = mNotificationView.getViewTreeObserver();
        notificationTreeObserver.addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        ViewTreeObserver obs = mNotificationView.getViewTreeObserver();
                        obs.removeOnGlobalLayoutListener(this);
                        float to = mNotificationView.getHeight();
                        animate(/* from= */ 0, to, velocity, isClosing);
                    }
                });
    }

    private void animate(float from, float to, float velocity, boolean isClosing) {
        if (mIsNotificationAnimating) {
            return;
        }
        mIsNotificationAnimating = true;
        mIsTracking = true;
        ValueAnimator animator = ValueAnimator.ofFloat(from, to);
        animator.addUpdateListener(
                animation -> {
                    float animatedValue = (Float) animation.getAnimatedValue();
                    setNotificationViewClipBounds((int) animatedValue);
                });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mIsNotificationAnimating = false;
                mIsTracking = false;
                mOpeningVelocity = DEFAULT_FLING_VELOCITY;
                mClosingVelocity = DEFAULT_FLING_VELOCITY;
                if (isClosing) {
                    mStatusBarWindowController.setPanelVisible(false);
                    mNotificationView.setVisibility(View.INVISIBLE);
                    mNotificationView.setClipBounds(null);
                    mNotificationViewController.setIsInForeground(false);
                    // let the status bar know that the panel is closed
                    setPanelExpanded(false);
                    mAutoHideController.userAutoHide();
                } else {
                    mAutoHideController.cancelAutoHide();
                    mNotificationViewController.setIsInForeground(true);
                    // let the status bar know that the panel is open
                    mNotificationView.setVisibleNotificationsAsSeen();
                    setPanelExpanded(true);
                }
            }
        });
        mFlingAnimationUtils.apply(animator, from, to, Math.abs(velocity));
        animator.start();
    }

    @Override
    protected QS createDefaultQSFragment() {
        return new CarQSFragment();
    }

    private BatteryController createBatteryController() {
        mCarBatteryController = new CarBatteryController(mContext);
        mCarBatteryController.addBatteryViewHandler(this);
        return mCarBatteryController;
    }

    @Override
    protected void createNavigationBar(@Nullable RegisterStatusBarResult result) {
        mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
        mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
        mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);

        buildNavBarWindows();
        buildNavBarContent();
        attachNavBarWindows();

        // Try setting up the initial state of the nav bar if applicable.
        if (result != null) {
            setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken,
                    result.mImeWindowVis, result.mImeBackDisposition,
                    result.mShowImeSwitcher);
        }

        // There has been a car customized nav bar on the default display, so just create nav bars
        // on external displays.
        mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */, result);
    }

    private void buildNavBarContent() {
        boolean shouldBuildNavBarContent = mDeviceIsSetUpForUser && !mIsUserSetupInProgress;

        // Always build top bar.
        buildTopBar(shouldBuildNavBarContent ? R.layout.car_top_navigation_bar :
                R.layout.car_top_navigation_bar_unprovisioned);

        if (mShowBottom) {
            buildBottomBar(shouldBuildNavBarContent ? R.layout.car_navigation_bar :
                    R.layout.car_navigation_bar_unprovisioned);
        }

        if (mShowLeft) {
            buildLeft(shouldBuildNavBarContent ? R.layout.car_left_navigation_bar :
                    R.layout.car_left_navigation_bar_unprovisioned);
        }

        if (mShowRight) {
            buildRight(shouldBuildNavBarContent ? R.layout.car_right_navigation_bar :
                    R.layout.car_right_navigation_bar_unprovisioned);
        }
    }

    private void buildNavBarWindows() {
        mTopNavigationBarContainer = mStatusBarWindow
            .findViewById(R.id.car_top_navigation_bar_container);

        if (mShowBottom) {
            mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
                    R.layout.navigation_bar_window, null);
            mNavBarTransitions = new BarTransitions(mNavigationBarWindow,
                    R.drawable.nav_background);
        }
        if (mShowLeft) {
            mLeftNavigationBarWindow = (ViewGroup) View.inflate(mContext,
                    R.layout.navigation_bar_window, null);
        }
        if (mShowRight) {
            mRightNavigationBarWindow = (ViewGroup) View.inflate(mContext,
                    R.layout.navigation_bar_window, null);
        }

    }

    /**
     * We register for soft keyboard visibility events such that we can hide the navigation bar
     * giving more screen space to the IME. Note: this is optional and controlled by
     * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}.
     */
    @Override
    public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
            boolean showImeSwitcher) {
        if (!mHideNavBarForKeyboard) {
            return;
        }

        if (mContext.getDisplay().getDisplayId() != displayId) {
            return;
        }

        boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
        showBottomNavBarWindow(isKeyboardVisible);
    }

    private void attachNavBarWindows() {
        if (mShowBottom && !mBottomNavBarVisible) {
            mBottomNavBarVisible = true;

            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                    LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                    PixelFormat.TRANSLUCENT);
            lp.setTitle("CarNavigationBar");
            lp.windowAnimations = 0;
            mWindowManager.addView(mNavigationBarWindow, lp);
        }

        if (mShowLeft) {
            int width = mContext.getResources().getDimensionPixelSize(
                    R.dimen.car_left_navigation_bar_width);
            WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
                    width, LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                    PixelFormat.TRANSLUCENT);
            leftlp.setTitle("LeftCarNavigationBar");
            leftlp.windowAnimations = 0;
            leftlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
            leftlp.gravity = Gravity.LEFT;
            mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
        }
        if (mShowRight) {
            int width = mContext.getResources().getDimensionPixelSize(
                    R.dimen.car_right_navigation_bar_width);
            WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
                    width, LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                            | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                            | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                            | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                    PixelFormat.TRANSLUCENT);
            rightlp.setTitle("RightCarNavigationBar");
            rightlp.windowAnimations = 0;
            rightlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
            rightlp.gravity = Gravity.RIGHT;
            mWindowManager.addView(mRightNavigationBarWindow, rightlp);
        }
    }

    private void showBottomNavBarWindow(boolean isKeyboardVisible) {
        if (!mShowBottom) {
            return;
        }

        // If keyboard is visible and bottom nav bar not visible, this is the correct state, so do
        // nothing. Same with if keyboard is not visible and bottom nav bar is visible.
        if (isKeyboardVisible ^ mBottomNavBarVisible) {
            return;
        }

        mNavigationBarWindow.setVisibility(isKeyboardVisible ? View.GONE : View.VISIBLE);
        setNotificationViewBottomMargin(isKeyboardVisible ? 0 : mNavigationBarWindow.getHeight());
        mBottomNavBarVisible = !isKeyboardVisible;
    }

    private void buildTopBar(int layout) {
        mTopNavigationBarContainer.removeAllViews();
        View.inflate(mContext, layout, mTopNavigationBarContainer);
        mTopNavigationBarView = (CarNavigationBarView) mTopNavigationBarContainer.getChildAt(0);
        if (mTopNavigationBarView == null) {
            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_top_navigation_bar");
            throw new RuntimeException("Unable to build top nav bar due to missing layout");
        }
        mTopNavigationBarView.setStatusBar(this);
        mTopNavigationBarView.setStatusBarWindowTouchListener(mTopNavBarNotificationTouchListener);
    }

    private void buildBottomBar(int layout) {
        // SystemUI requires that the navigation bar view have a parent. Since the regular
        // StatusBar inflates navigation_bar_window as this parent view, use the same view for the
        // CarNavigationBarView.
        View.inflate(mContext, layout, mNavigationBarWindow);
        mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
        if (mNavigationBarView == null) {
            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
            throw new RuntimeException("Unable to build bottom nav bar due to missing layout");
        }
        mNavigationBarView.setStatusBar(this);
        mNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
    }

    private void buildLeft(int layout) {
        View.inflate(mContext, layout, mLeftNavigationBarWindow);
        mLeftNavigationBarView = (CarNavigationBarView) mLeftNavigationBarWindow.getChildAt(0);
        if (mLeftNavigationBarView == null) {
            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_left_navigation_bar");
            throw new RuntimeException("Unable to build left nav bar due to missing layout");
        }
        mLeftNavigationBarView.setStatusBar(this);
        mLeftNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
    }


    private void buildRight(int layout) {
        View.inflate(mContext, layout, mRightNavigationBarWindow);
        mRightNavigationBarView = (CarNavigationBarView) mRightNavigationBarWindow.getChildAt(0);
        if (mRightNavigationBarView == null) {
            Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_right_navigation_bar");
            throw new RuntimeException("Unable to build right nav bar due to missing layout");
        }
        mRightNavigationBarView.setStatusBar(this);
        mRightNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
    }

    private void initHvac() {
        if (mHvacController == null) {
            mHvacController = Dependency.get(HvacController.class);
            mHvacController.connectToCarService();
        }
        addTemperatureViewToController(mTopNavigationBarView);
        addTemperatureViewToController(mNavigationBarView);
        addTemperatureViewToController(mLeftNavigationBarView);
        addTemperatureViewToController(mRightNavigationBarView);
    }

    private void setNotificationViewBottomMargin(int bottomMargin) {
        ViewGroup.MarginLayoutParams params =
                (ViewGroup.MarginLayoutParams) mNotificationView.getLayoutParams();
        params.setMargins(params.leftMargin, params.topMargin, params.rightMargin, bottomMargin);
        mNotificationView.setLayoutParams(params);
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        //When executing dump() function simultaneously, we need to serialize them
        //to get mStackScroller's position correctly.
        synchronized (mQueueLock) {
            pw.println("  mStackScroller: " + viewInfo(mStackScroller));
            pw.println("  mStackScroller: " + viewInfo(mStackScroller)
                    + " scroll " + mStackScroller.getScrollX()
                    + "," + mStackScroller.getScrollY());
        }

        pw.print("  mTaskStackListener=");
        pw.println(mTaskStackListener);
        pw.print("  mCarFacetButtonController=");
        pw.println(mCarFacetButtonController);
        pw.print("  mFullscreenUserSwitcher=");
        pw.println(mFullscreenUserSwitcher);
        pw.print("  mCarBatteryController=");
        pw.println(mCarBatteryController);
        pw.print("  mBatteryMeterView=");
        pw.println(mBatteryMeterView);
        pw.print("  mNavigationBarView=");
        pw.println(mNavigationBarView);

        if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
            KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
        }

        Dependency.get(FalsingManager.class).dump(pw);
        FalsingLog.dump(pw);

        pw.println("SharedPreferences:");
        for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
            pw.print("  ");
            pw.print(entry.getKey());
            pw.print("=");
            pw.println(entry.getValue());
        }
    }

    @Override
    public void showBatteryView() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "showBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
        }

        if (mBatteryMeterView != null) {
            mBatteryMeterView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public void hideBatteryView() {
        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "hideBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
        }

        if (mBatteryMeterView != null) {
            mBatteryMeterView.setVisibility(View.GONE);
        }
    }

    /**
     * An implementation of TaskStackChangeListener, that listens for changes in the system
     * task stack and notifies the navigation bar.
     */
    private class TaskStackListenerImpl extends TaskStackChangeListener {
        @Override
        public void onTaskStackChanged() {
            try {
                mCarFacetButtonController.taskChanged(
                        ActivityTaskManager.getService().getAllStackInfos());
            } catch (Exception e) {
                Log.e(TAG, "Getting StackInfo from activity manager failed", e);
            }
        }

        @Override
        public void onTaskDisplayChanged(int taskId, int newDisplayId) {
            try {
                mCarFacetButtonController.taskChanged(
                        ActivityTaskManager.getService().getAllStackInfos());
            } catch (Exception e) {
                Log.e(TAG, "Getting StackInfo from activity manager failed", e);
            }
        }
    }

    private void onDrivingStateChanged(CarDrivingStateEvent notUsed) {
        // Check if we need to start the timer every time driving state changes.
        startSwitchToGuestTimerIfDrivingOnKeyguard();
    }

    private void startSwitchToGuestTimerIfDrivingOnKeyguard() {
        if (mDrivingStateHelper.isCurrentlyDriving() && mState != StatusBarState.SHADE) {
            // We're driving while keyguard is up.
            mSwitchToGuestTimer.start();
        } else {
            mSwitchToGuestTimer.cancel();
        }
    }

    @Override
    protected void createUserSwitcher() {
        UserSwitcherController userSwitcherController =
                Dependency.get(UserSwitcherController.class);
        if (userSwitcherController.useFullscreenUserSwitcher()) {
            mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext);
        } else {
            super.createUserSwitcher();
        }
    }

    @Override
    public void setLockscreenUser(int newUserId) {
        super.setLockscreenUser(newUserId);
        // Try to dismiss the keyguard after every user switch.
        dismissKeyguardWhenUserSwitcherNotDisplayed();
    }

    @Override
    public void onStateChanged(int newState) {
        super.onStateChanged(newState);

        startSwitchToGuestTimerIfDrivingOnKeyguard();

        if (newState != StatusBarState.FULLSCREEN_USER_SWITCHER) {
            hideUserSwitcher();
        } else {
            dismissKeyguardWhenUserSwitcherNotDisplayed();
        }
    }

    /** Makes the full screen user switcher visible, if applicable. */
    public void showUserSwitcher() {
        if (mFullscreenUserSwitcher != null && mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
            mFullscreenUserSwitcher.show(); // Makes the switcher visible.
        }
    }

    private void hideUserSwitcher() {
        if (mFullscreenUserSwitcher != null) {
            mFullscreenUserSwitcher.hide();
        }
    }

    final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
        @Override
        public void onScreenTurnedOn() {
            dismissKeyguardWhenUserSwitcherNotDisplayed();
        }
    };

    // We automatically dismiss keyguard unless user switcher is being shown on the keyguard.
    private void dismissKeyguardWhenUserSwitcherNotDisplayed() {
        if (mFullscreenUserSwitcher == null) {
            return; // Not using the full screen user switcher.
        }

        if (mState == StatusBarState.FULLSCREEN_USER_SWITCHER
                && !mFullscreenUserSwitcher.isVisible()) {
            // Current execution path continues to set state after this, thus we deffer the
            // dismissal to the next execution cycle.
            postDismissKeyguard(); // Dismiss the keyguard if switcher is not visible.
        }
    }

    public void postDismissKeyguard() {
        mHandler.post(this::dismissKeyguard);
    }

    /**
     * Dismisses the keyguard and shows bouncer if authentication is necessary.
     */
    public void dismissKeyguard() {
        // Don't dismiss keyguard when the screen is off.
        if (mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_OFF) {
            return;
        }
        executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
                true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
    }

    /**
     * Ensures that relevant child views are appropriately recreated when the device's density
     * changes.
     */
    @Override
    public void onDensityOrFontScaleChanged() {
        super.onDensityOrFontScaleChanged();
        restartNavBars();
        // Need to update the background on density changed in case the change was due to night
        // mode.
        mNotificationPanelBackground = getDefaultWallpaper();
        mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
    }

    @Override
    public void onLocaleListChanged() {
        // When locale changes we need to reload the notification panel with the new language
        if (mNotificationView == null) {
            return;
        }

        LayoutParams params = mNotificationView.getLayoutParams();
        int index = mStatusBarWindow.indexOfChild(mNotificationView);

        mStatusBarWindow.removeView(mNotificationView);

        View v = View.inflate(mContext, R.layout.notification_center_activity, null);
        mStatusBarWindow.addView(v, index, params);

        restartNavBars();
        connectNotificationsUI();
    }

    /**
     * Returns the {@link Drawable} that represents the wallpaper that the user has currently set.
     */
    private Drawable getDefaultWallpaper() {
        return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
    }

    private void setNotificationViewClipBounds(int height) {
        if (height > mNotificationView.getHeight()) {
            height = mNotificationView.getHeight();
        }
        Rect clipBounds = new Rect();
        clipBounds.set(0, 0, mNotificationView.getWidth(), height);
        // Sets the clip region on the notification list view.
        mNotificationView.setClipBounds(clipBounds);
        if (mHandleBar != null) {
            ViewGroup.MarginLayoutParams lp =
                    (ViewGroup.MarginLayoutParams) mHandleBar.getLayoutParams();
            mHandleBar.setTranslationY(height - mHandleBar.getHeight() - lp.bottomMargin);
        }
        if (mNotificationView.getHeight() > 0) {
            Drawable background = mNotificationView.getBackground().mutate();
            background.setAlpha((int) (getBackgroundAlpha(height) * 255));
            mNotificationView.setBackground(background);
        }
    }

    /**
     * Calculates the alpha value for the background based on how much of the notification
     * shade is visible to the user. When the notification shade is completely open then
     * alpha value will be 1.
     */
    private float getBackgroundAlpha(int height) {
        return mInitialBackgroundAlpha +
            ((float) height / mNotificationView.getHeight() * mBackgroundAlphaDiff);
    }

    private void calculatePercentageFromBottom(float height) {
        if (mNotificationView.getHeight() > 0) {
            mPercentageFromBottom = (int) Math.abs(
                    height / mNotificationView.getHeight() * 100);
        }
    }

    private static final int SWIPE_DOWN_MIN_DISTANCE = 25;
    private static final int SWIPE_MAX_OFF_PATH = 75;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;

    /**
     * Only responsible for open hooks. Since once the panel opens it covers all elements
     * there is no need to merge with close.
     */
    private abstract class OpenNotificationGestureListener extends
            GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {

            if (mNotificationView.getVisibility() == View.INVISIBLE) {
                // when the on-scroll is called for the first time to open.
                mNotificationList.scrollToPosition(0);
            }
            mStatusBarWindowController.setPanelVisible(true);
            mNotificationView.setVisibility(View.VISIBLE);

            // clips the view for the notification shade when the user scrolls to open.
            setNotificationViewClipBounds((int) event2.getRawY());

            // Initially the scroll starts with height being zero. This checks protects from divide
            // by zero error.
            calculatePercentageFromBottom(event2.getRawY());

            mIsTracking = true;
            return true;
        }


        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            if (velocityY > SWIPE_THRESHOLD_VELOCITY) {
                mOpeningVelocity = velocityY;
                openNotification();
                return true;
            }
            animateNotificationPanel(DEFAULT_FLING_VELOCITY, true);

            return false;
        }

        protected abstract void openNotification();
    }

    /**
     * To be installed on the open panel notification panel
     */
    private abstract class CloseNotificationGestureListener extends
            GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            if (mPanelExpanded) {
                animateNotificationPanel(DEFAULT_FLING_VELOCITY, true);
            }
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {
            // should not clip while scroll to the bottom of the list.
            if (!mNotificationListAtBottomAtTimeOfTouch) {
                return false;
            }
            float actualNotificationHeight =
                    mNotificationView.getHeight() - (event1.getRawY() - event2.getRawY());
            if (actualNotificationHeight > mNotificationView.getHeight()) {
                actualNotificationHeight = mNotificationView.getHeight();
            }
            if (mNotificationView.getHeight() > 0) {
                mPercentageFromBottom = (int) Math.abs(
                        actualNotificationHeight / mNotificationView.getHeight() * 100);
                boolean isUp = distanceY > 0;

                // This check is to figure out if onScroll was called while swiping the card at
                // bottom of the list. At that time we should not allow notification shade to
                // close. We are also checking for the upwards swipe gesture here because it is
                // possible if a user is closing the notification shade and while swiping starts
                // to open again but does not fling. At that time we should allow the
                // notification shade to close fully or else it would stuck in between.
                if (Math.abs(mNotificationView.getHeight() - actualNotificationHeight)
                        > SWIPE_DOWN_MIN_DISTANCE && isUp) {
                    setNotificationViewClipBounds((int) actualNotificationHeight);
                    mIsTracking = true;
                } else if (!isUp) {
                    setNotificationViewClipBounds((int) actualNotificationHeight);
                }
            }
            // if we return true the the items in RV won't be scrollable.
            return false;
        }


        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            // should not fling if the touch does not start when view is at the bottom of the list.
            if (!mNotificationListAtBottomAtTimeOfTouch) {
                return false;
            }
            if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
                    || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
                // swipe was not vertical or was not fast enough
                return false;
            }
            boolean isUp = velocityY < 0;
            if (isUp) {
                close();
                return true;
            } else {
                // we should close the shade
                animateNotificationPanel(velocityY, false);
            }
            return false;
        }

        protected abstract void close();
    }

    /**
     * To be installed on the nav bars.
     */
    private abstract class NavBarCloseNotificationGestureListener extends
            CloseNotificationGestureListener {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            mClosingVelocity = DEFAULT_FLING_VELOCITY;
            if (mPanelExpanded) {
                close();
            }
            return super.onSingleTapUp(e);
        }

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {
            calculatePercentageFromBottom(event2.getRawY());
            setNotificationViewClipBounds((int) event2.getRawY());
            return true;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            mClosingVelocity = DEFAULT_FLING_VELOCITY;
            close();
            super.onLongPress(e);
        }
    }

    /**
     * To be installed on the handle bar.
     */
    private class HandleBarCloseNotificationGestureListener extends
            GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {
            calculatePercentageFromBottom(event2.getRawY());
            // To prevent the jump in the clip bounds while closing the notification shade using
            // the handle bar we should calculate the height using the diff of event1 and event2.
            // This will help the notification shade to clip smoothly as the event2 value changes
            // as event1 value will be fixed.
            int clipHeight =
                    mNotificationView.getHeight() - (int) (event1.getRawY() - event2.getRawY());
            setNotificationViewClipBounds(clipHeight);
            return true;
        }
    }

    /**
     * SystemUi version of the notification manager that overrides methods such that the
     * notifications end up in the status bar layouts instead of a standalone window.
     */
    private class CarSystemUIHeadsUpNotificationManager extends CarHeadsUpNotificationManager {

        CarSystemUIHeadsUpNotificationManager(Context context,
                NotificationClickHandlerFactory clickHandlerFactory,
                NotificationDataManager notificationDataManager) {
            super(context, clickHandlerFactory, notificationDataManager);
        }

        @Override
        protected View createHeadsUpPanel() {
            // In SystemUi the view is already in the window so just return a reference.
            return mStatusBarWindow.findViewById(R.id.notification_headsup);
        }

        @Override
        protected void addHeadsUpPanelToDisplay() {
            // Set the panel initial state to invisible
            mHeadsUpPanel.setVisibility(View.INVISIBLE);
        }

        @Override
        protected void setInternalInsetsInfo(ViewTreeObserver.InternalInsetsInfo info,
                HeadsUpEntry currentNotification, boolean panelExpanded) {
            super.setInternalInsetsInfo(info, currentNotification, mPanelExpanded);
        }

        @Override
        protected void setHeadsUpVisible() {
            // if the Notifications panel is showing or SUW for user is in progress then don't show
            // heads up notifications
            if ((!mEnableHeadsUpNotificationWhenNotificationShadeOpen && mPanelExpanded)
                    || !mDeviceIsSetUpForUser || mIsUserSetupInProgress) {
                return;
            }

            super.setHeadsUpVisible();
            if (mHeadsUpPanel.getVisibility() == View.VISIBLE) {
                mStatusBarWindowController.setHeadsUpShowing(true);
                mStatusBarWindowController.setForceStatusBarVisible(true);
            }
        }

        @Override
        protected void removeNotificationFromPanel(HeadsUpEntry currentHeadsUpNotification) {
            super.removeNotificationFromPanel(currentHeadsUpNotification);
            // If the panel ended up empty and hidden we can remove it from SystemUi
            if (mHeadsUpPanel.getVisibility() != View.VISIBLE) {
                mStatusBarWindowController.setHeadsUpShowing(false);
                mStatusBarWindowController.setForceStatusBarVisible(false);
            }
        }
    }
}
