Migrate car sysui to use new createCar call and prevent crash

- createCar(context) will lead into crash when car service is crashed.
- Migrate all createCar to new style which can handle car service crash
  while removing unnecessary delay for connect.

Bug: 142543455
Test: kill car service and check if systemui survives

Change-Id: I69298f763a2a2e63c0cf8deae13f747ea19bbf9d
Merged-In: I69298f763a2a2e63c0cf8deae13f747ea19bbf9d
(cherry picked from commit c83d7b93ae0620bac34af2a937d5855b05058213)
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 b7aa496..d9e395e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -26,7 +26,6 @@
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.CarUxRestrictionsManager;
 import android.car.hardware.power.CarPowerManager.CarPowerStateListener;
-import android.car.trust.CarTrustAgentEnrollmentManager;
 import android.content.Context;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
@@ -179,6 +178,8 @@
     private boolean mHideNavBarForKeyboard;
     private boolean mBottomNavBarVisible;
 
+    private CarUxRestrictionManagerWrapper mCarUxRestrictionManagerWrapper;
+
     private final CarPowerStateListener mCarPowerStateListener =
             (int state) -> {
                 // When the car powers on, clear all notifications and mute/unread states.
@@ -245,14 +246,16 @@
                     }
                 });
 
+        // Used by onDrivingStateChanged and it can be called inside
+        // DrivingStateHelper.connectToCarService()
+        mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
+
         // Register a listener for driving state changes.
         mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
         mDrivingStateHelper.connectToCarService();
 
         mPowerManagerHelper = new PowerManagerHelper(mContext, mCarPowerStateListener);
         mPowerManagerHelper.connectToCarService();
-
-        mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
     }
 
     private void restartNavBarsIfNecessary() {
@@ -454,13 +457,23 @@
                         animateCollapsePanels();
                     }
                 });
-        Car car = Car.createCar(mContext);
-        CarUxRestrictionsManager carUxRestrictionsManager = (CarUxRestrictionsManager)
-                car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
+
         CarNotificationListener carNotificationListener = new CarNotificationListener();
-        CarUxRestrictionManagerWrapper carUxRestrictionManagerWrapper =
-                new CarUxRestrictionManagerWrapper();
-        carUxRestrictionManagerWrapper.setCarUxRestrictionsManager(carUxRestrictionsManager);
+        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) -> {
+                    if (!ready) {
+                        return;
+                    }
+                    CarUxRestrictionsManager carUxRestrictionsManager =
+                            (CarUxRestrictionsManager)
+                                    car.getCarManager(Car.CAR_UX_RESTRICTION_SERVICE);
+                    mCarUxRestrictionManagerWrapper.setCarUxRestrictionsManager(
+                            carUxRestrictionsManager);
+                });
 
         mNotificationDataManager = new NotificationDataManager();
         mNotificationDataManager.setOnUnseenCountUpdateListener(
@@ -489,7 +502,7 @@
                         mNotificationClickHandlerFactory, mNotificationDataManager);
         mNotificationClickHandlerFactory.setNotificationDataManager(mNotificationDataManager);
 
-        carNotificationListener.registerAsSystemService(mContext, carUxRestrictionManagerWrapper,
+        carNotificationListener.registerAsSystemService(mContext, mCarUxRestrictionManagerWrapper,
                 carHeadsUpNotificationManager, mNotificationDataManager);
 
         mNotificationView = mStatusBarWindow.findViewById(R.id.notification_view);
@@ -589,7 +602,7 @@
                 mNotificationView,
                 PreprocessingManager.getInstance(mContext),
                 carNotificationListener,
-                carUxRestrictionManagerWrapper,
+                mCarUxRestrictionManagerWrapper,
                 mNotificationDataManager);
         mNotificationViewController.enable();
     }
