Fix missing path to crash client for car service crash

- Missed service connection for one path of createCar(context)
- Also store call stack for construction time so that crash log
  can tell where it was created.

Bug: 136079720
Test: kill car service and confirms clients crashing.

Change-Id: I4b695d267ed82997d0cf7073ad5c2fc77ad6f4db
diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java
index cc18688..4ca47f8 100644
--- a/car-lib/src/android/car/Car.java
+++ b/car-lib/src/android/car/Car.java
@@ -682,6 +682,8 @@
 
     private final Context mContext;
 
+    private final Exception mConstructionStack;
+
     private final Object mLock = new Object();
 
     @GuardedBy("mLock")
@@ -845,6 +847,8 @@
             }
             if (service != null) {
                 if (!started) {  // specialization for most common case.
+                    // Do this to crash client when car service crashes.
+                    car.startCarService();
                     return car;
                 }
                 break;
@@ -1030,6 +1034,13 @@
         }
         mServiceConnectionListenerClient = serviceConnectionListener;
         mStatusChangeCallback = statusChangeListener;
+        // Store construction stack so that client can get help when it crashes when car service
+        // crashes.
+        if (serviceConnectionListener == null && statusChangeListener == null) {
+            mConstructionStack = new RuntimeException();
+        } else {
+            mConstructionStack = null;
+        }
     }
 
     /**
@@ -1206,16 +1217,20 @@
         if (mContext instanceof Activity) {
             Activity activity = (Activity) mContext;
             if (!activity.isFinishing()) {
-                Log.w(TAG_CAR, "Car service crashed, client not handling it, finish Activity");
+                Log.w(TAG_CAR,
+                        "Car service crashed, client not handling it, finish Activity, created "
+                                + "from " + mConstructionStack);
                 activity.finish();
             }
             return;
         } else if (mContext instanceof Service) {
             Service service = (Service) mContext;
-            throw new RuntimeException("Car service has crashed, client not handle it:"
-                    + service.getPackageName() + "," + service.getClass().getSimpleName());
+            throw new IllegalStateException("Car service has crashed, client not handle it:"
+                    + service.getPackageName() + "," + service.getClass().getSimpleName(),
+                    mConstructionStack);
         }
-        throw new IllegalStateException("Car service crashed, client not handling it.");
+        throw new IllegalStateException("Car service crashed, client not handling it.",
+                mConstructionStack);
     }
 
     /** @hide */
diff --git a/tests/carservice_unit_test/src/android/car/CarTest.java b/tests/carservice_unit_test/src/android/car/CarTest.java
index d12334d..d1f5ac6 100644
--- a/tests/carservice_unit_test/src/android/car/CarTest.java
+++ b/tests/carservice_unit_test/src/android/car/CarTest.java
@@ -22,8 +22,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static junit.framework.Assert.fail;
-
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Matchers.anyObject;
 import static org.mockito.Mockito.times;
@@ -154,7 +152,9 @@
     @Test
     public void testCreateCarSuccessWithCarServiceRunning() {
         expectService(mService);
-        assertThat(Car.createCar(mContext)).isNotNull();
+        Car car = Car.createCar(mContext);
+        assertThat(car).isNotNull();
+        car.disconnect();
     }
 
     @Test
@@ -173,20 +173,7 @@
         Car car = Car.createCar(mContext);
         assertThat(car).isNotNull();
         assertServiceBoundOnce();
-
-        // Just call these to guarantee that nothing crashes when service is connected /
-        // disconnected.
-        runOnMainSyncSafe(() -> {
-            car.getServiceConnectionListener().onServiceConnected(new ComponentName("", ""),
-                    mService);
-            try {
-                car.getServiceConnectionListener().onServiceDisconnected(new ComponentName("", ""));
-            } catch (IllegalStateException e) {
-                // expected
-                return;
-            }
-            fail("onServiceDisconnected should have triggered exception");
-        });
+        car.disconnect();
     }
 
     @Test