summaryrefslogtreecommitdiff
path: root/packages/CarSystemUI/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/CarSystemUI/src')
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java34
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java10
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java18
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java10
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java7
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java6
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java (renamed from packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java)9
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarFacetButton.java (renamed from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java)4
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarFacetButtonController.java (renamed from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java)7
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java381
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java (renamed from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java)13
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java (renamed from packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java)4
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/FacetButtonTaskStackListener.java65
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java147
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java5
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java554
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java69
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java3
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java21
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java22
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java16
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java10
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java11
23 files changed, 1079 insertions, 347 deletions
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
new file mode 100644
index 000000000000..8e0a3eb53e6f
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIBinder.java
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+import com.android.systemui.navigationbar.car.CarNavigationBar;
+
+import dagger.Binds;
+import dagger.Module;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
+
+/** Binder for car specific {@link SystemUI} modules. */
+@Module
+public abstract class CarSystemUIBinder {
+ /** */
+ @Binds
+ @IntoMap
+ @ClassKey(CarNavigationBar.class)
+ public abstract SystemUI bindCarNavigationBar(CarNavigationBar sysui);
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
index c7654e81e0b1..be4b8897d00b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java
@@ -20,11 +20,10 @@ import android.content.Context;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.statusbar.car.CarFacetButtonController;
+import com.android.systemui.dagger.SystemUIRootComponent;
+import com.android.systemui.navigationbar.car.CarFacetButtonController;
import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.volume.CarVolumeDialogComponent;
-import com.android.systemui.volume.VolumeDialogComponent;
import javax.inject.Singleton;
@@ -43,7 +42,6 @@ public class CarSystemUIFactory extends SystemUIFactory {
.contextHolder(new ContextHolder(context))
.build();
return DaggerCarSystemUIRootComponent.builder()
- .dependencyProvider(new com.android.systemui.DependencyProvider())
.contextHolder(new ContextHolder(context))
.build();
}
@@ -57,10 +55,6 @@ public class CarSystemUIFactory extends SystemUIFactory {
return new CarStatusBarKeyguardViewManager(context, viewMediatorCallback, lockPatternUtils);
}
- public VolumeDialogComponent createVolumeDialogComponent(SystemUI systemUi, Context context) {
- return new CarVolumeDialogComponent(systemUi, context);
- }
-
@Singleton
@Component(modules = ContextHolder.class)
public interface CarDependencyComponent {
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 9a063aa7b791..93e553f59dcf 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -23,18 +23,22 @@ import android.content.Context;
import com.android.systemui.car.CarNotificationEntryManager;
import com.android.systemui.car.CarNotificationInterruptionStateProvider;
+import com.android.systemui.dagger.SystemUIRootComponent;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dock.DockManagerImpl;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
+import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.volume.CarVolumeDialogComponent;
+import com.android.systemui.volume.VolumeDialogComponent;
import javax.inject.Named;
import javax.inject.Singleton;
@@ -42,6 +46,8 @@ import javax.inject.Singleton;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
@Module
abstract class CarSystemUIModule {
@@ -94,4 +100,16 @@ abstract class CarSystemUIModule {
@Binds
abstract SystemUIRootComponent bindSystemUIRootComponent(
CarSystemUIRootComponent systemUIRootComponent);
+
+ @Binds
+ public abstract StatusBar bindStatusBar(CarStatusBar statusBar);
+
+ @Binds
+ @IntoMap
+ @ClassKey(StatusBar.class)
+ public abstract SystemUI providesStatusBar(CarStatusBar statusBar);
+
+ @Binds
+ abstract VolumeDialogComponent bindVolumeDialogComponent(
+ CarVolumeDialogComponent carVolumeDialogComponent);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
index 264b7d52c02f..c2847c88785b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIRootComponent.java
@@ -16,6 +16,12 @@
package com.android.systemui;
+import com.android.systemui.dagger.DependencyBinder;
+import com.android.systemui.dagger.DependencyProvider;
+import com.android.systemui.dagger.SystemServicesModule;
+import com.android.systemui.dagger.SystemUIModule;
+import com.android.systemui.dagger.SystemUIRootComponent;
+
import javax.inject.Singleton;
import dagger.Component;
@@ -26,8 +32,10 @@ import dagger.Component;
DependencyProvider.class,
DependencyBinder.class,
SystemUIFactory.ContextHolder.class,
+ SystemServicesModule.class,
SystemUIModule.class,
- CarSystemUIModule.class
+ CarSystemUIModule.class,
+ CarSystemUIBinder.class
})
interface CarSystemUIRootComponent extends SystemUIRootComponent {
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index a107dd793551..53a88a9a54e9 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -15,11 +15,12 @@
*/
package com.android.systemui.car;
-import android.content.Context;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.logging.NotifLog;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -34,8 +35,8 @@ import javax.inject.Singleton;
public class CarNotificationEntryManager extends NotificationEntryManager {
@Inject
- public CarNotificationEntryManager(Context context) {
- super(context);
+ public CarNotificationEntryManager(NotificationData notificationData, NotifLog notifLog) {
+ super(notificationData, notifLog);
}
@Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java
index afd722ba0091..447e579ece42 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationInterruptionStateProvider.java
@@ -22,6 +22,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationFilter;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.policy.BatteryController;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -34,8 +35,9 @@ public class CarNotificationInterruptionStateProvider extends
@Inject
public CarNotificationInterruptionStateProvider(Context context,
NotificationFilter filter,
- StatusBarStateController stateController) {
- super(context, filter, stateController);
+ StatusBarStateController stateController,
+ BatteryController batteryController) {
+ super(context, filter, stateController, batteryController);
}
@Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java
index b36a7da35acf..c50de22fb2d8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/AssitantButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/AssitantButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.car;
+package com.android.systemui.navigationbar.car;
import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_ASSIST_GESTURE;
@@ -33,6 +33,7 @@ import com.android.internal.app.IVoiceInteractionSessionShowCallback;
public class AssitantButton extends CarFacetButton {
private static final String TAG = "CarFacetButton";
+ private final AssistUtils mAssistUtils;
private IVoiceInteractionSessionShowCallback mShowCallback =
new IVoiceInteractionSessionShowCallback.Stub() {
@Override
@@ -45,8 +46,6 @@ public class AssitantButton extends CarFacetButton {
Log.d(TAG, "IVoiceInteractionSessionShowCallback onShown()");
}
};
-
- private final AssistUtils mAssistUtils;
public AssitantButton(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -63,7 +62,7 @@ public class AssitantButton extends CarFacetButton {
}
@Override
- protected void setupIntents(TypedArray typedArray){
+ protected void setupIntents(TypedArray typedArray) {
// left blank because for the assistant button Intent will not be passed from the layout.
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarFacetButton.java
index 0421c3bebcfc..c46e6e7433a3 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarFacetButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.car;
+package com.android.systemui.navigationbar.car;
import android.app.ActivityOptions;
import android.content.Context;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarFacetButtonController.java
index 5f99e1750bb6..30f63f052b9f 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarFacetButtonController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarFacetButtonController.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.car;
+package com.android.systemui.navigationbar.car;
import android.app.ActivityManager;
import android.content.ComponentName;
@@ -76,6 +76,7 @@ public class CarFacetButtonController {
}
}
+ /** Removes all buttons from the button maps. */
public void removeAll() {
mButtonsByCategory.clear();
mButtonsByPackage.clear();
@@ -129,7 +130,7 @@ public class CarFacetButtonController {
if (mSelectedFacetButtons != null) {
Iterator<CarFacetButton> iterator = mSelectedFacetButtons.iterator();
- while(iterator.hasNext()) {
+ while (iterator.hasNext()) {
CarFacetButton carFacetButton = iterator.next();
if (carFacetButton.getDisplayId() == validStackInfo.displayId) {
carFacetButton.setSelected(false);
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
new file mode 100644
index 000000000000..6fba1d516c73
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
@@ -0,0 +1,381 @@
+/*
+ * 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.navigationbar.car;
+
+import android.content.Context;
+import android.graphics.PixelFormat;
+import android.inputmethodservice.InputMethodService;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.view.Display;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+
+import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.statusbar.RegisterStatusBarResult;
+import com.android.systemui.R;
+import com.android.systemui.SystemUI;
+import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.car.hvac.HvacController;
+import com.android.systemui.statusbar.car.hvac.TemperatureView;
+import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+import javax.inject.Inject;
+
+import dagger.Lazy;
+
+/** Navigation bars customized for the automotive use case. */
+public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks {
+
+ private final NavigationBarViewFactory mNavigationBarViewFactory;
+ private final WindowManager mWindowManager;
+ private final DeviceProvisionedController mDeviceProvisionedController;
+ private final Lazy<FacetButtonTaskStackListener> mFacetButtonTaskStackListener;
+ private final Handler mMainHandler;
+ private final Lazy<KeyguardStateController> mKeyguardStateController;
+ private final Lazy<CarFacetButtonController> mFacetButtonController;
+ private final Lazy<NavigationBarController> mNavigationBarController;
+ private final Lazy<HvacController> mHvacController;
+
+ private IStatusBarService mBarService;
+ private CommandQueue mCommandQueue;
+ private ActivityManagerWrapper mActivityManagerWrapper;
+
+ // If the nav bar should be hidden when the soft keyboard is visible.
+ private boolean mHideNavBarForKeyboard;
+ private boolean mBottomNavBarVisible;
+
+ // Nav bar views.
+ private ViewGroup mNavigationBarWindow;
+ private ViewGroup mLeftNavigationBarWindow;
+ private ViewGroup mRightNavigationBarWindow;
+ private CarNavigationBarView mNavigationBarView;
+ private CarNavigationBarView mLeftNavigationBarView;
+ private CarNavigationBarView mRightNavigationBarView;
+
+ // To be attached to the navigation bars such that they can close the notification panel if
+ // it's open.
+ private boolean mDeviceIsSetUpForUser = true;
+
+ // Configuration values for if nav bars should be shown.
+ private boolean mShowBottom;
+ private boolean mShowLeft;
+ private boolean mShowRight;
+
+
+ @Inject
+ public CarNavigationBar(Context context,
+ NavigationBarViewFactory navigationBarViewFactory,
+ WindowManager windowManager,
+ DeviceProvisionedController deviceProvisionedController,
+ Lazy<FacetButtonTaskStackListener> facetButtonTaskStackListener,
+ @MainHandler Handler mainHandler,
+ Lazy<KeyguardStateController> keyguardStateController,
+ Lazy<CarFacetButtonController> facetButtonController,
+ Lazy<NavigationBarController> navigationBarController,
+ Lazy<HvacController> hvacController) {
+ super(context);
+ mNavigationBarViewFactory = navigationBarViewFactory;
+ mWindowManager = windowManager;
+ mDeviceProvisionedController = deviceProvisionedController;
+ mFacetButtonTaskStackListener = facetButtonTaskStackListener;
+ mMainHandler = mainHandler;
+ mKeyguardStateController = keyguardStateController;
+ mFacetButtonController = facetButtonController;
+ mNavigationBarController = navigationBarController;
+ mHvacController = hvacController;
+ }
+
+ @Override
+ public void start() {
+ // Set initial state.
+ mHideNavBarForKeyboard = mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
+ mBottomNavBarVisible = false;
+
+ // Read configuration.
+ mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
+ mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
+ mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
+
+ // Get bar service.
+ mBarService = IStatusBarService.Stub.asInterface(
+ ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+
+ // Connect into the status bar manager service
+ mCommandQueue = getComponent(CommandQueue.class);
+ mCommandQueue.addCallback(this);
+
+ RegisterStatusBarResult result = null;
+ try {
+ result = mBarService.registerStatusBar(mCommandQueue);
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ }
+
+ mDeviceIsSetUpForUser = mDeviceProvisionedController.isCurrentUserSetup();
+ mDeviceProvisionedController.addCallback(
+ new DeviceProvisionedController.DeviceProvisionedListener() {
+ @Override
+ public void onUserSetupChanged() {
+ mMainHandler.post(() -> restartNavBarsIfNecessary());
+ }
+
+ @Override
+ public void onUserSwitched() {
+ mMainHandler.post(() -> restartNavBarsIfNecessary());
+ }
+ });
+
+ createNavigationBar(result);
+
+ mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
+ mActivityManagerWrapper.registerTaskStackListener(mFacetButtonTaskStackListener.get());
+
+ mHvacController.get().connectToCarService();
+ }
+
+ private void restartNavBarsIfNecessary() {
+ boolean currentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
+ if (mDeviceIsSetUpForUser != currentUserSetup) {
+ mDeviceIsSetUpForUser = currentUserSetup;
+ 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
+ mHvacController.get().removeAllComponents();
+ mFacetButtonController.get().removeAll();
+
+ if (mNavigationBarWindow != null) {
+ mNavigationBarWindow.removeAllViews();
+ mNavigationBarView = null;
+ }
+
+ if (mLeftNavigationBarWindow != null) {
+ mLeftNavigationBarWindow.removeAllViews();
+ mLeftNavigationBarView = null;
+ }
+
+ if (mRightNavigationBarWindow != null) {
+ mRightNavigationBarWindow.removeAllViews();
+ mRightNavigationBarView = null;
+ }
+
+ buildNavBarContent();
+ // If the UI was rebuilt (day/night change) while the keyguard was up we need to
+ // correctly respect that state.
+ if (mKeyguardStateController.get().isShowing()) {
+ updateNavBarForKeyguardContent();
+ }
+
+ // CarFacetButtonController was reset therefore we need to re-add the status bar elements
+ // to the controller.
+ // TODO(hseog): Add facet buttons in status bar to controller.
+ }
+
+ private void createNavigationBar(RegisterStatusBarResult result) {
+ 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.get().createNavigationBars(/* includeDefaultDisplay= */ false,
+ result);
+ }
+
+ private void buildNavBarWindows() {
+ if (mShowBottom) {
+ mNavigationBarWindow = mNavigationBarViewFactory.getBottomWindow();
+ }
+
+ if (mShowLeft) {
+ mLeftNavigationBarWindow = mNavigationBarViewFactory.getLeftWindow();
+ }
+
+ if (mShowRight) {
+ mRightNavigationBarWindow = mNavigationBarViewFactory.getRightWindow();
+ }
+ }
+
+ private void buildNavBarContent() {
+ if (mShowBottom) {
+ mNavigationBarView = mNavigationBarViewFactory.getBottomBar(mDeviceIsSetUpForUser);
+ mNavigationBarWindow.addView(mNavigationBarView);
+ addTemperatureViewToController(mNavigationBarView);
+ }
+
+ if (mShowLeft) {
+ mLeftNavigationBarView = mNavigationBarViewFactory.getLeftBar(mDeviceIsSetUpForUser);
+ mLeftNavigationBarWindow.addView(mLeftNavigationBarView);
+ addTemperatureViewToController(mLeftNavigationBarView);
+ }
+
+ if (mShowRight) {
+ mRightNavigationBarView = mNavigationBarViewFactory.getRightBar(mDeviceIsSetUpForUser);
+ mRightNavigationBarWindow.addView(mRightNavigationBarView);
+ // Add ability to toggle notification center.
+ addTemperatureViewToController(mRightNavigationBarView);
+ // Add ability to close notification center on touch.
+ }
+ }
+
+ private void addTemperatureViewToController(View v) {
+ if (v instanceof TemperatureView) {
+ mHvacController.get().addHvacTextView((TemperatureView) v);
+ } else if (v instanceof ViewGroup) {
+ ViewGroup viewGroup = (ViewGroup) v;
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ addTemperatureViewToController(viewGroup.getChildAt(i));
+ }
+ }
+ }
+
+ private void attachNavBarWindows() {
+ if (mShowBottom && !mBottomNavBarVisible) {
+ mBottomNavBarVisible = true;
+
+ WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.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, ViewGroup.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, ViewGroup.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);
+ }
+ }
+
+ /**
+ * 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 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;
+ }
+
+ mNavigationBarViewFactory.getBottomWindow().setVisibility(
+ isKeyboardVisible ? View.GONE : View.VISIBLE);
+ mBottomNavBarVisible = !isKeyboardVisible;
+ }
+
+ private void updateNavBarForKeyguardContent() {
+ if (mNavigationBarView != null) {
+ mNavigationBarView.showKeyguardButtons();
+ }
+ if (mLeftNavigationBarView != null) {
+ mLeftNavigationBarView.showKeyguardButtons();
+ }
+ if (mRightNavigationBarView != null) {
+ mRightNavigationBarView.showKeyguardButtons();
+ }
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.print(" mTaskStackListener=");
+ pw.println(mFacetButtonTaskStackListener.get());
+ pw.print(" mNavigationBarView=");
+ pw.println(mNavigationBarView);
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
index 05a41e68e972..afb69547cb47 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBarView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.car;
+package com.android.systemui.navigationbar.car;
import android.content.Context;
import android.util.AttributeSet;
@@ -24,6 +24,7 @@ import android.widget.LinearLayout;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
/**
@@ -32,7 +33,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
* The navigation bar in the automotive use case is more like a list of shortcuts, rendered
* in a linear layout.
*/
-class CarNavigationBarView extends LinearLayout {
+public class CarNavigationBarView extends LinearLayout {
private View mNavButtons;
private CarNavigationButton mNotificationsButton;
private CarStatusBar mCarStatusBar;
@@ -81,7 +82,7 @@ class CarNavigationBarView extends LinearLayout {
return super.onInterceptTouchEvent(ev);
}
- void setStatusBar(CarStatusBar carStatusBar) {
+ public void setStatusBar(CarStatusBar carStatusBar) {
mCarStatusBar = carStatusBar;
}
@@ -90,7 +91,7 @@ class CarNavigationBarView extends LinearLayout {
*
* @param statusBarWindowTouchListener The listener to call from touch and intercept touch
*/
- void setStatusBarWindowTouchListener(OnTouchListener statusBarWindowTouchListener) {
+ public void setStatusBarWindowTouchListener(OnTouchListener statusBarWindowTouchListener) {
mStatusBarWindowTouchListener = statusBarWindowTouchListener;
}
@@ -134,7 +135,7 @@ class CarNavigationBarView extends LinearLayout {
*
* @param hasUnseen true if the unseen notification count is great than 0.
*/
- void toggleNotificationUnseenIndicator(Boolean hasUnseen) {
+ public void toggleNotificationUnseenIndicator(Boolean hasUnseen) {
if (mNotificationsButton == null) return;
mNotificationsButton.setUnseen(hasUnseen);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
index c0dcbbcf30d4..707d80fc0d3b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationButton.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.car;
+package com.android.systemui.navigationbar.car;
import android.app.ActivityOptions;
import android.content.Context;
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/FacetButtonTaskStackListener.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/FacetButtonTaskStackListener.java
new file mode 100644
index 000000000000..4925220d9cad
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/FacetButtonTaskStackListener.java
@@ -0,0 +1,65 @@
+/*
+ * 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.navigationbar.car;
+
+import android.app.ActivityTaskManager;
+import android.util.Log;
+
+import com.android.systemui.shared.system.TaskStackChangeListener;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import dagger.Lazy;
+
+/**
+ * An implementation of TaskStackChangeListener, that listens for changes in the system
+ * task stack and notifies the navigation bar.
+ */
+@Singleton
+class FacetButtonTaskStackListener extends TaskStackChangeListener {
+ private static final String TAG = FacetButtonTaskStackListener.class.getSimpleName();
+
+ private final Lazy<CarFacetButtonController> mFacetButtonControllerLazy;
+
+ @Inject
+ FacetButtonTaskStackListener(
+ Lazy<CarFacetButtonController> carFacetButtonControllerLazy) {
+ mFacetButtonControllerLazy = carFacetButtonControllerLazy;
+ }
+
+ @Override
+ public void onTaskStackChanged() {
+ try {
+ mFacetButtonControllerLazy.get().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 {
+ mFacetButtonControllerLazy.get().taskChanged(
+ ActivityTaskManager.getService().getAllStackInfos());
+ } catch (Exception e) {
+ Log.e(TAG, "Getting StackInfo from activity manager failed", e);
+ }
+
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
new file mode 100644
index 000000000000..519b33a2f53e
--- /dev/null
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/NavigationBarViewFactory.java
@@ -0,0 +1,147 @@
+/*
+ * 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.navigationbar.car;
+
+import android.content.Context;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.LayoutRes;
+
+import com.android.systemui.R;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+/** A factory that creates and caches views for navigation bars. */
+@Singleton
+public class NavigationBarViewFactory {
+
+ private static final String TAG = NavigationBarViewFactory.class.getSimpleName();
+ private static final ArrayMap<Type, Integer> sLayoutMap = setupLayoutMapping();
+
+ private static ArrayMap<Type, Integer> setupLayoutMapping() {
+ ArrayMap<Type, Integer> map = new ArrayMap<>();
+ map.put(Type.TOP, R.layout.car_top_navigation_bar);
+ map.put(Type.TOP_UNPROVISIONED, R.layout.car_top_navigation_bar_unprovisioned);
+ map.put(Type.BOTTOM, R.layout.car_navigation_bar);
+ map.put(Type.BOTTOM_UNPROVISIONED, R.layout.car_navigation_bar_unprovisioned);
+ map.put(Type.LEFT, R.layout.car_left_navigation_bar);
+ map.put(Type.LEFT_UNPROVISIONED, R.layout.car_left_navigation_bar_unprovisioned);
+ map.put(Type.RIGHT, R.layout.car_right_navigation_bar);
+ map.put(Type.RIGHT_UNPROVISIONED, R.layout.car_right_navigation_bar_unprovisioned);
+ return map;
+ }
+
+ private final Context mContext;
+ private final ArrayMap<Type, CarNavigationBarView> mCachedViewMap = new ArrayMap<>(
+ Type.values().length);
+ private final ArrayMap<Type, ViewGroup> mCachedContainerMap = new ArrayMap<>();
+
+ /** Type of navigation bar to be created. */
+ private enum Type {
+ TOP,
+ TOP_UNPROVISIONED,
+ BOTTOM,
+ BOTTOM_UNPROVISIONED,
+ LEFT,
+ LEFT_UNPROVISIONED,
+ RIGHT,
+ RIGHT_UNPROVISIONED
+ }
+
+ @Inject
+ public NavigationBarViewFactory(Context context) {
+ mContext = context;
+ }
+
+ /** Gets the bottom window. */
+ public ViewGroup getBottomWindow() {
+ return getWindowCached(Type.BOTTOM);
+ }
+
+ /** Gets the left window. */
+ public ViewGroup getLeftWindow() {
+ return getWindowCached(Type.LEFT);
+ }
+
+ /** Gets the right window. */
+ public ViewGroup getRightWindow() {
+ return getWindowCached(Type.RIGHT);
+ }
+
+ /** Gets the top bar. */
+ public CarNavigationBarView getTopBar(boolean isSetUp) {
+ return getBar(isSetUp, Type.TOP, Type.TOP_UNPROVISIONED);
+ }
+
+ /** Gets the bottom bar. */
+ public CarNavigationBarView getBottomBar(boolean isSetUp) {
+ return getBar(isSetUp, Type.BOTTOM, Type.BOTTOM_UNPROVISIONED);
+ }
+
+ /** Gets the left bar. */
+ public CarNavigationBarView getLeftBar(boolean isSetUp) {
+ return getBar(isSetUp, Type.LEFT, Type.LEFT_UNPROVISIONED);
+ }
+
+ /** Gets the right bar. */
+ public CarNavigationBarView getRightBar(boolean isSetUp) {
+ return getBar(isSetUp, Type.RIGHT, Type.RIGHT_UNPROVISIONED);
+ }
+
+ private ViewGroup getWindowCached(Type type) {
+ if (mCachedContainerMap.containsKey(type)) {
+ return mCachedContainerMap.get(type);
+ }
+
+ ViewGroup window = (ViewGroup) View.inflate(mContext,
+ R.layout.navigation_bar_window, /* root= */ null);
+ mCachedContainerMap.put(type, window);
+ return mCachedContainerMap.get(type);
+ }
+
+ private CarNavigationBarView getBar(boolean isSetUp, Type provisioned, Type unprovisioned) {
+ CarNavigationBarView view;
+ if (isSetUp) {
+ view = getBarCached(provisioned, sLayoutMap.get(provisioned));
+ } else {
+ view = getBarCached(unprovisioned, sLayoutMap.get(unprovisioned));
+ }
+
+ if (view == null) {
+ String name = isSetUp ? provisioned.name() : unprovisioned.name();
+ Log.e(TAG, "CarStatusBar failed inflate for " + name);
+ throw new RuntimeException(
+ "Unable to build " + name + " nav bar due to missing layout");
+ }
+ return view;
+ }
+
+ private CarNavigationBarView getBarCached(Type type, @LayoutRes int barLayout) {
+ if (mCachedViewMap.containsKey(type)) {
+ return mCachedViewMap.get(type);
+ }
+
+ CarNavigationBarView view = (CarNavigationBarView) View.inflate(mContext, barLayout,
+ /* root= */ null);
+ mCachedViewMap.put(type, view);
+ return mCachedViewMap.get(type);
+ }
+}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
index 58f80a4ed968..d79849ccafc6 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarBatteryController.java
@@ -257,6 +257,11 @@ public class CarBatteryController extends BroadcastReceiver implements BatteryCo
return false;
}
+ @Override
+ public boolean isAodPowerSave() {
+ return false;
+ }
+
private void notifyBatteryLevelChanged() {
for (int i = 0, size = mChangeCallbacks.size(); i < size; i++) {
mChangeCallbacks.get(i)
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index b0ab5b49f340..52aaf4f41eec 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,12 +16,13 @@
package com.android.systemui.statusbar.car;
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+
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.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarUxRestrictionsManager;
@@ -29,21 +30,16 @@ import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
import android.car.trust.CarTrustAgentEnrollmentManager;
import android.content.Context;
import android.content.res.Configuration;
-import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.inputmethodservice.InputMethodService;
-import android.os.IBinder;
+import android.os.PowerManager;
+import android.util.DisplayMetrics;
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;
@@ -57,38 +53,97 @@ 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.logging.MetricsLogger;
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.UiOffloadThread;
+import com.android.systemui.appops.AppOpsController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.classifier.FalsingLog;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
+import com.android.systemui.navigationbar.car.CarFacetButtonController;
+import com.android.systemui.navigationbar.car.CarNavigationBarView;
+import com.android.systemui.navigationbar.car.NavigationBarViewFactory;
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.FeatureFlags;
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.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.car.hvac.HvacController;
import com.android.systemui.statusbar.car.hvac.TemperatureView;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NewNotifPipeline;
+import com.android.systemui.statusbar.notification.NotificationAlertingManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotifLog;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.AutoHideController;
+import com.android.systemui.statusbar.phone.BiometricUnlockController;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.DozeScrimController;
+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.LockscreenWallpaper;
+import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
+import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
+import com.android.systemui.statusbar.phone.StatusBarWindowViewController;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import dagger.Lazy;
+
/**
- * A status bar (and navigation bar) tailored for the automotive use case.
+ * A status bar tailored for the automotive use case.
*/
public class CarStatusBar extends StatusBar implements CarBatteryController.BatteryViewHandler {
private static final String TAG = "CarStatusBar";
@@ -98,21 +153,22 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
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 final ScrimController mScrimController;
private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
private float mClosingVelocity = DEFAULT_FLING_VELOCITY;
- 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;
@@ -121,10 +177,10 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
private boolean mShowLeft;
private boolean mShowRight;
private boolean mShowBottom;
+ private final NavigationBarViewFactory mNavigationBarViewFactory;
private CarFacetButtonController mCarFacetButtonController;
- private ActivityManagerWrapper mActivityManagerWrapper;
private DeviceProvisionedController mDeviceProvisionedController;
- private boolean mDeviceIsProvisioned = true;
+ private boolean mDeviceIsSetUpForUser = true;
private HvacController mHvacController;
private DrivingStateHelper mDrivingStateHelper;
private PowerManagerHelper mPowerManagerHelper;
@@ -145,10 +201,12 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
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;
@@ -159,21 +217,16 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
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 final CarPowerStateListener mCarPowerStateListener =
(int state) -> {
@@ -189,27 +242,159 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
}
};
+ @Inject
+ public CarStatusBar(
+ Context context,
+ FeatureFlags featureFlags,
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ Lazy<NewNotifPipeline> newNotifPipeline,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController,
+ StatusBarWindowViewController.Builder statusBarWindowViewControllerBuild,
+ NotifLog notifLog,
+ DozeParameters dozeParameters,
+ ScrimController scrimController,
+ Lazy<LockscreenWallpaper> lockscreenWallpaperLazy,
+ Lazy<BiometricUnlockController> biometricUnlockControllerLazy,
+ DozeServiceHost dozeServiceHost,
+ PowerManager powerManager,
+ DozeScrimController dozeScrimController,
+
+ /* Car Settings injected components. */
+ NavigationBarViewFactory navigationBarViewFactory) {
+ super(
+ context,
+ featureFlags,
+ lightBarController,
+ autoHideController,
+ keyguardUpdateMonitor,
+ statusBarIconController,
+ dozeLog,
+ injectionInflationController,
+ pulseExpansionHandler,
+ notificationWakeUpCoordinator,
+ keyguardBypassController,
+ keyguardStateController,
+ headsUpManagerPhone,
+ dynamicPrivacyController,
+ bypassHeadsUpNotifier,
+ allowNotificationLongPress,
+ newNotifPipeline,
+ falsingManager,
+ broadcastDispatcher,
+ remoteInputQuickSettingsDisabler,
+ notificationGutsManager,
+ notificationLogger,
+ notificationEntryManager,
+ notificationInterruptionStateProvider,
+ notificationViewHierarchyManager,
+ foregroundServiceController,
+ appOpsController,
+ keyguardViewMediator,
+ zenModeController,
+ notificationAlertingManager,
+ displayMetrics,
+ metricsLogger,
+ uiOffloadThread,
+ notificationMediaManager,
+ lockScreenUserManager,
+ remoteInputManager,
+ userSwitcherController,
+ networkController,
+ batteryController,
+ colorExtractor,
+ screenLifecycle,
+ wakefulnessLifecycle,
+ statusBarStateController,
+ vibratorHelper,
+ bubbleController,
+ groupManager,
+ groupAlertTransferHelper,
+ visualStabilityManager,
+ deviceProvisionedController,
+ navigationBarController,
+ assistManager,
+ notificationListener,
+ configurationController,
+ statusBarWindowController,
+ statusBarWindowViewControllerBuild,
+ notifLog,
+ dozeParameters,
+ scrimController,
+ lockscreenWallpaperLazy,
+ biometricUnlockControllerLazy,
+ dozeServiceHost,
+ powerManager,
+ dozeScrimController);
+ mScrimController = scrimController;
+ mNavigationBarViewFactory = navigationBarViewFactory;
+ }
+
@Override
public void start() {
// get the provisioned state before calling the parent class since it's that flow that
// builds the nav bar
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
- mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
-
- // Keyboard related setup, before nav bars are created.
- mHideNavBarForKeyboard = mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
- mBottomNavBarVisible = false;
+ mDeviceIsSetUpForUser = mDeviceProvisionedController.isCurrentUserSetup();
// 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);
+
super.start();
- mTaskStackListener = new TaskStackListenerImpl();
- mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
- mActivityManagerWrapper.registerTaskStackListener(mTaskStackListener);
mNotificationPanel.setScrollingEnabled(true);
mSettleOpenPercentage = mContext.getResources().getInteger(
@@ -224,25 +409,18 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mHvacController.connectToCarService();
- CarSystemUIFactory factory = SystemUIFactory.getInstance();
- if (!mDeviceIsProvisioned) {
- mDeviceProvisionedController.addCallback(
- new DeviceProvisionedController.DeviceProvisionedListener() {
- @Override
- public void onDeviceProvisionedChanged() {
- mHandler.post(() -> {
- // on initial boot we are getting a call even though the value
- // is the same so we are confirming the reset is needed
- boolean deviceProvisioned =
- mDeviceProvisionedController.isDeviceProvisioned();
- if (mDeviceIsProvisioned != deviceProvisioned) {
- mDeviceIsProvisioned = deviceProvisioned;
- restartNavBars();
- }
- });
- }
- });
- }
+ mDeviceProvisionedController.addCallback(
+ new DeviceProvisionedController.DeviceProvisionedListener() {
+ @Override
+ public void onUserSetupChanged() {
+ mHandler.post(() -> restartNavBarsIfNecessary());
+ }
+
+ @Override
+ public void onUserSwitched() {
+ mHandler.post(() -> restartNavBarsIfNecessary());
+ }
+ });
// Register a listener for driving state changes.
mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
@@ -254,6 +432,14 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
}
+ private void restartNavBarsIfNecessary() {
+ boolean currentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
+ if (mDeviceIsSetUpForUser != currentUserSetup) {
+ mDeviceIsSetUpForUser = currentUserSetup;
+ 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.
@@ -262,29 +448,19 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
// remove and reattach all hvac components such that we don't keep a reference to unused
// ui elements
mHvacController.removeAllComponents();
- addTemperatureViewToController(mStatusBarWindow);
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 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);
@@ -317,7 +493,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
}
}
-
@Override
public boolean hideKeyguard() {
boolean result = super.hideKeyguard();
@@ -357,7 +532,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
@Override
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
super.makeStatusBarView(result);
- mHvacController = new HvacController(mContext);
CarSystemUIFactory factory = SystemUIFactory.getInstance();
mCarFacetButtonController = factory.getCarDependencyComponent()
@@ -382,7 +556,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
* touch listeners needed for opening and closing the notification panel
*/
private void connectNotificationsUI() {
- // Attached to the status bar to detect pull down of the notification shade.
+ // 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
@@ -415,6 +590,18 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
GestureDetector handleBarCloseNotificationGestureDetector = new GestureDetector(mContext,
new HandleBarCloseNotificationGestureListener());
+ mTopNavBarNotificationTouchListener = (v, event) -> {
+ if (!mDeviceIsSetUpForUser) {
+ return true;
+ }
+ boolean consumed = openGestureDetector.onTouchEvent(event);
+ if (consumed) {
+ return true;
+ }
+ maybeCompleteAnimation(event);
+ return true;
+ };
+
mNavBarNotificationTouchListener =
(v, event) -> {
boolean consumed = navBarCloseNotificationGestureDetector.onTouchEvent(event);
@@ -425,21 +612,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
return true;
};
- // The following are the ui elements that the user would call the status bar.
- // This will set the status bar so it they can make call backs.
- CarNavigationBarView topBar = mStatusBarWindow.findViewById(R.id.car_top_bar);
- topBar.setStatusBar(this);
- topBar.setStatusBarWindowTouchListener((v1, event1) -> {
-
- boolean consumed = openGestureDetector.onTouchEvent(event1);
- if (consumed) {
- return true;
- }
- maybeCompleteAnimation(event1);
- return true;
- }
- );
-
mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(mBarService);
mNotificationClickHandlerFactory.registerClickListener((launchResult, alertEntry) -> {
if (launchResult == ActivityManager.START_TASK_TO_FRONT
@@ -616,7 +788,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
return;
}
mStatusBarWindowController.setStatusBarFocusable(false);
- mStatusBarWindow.cancelExpandHelper();
+ mStatusBarWindowViewController.cancelExpandHelper();
mStatusBarView.collapsePanel(true /* animate */, delayed, speedUpFactor);
animateNotificationPanel(mClosingVelocity, true);
@@ -731,197 +903,55 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
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() {
+ buildTopBar();
+
if (mShowBottom) {
- buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar :
- R.layout.car_navigation_bar_unprovisioned);
+ mNavigationBarView = mNavigationBarViewFactory.getBottomBar(mDeviceIsSetUpForUser);
+ mNavigationBarView.setStatusBar(this);
+ mNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
}
if (mShowLeft) {
- buildLeft((mDeviceIsProvisioned) ? R.layout.car_left_navigation_bar :
- R.layout.car_left_navigation_bar_unprovisioned);
+ mLeftNavigationBarView = mNavigationBarViewFactory.getLeftBar(mDeviceIsSetUpForUser);
+ mLeftNavigationBarView.setStatusBar(this);
+ mLeftNavigationBarView.setStatusBarWindowTouchListener(
+ mNavBarNotificationTouchListener);
}
if (mShowRight) {
- buildRight((mDeviceIsProvisioned) ? R.layout.car_right_navigation_bar :
- R.layout.car_right_navigation_bar_unprovisioned);
+ mRightNavigationBarView = mNavigationBarViewFactory.getLeftBar(mDeviceIsSetUpForUser);
+ mRightNavigationBarView.setStatusBar(this);
+ mRightNavigationBarView.setStatusBarWindowTouchListener(
+ mNavBarNotificationTouchListener);
}
}
private void buildNavBarWindows() {
- if (mShowBottom) {
- mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
- R.layout.navigation_bar_window, null);
- }
- 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;
- }
+ mTopNavigationBarContainer = mStatusBarWindow
+ .findViewById(R.id.car_top_navigation_bar_container);
- if (mContext.getDisplay().getDisplayId() != displayId) {
- return;
- }
-
- boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
- if (!isKeyboardVisible) {
- attachBottomNavBarWindow();
- } else {
- detachBottomNavBarWindow();
+ if (mShowBottom) {
+ mNavigationBarWindow = mNavigationBarViewFactory.getBottomWindow();
}
- }
-
- private void attachNavBarWindows() {
- attachBottomNavBarWindow();
-
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);
+ mLeftNavigationBarWindow = mNavigationBarViewFactory.getLeftWindow();
}
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);
+ mRightNavigationBarWindow = mNavigationBarViewFactory.getRightWindow();
}
}
- /**
- * Attaches the bottom nav bar window. Can be extended to modify the specific behavior of
- * attaching the bottom nav bar.
- */
- protected void attachBottomNavBarWindow() {
- if (!mShowBottom) {
- return;
- }
+ private void buildTopBar() {
+ mTopNavigationBarContainer.removeAllViews();
+ mTopNavigationBarView = mNavigationBarViewFactory.getTopBar(mDeviceIsSetUpForUser);
+ mTopNavigationBarContainer.addView(mTopNavigationBarView);
- if (mBottomNavBarVisible) {
- return;
- }
- 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);
- }
-
- /**
- * Detaches the bottom nav bar window. Can be extended to modify the specific behavior of
- * detaching the bottom nav bar.
- */
- protected void detachBottomNavBarWindow() {
- if (!mShowBottom) {
- return;
- }
-
- if (!mBottomNavBarVisible) {
- return;
- }
- mBottomNavBarVisible = false;
- mWindowManager.removeView(mNavigationBarWindow);
- }
-
- 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 botom nav bar due to missing layout");
- }
- mNavigationBarView.setStatusBar(this);
- addTemperatureViewToController(mNavigationBarView);
- 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_navigation_bar");
- throw new RuntimeException("Unable to build left nav bar due to missing layout");
- }
- mLeftNavigationBarView.setStatusBar(this);
- addTemperatureViewToController(mLeftNavigationBarView);
- 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_navigation_bar");
- throw new RuntimeException("Unable to build right nav bar due to missing layout");
- }
- mRightNavigationBarView.setStatusBar(this);
- addTemperatureViewToController(mRightNavigationBarView);
- mRightNavigationBarView.setStatusBarWindowTouchListener(mNavBarNotificationTouchListener);
+ mTopNavigationBarView.setStatusBar(this);
+ addTemperatureViewToController(mTopNavigationBarView);
+ mTopNavigationBarView.setStatusBarWindowTouchListener(mTopNavBarNotificationTouchListener);
}
@Override
@@ -935,8 +965,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
+ "," + mStackScroller.getScrollY());
}
- pw.print(" mTaskStackListener=");
- pw.println(mTaskStackListener);
pw.print(" mCarFacetButtonController=");
pw.println(mCarFacetButtonController);
pw.print(" mFullscreenUserSwitcher=");
@@ -945,8 +973,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
pw.println(mCarBatteryController);
pw.print(" mBatteryMeterView=");
pw.println(mBatteryMeterView);
- pw.print(" mNavigationBarView=");
- pw.println(mNavigationBarView);
if (Dependency.get(KeyguardUpdateMonitor.class) != null) {
Dependency.get(KeyguardUpdateMonitor.class).dump(fd, pw, args);
@@ -986,32 +1012,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
}
}
- /**
- * 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();
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
index 827a59eddf56..3b482599b2a0 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/UserGridRecyclerView.java
@@ -18,18 +18,25 @@ package com.android.systemui.statusbar.car;
import static android.content.DialogInterface.BUTTON_NEGATIVE;
import static android.content.DialogInterface.BUTTON_POSITIVE;
+import static android.os.UserManager.DISALLOW_ADD_USER;
+import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.car.userlib.CarUserManagerHelper;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.AsyncTask;
+import android.os.UserHandle;
+import android.os.UserManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -48,24 +55,33 @@ import com.android.systemui.statusbar.phone.SystemUIDialog;
import java.util.ArrayList;
import java.util.List;
+import java.util.stream.Collectors;
/**
* Displays a GridLayout with icons for the users in the system to allow switching between users.
* One of the uses of this is for the lock screen in auto.
*/
-public class UserGridRecyclerView extends RecyclerView implements
- CarUserManagerHelper.OnUsersUpdateListener {
+public class UserGridRecyclerView extends RecyclerView {
private UserSelectionListener mUserSelectionListener;
private UserAdapter mAdapter;
private CarUserManagerHelper mCarUserManagerHelper;
+ private UserManager mUserManager;
private Context mContext;
+ private final BroadcastReceiver mUserUpdateReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ onUsersUpdate();
+ }
+ };
+
public UserGridRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mCarUserManagerHelper = new CarUserManagerHelper(mContext);
+ mUserManager = UserManager.get(mContext);
- addItemDecoration(new ItemSpacingDecoration(context.getResources().getDimensionPixelSize(
+ addItemDecoration(new ItemSpacingDecoration(mContext.getResources().getDimensionPixelSize(
R.dimen.car_user_switcher_vertical_spacing_between_users)));
}
@@ -75,7 +91,7 @@ public class UserGridRecyclerView extends RecyclerView implements
@Override
public void onFinishInflate() {
super.onFinishInflate();
- mCarUserManagerHelper.registerOnUsersUpdateListener(this);
+ registerForUserEvents();
}
/**
@@ -84,7 +100,7 @@ public class UserGridRecyclerView extends RecyclerView implements
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mCarUserManagerHelper.unregisterOnUsersUpdateListener(this);
+ unregisterForUserEvents();
}
/**
@@ -93,12 +109,18 @@ public class UserGridRecyclerView extends RecyclerView implements
* @return the adapter
*/
public void buildAdapter() {
- List<UserRecord> userRecords = createUserRecords(mCarUserManagerHelper
- .getAllUsers());
+ List<UserRecord> userRecords = createUserRecords(getUsersForUserGrid());
mAdapter = new UserAdapter(mContext, userRecords);
super.setAdapter(mAdapter);
}
+ private List<UserInfo> getUsersForUserGrid() {
+ return mUserManager.getUsers(/* excludeDying= */ true)
+ .stream()
+ .filter(UserInfo::supportsSwitchToByUser)
+ .collect(Collectors.toList());
+ }
+
private List<UserRecord> createUserRecords(List<UserInfo> userInfoList) {
List<UserRecord> userRecords = new ArrayList<>();
@@ -114,8 +136,7 @@ public class UserGridRecyclerView extends RecyclerView implements
continue;
}
- boolean isForeground =
- mCarUserManagerHelper.getCurrentForegroundUserId() == userInfo.id;
+ boolean isForeground = ActivityManager.getCurrentUser() == userInfo.id;
UserRecord record = new UserRecord(userInfo, false /* isStartGuestSession */,
false /* isAddUser */, isForeground);
userRecords.add(record);
@@ -125,7 +146,8 @@ public class UserGridRecyclerView extends RecyclerView implements
userRecords.add(createStartGuestUserRecord());
// Add add user record if the foreground user can add users
- if (mCarUserManagerHelper.canForegroundUserAddUsers()) {
+ UserHandle fgUserHandle = UserHandle.of(ActivityManager.getCurrentUser());
+ if (!mUserManager.hasUserRestriction(DISALLOW_ADD_USER, fgUserHandle)) {
userRecords.add(createAddUserRecord());
}
@@ -133,7 +155,7 @@ public class UserGridRecyclerView extends RecyclerView implements
}
private UserRecord createForegroundUserRecord() {
- return new UserRecord(mCarUserManagerHelper.getCurrentForegroundUserInfo(),
+ return new UserRecord(mUserManager.getUserInfo(ActivityManager.getCurrentUser()),
false /* isStartGuestSession */, false /* isAddUser */, true /* isForeground */);
}
@@ -161,13 +183,30 @@ public class UserGridRecyclerView extends RecyclerView implements
mUserSelectionListener = userSelectionListener;
}
- @Override
- public void onUsersUpdate() {
+ private void onUsersUpdate() {
mAdapter.clearUsers();
- mAdapter.updateUsers(createUserRecords(mCarUserManagerHelper.getAllUsers()));
+ mAdapter.updateUsers(createUserRecords(getUsersForUserGrid()));
mAdapter.notifyDataSetChanged();
}
+ private void registerForUserEvents() {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(Intent.ACTION_USER_ADDED);
+ filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
+ filter.addAction(Intent.ACTION_USER_SWITCHED);
+ mContext.registerReceiverAsUser(
+ mUserUpdateReceiver,
+ UserHandle.ALL, // Necessary because CarSystemUi lives in User 0
+ filter,
+ /* broadcastPermission= */ null,
+ /* scheduler= */ null);
+ }
+
+ private void unregisterForUserEvents() {
+ mContext.unregisterReceiver(mUserUpdateReceiver);
+ }
+
/**
* Adapter to populate the grid layout with the available user profiles
*/
@@ -248,7 +287,7 @@ public class UserGridRecyclerView extends RecyclerView implements
}
private void handleAddUserClicked() {
- if (mCarUserManagerHelper.isUserLimitReached()) {
+ if (!mUserManager.canAddMoreUsers()) {
mAddUserView.setEnabled(true);
showMaxUserLimitReachedDialog();
} else {
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
index 30429eda7be7..e81be1b0b186 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/hvac/HvacController.java
@@ -38,6 +38,8 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
+import javax.inject.Inject;
+
/**
* Manages the connection to the Car service and delegates value changes to the registered
* {@link TemperatureView}s
@@ -119,6 +121,7 @@ public class HvacController {
}
};
+ @Inject
public HvacController(Context context) {
mContext = context;
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java
index ead1de2bd352..88d641e8bb36 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/OngoingPrivacyChip.java
@@ -47,6 +47,7 @@ import java.util.stream.Collectors;
public class OngoingPrivacyChip extends LinearLayout implements View.OnClickListener {
private Context mContext;
+ private Handler mHandler;
private LinearLayout mIconsContainer;
private List<PrivacyItem> mPrivacyItems;
@@ -88,6 +89,7 @@ public class OngoingPrivacyChip extends LinearLayout implements View.OnClickList
private void init(Context context) {
mContext = context;
+ mHandler = new Handler(Looper.getMainLooper());
mPrivacyItems = new ArrayList<>();
sAppOpsController = Dependency.get(AppOpsController.class);
mUserManager = mContext.getSystemService(UserManager.class);
@@ -131,8 +133,7 @@ public class OngoingPrivacyChip extends LinearLayout implements View.OnClickList
@Override
public void onClick(View v) {
updatePrivacyList();
- Handler mUiHandler = new Handler(Looper.getMainLooper());
- mUiHandler.post(() -> {
+ mHandler.post(() -> {
mActivityStarter.postStartActivityDismissingKeyguard(
new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
});
@@ -152,21 +153,17 @@ public class OngoingPrivacyChip extends LinearLayout implements View.OnClickList
}
private void updatePrivacyList() {
- mPrivacyItems = mCurrentUserIds.stream()
+ List<PrivacyItem> privacyItems = mCurrentUserIds.stream()
.flatMap(item -> sAppOpsController.getActiveAppOpsForUser(item).stream())
.filter(Objects::nonNull)
.map(item -> toPrivacyItem(item))
.filter(Objects::nonNull)
.collect(Collectors.toList());
- mPrivacyDialogBuilder = new PrivacyDialogBuilder(mContext, mPrivacyItems);
-
- Handler refresh = new Handler(Looper.getMainLooper());
- refresh.post(new Runnable() {
- @Override
- public void run() {
- updateView();
- }
- });
+ if (!privacyItems.equals(mPrivacyItems)) {
+ mPrivacyItems = privacyItems;
+ mPrivacyDialogBuilder = new PrivacyDialogBuilder(mContext, mPrivacyItems);
+ mHandler.post(this::updateView);
+ }
}
private PrivacyItem toPrivacyItem(AppOpItem appOpItem) {
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java
index 5ec7a77cb305..a5d3bf7cc9c1 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyApplication.java
@@ -16,28 +16,31 @@
package com.android.systemui.statusbar.car.privacy;
-import android.car.userlib.CarUserManagerHelper;
+import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.util.Log;
+import java.util.Objects;
+
/**
* Class to hold the data for the applications that are using the AppOps permissions.
*/
public class PrivacyApplication {
private static final String TAG = "PrivacyApplication";
+ private String mPackageName;
private Drawable mIcon;
private String mApplicationName;
public PrivacyApplication(String packageName, Context context) {
+ mPackageName = packageName;
try {
- CarUserManagerHelper carUserManagerHelper = new CarUserManagerHelper(context);
ApplicationInfo app = context.getPackageManager()
.getApplicationInfoAsUser(packageName, 0,
- carUserManagerHelper.getCurrentForegroundUserId());
+ ActivityManager.getCurrentUser());
mIcon = context.getPackageManager().getApplicationIcon(app);
mApplicationName = context.getPackageManager().getApplicationLabel(app).toString();
} catch (PackageManager.NameNotFoundException e) {
@@ -59,4 +62,17 @@ public class PrivacyApplication {
public String getApplicationName() {
return mApplicationName;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PrivacyApplication that = (PrivacyApplication) o;
+ return mPackageName.equals(that.mPackageName);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPackageName);
+ }
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java
index fca137392d74..d3e123ed8c25 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/privacy/PrivacyItem.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.car.privacy;
+import java.util.Objects;
+
/**
* Class for holding the data of each privacy item displayed in {@link OngoingPrivacyDialog}
*/
@@ -43,4 +45,18 @@ public class PrivacyItem {
public PrivacyType getPrivacyType() {
return mPrivacyType;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PrivacyItem that = (PrivacyItem) o;
+ return mPrivacyType == that.mPrivacyType
+ && mPrivacyApplication.equals(that.mPrivacyApplication);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mPrivacyType, mPrivacyApplication);
+ }
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
index 71cc19b63ac1..4d6af95b3f9c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogComponent.java
@@ -19,15 +19,21 @@ package com.android.systemui.volume;
import android.content.Context;
import com.android.systemui.SystemUI;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.VolumeDialog;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* Allows for adding car specific dialog when the volume dialog is created.
*/
+@Singleton
public class CarVolumeDialogComponent extends VolumeDialogComponent {
- public CarVolumeDialogComponent(SystemUI sysui, Context context) {
- super(sysui, context);
+ @Inject
+ public CarVolumeDialogComponent(Context context, KeyguardViewMediator keyguardViewMediator) {
+ super(context, keyguardViewMediator);
}
protected VolumeDialog createDefault() {
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index d0a63f058291..22c7c7a3d6af 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -143,6 +143,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
private boolean mHovering;
private int mCurrentlyDisplayingGroupId;
private boolean mShowing;
+ private boolean mDismissing;
private boolean mExpanded;
private View mExpandIcon;
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@@ -244,6 +245,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
mHovering = false;
mShowing = false;
+ mDismissing = false;
mExpanded = false;
mWindow = mDialog.getWindow();
mWindow.requestFeature(Window.FEATURE_NO_TITLE);
@@ -335,14 +337,11 @@ public class CarVolumeDialogImpl implements VolumeDialog {
mHandler.removeMessages(H.DISMISS);
mHandler.removeMessages(H.SHOW);
- if (!mShowing) {
+ if (!mShowing || mDismissing) {
return;
}
- mListView.animate().cancel();
-
- mListView.setTranslationY(0);
- mListView.setAlpha(1);
+ mDismissing = true;
mListView.animate()
.alpha(0)
.translationY(-mListView.getHeight())
@@ -354,7 +353,7 @@ public class CarVolumeDialogImpl implements VolumeDialog {
}
mDialog.dismiss();
mShowing = false;
- mShowing = false;
+ mDismissing = false;
// if mExpandIcon is null that means user never clicked on the expanded arrow
// which implies that the dialog is still not expanded. In that case we do
// not want to reset the state