Merge "Migrate car sysui to use new createCar call and prevent crash" into qt-qpr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
eeb9a61f63
@@ -26,7 +26,6 @@ import android.car.Car;
|
|||||||
import android.car.drivingstate.CarDrivingStateEvent;
|
import android.car.drivingstate.CarDrivingStateEvent;
|
||||||
import android.car.drivingstate.CarUxRestrictionsManager;
|
import android.car.drivingstate.CarUxRestrictionsManager;
|
||||||
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
|
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
|
||||||
import android.car.trust.CarTrustAgentEnrollmentManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -182,6 +181,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
|
|||||||
private boolean mHideNavBarForKeyboard;
|
private boolean mHideNavBarForKeyboard;
|
||||||
private boolean mBottomNavBarVisible;
|
private boolean mBottomNavBarVisible;
|
||||||
|
|
||||||
|
private CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper;
|
||||||
|
|
||||||
private final CarPowerStateListener mCarPowerStateListener =
|
private final CarPowerStateListener mCarPowerStateListener =
|
||||||
(int state) -> {
|
(int state) -> {
|
||||||
// When the car powers on, clear all notifications and mute/unread states.
|
// When the car powers on, clear all notifications and mute/unread states.
|
||||||
@@ -267,14 +268,16 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Used by onDrivingStateChanged and it can be called inside
|
||||||
|
// DrivingStateHelper.connectToCarService()
|
||||||
|
mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
|
||||||
|
|
||||||
// Register a listener for driving state changes.
|
// Register a listener for driving state changes.
|
||||||
mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
|
mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
|
||||||
mDrivingStateHelper.connectToCarService();
|
mDrivingStateHelper.connectToCarService();
|
||||||
|
|
||||||
mPowerManagerHelper = new PowerManagerHelper(mContext, mCarPowerStateListener);
|
mPowerManagerHelper = new PowerManagerHelper(mContext, mCarPowerStateListener);
|
||||||
mPowerManagerHelper.connectToCarService();
|
mPowerManagerHelper.connectToCarService();
|
||||||
|
|
||||||
mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartNavBarsIfNecessary() {
|
private void restartNavBarsIfNecessary() {
|
||||||
@@ -476,13 +479,23 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
|
|||||||
animateCollapsePanels();
|
animateCollapsePanels();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Car car = Car.createCar(mContext);
|
|
||||||
CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
|
|
||||||
car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
|
|
||||||
CarNotificationListener carNotificationListener = new CarNotificationListener();
|
CarNotificationListener carNotificationListener = new CarNotificationListener();
|
||||||
CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper =
|
mCarUxRestrictionManagerWrapper = new CarUxRestrictionManagerWrapper();
|
||||||
new CarUxRestrictionManagerWrapper();
|
// This can take time if car service is not ready up to this time.
|
||||||
carUxRestrictionManagerWrapper.setCarUxRestrictionsManager(carUxRestrictionsManager);
|
// 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) -> {
|
||||||
|
if (!ready) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CarUxRestrictionsManager carUxRestrictionsManager =
|
||||||
|
(CarUxRestrictionsManager)
|
||||||
|
car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
|
||||||
|
mCarUxRestrictionManagerWrapper.setCarUxRestrictionsManager(
|
||||||
|
carUxRestrictionsManager);
|
||||||
|
});
|
||||||
|
|
||||||
mNotificationDataManager = new NotificationDataManager();
|
mNotificationDataManager = new NotificationDataManager();
|
||||||
mNotificationDataManager.setOnUnseenCountUpdateListener(
|
mNotificationDataManager.setOnUnseenCountUpdateListener(
|
||||||
@@ -511,7 +524,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
|
|||||||
mNotificationClickHandlerFactory, mNotificationDataManager);
|
mNotificationClickHandlerFactory, mNotificationDataManager);
|
||||||
mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager);
|
mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager);
|
||||||
|
|
||||||
carNotificationListener.registerAsSystemService(mContext, carUxRestrictionManagerWrapper,
|
carNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper,
|
||||||
carHeadsUpNotificationManager, mNotificationDataManager);
|
carHeadsUpNotificationManager, mNotificationDataManager);
|
||||||
|
|
||||||
mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view);
|
mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view);
|
||||||
@@ -611,7 +624,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
|
|||||||
mNotificationView,
|
mNotificationView,
|
||||||
PreprocessingManager.getInstance(mContext),
|
PreprocessingManager.getInstance(mContext),
|
||||||
carNotificationListener,
|
carNotificationListener,
|
||||||
carUxRestrictionManagerWrapper,
|
mCarUxRestrictionManagerWrapper,
|
||||||
mNotificationDataManager);
|
mNotificationDataManager);
|
||||||
mNotificationViewController.enable();
|
mNotificationViewController.enable();
|
||||||
}
|
}
|
||||||
@@ -1061,12 +1074,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
|
|||||||
UserSwitcherController userSwitcherController =
|
UserSwitcherController userSwitcherController =
|
||||||
Dependency.get(UserSwitcherController.class);
|
Dependency.get(UserSwitcherController.class);
|
||||||
if (userSwitcherController.useFullscreenUserSwitcher()) {
|
if (userSwitcherController.useFullscreenUserSwitcher()) {
|
||||||
Car car = Car.createCar(mContext);
|
|
||||||
CarTrustAgentEnrollmentManager enrollmentManager = (CarTrustAgentEnrollmentManager) car
|
|
||||||
.getCarManager(Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE);
|
|
||||||
mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
|
mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
|
||||||
mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub),
|
mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext);
|
||||||
enrollmentManager, mContext);
|
|
||||||
} else {
|
} else {
|
||||||
super.createUserSwitcher();
|
super.createUserSwitcher();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,11 @@
|
|||||||
package com.android.systemui.statusbar.car;
|
package com.android.systemui.statusbar.car;
|
||||||
|
|
||||||
import android.car.Car;
|
import android.car.Car;
|
||||||
import android.car.CarNotConnectedException;
|
import android.car.Car.CarServiceLifecycleListener;
|
||||||
import android.car.drivingstate.CarDrivingStateEvent;
|
import android.car.drivingstate.CarDrivingStateEvent;
|
||||||
import android.car.drivingstate.CarDrivingStateManager;
|
import android.car.drivingstate.CarDrivingStateManager;
|
||||||
import android.car.drivingstate.CarDrivingStateManager.CarDrivingStateEventListener;
|
import android.car.drivingstate.CarDrivingStateManager.CarDrivingStateEventListener;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@@ -55,16 +52,11 @@ public class DrivingStateHelper {
|
|||||||
if (mDrivingStateManager == null) {
|
if (mDrivingStateManager == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try {
|
CarDrivingStateEvent currentState = mDrivingStateManager.getCurrentCarDrivingState();
|
||||||
CarDrivingStateEvent currentState = mDrivingStateManager.getCurrentCarDrivingState();
|
if (currentState != null) {
|
||||||
if (currentState != null) {
|
return currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_IDLING
|
||||||
return currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_IDLING
|
|| currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING;
|
||||||
|| currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING;
|
|
||||||
}
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Cannot determine current driving state. Car not connected", e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // Default to false.
|
return false; // Default to false.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,55 +64,25 @@ public class DrivingStateHelper {
|
|||||||
* Establishes connection with the Car service.
|
* Establishes connection with the Car service.
|
||||||
*/
|
*/
|
||||||
public void connectToCarService() {
|
public void connectToCarService() {
|
||||||
mCar = Car.createCar(mContext, mCarConnectionListener);
|
mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
|
||||||
if (mCar != null) {
|
mCarServiceLifecycleListener);
|
||||||
mCar.connect();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
|
||||||
* Disconnects from Car service and cleans up listeners.
|
if (!ready) {
|
||||||
*/
|
return;
|
||||||
public void disconnectFromCarService() {
|
|
||||||
if (mCar != null) {
|
|
||||||
mCar.disconnect();
|
|
||||||
}
|
}
|
||||||
}
|
logD("Car Service connected");
|
||||||
|
mDrivingStateManager = (CarDrivingStateManager) car.getCarManager(
|
||||||
private final ServiceConnection mCarConnectionListener =
|
Car.CAR_DRIVING_STATE_SERVICE);
|
||||||
new ServiceConnection() {
|
if (mDrivingStateManager != null) {
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
mDrivingStateManager.registerListener(mDrivingStateHandler);
|
||||||
logD("Car Service connected");
|
mDrivingStateHandler.onDrivingStateChanged(
|
||||||
try {
|
mDrivingStateManager.getCurrentCarDrivingState());
|
||||||
mDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(
|
} else {
|
||||||
Car.CAR_DRIVING_STATE_SERVICE);
|
Log.e(TAG, "CarDrivingStateService service not available");
|
||||||
if (mDrivingStateManager != null) {
|
|
||||||
mDrivingStateManager.registerListener(mDrivingStateHandler);
|
|
||||||
mDrivingStateHandler.onDrivingStateChanged(
|
|
||||||
mDrivingStateManager.getCurrentCarDrivingState());
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "CarDrivingStateService service not available");
|
|
||||||
}
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Car not connected", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
destroyDrivingStateManager();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void destroyDrivingStateManager() {
|
|
||||||
try {
|
|
||||||
if (mDrivingStateManager != null) {
|
|
||||||
mDrivingStateManager.unregisterListener();
|
|
||||||
}
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Error unregistering listeners", e);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
private void logD(String message) {
|
private void logD(String message) {
|
||||||
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
if (Log.isLoggable(TAG, Log.DEBUG)) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.car;
|
|||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
import android.car.Car;
|
||||||
import android.car.trust.CarTrustAgentEnrollmentManager;
|
import android.car.trust.CarTrustAgentEnrollmentManager;
|
||||||
import android.car.userlib.CarUserManagerHelper;
|
import android.car.userlib.CarUserManagerHelper;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -50,7 +51,7 @@ public class FullscreenUserSwitcher {
|
|||||||
private final CarStatusBar mStatusBar;
|
private final CarStatusBar mStatusBar;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
private final UserManager mUserManager;
|
private final UserManager mUserManager;
|
||||||
private final CarTrustAgentEnrollmentManager mEnrollmentManager;
|
private CarTrustAgentEnrollmentManager mEnrollmentManager;
|
||||||
private CarTrustAgentUnlockDialogHelper mUnlockDialogHelper;
|
private CarTrustAgentUnlockDialogHelper mUnlockDialogHelper;
|
||||||
private UserGridRecyclerView.UserRecord mSelectedUser;
|
private UserGridRecyclerView.UserRecord mSelectedUser;
|
||||||
private CarUserManagerHelper mCarUserManagerHelper;
|
private CarUserManagerHelper mCarUserManagerHelper;
|
||||||
@@ -64,13 +65,11 @@ public class FullscreenUserSwitcher {
|
|||||||
mContext.unregisterReceiver(mUserUnlockReceiver);
|
mContext.unregisterReceiver(mUserUnlockReceiver);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private final Car mCar;
|
||||||
|
|
||||||
|
public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) {
|
||||||
public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub,
|
|
||||||
CarTrustAgentEnrollmentManager enrollmentManager, Context context) {
|
|
||||||
mStatusBar = statusBar;
|
mStatusBar = statusBar;
|
||||||
mParent = containerStub.inflate();
|
mParent = containerStub.inflate();
|
||||||
mEnrollmentManager = enrollmentManager;
|
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
|
||||||
View container = mParent.findViewById(R.id.container);
|
View container = mParent.findViewById(R.id.container);
|
||||||
@@ -86,6 +85,15 @@ public class FullscreenUserSwitcher {
|
|||||||
mUnlockDialogHelper = new CarTrustAgentUnlockDialogHelper(mContext);
|
mUnlockDialogHelper = new CarTrustAgentUnlockDialogHelper(mContext);
|
||||||
mUserManager = mContext.getSystemService(UserManager.class);
|
mUserManager = mContext.getSystemService(UserManager.class);
|
||||||
|
|
||||||
|
mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
|
||||||
|
(car, ready) -> {
|
||||||
|
if (!ready) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mEnrollmentManager = (CarTrustAgentEnrollmentManager) car
|
||||||
|
.getCarManager(Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE);
|
||||||
|
});
|
||||||
|
|
||||||
mShortAnimDuration = container.getResources()
|
mShortAnimDuration = container.getResources()
|
||||||
.getInteger(android.R.integer.config_shortAnimTime);
|
.getInteger(android.R.integer.config_shortAnimTime);
|
||||||
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
|
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
|
||||||
@@ -201,6 +209,9 @@ public class FullscreenUserSwitcher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasTrustedDevice(int uid) {
|
private boolean hasTrustedDevice(int uid) {
|
||||||
|
if (mEnrollmentManager == null) { // car service not ready, so it cannot be available.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return !mEnrollmentManager.getEnrolledDeviceInfoForUser(uid).isEmpty();
|
return !mEnrollmentManager.getEnrolledDeviceInfoForUser(uid).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,10 @@ package com.android.systemui.statusbar.car;
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.car.Car;
|
import android.car.Car;
|
||||||
import android.car.CarNotConnectedException;
|
import android.car.Car.CarServiceLifecycleListener;
|
||||||
import android.car.hardware.power.CarPowerManager;
|
import android.car.hardware.power.CarPowerManager;
|
||||||
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
|
import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.os.IBinder;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,55 +36,30 @@ public class PowerManagerHelper {
|
|||||||
private Car mCar;
|
private Car mCar;
|
||||||
private CarPowerManager mCarPowerManager;
|
private CarPowerManager mCarPowerManager;
|
||||||
|
|
||||||
private final ServiceConnection mCarConnectionListener =
|
private final CarServiceLifecycleListener mCarServiceLifecycleListener;
|
||||||
new ServiceConnection() {
|
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
|
||||||
Log.d(TAG, "Car Service connected");
|
|
||||||
try {
|
|
||||||
mCarPowerManager = (CarPowerManager) mCar.getCarManager(Car.POWER_SERVICE);
|
|
||||||
if (mCarPowerManager != null) {
|
|
||||||
mCarPowerManager.setListener(mCarPowerStateListener);
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "CarPowerManager service not available");
|
|
||||||
}
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Car not connected", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
destroyCarPowerManager();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PowerManagerHelper(Context context, @NonNull CarPowerStateListener listener) {
|
PowerManagerHelper(Context context, @NonNull CarPowerStateListener listener) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mCarPowerStateListener = listener;
|
mCarPowerStateListener = listener;
|
||||||
|
mCarServiceLifecycleListener = (car, ready) -> {
|
||||||
|
if (!ready) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "Car Service connected");
|
||||||
|
mCarPowerManager = (CarPowerManager) car.getCarManager(Car.POWER_SERVICE);
|
||||||
|
if (mCarPowerManager != null) {
|
||||||
|
mCarPowerManager.setListener(mCarPowerStateListener);
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "CarPowerManager service not available");
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to Car service.
|
* Connect to Car service.
|
||||||
*/
|
*/
|
||||||
void connectToCarService() {
|
void connectToCarService() {
|
||||||
mCar = Car.createCar(mContext, mCarConnectionListener);
|
mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
|
||||||
if (mCar != null) {
|
mCarServiceLifecycleListener);
|
||||||
mCar.connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disconnects from Car service.
|
|
||||||
*/
|
|
||||||
void disconnectFromCarService() {
|
|
||||||
if (mCar != null) {
|
|
||||||
mCar.disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void destroyCarPowerManager() {
|
|
||||||
if (mCarPowerManager != null) {
|
|
||||||
mCarPowerManager.clearListener();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,15 +20,13 @@ import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;
|
|||||||
import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
|
import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
|
||||||
|
|
||||||
import android.car.Car;
|
import android.car.Car;
|
||||||
|
import android.car.Car.CarServiceLifecycleListener;
|
||||||
import android.car.VehicleUnit;
|
import android.car.VehicleUnit;
|
||||||
import android.car.hardware.CarPropertyValue;
|
import android.car.hardware.CarPropertyValue;
|
||||||
import android.car.hardware.hvac.CarHvacManager;
|
import android.car.hardware.hvac.CarHvacManager;
|
||||||
import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback;
|
import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -52,6 +50,7 @@ public class HvacController {
|
|||||||
private Car mCar;
|
private Car mCar;
|
||||||
private CarHvacManager mHvacManager;
|
private CarHvacManager mHvacManager;
|
||||||
private HashMap<HvacKey, List<TemperatureView>> mTempComponents = new HashMap<>();
|
private HashMap<HvacKey, List<TemperatureView>> mTempComponents = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for getting changes from {@link CarHvacManager} and setting the UI elements to
|
* Callback for getting changes from {@link CarHvacManager} and setting the UI elements to
|
||||||
* match.
|
* match.
|
||||||
@@ -83,39 +82,17 @@ public class HvacController {
|
|||||||
+ " zone: " + zone);
|
+ " zone: " + zone);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/**
|
|
||||||
* If the connection to car service goes away then restart it.
|
|
||||||
*/
|
|
||||||
private final IBinder.DeathRecipient mRestart = new IBinder.DeathRecipient() {
|
|
||||||
@Override
|
|
||||||
public void binderDied() {
|
|
||||||
Log.d(TAG, "Death of HVAC triggering a restart");
|
|
||||||
if (mCar != null) {
|
|
||||||
mCar.disconnect();
|
|
||||||
}
|
|
||||||
destroyHvacManager();
|
|
||||||
mHandler.postDelayed(() -> mCar.connect(), BIND_TO_HVAC_RETRY_DELAY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
* Registers callbacks and initializes components upon connection.
|
|
||||||
*/
|
|
||||||
private ServiceConnection mServiceConnection = new ServiceConnection() {
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
|
||||||
try {
|
|
||||||
service.linkToDeath(mRestart, 0);
|
|
||||||
mHvacManager = (CarHvacManager) mCar.getCarManager(Car.HVAC_SERVICE);
|
|
||||||
mHvacManager.registerCallback(mHardwareCallback);
|
|
||||||
initComponents();
|
|
||||||
} catch (Exception e) {
|
|
||||||
Log.e(TAG, "Failed to correctly connect to HVAC", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
if (!ready) {
|
||||||
destroyHvacManager();
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mHvacManager = (CarHvacManager) car.getCarManager(Car.HVAC_SERVICE);
|
||||||
|
mHvacManager.registerCallback(mHardwareCallback);
|
||||||
|
initComponents();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Failed to correctly connect to HVAC", e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -129,18 +106,8 @@ public class HvacController {
|
|||||||
*/
|
*/
|
||||||
public void connectToCarService() {
|
public void connectToCarService() {
|
||||||
mHandler = new Handler();
|
mHandler = new Handler();
|
||||||
mCar = Car.createCar(mContext, mServiceConnection, mHandler);
|
mCar = Car.createCar(mContext, /* handler= */ mHandler, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
|
||||||
if (mCar != null) {
|
mCarServiceLifecycleListener);
|
||||||
// note: this connect call handles the retries
|
|
||||||
mCar.connect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void destroyHvacManager() {
|
|
||||||
if (mHvacManager != null) {
|
|
||||||
mHvacManager.unregisterCallback(mHardwareCallback);
|
|
||||||
mHvacManager = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -24,12 +24,10 @@ import android.annotation.Nullable;
|
|||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.car.Car;
|
import android.car.Car;
|
||||||
import android.car.CarNotConnectedException;
|
import android.car.Car.CarServiceLifecycleListener;
|
||||||
import android.car.media.CarAudioManager;
|
import android.car.media.CarAudioManager;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.ServiceConnection;
|
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
@@ -39,7 +37,6 @@ import android.graphics.drawable.Drawable;
|
|||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -146,42 +143,30 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
|||||||
private boolean mDismissing;
|
private boolean mDismissing;
|
||||||
private boolean mExpanded;
|
private boolean mExpanded;
|
||||||
private View mExpandIcon;
|
private View mExpandIcon;
|
||||||
private final ServiceConnection mServiceConnection = new ServiceConnection() {
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
|
||||||
try {
|
|
||||||
mExpanded = false;
|
|
||||||
mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
|
|
||||||
int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
|
|
||||||
// Populates volume slider items from volume groups to UI.
|
|
||||||
for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
|
|
||||||
VolumeItem volumeItem = getVolumeItemForUsages(
|
|
||||||
mCarAudioManager.getUsagesForVolumeGroupId(groupId));
|
|
||||||
mAvailableVolumeItems.add(volumeItem);
|
|
||||||
// The first one is the default item.
|
|
||||||
if (groupId == 0) {
|
|
||||||
setuptListItem(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If list is already initiated, update its content.
|
private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
|
||||||
if (mVolumeItemsAdapter != null) {
|
if (!ready) {
|
||||||
mVolumeItemsAdapter.notifyDataSetChanged();
|
return;
|
||||||
}
|
}
|
||||||
mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
|
mExpanded = false;
|
||||||
} catch (CarNotConnectedException e) {
|
mCarAudioManager = (CarAudioManager) car.getCarManager(Car.AUDIO_SERVICE);
|
||||||
Log.e(TAG, "Car is not connected!", e);
|
int volumeGroupCount = mCarAudioManager.getVolumeGroupCount();
|
||||||
|
// Populates volume slider items from volume groups to UI.
|
||||||
|
for (int groupId = 0; groupId < volumeGroupCount; groupId++) {
|
||||||
|
VolumeItem volumeItem = getVolumeItemForUsages(
|
||||||
|
mCarAudioManager.getUsagesForVolumeGroupId(groupId));
|
||||||
|
mAvailableVolumeItems.add(volumeItem);
|
||||||
|
// The first one is the default item.
|
||||||
|
if (groupId == 0) {
|
||||||
|
setuptListItem(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// If list is already initiated, update its content.
|
||||||
* This does not get called when service is properly disconnected.
|
if (mVolumeItemsAdapter != null) {
|
||||||
* So we need to also handle cleanups in destroy().
|
mVolumeItemsAdapter.notifyDataSetChanged();
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
cleanupAudioManager();
|
|
||||||
}
|
}
|
||||||
|
mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
|
||||||
};
|
};
|
||||||
|
|
||||||
private void setuptListItem(int groupId) {
|
private void setuptListItem(int groupId) {
|
||||||
@@ -196,25 +181,14 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
|||||||
public CarVolumeDialogImpl(Context context) {
|
public CarVolumeDialogImpl(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
|
mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
|
||||||
mCar = Car.createCar(mContext, mServiceConnection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
|
private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
|
||||||
try {
|
return carAudioManager.getGroupVolume(volumeGroupId);
|
||||||
return carAudioManager.getGroupVolume(volumeGroupId);
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Car is not connected!", e);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
|
private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
|
||||||
try {
|
return carAudioManager.getGroupMaxVolume(volumeGroupId);
|
||||||
return carAudioManager.getGroupMaxVolume(volumeGroupId);
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Car is not connected!", e);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -224,8 +198,8 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
|||||||
@Override
|
@Override
|
||||||
public void init(int windowType, Callback callback) {
|
public void init(int windowType, Callback callback) {
|
||||||
initDialog();
|
initDialog();
|
||||||
|
mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
|
||||||
mCar.connect();
|
mCarServiceLifecycleListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -235,7 +209,10 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
|||||||
cleanupAudioManager();
|
cleanupAudioManager();
|
||||||
// unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
|
// unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
|
||||||
// audio manager beforehand.
|
// audio manager beforehand.
|
||||||
mCar.disconnect();
|
if (mCar != null) {
|
||||||
|
mCar.disconnect();
|
||||||
|
mCar = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDialog() {
|
private void initDialog() {
|
||||||
@@ -605,18 +582,14 @@ public class CarVolumeDialogImpl implements VolumeDialog {
|
|||||||
// sent back down again.
|
// sent back down again.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
if (mCarAudioManager == null) {
|
||||||
if (mCarAudioManager == null) {
|
Log.w(TAG, "Ignoring volume change event because the car isn't connected");
|
||||||
Log.w(TAG, "Ignoring volume change event because the car isn't connected");
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
|
|
||||||
mAvailableVolumeItems.get(
|
|
||||||
mVolumeGroupId).carVolumeItem.setProgress(progress);
|
|
||||||
mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
|
|
||||||
} catch (CarNotConnectedException e) {
|
|
||||||
Log.e(TAG, "Car is not connected!", e);
|
|
||||||
}
|
}
|
||||||
|
mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
|
||||||
|
mAvailableVolumeItems.get(
|
||||||
|
mVolumeGroupId).carVolumeItem.setProgress(progress);
|
||||||
|
mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user