@@ -1039,12 +1052,8 @@
         UserSwitcherController userSwitcherController =
                 Dependency.get(UserSwitcherController.class);
         if (userSwitcherController.useFullscreenUserSwitcher()) {
-            Car car = Car.createCar(mContext);
-            CarTrustAgentEnrollmentManager enrollmentManager = (CarTrustAgentEnrollmentManager) car
-                    .getCarManager(Car.CAR_TRUST_AGENT_ENROLLMENT_SERVICE);
             mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
-                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub),
-                    enrollmentManager, mContext);
+                    mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext);
         } else {
             super.createUserSwitcher();
         }
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 a442426..cd87e78 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/DrivingStateHelper.java
@@ -17,14 +17,11 @@
 package com.android.systemui.statusbar.car;
 
 import android.car.Car;
-import android.car.CarNotConnectedException;
+import android.car.Car.CarServiceLifecycleListener;
 import android.car.drivingstate.CarDrivingStateEvent;
 import android.car.drivingstate.CarDrivingStateManager;
 import android.car.drivingstate.CarDrivingStateManager.CarDrivingStateEventListener;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -55,16 +52,11 @@
         if (mDrivingStateManager == null) {
             return false;
         }
-        try {
-            CarDrivingStateEvent currentState = mDrivingStateManager.getCurrentCarDrivingState();
-            if (currentState != null) {
-                return currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_IDLING
-                        || currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING;
-            }
-        } catch (CarNotConnectedException e) {
-            Log.e(TAG, "Cannot determine current driving state. Car not connected", e);
+        CarDrivingStateEvent currentState = mDrivingStateManager.getCurrentCarDrivingState();
+        if (currentState != null) {
+            return currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_IDLING
+                    || currentState.eventValue == CarDrivingStateEvent.DRIVING_STATE_MOVING;
         }
-
         return false; // Default to false.
     }
 
@@ -72,55 +64,25 @@
      * Establishes connection with the Car service.
      */
     public void connectToCarService() {
-        mCar = Car.createCar(mContext, mCarConnectionListener);
-        if (mCar != null) {
-            mCar.connect();
-        }
+        mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
+                mCarServiceLifecycleListener);
     }
 
