add skeleton CarServiceHelperService

- CarServiceHelperService is a companion service for car service which
  is used only for car product.
- HelperService starts car service and provide necessary interface
  for system server internal behavior control.

bug: 62342376
Test: test boot-up
Change-Id: I1728437434eab36bd2df6ba0a534731823bbcf35
diff --git a/Android.mk b/Android.mk
index d847d49..6631ada 100644
--- a/Android.mk
+++ b/Android.mk
@@ -385,6 +385,7 @@
 	core/java/com/android/internal/appwidget/IAppWidgetHost.aidl \
 	core/java/com/android/internal/backup/IBackupTransport.aidl \
 	core/java/com/android/internal/backup/IObbBackupService.aidl \
+	core/java/com/android/internal/car/ICarServiceHelper.aidl \
 	core/java/com/android/internal/inputmethod/IInputContentUriToken.aidl \
 	core/java/com/android/internal/policy/IKeyguardDrawnCallback.aidl \
 	core/java/com/android/internal/policy/IKeyguardDismissCallback.aidl \
diff --git a/core/java/com/android/internal/car/ICarServiceHelper.aidl b/core/java/com/android/internal/car/ICarServiceHelper.aidl
new file mode 100644
index 0000000..9ee330b
--- /dev/null
+++ b/core/java/com/android/internal/car/ICarServiceHelper.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2017 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.internal.car;
+
+/**
+ * Helper API for car service. Only for itneraction between system server and car service.
+ * @hide
+ */
+interface ICarServiceHelper {
+}
diff --git a/services/core/java/com/android/server/car/CarServiceHelperService.java b/services/core/java/com/android/server/car/CarServiceHelperService.java
new file mode 100644
index 0000000..9392a6a
--- /dev/null
+++ b/services/core/java/com/android/server/car/CarServiceHelperService.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2017 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.server.car;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.car.ICarServiceHelper;
+import com.android.server.SystemService;
+
+/**
+ * System service side companion service for CarService.
+ * Starts car service and provide necessary API for CarService. Only for car product.
+ */
+public class CarServiceHelperService extends SystemService {
+    private static final String TAG = "CarServiceHelper";
+    private static final String CAR_SERVICE_INTERFACE = "android.car.ICar";
+    private final ICarServiceHelperImpl mHelper = new ICarServiceHelperImpl();
+    private IBinder mCarService;
+    private final ServiceConnection mCarServiceConnection = new ServiceConnection() {
+
+        @Override
+        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+            Slog.i(TAG, "**CarService connected**");
+            mCarService = iBinder;
+            // Cannot depend on ICar which is defined in CarService, so handle binder call directly
+            // instead.
+            // void setCarServiceHelper(in IBinder helper)
+            Parcel data = Parcel.obtain();
+            data.writeInterfaceToken(CAR_SERVICE_INTERFACE);
+            data.writeStrongBinder(mHelper.asBinder());
+            try {
+                mCarService.transact(IBinder.FIRST_CALL_TRANSACTION, // setCarServiceHelper
+                        data, null, Binder.FLAG_ONEWAY);
+            } catch (RemoteException e) {
+                Slog.w(TAG, "RemoteException from car service", e);
+                handleCarServiceCrash();
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName componentName) {
+            handleCarServiceCrash();
+        }
+    };
+
+    public CarServiceHelperService(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onStart() {
+        Intent intent = new Intent();
+        intent.setPackage("com.android.car");
+        intent.setAction(CAR_SERVICE_INTERFACE);
+        if (!getContext().bindServiceAsUser(intent, mCarServiceConnection, Context.BIND_AUTO_CREATE,
+                UserHandle.SYSTEM)) {
+            Slog.wtf(TAG, "cannot start car service");
+        }
+    }
+
+    private void handleCarServiceCrash() {
+        //TODO define recovery bahavior
+    }
+
+    private class ICarServiceHelperImpl extends ICarServiceHelper.Stub {
+        //TODO
+    }
+}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 66849c3..272c11b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -63,6 +63,7 @@
 import com.android.server.am.ActivityManagerService;
 import com.android.server.audio.AudioService;
 import com.android.server.camera.CameraServiceProxy;
+import com.android.server.car.CarServiceHelperService;
 import com.android.server.clipboard.ClipboardService;
 import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.coverage.CoverageService;
@@ -1697,6 +1698,12 @@
                 }, WEBVIEW_PREPARATION);
             }
 
+            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
+                traceBeginAndSlog("StartCarServiceHelperService");
+                mSystemServiceManager.startService(CarServiceHelperService.class);
+                traceEnd();
+            }
+
             traceBeginAndSlog("StartSystemUI");
             try {
                 startSystemUi(context, windowManagerF);