From e0e71bcabb7225738d9a21f9949a7ccd71268762 Mon Sep 17 00:00:00 2001 From: Heemin Seog Date: Thu, 7 Nov 2019 16:38:03 -0800 Subject: [PATCH] DO NOT MERGE Create a single provider of car service This should be shared across all things requiring it in system UI. Test: manual Bug: 142808072 Change-Id: I334d74c3bbe8270822feae268513bf93a4160a5b --- .../android/systemui/CarSystemUIFactory.java | 10 ++++ .../systemui/car/CarServiceProvider.java | 59 +++++++++++++++++++ .../systemui/statusbar/car/CarStatusBar.java | 11 ++-- .../statusbar/car/DrivingStateHelper.java | 8 ++- .../statusbar/car/FullscreenUserSwitcher.java | 7 ++- .../statusbar/car/PowerManagerHelper.java | 8 ++- .../statusbar/car/hvac/HvacController.java | 13 ++-- .../systemui/volume/CarVolumeDialogImpl.java | 13 ++-- 8 files changed, 98 insertions(+), 31 deletions(-) create mode 100644 packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java index c7654e81e0b17..a4235540e3375 100644 --- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java +++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIFactory.java @@ -20,6 +20,7 @@ import android.content.Context; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.ViewMediatorCallback; +import com.android.systemui.car.CarServiceProvider; import com.android.systemui.statusbar.car.CarFacetButtonController; import com.android.systemui.statusbar.car.CarStatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -36,6 +37,7 @@ import dagger.Component; public class CarSystemUIFactory extends SystemUIFactory { private CarDependencyComponent mCarDependencyComponent; + private CarServiceProvider mCarServiceProvider; @Override protected SystemUIRootComponent buildSystemUIRootComponent(Context context) { @@ -48,6 +50,14 @@ public class CarSystemUIFactory extends SystemUIFactory { .build(); } + /** Gets a {@link CarServiceProvider}. */ + public CarServiceProvider getCarServiceProvider(Context context) { + if (mCarServiceProvider == null) { + mCarServiceProvider = new CarServiceProvider(context); + } + return mCarServiceProvider; + } + public CarDependencyComponent getCarDependencyComponent() { return mCarDependencyComponent; } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java b/packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java new file mode 100644 index 0000000000000..9ee368ee497fd --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/CarServiceProvider.java @@ -0,0 +1,59 @@ +/* + * 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.car; + +import android.car.Car; +import android.car.Car.CarServiceLifecycleListener; +import android.content.Context; + +import java.util.ArrayList; +import java.util.List; + +/** + * Connects to the car service a single time for shared use across all of system ui. + */ +public class CarServiceProvider { + + private final Context mContext; + private final List mListeners = new ArrayList<>(); + private Car mCar; + + public CarServiceProvider(Context context) { + mContext = context; + mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT, + (car, ready) -> { + mCar = car; + + synchronized (mListeners) { + for (CarServiceLifecycleListener listener : mListeners) { + listener.onLifecycleChanged(mCar, ready); + } + } + }); + } + + /** + * Let's other components hook into the connection to the car service. If we're already + * connected + * to the car service, the callback is immediately triggered. + */ + public void addListener(CarServiceLifecycleListener listener) { + if (mCar.isConnected()) { + listener.onLifecycleChanged(mCar, /* ready= */ true); + } + mListeners.add(listener); + } +} 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 1a1a8ea501bb1..4e98da6b1833e 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java @@ -199,6 +199,10 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt @Override public void start() { + // Non blocking call to connect to car service. Call this early so that we'll be connected + // asap. + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext); + // get the provisioned state before calling the parent class since it's that flow that // builds the nav bar mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class); @@ -482,11 +486,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt CarNotificationListener carNotificationListener = new CarNotificationListener(); mCarUxRestrictionManagerWrapper = new CarUxRestrictionManagerWrapper(); - // This can take time if car service is not ready up to this time. - // TODO(b/142808072) Refactor CarUxRestrictionManagerWrapper to allow setting - // CarUxRestrictionsManager later and switch to Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT. - Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_WAIT_FOREVER, - (car, ready) -> { + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) + .addListener((car, ready) -> { if (!ready) { return; } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java index cd87e78e4be9b..76ad04f6716f2 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java @@ -26,6 +26,9 @@ import android.util.Log; import androidx.annotation.NonNull; +import com.android.systemui.CarSystemUIFactory; +import com.android.systemui.SystemUIFactory; + /** * Helper class for connecting to the {@link CarDrivingStateManager} and listening for driving state * changes. @@ -35,7 +38,6 @@ public class DrivingStateHelper { private final Context mContext; private CarDrivingStateManager mDrivingStateManager; - private Car mCar; private CarDrivingStateEventListener mDrivingStateHandler; public DrivingStateHelper(Context context, @@ -64,8 +66,8 @@ public class DrivingStateHelper { * Establishes connection with the Car service. */ public void connectToCarService() { - mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT, - mCarServiceLifecycleListener); + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) + .addListener(mCarServiceLifecycleListener); } private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> { diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java index 31aced02b15e3..0ebfa84a13f1b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java @@ -34,7 +34,9 @@ import android.view.ViewStub; import androidx.recyclerview.widget.GridLayoutManager; +import com.android.systemui.CarSystemUIFactory; import com.android.systemui.R; +import com.android.systemui.SystemUIFactory; import com.android.systemui.statusbar.car.CarTrustAgentUnlockDialogHelper.OnHideListener; import com.android.systemui.statusbar.car.UserGridRecyclerView.UserRecord; @@ -65,7 +67,6 @@ public class FullscreenUserSwitcher { mContext.unregisterReceiver(mUserUnlockReceiver); } }; - private final Car mCar; public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) { mStatusBar = statusBar; @@ -85,8 +86,8 @@ public class FullscreenUserSwitcher { mUnlockDialogHelper = new CarTrustAgentUnlockDialogHelper(mContext); mUserManager = mContext.getSystemService(UserManager.class); - mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT, - (car, ready) -> { + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) + .addListener((car, ready) -> { if (!ready) { return; } diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java index a27dd341d4495..d87b54c39fd7f 100644 --- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java +++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java @@ -24,6 +24,9 @@ import android.car.hardware.power.CarPowerManager.CarPowerStateListener; import android.content.Context; import android.util.Log; +import com.android.systemui.CarSystemUIFactory; +import com.android.systemui.SystemUIFactory; + /** * Helper class for connecting to the {@link CarPowerManager} and listening for power state changes. */ @@ -33,7 +36,6 @@ public class PowerManagerHelper { private final Context mContext; private final CarPowerStateListener mCarPowerStateListener; - private Car mCar; private CarPowerManager mCarPowerManager; private final CarServiceLifecycleListener mCarServiceLifecycleListener; @@ -59,7 +61,7 @@ public class PowerManagerHelper { * Connect to Car service. */ void connectToCarService() { - mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT, - mCarServiceLifecycleListener); + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) + .addListener(mCarServiceLifecycleListener); } } 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 a8515f94517ee..1d9675034bc51 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 @@ -26,9 +26,11 @@ import android.car.hardware.CarPropertyValue; import android.car.hardware.hvac.CarHvacManager; import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback; import android.content.Context; -import android.os.Handler; import android.util.Log; +import com.android.systemui.CarSystemUIFactory; +import com.android.systemui.SystemUIFactory; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -41,13 +43,9 @@ import java.util.Objects; * {@link TemperatureView}s */ public class HvacController { - public static final String TAG = "HvacController"; - public static final int BIND_TO_HVAC_RETRY_DELAY = 5000; private Context mContext; - private Handler mHandler; - private Car mCar; private CarHvacManager mHvacManager; private HashMap> mTempComponents = new HashMap<>(); @@ -105,9 +103,8 @@ public class HvacController { * ({@link CarHvacManager}) will happen on the same thread this method was called from. */ public void connectToCarService() { - mHandler = new Handler(); - mCar = Car.createCar(mContext, /* handler= */ mHandler, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT, - mCarServiceLifecycleListener); + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) + .addListener(mCarServiceLifecycleListener); } /** diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java index 09223e8ff4c3a..0dad8e51ad7d0 100644 --- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java +++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java @@ -55,7 +55,9 @@ import android.widget.SeekBar.OnSeekBarChangeListener; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import com.android.systemui.CarSystemUIFactory; import com.android.systemui.R; +import com.android.systemui.SystemUIFactory; import com.android.systemui.plugins.VolumeDialog; import org.xmlpull.v1.XmlPullParserException; @@ -95,7 +97,6 @@ public class CarVolumeDialogImpl implements VolumeDialog { private CustomDialog mDialog; private RecyclerView mListView; private CarVolumeItemAdapter mVolumeItemsAdapter; - private Car mCar; private CarAudioManager mCarAudioManager; private boolean mHovering; private int mCurrentlyDisplayingGroupId; @@ -196,8 +197,8 @@ public class CarVolumeDialogImpl implements VolumeDialog { @Override public void init(int windowType, Callback callback) { initDialog(); - mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT, - mCarServiceLifecycleListener); + ((CarSystemUIFactory) SystemUIFactory.getInstance()).getCarServiceProvider(mContext) + .addListener(mCarServiceLifecycleListener); } @Override @@ -205,12 +206,6 @@ public class CarVolumeDialogImpl implements VolumeDialog { mHandler.removeCallbacksAndMessages(/* token= */ null); cleanupAudioManager(); - // unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup - // audio manager beforehand. - if (mCar != null) { - mCar.disconnect(); - mCar = null; - } } private void initDialog() {