-    /**
-     * Disconnects from Car service and cleans up listeners.
-     */
-    public void disconnectFromCarService() {
-        if (mCar != null) {
-            mCar.disconnect();
+    private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
+        if (!ready) {
+            return;
         }
-    }
-
-    private final ServiceConnection mCarConnectionListener =
-            new ServiceConnection() {
-                public void onServiceConnected(ComponentName name, IBinder service) {
-                    logD("Car Service connected");
-                    try {
-                        mDrivingStateManager = (CarDrivingStateManager) mCar.getCarManager(
-                                Car.CAR_DRIVING_STATE_SERVICE);
-                        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);
+        logD("Car Service connected");
+        mDrivingStateManager = (CarDrivingStateManager) car.getCarManager(
+                Car.CAR_DRIVING_STATE_SERVICE);
+        if (mDrivingStateManager != null) {
+            mDrivingStateManager.registerListener(mDrivingStateHandler);
+            mDrivingStateHandler.onDrivingStateChanged(
+                    mDrivingStateManager.getCurrentCarDrivingState());
+        } else {
+            Log.e(TAG, "CarDrivingStateService service not available");
         }
-    }
+    };
 
     private void logD(String message) {
         if (Log.isLoggable(TAG, Log.DEBUG)) {
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 0f7c1ee..31aced0 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -18,6 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.car.Car;
 import android.car.trust.CarTrustAgentEnrollmentManager;
 import android.car.userlib.CarUserManagerHelper;
 import android.content.BroadcastReceiver;
@@ -50,7 +51,7 @@
     private final CarStatusBar mStatusBar;
     private final Context mContext;
     private final UserManager mUserManager;
-    private final CarTrustAgentEnrollmentManager mEnrollmentManager;
+    private CarTrustAgentEnrollmentManager mEnrollmentManager;
     private CarTrustAgentUnlockDialogHelper mUnlockDialogHelper;
     private UserGridRecyclerView.UserRecord mSelectedUser;
     private CarUserManagerHelper mCarUserManagerHelper;
@@ -64,13 +65,11 @@
             mContext.unregisterReceiver(mUserUnlockReceiver);
         }
     };
+    private final Car mCar;
 
-
-    public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub,
-            CarTrustAgentEnrollmentManager enrollmentManager, Context context) {
+    public FullscreenUserSwitcher(CarStatusBar statusBar, ViewStub containerStub, Context context) {
         mStatusBar = statusBar;
         mParent = containerStub.inflate();
-        mEnrollmentManager = enrollmentManager;
         mContext = context;
 
         View container = mParent.findViewById(R.id.container);
@@ -86,6 +85,15 @@
         mUnlockDialogHelper = new CarTrustAgentUnlockDialogHelper(mContext);
         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()
                 .getInteger(android.R.integer.config_shortAnimTime);
         IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
@@ -201,6 +209,9 @@
     }
 
     private boolean hasTrustedDevice(int uid) {
+        if (mEnrollmentManager == null) { // car service not ready, so it cannot be available.
+            return false;
+        }
         return !mEnrollmentManager.getEnrolledDeviceInfoForUser(uid).isEmpty();
     }
 
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 8de1439..a27dd34 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/PowerManagerHelper.java
@@ -18,13 +18,10 @@
 
 import android.annotation.NonNull;
 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.CarPowerStateListener;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.ServiceConnection;
-import android.os.IBinder;
 import android.util.Log;
 
 /**
@@ -39,55 +36,30 @@
     private Car mCar;
     private CarPowerManager mCarPowerManager;
 
-    private final ServiceConnection mCarConnectionListener =
-            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();
-                }
-            };
+    private final CarServiceLifecycleListener mCarServiceLifecycleListener;
 
     PowerManagerHelper(Context context, @NonNull CarPowerStateListener listener) {
         mContext = context;
         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.
      */
     void connectToCarService() {
-        mCar = Car.createCar(mContext, mCarConnectionListener);
-        if (mCar != null) {
-            mCar.connect();
-        }
-    }
-
-    /**
-     * Disconnects from Car service.
-     */
-    void disconnectFromCarService() {
-        if (mCar != null) {
-            mCar.disconnect();
-        }
-    }
-
-    private void destroyCarPowerManager() {
-        if (mCarPowerManager != null) {
-            mCarPowerManager.clearListener();
-        }
+        mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
+                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 30429ed..a8515f9 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
@@ -20,15 +20,13 @@
 import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS;
 
 import android.car.Car;
+import android.car.Car.CarServiceLifecycleListener;
 import android.car.VehicleUnit;
 import android.car.hardware.CarPropertyValue;
 import android.car.hardware.hvac.CarHvacManager;
 import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback;
-import android.content.ComponentName;
 import android.content.Context;
-import android.content.ServiceConnection;
 import android.os.Handler;
-import android.os.IBinder;
 import android.util.Log;
 
 import java.util.ArrayList;
@@ -52,6 +50,7 @@
     private Car mCar;
     private CarHvacManager mHvacManager;
     private HashMap<HvacKey, List<TemperatureView>> mTempComponents = new HashMap<>();
+
     /**
      * Callback for getting changes from {@link CarHvacManager} and setting the UI elements to
      * match.
@@ -83,39 +82,17 @@
                     + " 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
-        public void onServiceDisconnected(ComponentName name) {
-            destroyHvacManager();
+    private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
+        if (!ready) {
+            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 void connectToCarService() {
         mHandler = new Handler();
-        mCar = Car.createCar(mContext, mServiceConnection, mHandler);
-        if (mCar != null) {
-            // note: this connect call handles the retries
-            mCar.connect();
-        }
-    }
-
-    private void destroyHvacManager() {
-        if (mHvacManager != null) {
-            mHvacManager.unregisterCallback(mHardwareCallback);
-            mHvacManager = null;
-        }
+        mCar = Car.createCar(mContext, /* handler= */ mHandler, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
+                mCarServiceLifecycleListener);
     }
 
     /**
diff --git a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
index 22c7c7a..d979bad 100644
--- a/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/volume/CarVolumeDialogImpl.java
@@ -24,12 +24,10 @@
 import android.app.Dialog;
 import android.app.KeyguardManager;
 import android.car.Car;
-import android.car.CarNotConnectedException;
+import android.car.Car.CarServiceLifecycleListener;
 import android.car.media.CarAudioManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
-import android.content.ServiceConnection;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Color;
@@ -39,7 +37,6 @@
 import android.media.AudioManager;
 import android.os.Debug;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.util.AttributeSet;
@@ -146,42 +143,30 @@
     private boolean mDismissing;
     private boolean mExpanded;
     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.
-                if (mVolumeItemsAdapter != null) {
-                    mVolumeItemsAdapter.notifyDataSetChanged();
-                }
-                mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
-            } catch (CarNotConnectedException e) {
-                Log.e(TAG, "Car is not connected!", e);
+    private final CarServiceLifecycleListener mCarServiceLifecycleListener = (car, ready) -> {
+        if (!ready) {
+            return;
+        }
+        mExpanded = false;
+        mCarAudioManager = (CarAudioManager) car.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);
             }
         }
 
-        /**
-         * This does not get called when service is properly disconnected.
-         * So we need to also handle cleanups in destroy().
-         */
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            cleanupAudioManager();
+        // If list is already initiated, update its content.
+        if (mVolumeItemsAdapter != null) {
+            mVolumeItemsAdapter.notifyDataSetChanged();
         }
