Merge "Move out emulator-specific configs."
diff --git a/car-lib/src/android/car/settings/CarSettings.java b/car-lib/src/android/car/settings/CarSettings.java
index d3f833d..888ccad 100644
--- a/car-lib/src/android/car/settings/CarSettings.java
+++ b/car-lib/src/android/car/settings/CarSettings.java
@@ -162,5 +162,14 @@
*/
public static final String KEY_ENABLE_INITIAL_NOTICE_SCREEN_TO_USER =
"android.car.ENABLE_INITIAL_NOTICE_SCREEN_TO_USER";
+
+ /**
+ * Key to indicate Setup Wizard is in progress. It differs from USER_SETUP_COMPLETE in
+ * that this flag can be reset to 0 in deferred Setup Wizard flow.
+ * The value is boolean (1 or 0).
+ * @hide
+ */
+ public static final String KEY_SETUP_WIZARD_IN_PROGRESS =
+ "android.car.SETUP_WIZARD_IN_PROGRESS";
}
}
diff --git a/car-usb-handler/src/android/car/usb/handler/BootUsbService.java b/car-usb-handler/src/android/car/usb/handler/BootUsbService.java
index 909be07..5d29f54 100644
--- a/car-usb-handler/src/android/car/usb/handler/BootUsbService.java
+++ b/car-usb-handler/src/android/car/usb/handler/BootUsbService.java
@@ -46,14 +46,14 @@
static final String USB_DEVICE_LIST_KEY = "usb_device_list";
private ArrayList<UsbDevice> mDeviceList;
-
- private class UserSwitchBroadcastReceiver extends BroadcastReceiver {
+ private boolean mReceiverRegistered = false;
+ private final BroadcastReceiver mUserSwitchBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
processDevices();
- unregisterReceiver(this);
+ unregisterUserSwitchReceiver();
}
- }
+ };
@Override
public Binder onBind(Intent intent) {
@@ -86,8 +86,7 @@
// immediately.
if (ActivityManager.getCurrentUser() == UserHandle.USER_SYSTEM) {
Log.d(TAG, "Current user is still the system user, waiting for user switch");
- registerReceiver(
- new UserSwitchBroadcastReceiver(), new IntentFilter(ACTION_USER_SWITCHED));
+ registerUserSwitchReceiver();
} else {
processDevices();
}
@@ -95,6 +94,11 @@
return START_NOT_STICKY;
}
+ @Override
+ public void onDestroy() {
+ unregisterUserSwitchReceiver();
+ }
+
private void processDevices() {
Log.d(TAG, "Processing connected USB devices and starting handlers");
for (UsbDevice device : mDeviceList) {
@@ -110,4 +114,18 @@
manageDevice.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivityAsUser(manageDevice, UserHandle.CURRENT);
}
+
+ private void registerUserSwitchReceiver() {
+ if (!mReceiverRegistered) {
+ registerReceiver(mUserSwitchBroadcastReceiver, new IntentFilter(ACTION_USER_SWITCHED));
+ mReceiverRegistered = true;
+ }
+ }
+
+ private void unregisterUserSwitchReceiver() {
+ if (mReceiverRegistered) {
+ unregisterReceiver(mUserSwitchBroadcastReceiver);
+ mReceiverRegistered = false;
+ }
+ }
}
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/strings.xml b/car_product/overlay/frameworks/base/core/res/res/values/strings.xml
index 9217647..34fd92f 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values/strings.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values/strings.xml
@@ -18,4 +18,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Default name of the owner user [CHAR LIMIT=20] -->
<string name="owner_name">Driver</string>
+ <string name="permlab_accessCoarseLocation">access approximate location only in the foreground</string>
</resources>
diff --git a/car_product/sepolicy/private/carservice_app.te b/car_product/sepolicy/private/carservice_app.te
index a272e4a..c5f1108 100644
--- a/car_product/sepolicy/private/carservice_app.te
+++ b/car_product/sepolicy/private/carservice_app.te
@@ -15,8 +15,6 @@
# Allow Car Service to register its stats service with ServiceManager
add_service(carservice_app, carstats_service)
-allow carservice_app wifi_service:service_manager find;
-
# Allow Car Service to access certain system services.
# Keep alphabetically sorted.
allow carservice_app {
@@ -44,6 +42,8 @@
telecom_service
uimode_service
voiceinteraction_service
+ wifi_service
+ wifiscanner_service
}:service_manager find;
# Read and write /data/data subdirectory.
diff --git a/computepipe/aidl/android/automotive/computepipe/runner/IPipeStream.aidl b/computepipe/aidl/android/automotive/computepipe/runner/IPipeStream.aidl
index 36aa38b..8ea6481 100644
--- a/computepipe/aidl/android/automotive/computepipe/runner/IPipeStream.aidl
+++ b/computepipe/aidl/android/automotive/computepipe/runner/IPipeStream.aidl
@@ -20,10 +20,11 @@
@VintfStability
interface IPipeStream {
/**
- * Receives calls from the HIDL implementation each time a new packet is available.
- * Packets received by this method must be returned via calls to
- * IPipeRunner::doneWithPacket(). After the pipe execution has
- * stopped this callback may continue to happen for sometime.
+ * Receives calls from the AIDL implementation each time a new packet is available.
+ * Semantic data is contaied in the packet descriptor.
+ * Only Zero copy data packets received by this method must be returned via calls to
+ * IPipeRunner::doneWithPacket(), using the bufId field in the descriptor.
+ * After the pipe execution has stopped this callback may continue to happen for sometime.
* Those packets must still be returned. Last frame will be indicated with
* a null packet. After that there will not be any further packets.
*
diff --git a/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl b/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl
index 1b818f0..b76210c 100644
--- a/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl
+++ b/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptor.aidl
@@ -25,7 +25,8 @@
@VintfStability
parcelable PacketDescriptor {
/**
- * packet id
+ * packet id, used in case of zero copy data.
+ * Used to notify the runner of consumption.
*/
int bufId;
/**
@@ -37,14 +38,17 @@
*/
int size;
/**
- * handle to memory region containing zero copy or semantic data
- *
- * android.os.NativeHandle memHandle;
+ * handle to memory region containing zero copy data
+ * This handle can be mapped and data retrieved.
*/
NativeHandle handle;
/**
* Timestamp of event at source. Timestamp value is milliseconds since epoch.
*/
long sourceTimeStampMillis;
+ /**
+ * semantic data. Requires no doneWithPacket() acknowledgement.
+ */
+ @utf8InCpp String data;
}
diff --git a/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptorPacketType.aidl b/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptorPacketType.aidl
index 3ff29e8..fd1f5ce 100644
--- a/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptorPacketType.aidl
+++ b/computepipe/aidl/android/automotive/computepipe/runner/PacketDescriptorPacketType.aidl
@@ -30,7 +30,7 @@
*/
PIXEL_DATA,
/**
- * Pixel data with zero copy semantics
+ * Semantic data with zero copy requirements.
*/
- PIXEL_ZERO_COPY_DATA,
+ SEMANTIC_ZERO_COPY_DATA,
}
diff --git a/computepipe/runner/Android.bp b/computepipe/runner/Android.bp
new file mode 100644
index 0000000..0007512
--- /dev/null
+++ b/computepipe/runner/Android.bp
@@ -0,0 +1,22 @@
+// 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.
+
+cc_library_headers {
+ name: "computepipe_runner_includes",
+ export_include_dirs: ["include"],
+ static_libs: [
+ "libcomputepipeprotos",
+ ],
+ visibility:["//packages/services/Car/computepipe/runner:__subpackages__"],
+}
diff --git a/computepipe/runner/stream_manager/MemHandle.h b/computepipe/runner/include/MemHandle.h
similarity index 89%
rename from computepipe/runner/stream_manager/MemHandle.h
rename to computepipe/runner/include/MemHandle.h
index 026ee43..19c5c73 100644
--- a/computepipe/runner/stream_manager/MemHandle.h
+++ b/computepipe/runner/include/MemHandle.h
@@ -15,10 +15,9 @@
#ifndef COMPUTEPIPE_RUNNER_STREAM_MANAGER_MEMHANDLE_H
#define COMPUTEPIPE_RUNNER_STREAM_MANAGER_MEMHANDLE_H
+#include <OutputConfig.pb.h>
#include <cutils/native_handle.h>
-#include "OutputConfig.pb.h"
-
namespace android {
namespace automotive {
namespace computepipe {
@@ -32,15 +31,16 @@
/* Get size */
virtual uint32_t getSize() = 0;
/* Get data, raw pointer. Only implemented for copy semantics */
- virtual const void *getData() = 0;
+ virtual const char* getData() = 0;
/* Get native handle. data with zero copy semantics */
virtual native_handle_t getNativeHandle() = 0;
- virtual ~MemHandle() {}
+ virtual ~MemHandle() {
+ }
};
} // namespace computepipe
} // namespace automotive
} // namespace android
-#endif // COMPUTEPIPE_RUNNER_STREAM_MANAGER_MEMHANDLE_H
+#endif // COMPUTEPIPE_RUNNER_STREAM_MANAGER_MEMHANDLE_H
diff --git a/computepipe/runner/utils/Android.bp b/computepipe/runner/utils/Android.bp
index 3328615..b820de0 100644
--- a/computepipe/runner/utils/Android.bp
+++ b/computepipe/runner/utils/Android.bp
@@ -14,7 +14,6 @@
cc_library {
name: "libRunnerInterface",
- vendor_available: true,
cflags: [
"-Wall",
@@ -27,6 +26,7 @@
"libcomputepipeprotos",
],
+ header_libs: ["computepipe_runner_includes"],
include_dirs: ["packages/services/Car/computepipe"],
shared_libs: [
@@ -38,6 +38,7 @@
"libprotobuf-cpp-lite",
],
+ visibility:["//packages/services/Car/computepipe/runner:__subpackages__"],
srcs: [
"RunnerInterface.cc",
],
diff --git a/computepipe/runner/utils/RunnerInterface.h b/computepipe/runner/utils/RunnerInterface.h
index 7397448..bc6856e 100644
--- a/computepipe/runner/utils/RunnerInterface.h
+++ b/computepipe/runner/utils/RunnerInterface.h
@@ -18,8 +18,8 @@
#include <string>
+#include "MemHandle.h"
#include "RunnerInterfaceCallbacks.h"
-#include "runner/stream_manager/MemHandle.h"
#include "types/GraphState.h"
#include "types/Status.h"
diff --git a/computepipe/runner/utils/RunnerInterfaceCallbacks.h b/computepipe/runner/utils/RunnerInterfaceCallbacks.h
index c03b1de..b3e29f6 100644
--- a/computepipe/runner/utils/RunnerInterfaceCallbacks.h
+++ b/computepipe/runner/utils/RunnerInterfaceCallbacks.h
@@ -18,11 +18,11 @@
#include <functional>
#include <string>
-#include "RunnerInterface.h"
#include "ConfigurationCommand.pb.h"
#include "ControlCommand.pb.h"
+#include "MemHandle.h"
+#include "RunnerInterface.h"
#include "types/Status.h"
-#include "runner/stream_manager/MemHandle.h"
namespace android {
namespace automotive {
diff --git a/computepipe/types/Status.h b/computepipe/types/Status.h
index 2f78672..ca2bc6e 100644
--- a/computepipe/types/Status.h
+++ b/computepipe/types/Status.h
@@ -23,6 +23,7 @@
SUCCESS = 0,
INTERNAL_ERROR,
INVALID_ARGUMENT,
+ NO_MEMORY,
FATAL_ERROR,
};
diff --git a/service/src/com/android/car/CarLocationService.java b/service/src/com/android/car/CarLocationService.java
index 34a6885..ffe4301 100644
--- a/service/src/com/android/car/CarLocationService.java
+++ b/service/src/com/android/car/CarLocationService.java
@@ -296,7 +296,7 @@
if (location == null) {
logd("Not storing null location");
} else {
- logd("Storing location: " + location);
+ logd("Storing location");
AtomicFile atomicFile = new AtomicFile(getLocationCacheFile());
FileOutputStream fos = null;
try {
@@ -436,7 +436,7 @@
}
}
}
- logd("Injected location " + location + " with result " + success + " on attempt "
+ logd("Injected location with result " + success + " on attempt "
+ attemptCount);
if (success) {
return;
diff --git a/service/src/com/android/car/CarMediaService.java b/service/src/com/android/car/CarMediaService.java
index 0bec4e8..f3c9b79 100644
--- a/service/src/com/android/car/CarMediaService.java
+++ b/service/src/com/android/car/CarMediaService.java
@@ -389,9 +389,12 @@
/**
* Attempts to stop the current source using MediaController.TransportControls.stop()
+ * This method also unregisters callbacks to the active media controller before calling stop(),
+ * to preserve the PlaybackState before stopping.
*/
- private void stop() {
+ private void stopAndUnregisterCallback() {
if (mActiveUserMediaController != null) {
+ mActiveUserMediaController.unregisterCallback(mMediaControllerCallback);
if (Log.isLoggable(CarLog.TAG_MEDIA, Log.DEBUG)) {
Log.d(CarLog.TAG_MEDIA, "stopping " + mActiveUserMediaController.getPackageName());
}
@@ -519,13 +522,9 @@
return;
}
- // Clear playback state callback so we preserve the state before stopping
- if (mActiveUserMediaController != null) {
- mActiveUserMediaController.unregisterCallback(mMediaControllerCallback);
- mActiveUserMediaController = null;
- }
- stop();
+ stopAndUnregisterCallback();
+ mActiveUserMediaController = null;
mPreviousMediaComponent = mPrimaryMediaComponent;
mPrimaryMediaComponent = componentName;
updateActiveMediaController(mMediaSessionManager
diff --git a/service/src/com/android/car/CarProjectionService.java b/service/src/com/android/car/CarProjectionService.java
index 8c94915..69d3b05 100644
--- a/service/src/com/android/car/CarProjectionService.java
+++ b/service/src/com/android/car/CarProjectionService.java
@@ -26,7 +26,6 @@
import static android.net.wifi.WifiManager.WIFI_AP_STATE_DISABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
-import static android.net.wifi.WifiManager.WIFI_FREQUENCY_BAND_5GHZ;
import android.annotation.Nullable;
import android.app.ActivityOptions;
@@ -938,9 +937,9 @@
private void ensureApConfiguration() {
// Always prefer 5GHz configuration whenever it is available.
WifiConfiguration apConfig = mWifiManager.getWifiApConfiguration();
- if (apConfig != null && apConfig.apBand != WIFI_FREQUENCY_BAND_5GHZ
+ if (apConfig != null && apConfig.apBand != WifiConfiguration.AP_BAND_5GHZ
&& mWifiManager.is5GHzBandSupported()) {
- apConfig.apBand = WIFI_FREQUENCY_BAND_5GHZ;
+ apConfig.apBand = WifiConfiguration.AP_BAND_5GHZ;
mWifiManager.setWifiApConfiguration(apConfig);
}
}
diff --git a/tests/BugReportApp/AndroidManifest.xml b/tests/BugReportApp/AndroidManifest.xml
index be7e158..cf0a7a9 100644
--- a/tests/BugReportApp/AndroidManifest.xml
+++ b/tests/BugReportApp/AndroidManifest.xml
@@ -47,6 +47,7 @@
android:theme="@android:style/Theme.DeviceDefault.Dialog"
android:exported="true"
android:launchMode="singleInstance">
+ <meta-data android:name="distractionOptimized" android:value="true"/>
</activity>
<service android:name=".BugReportService"
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/CryptKeeper.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/CryptKeeper.java
index 3e5fead..c6cbf53 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/CryptKeeper.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/CryptKeeper.java
@@ -964,7 +964,7 @@
}
private boolean isEmergencyCallCapable() {
- return getResources().getBoolean(com.android.internal.R.bool.config_voice_capable);
+ return getTelephonyManager().isVoiceCapable();
}
private void takeEmergencyCallAction() {
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingController.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingController.java
index b016b8c..9073e4a 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingController.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingController.java
@@ -294,8 +294,7 @@
if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY) {
mDevice.setPairingConfirmation(true);
} else if (mType == BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN) {
- byte[] pinBytes = BluetoothDevice.convertPinToBytes(mPasskeyFormatted);
- mDevice.setPin(pinBytes);
+ mDevice.setPin(mPasskeyFormatted);
}
}
@@ -391,17 +390,9 @@
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN:
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
- byte[] pinBytes = BluetoothDevice.convertPinToBytes(passkey);
- if (pinBytes == null) {
- return;
- }
- mDevice.setPin(pinBytes);
+ mDevice.setPin(passkey);
break;
- case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
- int pass = Integer.parseInt(passkey);
- mDevice.setPasskey(pass);
- break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
@@ -410,11 +401,9 @@
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
- // Do nothing.
- break;
-
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
- mDevice.setRemoteOutOfBandData();
+ case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
+ // Do nothing.
break;
default:
@@ -428,7 +417,7 @@
*/
public void onCancel() {
Log.d(TAG, "Pairing dialog canceled");
- mDevice.cancelPairingUserInput();
+ mDevice.cancelPairing();
}
/**
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingService.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingService.java
index 83584c4..5801e2c 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingService.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/bluetooth/BluetoothPairingService.java
@@ -85,7 +85,7 @@
} else if (action.equals(ACTION_DISMISS_PAIRING)) {
Log.d(TAG, "Notification cancel " + mDevice.getAddress() + " (" +
mDevice.getName() + ")");
- mDevice.cancelPairingUserInput();
+ mDevice.cancelPairing();
} else {
int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
BluetoothDevice.ERROR);
diff --git a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/fuelgauge/BatteryWifiParser.java b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/fuelgauge/BatteryWifiParser.java
index d6677bf..c228254 100644
--- a/tests/CarDeveloperOptions/src/com/android/car/developeroptions/fuelgauge/BatteryWifiParser.java
+++ b/tests/CarDeveloperOptions/src/com/android/car/developeroptions/fuelgauge/BatteryWifiParser.java
@@ -14,8 +14,8 @@
package com.android.car.developeroptions.fuelgauge;
-import android.os.BatteryStats;
import android.os.BatteryStats.HistoryItem;
+import android.os.BatteryStatsManager;
public class BatteryWifiParser extends BatteryFlagParser {
@@ -27,12 +27,12 @@
protected boolean isSet(HistoryItem record) {
switch ((record.states2 & HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
>> HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT) {
- case BatteryStats.WIFI_SUPPL_STATE_DISCONNECTED:
- case BatteryStats.WIFI_SUPPL_STATE_DORMANT:
- case BatteryStats.WIFI_SUPPL_STATE_INACTIVE:
- case BatteryStats.WIFI_SUPPL_STATE_INTERFACE_DISABLED:
- case BatteryStats.WIFI_SUPPL_STATE_INVALID:
- case BatteryStats.WIFI_SUPPL_STATE_UNINITIALIZED:
+ case BatteryStatsManager.WIFI_SUPPL_STATE_DISCONNECTED:
+ case BatteryStatsManager.WIFI_SUPPL_STATE_DORMANT:
+ case BatteryStatsManager.WIFI_SUPPL_STATE_INACTIVE:
+ case BatteryStatsManager.WIFI_SUPPL_STATE_INTERFACE_DISABLED:
+ case BatteryStatsManager.WIFI_SUPPL_STATE_INVALID:
+ case BatteryStatsManager.WIFI_SUPPL_STATE_UNINITIALIZED:
return false;
}
return true;
diff --git a/tests/CarVoiceServiceTriggerApp/Android.mk b/tests/CarVoiceServiceTriggerApp/Android.mk
new file mode 100644
index 0000000..b492e1d
--- /dev/null
+++ b/tests/CarVoiceServiceTriggerApp/Android.mk
@@ -0,0 +1,50 @@
+# Copyright (C) 2015 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.
+#
+#
+
+ifneq ($(TARGET_BUILD_PDK),true)
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_USE_AAPT2 := true
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := CarVoiceTriggerApp
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_PRIVILEGED_MODULE := true
+
+LOCAL_CERTIFICATE := platform
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_PACKAGE)
+
+include $(CLEAR_VARS)
+
+include $(BUILD_MULTI_PREBUILT)
+
+include $(CLEAR_VARS)
+
+endif #TARGET_BUILD_PDK
diff --git a/tests/CarVoiceServiceTriggerApp/AndroidManifest.xml b/tests/CarVoiceServiceTriggerApp/AndroidManifest.xml
new file mode 100644
index 0000000..0e43fa7
--- /dev/null
+++ b/tests/CarVoiceServiceTriggerApp/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.voicetrigger">
+
+ <uses-permission android:name="android.permission.ACCESS_VOICE_INTERACTION_SERVICE"/>
+
+ <application android:label="@string/app_title">
+ <receiver android:name=".VoiceTriggerReceiver" android:exported="true">
+ <intent-filter>
+ <action android:name="android.intent.action.VOICE_ASSIST"/>
+ </intent-filter>
+ </receiver>
+ </application>
+</manifest>
+
diff --git a/tests/CarVoiceServiceTriggerApp/res/values/strings.xml b/tests/CarVoiceServiceTriggerApp/res/values/strings.xml
new file mode 100644
index 0000000..3edaf54
--- /dev/null
+++ b/tests/CarVoiceServiceTriggerApp/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2015 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_title" translatable="false">Voice Service Trigger</string>
+</resources>
diff --git a/tests/CarVoiceServiceTriggerApp/src/com/android/voicetrigger/VoiceTriggerReceiver.java b/tests/CarVoiceServiceTriggerApp/src/com/android/voicetrigger/VoiceTriggerReceiver.java
new file mode 100644
index 0000000..f022fb1
--- /dev/null
+++ b/tests/CarVoiceServiceTriggerApp/src/com/android/voicetrigger/VoiceTriggerReceiver.java
@@ -0,0 +1,42 @@
+/*
+ * 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.voicetrigger;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+
+import com.android.internal.app.AssistUtils;
+
+/**
+ * The exported {@link BroadcastReceiver} which receives an Intent to trigger the current active
+ * voice service. The voice service will be triggered as if the assistant button in the system UI
+ * is clicked.
+ *
+ * Run adb shell am broadcast -a android.intent.action.VOICE_ASSIST -n
+ * com.android.voicetrigger/.VoiceTriggerReceiver to use.
+ */
+public class VoiceTriggerReceiver extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ AssistUtils assistUtils = new AssistUtils(context);
+ assistUtils.showSessionForActiveService(new Bundle(),
+ VoiceInteractionSession.SHOW_SOURCE_AUTOMOTIVE_SYSTEM_UI, null, null);
+ }
+}
diff --git a/tests/carservice_test/src/com/android/car/ICarImplTest.java b/tests/carservice_test/src/com/android/car/ICarImplTest.java
new file mode 100644
index 0000000..9502602
--- /dev/null
+++ b/tests/carservice_test/src/com/android/car/ICarImplTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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.car;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
+
+import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+
+import android.car.Car;
+import android.content.Context;
+import android.content.res.Resources;
+import android.hardware.automotive.vehicle.V2_0.IVehicle;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.car.systeminterface.ActivityManagerInterface;
+import com.android.car.systeminterface.DisplayInterface;
+import com.android.car.systeminterface.IOInterface;
+import com.android.car.systeminterface.StorageMonitoringInterface;
+import com.android.car.systeminterface.SystemInterface;
+import com.android.car.systeminterface.SystemInterface.Builder;
+import com.android.car.systeminterface.SystemStateInterface;
+import com.android.car.systeminterface.TimeInterface;
+import com.android.car.systeminterface.WakeLockInterface;
+import com.android.car.test.utils.TemporaryDirectory;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoSession;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.mockito.quality.Strictness;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * This class contains unit tests for the {@link ICarImpl}.
+ * It tests that services started with {@link ICarImpl} are initialized properly.
+ *
+ * The following mocks are used:
+ * 1. {@link ActivityManagerInterface} broadcasts intent for a user.
+ * 2. {@link DisplayInterface} provides access to display operations.
+ * 3. {@link IVehicle} provides access to vehicle properties.
+ * 4. {@link StorageMonitoringInterface} provides access to storage monitoring operations.
+ * 5. {@link SystemStateInterface} provides system statuses (booting, sleeping, ...).
+ * 6. {@link TimeInterface} provides access to time operations.
+ * 7. {@link TimeInterface} provides access to wake lock operations.
+ */
+@RunWith(MockitoJUnitRunner.class)
+public class ICarImplTest {
+ private static final String TAG = "ICarImplTest";
+
+ @Mock private ActivityManagerInterface mMockActivityManagerInterface;
+ @Mock private DisplayInterface mMockDisplayInterface;
+ @Mock private IVehicle mMockVehicle;
+ @Mock private StorageMonitoringInterface mMockStorageMonitoringInterface;
+ @Mock private SystemStateInterface mMockSystemStateInterface;
+ @Mock private TimeInterface mMockTimeInterface;
+ @Mock private WakeLockInterface mMockWakeLockInterface;
+
+ private Context mContext;
+ private MockitoSession mSession;
+ private SystemInterface mFakeSystemInterface;
+ private UserManager mUserManager;
+
+ private final MockIOInterface mMockIOInterface = new MockIOInterface();
+
+ /**
+ * Initialize all of the objects with the @Mock annotation.
+ */
+ @Before
+ public void setUp() throws Exception {
+ mSession = mockitoSession()
+ .initMocks(this)
+ .strictness(Strictness.LENIENT)
+ .startMocking();
+
+ // InstrumentationTestRunner prepares a looper, but AndroidJUnitRunner does not.
+ // http://b/25897652.
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+
+ mContext = spy(InstrumentationRegistry.getInstrumentation().getTargetContext());
+
+ mUserManager = spy(mContext.getSystemService(UserManager.class));
+ doReturn(mUserManager).when(mContext).getSystemService(eq(UserManager.class));
+ doReturn(mUserManager).when(mContext).getSystemService(eq(Context.USER_SERVICE));
+
+ Resources resources = spy(mContext.getResources());
+ doReturn("").when(resources).getString(
+ eq(com.android.car.R.string.instrumentClusterRendererService));
+ doReturn(false).when(resources).getBoolean(
+ eq(com.android.car.R.bool.audioUseDynamicRouting));
+ doReturn(new String[0]).when(resources).getStringArray(
+ eq(com.android.car.R.array.config_earlyStartupServices));
+ doReturn(resources).when(mContext).getResources();
+
+ mFakeSystemInterface = Builder.newSystemInterface()
+ .withSystemStateInterface(mMockSystemStateInterface)
+ .withActivityManagerInterface(mMockActivityManagerInterface)
+ .withDisplayInterface(mMockDisplayInterface)
+ .withIOInterface(mMockIOInterface)
+ .withStorageMonitoringInterface(mMockStorageMonitoringInterface)
+ .withTimeInterface(mMockTimeInterface)
+ .withWakeLockInterface(mMockWakeLockInterface).build();
+ // ICarImpl will register new CarLocalServices services.
+ // This prevents one test failure in tearDown from triggering assertion failure for single
+ // CarLocalServices service.
+ CarLocalServices.removeAllServices();
+ }
+
+ /**
+ * Clean up before running the next test.
+ */
+ @After
+ public void tearDown() {
+ if (mMockIOInterface != null) {
+ mMockIOInterface.tearDown();
+ }
+ mSession.finishMocking();
+ CarLocalServices.removeAllServices();
+ }
+
+ @Test
+ public void testNoShardedPreferencesAccessedBeforeUserZeroUnlock() {
+ doReturn(true).when(mContext).isCredentialProtectedStorage();
+ doReturn(false).when(mUserManager).isUserUnlockingOrUnlocked(anyInt());
+ doReturn(false).when(mUserManager).isUserUnlocked();
+ doReturn(false).when(mUserManager).isUserUnlocked(anyInt());
+ doReturn(false).when(mUserManager).isUserUnlocked(any(UserHandle.class));
+ doReturn(false).when(mUserManager).isUserUnlockingOrUnlocked(any(UserHandle.class));
+
+ doThrow(new NullPointerException()).when(mContext).getSharedPrefsFile(anyString());
+ doThrow(new NullPointerException()).when(mContext).getSharedPreferencesPath(any());
+ doThrow(new NullPointerException()).when(mContext).getSharedPreferences(
+ anyString(), anyInt());
+ doThrow(new NullPointerException()).when(mContext).getSharedPreferences(
+ any(File.class), anyInt());
+ doThrow(new NullPointerException()).when(mContext).getDataDir();
+
+ ICarImpl carImpl = new ICarImpl(mContext, mMockVehicle, mFakeSystemInterface,
+ /* errorNotifier= */ null, "MockedCar");
+ carImpl.init();
+ Car mCar = new Car(mContext, carImpl, /* handler= */ null);
+
+ // Post tasks for Handler Threads to ensure all the tasks that will be queued inside init
+ // will be done.
+ for (Thread t : Thread.getAllStackTraces().keySet()) {
+ if (!HandlerThread.class.isInstance(t)) {
+ continue;
+ }
+ HandlerThread ht = (HandlerThread) t;
+ CarServiceUtils.runOnLooperSync(ht.getLooper(), () -> {
+ // Do nothing, just need to make sure looper finishes current task.
+ });
+ }
+
+ mCar.disconnect();
+ carImpl.release();
+ }
+
+ static final class MockIOInterface implements IOInterface {
+ private TemporaryDirectory mFilesDir = null;
+
+ @Override
+ public File getSystemCarDir() {
+ if (mFilesDir == null) {
+ try {
+ mFilesDir = new TemporaryDirectory(TAG);
+ } catch (IOException e) {
+ Log.e(TAG, "failed to create temporary directory", e);
+ fail("failed to create temporary directory. exception was: " + e);
+ }
+ }
+ return mFilesDir.getDirectory();
+ }
+
+ public void tearDown() {
+ if (mFilesDir != null) {
+ try {
+ mFilesDir.close();
+ } catch (Exception e) {
+ Log.w(TAG, "could not remove temporary directory", e);
+ }
+ }
+ }
+ }
+}
diff --git a/watchdog/Android.mk b/watchdog/Android.mk
new file mode 100644
index 0000000..f0724fc
--- /dev/null
+++ b/watchdog/Android.mk
@@ -0,0 +1,16 @@
+# 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/watchdog/aidl/Android.bp b/watchdog/aidl/Android.bp
new file mode 100644
index 0000000..5e80398
--- /dev/null
+++ b/watchdog/aidl/Android.bp
@@ -0,0 +1,27 @@
+// 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.
+
+aidl_interface {
+ name: "carwatchdog_aidl_interface",
+ srcs: [
+ "android/automotive/watchdog/*.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ java: {
+ platform_apis: true,
+ enabled: true,
+ },
+ },
+}
diff --git a/watchdog/aidl/android/automotive/watchdog/ICarWatchdog.aidl b/watchdog/aidl/android/automotive/watchdog/ICarWatchdog.aidl
new file mode 100644
index 0000000..60115eb
--- /dev/null
+++ b/watchdog/aidl/android/automotive/watchdog/ICarWatchdog.aidl
@@ -0,0 +1,137 @@
+/*
+ * 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 android.automotive.watchdog;
+
+import android.automotive.watchdog.ICarWatchdogClient;
+import android.automotive.watchdog.ICarWatchdogMonitor;
+import android.automotive.watchdog.PowerCycle;
+import android.automotive.watchdog.TimeoutLength;
+import android.automotive.watchdog.UserState;
+
+/**
+ * ICarWatchdog is an interface implemented by watchdog server.
+ * For health check, 4 components are involved: watchdog server, watchdog mediator, watchdog
+ * client, and watchdog monitor.
+ * - watchdog server: checks clients' health status by pinging and waiting for the response.
+ * - watchdog mediator: is a watchdog client by reporting its health status to the server, and
+ * at the same time plays a role of watchdog server by checking its clients'
+ * health status.
+ * - watchdog client: reports its health status by responding to server's ping within timeout.
+ * - watchdog monitor: captures and reports the process state of watchdog clients.
+ */
+
+@VintfStability
+interface ICarWatchdog {
+ /**
+ * Register the client to the watchdog server.
+ *
+ * @param client Watchdog client to register.
+ * @param timeout Timeout length specified through enum.
+ */
+ oneway void registerClient(in ICarWatchdogClient client, in TimeoutLength timeout);
+
+ /**
+ * Unregister the client from the watchdog server.
+ *
+ * @param client Watchdog client to unregister.
+ */
+ oneway void unregisterClient(in ICarWatchdogClient client);
+
+ /**
+ * Register the mediator to the watchdog server.
+ * Note that watchdog mediator is also a watchdog client.
+ * The caller should have system UID.
+ *
+ * @param mediator Watchdog mediator to register.
+ */
+ oneway void registerMediator(in ICarWatchdogClient mediator);
+
+ /**
+ * Unregister the mediator from the watchdog server.
+ * Note that watchdog mediator is also a watchdog client.
+ * The caller should have system UID.
+ *
+ * @param mediator Watchdog mediator to unregister.
+ */
+ oneway void unregisterMediator(in ICarWatchdogClient mediator);
+
+ /**
+ * Register the monitor to the watchdog server.
+ * The caller should have system UID.
+ *
+ * @param monitor Watchdog monitor to register.
+ */
+ oneway void registerMonitor(in ICarWatchdogMonitor monitor);
+
+ /**
+ * Unregister the monitor from the watchdog server.
+ * The caller should have system UID.
+ *
+ * @param monitor Watchdog monitor to unregister.
+ */
+ oneway void unregisterMonitor(in ICarWatchdogMonitor monitor);
+
+ /**
+ * Tell watchdog server that the client is alive.
+ *
+ * @param client Watchdog client that is responding.
+ * @param sessionId Session id given by watchdog server.
+ * @return Whether the response is accepted.
+ */
+ boolean tellClientAlive(in ICarWatchdogClient client, in int sessionId);
+
+ /**
+ * Tell watchdog server that the mediator is alive together with the status of clients under
+ * the mediator.
+ * The caller should have system UID.
+ *
+ * @param mediator Watchdog mediator that is responding.
+ * @param clientsNotResponding Array of process id of clients which haven't responded to the
+ * mediator.
+ * @param sessionId Session id given by watchdog server.
+ * @return Whether the response is accepted.
+ */
+ boolean tellMediatorAlive(
+ in ICarWatchdogClient mediator, in int[] clientsNotResponding, in int sessionId);
+
+ /**
+ * Tell watchdog server that the monitor has finished dumping process information.
+ * The caller should have system UID.
+ *
+ * @param monitor Watchdog monitor that is registered to watchdog server.
+ * @param pid Process id that has been dumped.
+ */
+ oneway void tellDumpFinished(in ICarWatchdogMonitor monitor, in int pid);
+
+ /**
+ * Notify watchdog server that the device goes into a new power cycle.
+ * The caller should have system UID.
+ *
+ * @param cycle Power cycle of the device.
+ * @return Whether the notification is processed.
+ */
+ boolean notifyPowerCycleChange(in PowerCycle cycle);
+
+ /**
+ * Notify watchdog server that Android user is started or stopped.
+ * The caller should have system UID.
+ *
+ * @param userId Android user id.
+ * @return Whether the notification is processed.
+ */
+ boolean notifyUserStateChange(in int userId, in UserState state);
+}
diff --git a/watchdog/aidl/android/automotive/watchdog/ICarWatchdogClient.aidl b/watchdog/aidl/android/automotive/watchdog/ICarWatchdogClient.aidl
new file mode 100644
index 0000000..1d33957
--- /dev/null
+++ b/watchdog/aidl/android/automotive/watchdog/ICarWatchdogClient.aidl
@@ -0,0 +1,34 @@
+/*
+ * 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 android.automotive.watchdog;
+
+import android.automotive.watchdog.TimeoutLength;
+
+@VintfStability
+oneway interface ICarWatchdogClient {
+ /**
+ * Check if the client is alive.
+ * Watchdog server or mediator calls this method, expecting the clients will respond within
+ * timeout. The final timeout is decided by the server, considering the requested timeout on
+ * client registration. If no response from the clients, watchdog server will dump process
+ * information and kill them.
+ *
+ * @param sessionId Unique id to identify each health check session.
+ * @param timeout Final timeout given by the server based on client request.
+ */
+ void checkIfAlive(in int sessionId, in TimeoutLength timeout);
+}
diff --git a/watchdog/aidl/android/automotive/watchdog/ICarWatchdogMonitor.aidl b/watchdog/aidl/android/automotive/watchdog/ICarWatchdogMonitor.aidl
new file mode 100644
index 0000000..d55434c
--- /dev/null
+++ b/watchdog/aidl/android/automotive/watchdog/ICarWatchdogMonitor.aidl
@@ -0,0 +1,32 @@
+/*
+ * 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 android.automotive.watchdog;
+
+import android.automotive.watchdog.ICarWatchdogClient;
+
+@VintfStability
+oneway interface ICarWatchdogMonitor {
+ /**
+ * Called when the client has not responded within the given timeout.
+ * Watchdog server calls this method, requesting the monitor to dump process information of the
+ * client.
+ *
+ * @param client Binder object of the client.
+ * @param pid Process id of the client.
+ */
+ void onClientNotResponding(in ICarWatchdogClient client, in int pid);
+}
diff --git a/watchdog/aidl/android/automotive/watchdog/PowerCycle.aidl b/watchdog/aidl/android/automotive/watchdog/PowerCycle.aidl
new file mode 100644
index 0000000..d0e82bd
--- /dev/null
+++ b/watchdog/aidl/android/automotive/watchdog/PowerCycle.aidl
@@ -0,0 +1,40 @@
+/*
+ * 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 android.automotive.watchdog;
+
+/**
+ * Used by ICarWatchdog to describe the device power status.
+ */
+
+@VintfStability
+@Backing(type="int")
+enum PowerCycle {
+ /**
+ * The system is about to shut down.
+ */
+ POWER_CYCLE_SHUTDOWN,
+
+ /**
+ * The system is being suspended.
+ */
+ POWER_CYCLE_SUSPEND,
+
+ /**
+ * The system resumes working.
+ */
+ POWER_CYCLE_RESUME,
+}
diff --git a/watchdog/aidl/android/automotive/watchdog/TimeoutLength.aidl b/watchdog/aidl/android/automotive/watchdog/TimeoutLength.aidl
new file mode 100644
index 0000000..20fa7d7
--- /dev/null
+++ b/watchdog/aidl/android/automotive/watchdog/TimeoutLength.aidl
@@ -0,0 +1,46 @@
+/*
+ * 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 android.automotive.watchdog;
+
+/**
+ * Used by ICarWatchdog and ICarWatchdogMediator to determine if the clients are in bad state.
+ * Watchdog server will decide that the clients are in bad state when they don't respond within
+ * the timeout. Different timeouts are used by different clients based on how responsive they
+ * should be.
+ */
+
+@VintfStability
+@Backing(type="int")
+enum TimeoutLength {
+ /**
+ * Timeout is 3 seconds.
+ * This is for services which should be responsive.
+ */
+ TIMEOUT_CRITICAL,
+
+ /**
+ * Timeout is 5 seconds.
+ * This is for services which are relatively responsive.
+ */
+ TIMEOUT_MODERATE,
+
+ /**
+ * Timeout is 10 seconds.
+ * This is for all other services.
+ */
+ TIMEOUT_NORMAL,
+}
diff --git a/watchdog/aidl/android/automotive/watchdog/UserState.aidl b/watchdog/aidl/android/automotive/watchdog/UserState.aidl
new file mode 100644
index 0000000..d55ea11
--- /dev/null
+++ b/watchdog/aidl/android/automotive/watchdog/UserState.aidl
@@ -0,0 +1,35 @@
+/*
+ * 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 android.automotive.watchdog;
+
+/**
+ * Used by ICarWatchdog to describe whether user is started or stopped.
+ */
+
+@VintfStability
+@Backing(type="int")
+enum UserState {
+ /**
+ * The user is started.
+ */
+ USER_STATE_STARTED,
+
+ /**
+ * The user is stopped.
+ */
+ USER_STATE_STOPPED,
+}