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

Commit 19f236a2 authored by Brad Stenning's avatar Brad Stenning
Browse files

Add NotificationsUI SystemUI service that can display the notification

implementation for cars

Bug: 116595026
Test: manual
Change-Id: I8631e70241698aa51f94a5fdfacaea17db18841d
(cherry picked from commit 2a9907c4737b46ca0c3230a4d7f7844e4f849ce2)
parent f9eeca13
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ android_app {
    ],

    static_libs: [
        "CarNotificationLib",
        "SystemUI-core",
        "SystemUIPluginLib",
        "SystemUISharedLib",
+27 −0
Original line number Diff line number Diff line
@@ -28,4 +28,31 @@
    <bool name="config_enableRightNavigationBar">false</bool>
    <bool name="config_enableBottomNavigationBar">true</bool>

    <!-- SystemUI Services: The classes of the stuff to start. This is duplicated from core
         SystemUi b/c it can't be overlayed at this level for now
    -->
    <string-array name="config_systemUIServiceComponents" translatable="false">
        <item>com.android.systemui.Dependency</item>
        <item>com.android.systemui.util.NotificationChannels</item>
        <item>com.android.systemui.statusbar.CommandQueue$CommandQueueStart</item>
        <item>com.android.systemui.keyguard.KeyguardViewMediator</item>
        <item>com.android.systemui.recents.Recents</item>
        <item>com.android.systemui.volume.VolumeUI</item>
        <item>com.android.systemui.stackdivider.Divider</item>
        <item>com.android.systemui.SystemBars</item>
        <item>com.android.systemui.usb.StorageNotification</item>
        <item>com.android.systemui.power.PowerUI</item>
        <item>com.android.systemui.media.RingtonePlayer</item>
        <item>com.android.systemui.keyboard.KeyboardUI</item>
        <item>com.android.systemui.pip.PipUI</item>
        <item>com.android.systemui.shortcut.ShortcutKeyDispatcher</item>
        <item>@string/config_systemUIVendorServiceComponent</item>
        <item>com.android.systemui.util.leak.GarbageMonitor$Service</item>
        <item>com.android.systemui.LatencyTester</item>
        <item>com.android.systemui.globalactions.GlobalActionsComponent</item>
        <item>com.android.systemui.ScreenDecorations</item>
        <item>com.android.systemui.fingerprint.FingerprintDialogImpl</item>
        <item>com.android.systemui.SliceBroadcastRelayHandler</item>
        <item>com.android.systemui.notifications.NotificationsUI</item>
    </string-array>
</resources>
+161 −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.notifications;

import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.drivingstate.CarUxRestrictionsManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.ServiceConnection;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import com.android.car.notification.CarNotificationListener;
import com.android.car.notification.CarUxRestrictionManagerWrapper;
import com.android.car.notification.NotificationViewController;
import com.android.car.notification.PreprocessingManager;
import com.android.systemui.R;
import com.android.systemui.SystemUI;

/**
 * Standalone SystemUI for displaying Notifications that have been designed to be used in the car
 */
public class NotificationsUI extends SystemUI {

    private static final String TAG = "NotificationsUI";
    private CarNotificationListener mCarNotificationListener;
    private CarUxRestrictionsManager mCarUxRestrictionsManager;
    private Car mCar;
    private ViewGroup mCarNotificationWindow;
    private NotificationViewController mNotificationViewController;
    private boolean mIsShowing;
    private CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper =
            new CarUxRestrictionManagerWrapper();

    /**
     * Inits the window that hosts the notifications and establishes the connections
     * to the car related services.
     */
    @Override
    public void start() {
        WindowManager windowManager =
                (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        mCarNotificationListener = new CarNotificationListener();
        mCarNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper);
        mCar = Car.createCar(mContext, mCarConnectionListener);
        mCar.connect();


        mCarNotificationWindow = (ViewGroup) View.inflate(mContext,
                R.layout.navigation_bar_window, null);
        View.inflate(mContext,
                com.android.car.notification.R.layout.notification_center_activity,
                mCarNotificationWindow);
        mCarNotificationWindow.findViewById(
                com.android.car.notification.R.id.exit_button_container)
                .setOnClickListener(v -> toggleShowingCarNotifications());

        WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
                WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
                        | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
                        | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
                PixelFormat.TRANSLUCENT);
        layoutParams.setTitle("Car Notification Window");
        // start in the hidden state
        mCarNotificationWindow.setVisibility(View.GONE);
        windowManager.addView(mCarNotificationWindow, layoutParams);
        mNotificationViewController = new NotificationViewController(
                mCarNotificationWindow
                        .findViewById(com.android.car.notification.R.id.notification_view),
                PreprocessingManager.getInstance(mContext),
                mCarNotificationListener,
                mCarUxRestrictionManagerWrapper
        );
        // Add to the SystemUI component registry
        putComponent(NotificationsUI.class, this);
    }

    /**
     * Connection callback to establish UX Restrictions
     */
    private ServiceConnection mCarConnectionListener = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            try {
                mCarUxRestrictionsManager = (CarUxRestrictionsManager) mCar.getCarManager(
                        Car.CAR_UX_RESTRICTION_SERVICE);
                mCarUxRestrictionManagerWrapper
                        .setCarUxRestrictionsManager(mCarUxRestrictionsManager);
                PreprocessingManager preprocessingManager = PreprocessingManager.getInstance(
                        mContext);
                preprocessingManager
                        .setCarUxRestrictionManagerWrapper(mCarUxRestrictionManagerWrapper);
            } catch (CarNotConnectedException e) {
                Log.e(TAG, "Car not connected in CarConnectionListener", e);
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG, "Car service disconnected unexpectedly");
        }
    };

    /**
     * Toggles the visiblity of the notifications
     */
    public void toggleShowingCarNotifications() {
        if (mCarNotificationWindow.getVisibility() == View.VISIBLE) {
            closeCarNotifications();
            return;
        }
        openCarNotifications();
    }

    /**
     * Hides the notifications
     */
    public void closeCarNotifications() {
        mCarNotificationWindow.setVisibility(View.GONE);
        mNotificationViewController.disable();
        mIsShowing = false;
    }

    /**
     * Sets the notifications to visible
     */
    public void openCarNotifications() {
        mCarNotificationWindow.setVisibility(View.VISIBLE);
        mNotificationViewController.enable();
        mIsShowing = true;
    }

    /**
     * Returns {@code true} if notifications are currently on the screen
     */
    public boolean isShowing() {
        return mIsShowing;
    }
}
+2 −3
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;

import com.android.keyguard.AlphaOptimizedImageButton;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -34,7 +33,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
 */
class CarNavigationBarView extends LinearLayout {
    private View mNavButtons;
    private AlphaOptimizedImageButton mNotificationsButton;
    private CarFacetButton mNotificationsButton;
    private CarStatusBar mCarStatusBar;
    private Context mContext;
    private View mLockScreenButtons;
@@ -71,7 +70,7 @@ class CarNavigationBarView extends LinearLayout {
    }

    protected void onNotificationsClick(View v) {
        mCarStatusBar.togglePanel();
        mCarStatusBar.toggleCarNotifications();
    }

    /**
+6 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.systemui.R;
import com.android.systemui.classifier.FalsingLog;
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.notifications.NotificationsUI;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.car.CarQSFragment;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -587,4 +588,9 @@ public class CarStatusBar extends StatusBar implements
    private Drawable getDefaultWallpaper() {
        return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
    }

    public void toggleCarNotifications() {
        getComponent(NotificationsUI.class).toggleShowingCarNotifications();
    }

}