+        mCarAudioManager.registerCarVolumeCallback(mVolumeChangeCallback);
     };
 
     private void setuptListItem(int groupId) {
@@ -196,25 +181,14 @@
     public CarVolumeDialogImpl(Context context) {
         mContext = context;
         mKeyguard = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
-        mCar = Car.createCar(mContext, mServiceConnection);
     }
 
     private static int getSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
-        try {
-            return carAudioManager.getGroupVolume(volumeGroupId);
-        } catch (CarNotConnectedException e) {
-            Log.e(TAG, "Car is not connected!", e);
-        }
-        return 0;
+        return carAudioManager.getGroupVolume(volumeGroupId);
     }
 
     private static int getMaxSeekbarValue(CarAudioManager carAudioManager, int volumeGroupId) {
-        try {
-            return carAudioManager.getGroupMaxVolume(volumeGroupId);
-        } catch (CarNotConnectedException e) {
-            Log.e(TAG, "Car is not connected!", e);
-        }
-        return 0;
+        return carAudioManager.getGroupMaxVolume(volumeGroupId);
     }
 
     /**
@@ -224,8 +198,8 @@
     @Override
     public void init(int windowType, Callback callback) {
         initDialog();
-
-        mCar.connect();
+        mCar = Car.createCar(mContext, /* handler= */ null, Car.CAR_WAIT_TIMEOUT_DO_NOT_WAIT,
+                mCarServiceLifecycleListener);
     }
 
     @Override
@@ -235,7 +209,10 @@
         cleanupAudioManager();
         // unregisterVolumeCallback is not being called when disconnect car, so we manually cleanup
         // audio manager beforehand.
-        mCar.disconnect();
+        if (mCar != null) {
+            mCar.disconnect();
+            mCar = null;
+        }
     }
 
     private void initDialog() {
@@ -605,18 +582,14 @@
                 // sent back down again.
                 return;
             }
-            try {
-                if (mCarAudioManager == null) {
-                    Log.w(TAG, "Ignoring volume change event because the car isn't connected");
-                    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);
+            if (mCarAudioManager == null) {
+                Log.w(TAG, "Ignoring volume change event because the car isn't connected");
+                return;
             }
+            mAvailableVolumeItems.get(mVolumeGroupId).progress = progress;
+            mAvailableVolumeItems.get(
+                    mVolumeGroupId).carVolumeItem.setProgress(progress);
+            mCarAudioManager.setGroupVolume(mVolumeGroupId, progress, 0);
         }
 
         @Override