summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXin Li <delphij@google.com>2017-12-06 11:51:43 -0800
committerXin Li <delphij@google.com>2017-12-06 14:24:44 -0800
commit6bb6b9542d3e296fbfc7f4e0f5b744dde71287bc (patch)
treee9c0975f37cb207cc0065d80d25807bb704678a0
parent25a3861acf9187385d9ece5071ef06ca28f73746 (diff)
parente8db47d39733ee7608a698fbe7dfcd1bf7a5a0b1 (diff)
downloaddragon-6bb6b9542d3e296fbfc7f4e0f5b744dde71287bc.tar.gz
DO NOT MERGE: Merge Oreo MR1 into master
Exempt-From-Owner-Approval: Changes already landed internally Change-Id: Ibafd36d2a04f37f656c2f94691a05cd2ce5572ff
-rw-r--r--Android.bp18
-rw-r--r--AndroidProducts.mk3
-rw-r--r--CleanSpec.mk2
-rw-r--r--aosp_dragon_car.mk37
-rw-r--r--bluetooth/Android.bp45
-rw-r--r--bluetooth/bluetooth_address.cc79
-rw-r--r--bluetooth/bluetooth_address.h58
-rw-r--r--bluetooth/bluetooth_hci.cc145
-rw-r--r--bluetooth/bluetooth_hci.h59
-rw-r--r--bluetooth/bt_vendor_lib.h434
-rw-r--r--bluetooth/vendor_interface.cc363
-rw-r--r--bluetooth/vendor_interface.h76
-rw-r--r--device.mk3
-rw-r--r--manifest_dragon_car.xml39
-rw-r--r--media_codecs_performance.xml142
-rw-r--r--overlay/frameworks/base/core/res/res/values/config.xml7
16 files changed, 1440 insertions, 70 deletions
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..f31b444
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,18 @@
+//
+// 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.
+
+subdirs = [
+ "bluetooth",
+]
diff --git a/AndroidProducts.mk b/AndroidProducts.mk
index 7bc7d5b..5faaef4 100644
--- a/AndroidProducts.mk
+++ b/AndroidProducts.mk
@@ -15,4 +15,5 @@
#
PRODUCT_MAKEFILES := \
- $(LOCAL_DIR)/aosp_dragon.mk
+ $(LOCAL_DIR)/aosp_dragon.mk \
+ $(LOCAL_DIR)/aosp_dragon_car.mk
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 8933ebc..c9e5cf0 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -49,3 +49,5 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/permissions/android.hard
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/permissions/android.hardware.location.gps.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/permissions/android.hardware.camera.full.xml)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/permissions/android.hardware.camera.manual_sensor.xml)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib/hw/android.hardware.broadcastradio@1.0-impl.so)
+$(call add-clean-step, rm -f $(PRODUCT_OUT)/system/lib64/hw/android.hardware.broadcastradio@1.0-impl.so)
diff --git a/aosp_dragon_car.mk b/aosp_dragon_car.mk
new file mode 100644
index 0000000..34aa6c7
--- /dev/null
+++ b/aosp_dragon_car.mk
@@ -0,0 +1,37 @@
+# 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.
+
+#
+# This file is the build configuration for an aosp Android
+# build for dragon hardware. This cleanly combines a set of
+# device-specific aspects (drivers) with a device-agnostic
+# product configuration (apps). Except for a few implementation
+# details, it only fundamentally contains two inherit-product
+# lines, aosp and dragon, hence its name.
+#
+
+PRODUCT_COPY_FILES += \
+ device/google/dragon/manifest_dragon_car.xml:vendor/manifest.xml
+
+$(call inherit-product, packages/services/Car/car_product/build/car.mk)
+$(call inherit-product, device/google/dragon/aosp_dragon.mk)
+
+BOARD_SEPOLICY_DIRS += packages/services/Car/car_product/sepolicy
+
+PRODUCT_NAME := aosp_dragon_car
+PRODUCT_DEVICE := dragon
+PRODUCT_BRAND := Android
+PRODUCT_MODEL := Android Auto Embedded on dragon
+PRODUCT_MANUFACTURER := Google
+PRODUCT_RESTRICT_VENDOR_FILES := true
diff --git a/bluetooth/Android.bp b/bluetooth/Android.bp
new file mode 100644
index 0000000..0f38d9b
--- /dev/null
+++ b/bluetooth/Android.bp
@@ -0,0 +1,45 @@
+//
+// 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.
+
+cc_library_shared {
+ name: "android.hardware.bluetooth@1.0-impl-dragon",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "bluetooth_address.cc",
+ "bluetooth_hci.cc",
+ "vendor_interface.cc",
+ ],
+ shared_libs: [
+ "android.frameworks.schedulerservice@1.0",
+ "android.hardware.bluetooth@1.0",
+ "libbase",
+ "libcutils",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libutils",
+ ],
+ static_libs: [
+ "android.hardware.bluetooth-async",
+ "android.hardware.bluetooth-hci",
+ ],
+}
diff --git a/bluetooth/bluetooth_address.cc b/bluetooth/bluetooth_address.cc
new file mode 100644
index 0000000..f3ec963
--- /dev/null
+++ b/bluetooth/bluetooth_address.cc
@@ -0,0 +1,79 @@
+//
+// Copyright 2016 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.
+//
+
+#include "bluetooth_address.h"
+
+#include <android-base/logging.h>
+#include <cutils/properties.h>
+#include <fcntl.h>
+#include <utils/Log.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace dragon {
+
+void BluetoothAddress::bytes_to_string(const uint8_t* addr, char* addr_str) {
+ sprintf(addr_str, "%02x:%02x:%02x:%02x:%02x:%02x", addr[0], addr[1], addr[2],
+ addr[3], addr[4], addr[5]);
+}
+
+bool BluetoothAddress::string_to_bytes(const char* addr_str, uint8_t* addr) {
+ if (addr_str == NULL) return false;
+ if (strnlen(addr_str, kStringLength) != kStringLength) return false;
+ unsigned char trailing_char = '\0';
+
+ return (sscanf(addr_str, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx%1c",
+ &addr[0], &addr[1], &addr[2], &addr[3], &addr[4], &addr[5],
+ &trailing_char) == kBytes);
+}
+
+bool BluetoothAddress::get_local_address(uint8_t* local_addr) {
+ char property[PROPERTY_VALUE_MAX] = {0};
+
+ // No factory BDADDR found. Look for a previously stored BDA.
+ if (property_get(PERSIST_BDADDR_PROPERTY, property, NULL) &&
+ string_to_bytes(property, local_addr)) {
+ return true;
+ }
+
+ // Look for an the WiFi MAC from an AzureWave module.
+ int wifi_mac_fd = open(AZW_WIFI_MAC_PATH, O_RDONLY);
+ if (wifi_mac_fd != -1) {
+ int bytes_read = read(wifi_mac_fd, property, kStringLength);
+ close(wifi_mac_fd);
+ if (bytes_read != kStringLength) return false;
+
+ // Null terminate the string.
+ property[kStringLength] = '\0';
+
+ // Zero last bit to calculate the Bluetooth address. This works because the
+ // WiFi address is always odd (never ending in 0x0 or 0xa).
+ property[kStringLength - 1] = property[kStringLength - 1] - 1;
+
+ ALOGD("%s: Got BDA from WiFi MAC %s", __func__, property);
+ return string_to_bytes(property, local_addr);
+ }
+
+ return false;
+}
+
+} // namespace dragon
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/bluetooth_address.h b/bluetooth/bluetooth_address.h
new file mode 100644
index 0000000..40e84d7
--- /dev/null
+++ b/bluetooth/bluetooth_address.h
@@ -0,0 +1,58 @@
+//
+// Copyright 2016 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.
+//
+
+#pragma once
+
+#include <fcntl.h>
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace dragon {
+
+// Check for a legacy address stored as a property.
+static constexpr char PERSIST_BDADDR_PROPERTY[] =
+ "persist.service.bdroid.bdaddr";
+
+// Use the WiFi MAC with bit 0 cleared for AzureWave modules
+static constexpr char AZW_WIFI_MAC_PATH[] =
+ "/sys/devices/700b0200.sdhci/mmc_host/mmc0/"
+ "mmc0:0001/mmc0:0001:2/net/wlan0/address";
+
+// Encapsulate handling for Bluetooth Addresses:
+class BluetoothAddress {
+ public:
+ // Conversion constants
+ static constexpr size_t kStringLength = sizeof("XX:XX:XX:XX:XX:XX") - 1;
+ static constexpr size_t kBytes = (kStringLength + 1) / 3;
+
+ static void bytes_to_string(const uint8_t* addr, char* addr_str);
+
+ static bool string_to_bytes(const char* addr_str, uint8_t* addr);
+
+ static bool get_local_address(uint8_t* addr);
+};
+
+} // namespace dragon
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/bluetooth_hci.cc b/bluetooth/bluetooth_hci.cc
new file mode 100644
index 0000000..b5e6fdc
--- /dev/null
+++ b/bluetooth/bluetooth_hci.cc
@@ -0,0 +1,145 @@
+//
+// Copyright 2016 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.
+//
+
+#define LOG_TAG "android.hardware.bluetooth@1.0-impl-dragon"
+#include "bluetooth_hci.h"
+
+#include <log/log.h>
+
+#include "vendor_interface.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace dragon {
+
+static const uint8_t HCI_DATA_TYPE_COMMAND = 1;
+static const uint8_t HCI_DATA_TYPE_ACL = 2;
+static const uint8_t HCI_DATA_TYPE_SCO = 3;
+
+class BluetoothDeathRecipient : public hidl_death_recipient {
+ public:
+ BluetoothDeathRecipient(const sp<IBluetoothHci> hci) : mHci(hci) {}
+
+ virtual void serviceDied(
+ uint64_t /*cookie*/,
+ const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+ ALOGE("BluetoothDeathRecipient::serviceDied - Bluetooth service died");
+ has_died_ = true;
+ mHci->close();
+ }
+ sp<IBluetoothHci> mHci;
+ bool getHasDied() const { return has_died_; }
+ void setHasDied(bool has_died) { has_died_ = has_died; }
+
+ private:
+ bool has_died_;
+};
+
+BluetoothHci::BluetoothHci()
+ : death_recipient_(new BluetoothDeathRecipient(this)) {}
+
+Return<void> BluetoothHci::initialize(
+ const ::android::sp<IBluetoothHciCallbacks>& cb) {
+ ALOGI("BluetoothHci::initialize()");
+ if (cb == nullptr) {
+ ALOGE("cb == nullptr! -> Unable to call initializationComplete(ERR)");
+ return Void();
+ }
+
+ death_recipient_->setHasDied(false);
+ cb->linkToDeath(death_recipient_, 0);
+
+ bool rc = VendorInterface::Initialize(
+ [cb](bool status) {
+ auto hidl_status = cb->initializationComplete(
+ status ? Status::SUCCESS : Status::INITIALIZATION_ERROR);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call initializationComplete()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->hciEventReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call hciEventReceived()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->aclDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call aclDataReceived()");
+ }
+ },
+ [cb](const hidl_vec<uint8_t>& packet) {
+ auto hidl_status = cb->scoDataReceived(packet);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call scoDataReceived()");
+ }
+ });
+ if (!rc) {
+ auto hidl_status = cb->initializationComplete(Status::INITIALIZATION_ERROR);
+ if (!hidl_status.isOk()) {
+ ALOGE("VendorInterface -> Unable to call initializationComplete(ERR)");
+ }
+ }
+
+ unlink_cb_ = [cb](sp<BluetoothDeathRecipient>& death_recipient) {
+ if (death_recipient->getHasDied())
+ ALOGI("Skipping unlink call, service died.");
+ else
+ cb->unlinkToDeath(death_recipient);
+ };
+
+ return Void();
+}
+
+Return<void> BluetoothHci::close() {
+ ALOGI("BluetoothHci::close()");
+ unlink_cb_(death_recipient_);
+ VendorInterface::Shutdown();
+ return Void();
+}
+
+Return<void> BluetoothHci::sendHciCommand(const hidl_vec<uint8_t>& command) {
+ sendDataToController(HCI_DATA_TYPE_COMMAND, command);
+ return Void();
+}
+
+Return<void> BluetoothHci::sendAclData(const hidl_vec<uint8_t>& data) {
+ sendDataToController(HCI_DATA_TYPE_ACL, data);
+ return Void();
+}
+
+Return<void> BluetoothHci::sendScoData(const hidl_vec<uint8_t>& data) {
+ sendDataToController(HCI_DATA_TYPE_SCO, data);
+ return Void();
+}
+
+void BluetoothHci::sendDataToController(const uint8_t type,
+ const hidl_vec<uint8_t>& data) {
+ VendorInterface::get()->Send(type, data.data(), data.size());
+}
+
+IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* /* name */) {
+ return new BluetoothHci();
+}
+
+} // namespace dragon
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/bluetooth_hci.h b/bluetooth/bluetooth_hci.h
new file mode 100644
index 0000000..4661d92
--- /dev/null
+++ b/bluetooth/bluetooth_hci.h
@@ -0,0 +1,59 @@
+//
+// Copyright 2016 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.
+//
+
+#ifndef android_hardware_bluetooth_V1_0_BluetoothHci_H_
+#define android_hardware_bluetooth_V1_0_BluetoothHci_H_
+
+#include <android/hardware/bluetooth/1.0/IBluetoothHci.h>
+
+#include <hidl/MQDescriptor.h>
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace dragon {
+
+using ::android::hardware::Return;
+using ::android::hardware::hidl_vec;
+
+class BluetoothDeathRecipient;
+
+class BluetoothHci : public IBluetoothHci {
+ public:
+ BluetoothHci();
+ Return<void> initialize(
+ const ::android::sp<IBluetoothHciCallbacks>& cb) override;
+ Return<void> sendHciCommand(const hidl_vec<uint8_t>& packet) override;
+ Return<void> sendAclData(const hidl_vec<uint8_t>& data) override;
+ Return<void> sendScoData(const hidl_vec<uint8_t>& data) override;
+ Return<void> close() override;
+
+ private:
+ void sendDataToController(const uint8_t type, const hidl_vec<uint8_t>& data);
+ ::android::sp<BluetoothDeathRecipient> death_recipient_;
+ std::function<void(sp<BluetoothDeathRecipient>&)> unlink_cb_;
+};
+
+extern "C" IBluetoothHci* HIDL_FETCH_IBluetoothHci(const char* name);
+
+} // namespace dragon
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_bluetooth_V1_0_BluetoothHci_H_
diff --git a/bluetooth/bt_vendor_lib.h b/bluetooth/bt_vendor_lib.h
new file mode 100644
index 0000000..c4035b7
--- /dev/null
+++ b/bluetooth/bt_vendor_lib.h
@@ -0,0 +1,434 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2009-2012 Broadcom Corporation
+ *
+ * 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.
+ *
+ ******************************************************************************/
+
+#ifndef BT_VENDOR_LIB_H
+#define BT_VENDOR_LIB_H
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Struct types */
+
+/** Typedefs and defines */
+
+/** Vendor specific operations OPCODE */
+typedef enum {
+ /* [operation]
+ * Power on or off the BT Controller.
+ * [input param]
+ * A pointer to int type with content of bt_vendor_power_state_t.
+ * Typecasting conversion: (int *) param.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * None.
+ */
+ BT_VND_OP_POWER_CTRL,
+
+ /* [operation]
+ * Perform any vendor specific initialization or configuration
+ * on the BT Controller. This is called before stack initialization.
+ * [input param]
+ * None.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * Must call fwcfg_cb to notify the stack of the completion of vendor
+ * specific initialization once it has been done.
+ */
+ BT_VND_OP_FW_CFG,
+
+ /* [operation]
+ * Perform any vendor specific SCO/PCM configuration on the BT
+ * Controller.
+ * This is called after stack initialization.
+ * [input param]
+ * None.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * Must call scocfg_cb to notify the stack of the completion of vendor
+ * specific SCO configuration once it has been done.
+ */
+ BT_VND_OP_SCO_CFG,
+
+ /* [operation]
+ * Open UART port on where the BT Controller is attached.
+ * This is called before stack initialization.
+ * [input param]
+ * A pointer to int array type for open file descriptors.
+ * The mapping of HCI channel to fd slot in the int array is given in
+ * bt_vendor_hci_channels_t.
+ * And, it requires the vendor lib to fill up the content before
+ * returning
+ * the call.
+ * Typecasting conversion: (int (*)[]) param.
+ * [return]
+ * Numbers of opened file descriptors.
+ * Valid number:
+ * 1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART)
+ * 2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd
+ * 4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd
+ * [callback]
+ * None.
+ */
+ BT_VND_OP_USERIAL_OPEN,
+
+ /* [operation]
+ * Close the previously opened UART port.
+ * [input param]
+ * None.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * None.
+ */
+ BT_VND_OP_USERIAL_CLOSE,
+
+ /* [operation]
+ * Get the LPM idle timeout in milliseconds.
+ * The stack uses this information to launch a timer delay before it
+ * attempts to de-assert LPM WAKE signal once downstream HCI packet
+ * has been delivered.
+ * [input param]
+ * A pointer to uint32_t type which is passed in by the stack. And, it
+ * requires the vendor lib to fill up the content before returning
+ * the call.
+ * Typecasting conversion: (uint32_t *) param.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * None.
+ */
+ BT_VND_OP_GET_LPM_IDLE_TIMEOUT,
+
+ /* [operation]
+ * Enable or disable LPM mode on BT Controller.
+ * [input param]
+ * A pointer to uint8_t type with content of bt_vendor_lpm_mode_t.
+ * Typecasting conversion: (uint8_t *) param.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * Must call lpm_cb to notify the stack of the completion of LPM
+ * disable/enable process once it has been done.
+ */
+ BT_VND_OP_LPM_SET_MODE,
+
+ /* [operation]
+ * Assert or Deassert LPM WAKE on BT Controller.
+ * [input param]
+ * A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t.
+ * Typecasting conversion: (uint8_t *) param.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * None.
+ */
+ BT_VND_OP_LPM_WAKE_SET_STATE,
+
+ /* [operation]
+ * Perform any vendor specific commands related to audio state changes.
+ * [input param]
+ * a pointer to bt_vendor_op_audio_state_t indicating what audio state is
+ * set.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * None.
+ */
+ BT_VND_OP_SET_AUDIO_STATE,
+
+ /* [operation]
+ * The epilog call to the vendor module so that it can perform any
+ * vendor-specific processes (e.g. send a HCI_RESET to BT Controller)
+ * before the caller calls for cleanup().
+ * [input param]
+ * None.
+ * [return]
+ * 0 - default, don't care.
+ * [callback]
+ * Must call epilog_cb to notify the stack of the completion of vendor
+ * specific epilog process once it has been done.
+ */
+ BT_VND_OP_EPILOG,
+
+ /* [operation]
+ * Call to the vendor module so that it can perform all vendor-specific
+ * operations to start offloading a2dp media encode & tx.
+ * [input param]
+ * pointer to bt_vendor_op_a2dp_offload_start_t containing elements
+ * required for VND FW to setup a2dp offload.
+ * [return]
+ * 0 - default, dont care.
+ * [callback]
+ * Must call a2dp_offload_start_cb to notify the stack of the
+ * completion of vendor specific setup process once it has been done.
+ */
+ BT_VND_OP_A2DP_OFFLOAD_START,
+
+ /* [operation]
+ * Call to the vendor module so that it can perform all vendor-specific
+ * operations to suspend offloading a2dp media encode & tx.
+ * [input param]
+ * pointer to bt_vendor_op_a2dp_offload_t containing elements
+ * required for VND FW to setup a2dp offload.
+ * [return]
+ * 0 - default, dont care.
+ * [callback]
+ * Must call a2dp_offload_cb to notify the stack of the
+ * completion of vendor specific setup process once it has been done.
+ */
+ BT_VND_OP_A2DP_OFFLOAD_STOP,
+
+} bt_vendor_opcode_t;
+
+/** Power on/off control states */
+typedef enum {
+ BT_VND_PWR_OFF,
+ BT_VND_PWR_ON,
+} bt_vendor_power_state_t;
+
+/** Define HCI channel identifier in the file descriptors array
+ used in BT_VND_OP_USERIAL_OPEN operation.
+ */
+typedef enum {
+ CH_CMD, // HCI Command channel
+ CH_EVT, // HCI Event channel
+ CH_ACL_OUT, // HCI ACL downstream channel
+ CH_ACL_IN, // HCI ACL upstream channel
+
+ CH_MAX // Total channels
+} bt_vendor_hci_channels_t;
+
+/** LPM disable/enable request */
+typedef enum {
+ BT_VND_LPM_DISABLE,
+ BT_VND_LPM_ENABLE,
+} bt_vendor_lpm_mode_t;
+
+/** LPM WAKE set state request */
+typedef enum {
+ BT_VND_LPM_WAKE_ASSERT,
+ BT_VND_LPM_WAKE_DEASSERT,
+} bt_vendor_lpm_wake_state_t;
+
+/** Callback result values */
+typedef enum {
+ BT_VND_OP_RESULT_SUCCESS,
+ BT_VND_OP_RESULT_FAIL,
+} bt_vendor_op_result_t;
+
+/** audio (SCO) state changes triggering VS commands for configuration */
+typedef struct {
+ uint16_t handle;
+ uint16_t peer_codec;
+ uint16_t state;
+} bt_vendor_op_audio_state_t;
+
+/*
+ * Bluetooth Host/Controller Vendor callback structure.
+ */
+
+/* vendor initialization/configuration callback */
+typedef void (*cfg_result_cb)(bt_vendor_op_result_t result);
+
+/* datapath buffer allocation callback (callout)
+ *
+ * Vendor lib needs to request a buffer through the alloc callout function
+ * from HCI lib if the buffer is for constructing a HCI Command packet which
+ * will be sent through xmit_cb to BT Controller.
+ *
+ * For each buffer allocation, the requested size needs to be big enough to
+ * accommodate the below header plus a complete HCI packet --
+ * typedef struct
+ * {
+ * uint16_t event;
+ * uint16_t len;
+ * uint16_t offset;
+ * uint16_t layer_specific;
+ * } HC_BT_HDR;
+ *
+ * HCI lib returns a pointer to the buffer where Vendor lib should use to
+ * construct a HCI command packet as below format:
+ *
+ * --------------------------------------------
+ * | HC_BT_HDR | HCI command |
+ * --------------------------------------------
+ * where
+ * HC_BT_HDR.event = 0x2000;
+ * HC_BT_HDR.len = Length of HCI command;
+ * HC_BT_HDR.offset = 0;
+ * HC_BT_HDR.layer_specific = 0;
+ *
+ * For example, a HCI_RESET Command will be formed as
+ * ------------------------
+ * | HC_BT_HDR |03|0c|00|
+ * ------------------------
+ * with
+ * HC_BT_HDR.event = 0x2000;
+ * HC_BT_HDR.len = 3;
+ * HC_BT_HDR.offset = 0;
+ * HC_BT_HDR.layer_specific = 0;
+ */
+typedef void* (*malloc_cb)(int size);
+
+/* datapath buffer deallocation callback (callout) */
+typedef void (*mdealloc_cb)(void* p_buf);
+
+/* define callback of the cmd_xmit_cb
+ *
+ * The callback function which HCI lib will call with the return of command
+ * complete packet. Vendor lib is responsible for releasing the buffer passed
+ * in at the p_mem parameter by calling dealloc callout function.
+ */
+typedef void (*tINT_CMD_CBACK)(void* p_mem);
+
+/* hci command packet transmit callback (callout)
+ *
+ * Vendor lib calls xmit_cb callout function in order to send a HCI Command
+ * packet to BT Controller. The buffer carrying HCI Command packet content
+ * needs to be first allocated through the alloc callout function.
+ * HCI lib will release the buffer for Vendor lib once it has delivered the
+ * packet content to BT Controller.
+ *
+ * Vendor lib needs also provide a callback function (p_cback) which HCI lib
+ * will call with the return of command complete packet.
+ *
+ * The opcode parameter gives the HCI OpCode (combination of OGF and OCF) of
+ * HCI Command packet. For example, opcode = 0x0c03 for the HCI_RESET command
+ * packet.
+ */
+typedef uint8_t (*cmd_xmit_cb)(uint16_t opcode, void* p_buf,
+ tINT_CMD_CBACK p_cback);
+
+typedef void (*cfg_a2dp_cb)(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
+ uint8_t bta_av_handle);
+
+typedef struct {
+ /** set to sizeof(bt_vendor_callbacks_t) */
+ size_t size;
+
+ /*
+ * Callback and callout functions have implemented in HCI libray
+ * (libbt-hci.so).
+ */
+
+ /* notifies caller result of firmware configuration request */
+ cfg_result_cb fwcfg_cb;
+
+ /* notifies caller result of sco configuration request */
+ cfg_result_cb scocfg_cb;
+
+ /* notifies caller result of lpm enable/disable */
+ cfg_result_cb lpm_cb;
+
+ /* notifies the result of codec setting */
+ cfg_result_cb audio_state_cb;
+
+ /* buffer allocation request */
+ malloc_cb alloc;
+
+ /* buffer deallocation request */
+ mdealloc_cb dealloc;
+
+ /* hci command packet transmit request */
+ cmd_xmit_cb xmit_cb;
+
+ /* notifies caller completion of epilog process */
+ cfg_result_cb epilog_cb;
+
+ /* notifies status of a2dp offload cmd's */
+ cfg_a2dp_cb a2dp_offload_cb;
+} bt_vendor_callbacks_t;
+
+/** A2DP offload request */
+typedef struct {
+ uint8_t bta_av_handle; /* BTA_AV Handle for callbacks */
+ uint16_t xmit_quota; /* Total ACL quota for light stack */
+ uint16_t acl_data_size; /* Max ACL data size across HCI transport */
+ uint16_t stream_mtu;
+ uint16_t local_cid;
+ uint16_t remote_cid;
+ uint16_t lm_handle;
+ uint8_t is_flushable; /* true if flushable channel */
+ uint32_t stream_source;
+ uint8_t codec_info[10]; /* Codec capabilities array */
+} bt_vendor_op_a2dp_offload_t;
+
+/*
+ * Bluetooth Host/Controller VENDOR Interface
+ */
+typedef struct {
+ /** Set to sizeof(bt_vndor_interface_t) */
+ size_t size;
+
+ /*
+ * Functions need to be implemented in Vendor libray (libbt-vendor.so).
+ */
+
+ /**
+ * Caller will open the interface and pass in the callback routines
+ * to the implemenation of this interface.
+ */
+ int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char* local_bdaddr);
+
+ /** Vendor specific operations */
+ int (*op)(bt_vendor_opcode_t opcode, void* param);
+
+ /** Closes the interface */
+ void (*cleanup)(void);
+} bt_vendor_interface_t;
+
+/*
+ * External shared lib functions/data
+ */
+
+/* Entry point of DLib --
+ * Vendor library needs to implement the body of bt_vendor_interface_t
+ * structure and uses the below name as the variable name. HCI library
+ * will use this symbol name to get address of the object through the
+ * dlsym call.
+ */
+extern const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE;
+
+// MODIFICATION FOR NEW HAL/HIDL IMPLEMENTATION:
+// EXPOSE THE BT_HDR STRUCT HERE FOR THE VENDOR INTERFACE
+// ONLY, WITHOUT REQUIRING INCLUDES FROM system/bt OR OTHER
+// DIRECTORIES.
+// ONLY USED INSIDE transmit_cb.
+// DO NOT USE IN NEW HAL IMPLEMENTATIONS GOING FORWARD
+typedef struct {
+ uint16_t event;
+ uint16_t len;
+ uint16_t offset;
+ uint16_t layer_specific;
+ uint8_t data[];
+} HC_BT_HDR;
+// /MODIFICATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BT_VENDOR_LIB_H */
diff --git a/bluetooth/vendor_interface.cc b/bluetooth/vendor_interface.cc
new file mode 100644
index 0000000..d485185
--- /dev/null
+++ b/bluetooth/vendor_interface.cc
@@ -0,0 +1,363 @@
+//
+// Copyright 2016 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.
+//
+
+#include "vendor_interface.h"
+
+#define LOG_TAG "android.hardware.bluetooth@1.0-impl-dragon"
+#include <cutils/properties.h>
+#include <utils/Log.h>
+
+#include <dlfcn.h>
+#include <fcntl.h>
+
+#include "bluetooth_address.h"
+#include "h4_protocol.h"
+
+static const char* VENDOR_LIBRARY_NAME = "libbt-vendor.so";
+static const char* VENDOR_LIBRARY_SYMBOL_NAME =
+ "BLUETOOTH_VENDOR_LIB_INTERFACE";
+
+static const int INVALID_FD = -1;
+
+namespace {
+
+using android::hardware::bluetooth::V1_0::dragon::VendorInterface;
+using android::hardware::hidl_vec;
+
+struct {
+ tINT_CMD_CBACK cb;
+ uint16_t opcode;
+} internal_command;
+
+// True when LPM is not enabled yet or wake is not asserted.
+bool lpm_wake_deasserted;
+uint32_t lpm_timeout_ms;
+bool recent_activity_flag;
+
+VendorInterface* g_vendor_interface = nullptr;
+
+HC_BT_HDR* WrapPacketAndCopy(uint16_t event, const hidl_vec<uint8_t>& data) {
+ size_t packet_size = data.size() + sizeof(HC_BT_HDR);
+ HC_BT_HDR* packet = reinterpret_cast<HC_BT_HDR*>(new uint8_t[packet_size]);
+ packet->offset = 0;
+ packet->len = data.size();
+ packet->layer_specific = 0;
+ packet->event = event;
+ // TODO(eisenbach): Avoid copy here; if BT_HDR->data can be ensured to
+ // be the only way the data is accessed, a pointer could be passed here...
+ memcpy(packet->data, data.data(), data.size());
+ return packet;
+}
+
+bool internal_command_event_match(const hidl_vec<uint8_t>& packet) {
+ uint8_t event_code = packet[0];
+ if (event_code != HCI_COMMAND_COMPLETE_EVENT) {
+ ALOGE("%s: Unhandled event type %02X", __func__, event_code);
+ return false;
+ }
+
+ size_t opcode_offset = HCI_EVENT_PREAMBLE_SIZE + 1; // Skip num packets.
+
+ uint16_t opcode = packet[opcode_offset] | (packet[opcode_offset + 1] << 8);
+
+ ALOGV("%s internal_command.opcode = %04X opcode = %04x", __func__,
+ internal_command.opcode, opcode);
+ return opcode == internal_command.opcode;
+}
+
+uint8_t transmit_cb(uint16_t opcode, void* buffer, tINT_CMD_CBACK callback) {
+ ALOGV("%s opcode: 0x%04x, ptr: %p, cb: %p", __func__, opcode, buffer,
+ callback);
+ internal_command.cb = callback;
+ internal_command.opcode = opcode;
+ uint8_t type = HCI_PACKET_TYPE_COMMAND;
+ HC_BT_HDR* bt_hdr = reinterpret_cast<HC_BT_HDR*>(buffer);
+ VendorInterface::get()->Send(type, bt_hdr->data, bt_hdr->len);
+ delete[] reinterpret_cast<uint8_t*>(buffer);
+ return true;
+}
+
+void firmware_config_cb(bt_vendor_op_result_t result) {
+ ALOGV("%s result: %d", __func__, result);
+ VendorInterface::get()->OnFirmwareConfigured(result);
+}
+
+void sco_config_cb(bt_vendor_op_result_t result) {
+ ALOGD("%s result: %d", __func__, result);
+}
+
+void low_power_mode_cb(bt_vendor_op_result_t result) {
+ ALOGD("%s result: %d", __func__, result);
+}
+
+void sco_audiostate_cb(bt_vendor_op_result_t result) {
+ ALOGD("%s result: %d", __func__, result);
+}
+
+void* buffer_alloc_cb(int size) {
+ void* p = new uint8_t[size];
+ ALOGV("%s pts: %p, size: %d", __func__, p, size);
+ return p;
+}
+
+void buffer_free_cb(void* buffer) {
+ ALOGV("%s ptr: %p", __func__, buffer);
+ delete[] reinterpret_cast<uint8_t*>(buffer);
+}
+
+void epilog_cb(bt_vendor_op_result_t result) {
+ ALOGD("%s result: %d", __func__, result);
+}
+
+void a2dp_offload_cb(bt_vendor_op_result_t result, bt_vendor_opcode_t op,
+ uint8_t av_handle) {
+ ALOGD("%s result: %d, op: %d, handle: %d", __func__, result, op, av_handle);
+}
+
+const bt_vendor_callbacks_t lib_callbacks = {
+ sizeof(lib_callbacks), firmware_config_cb, sco_config_cb,
+ low_power_mode_cb, sco_audiostate_cb, buffer_alloc_cb,
+ buffer_free_cb, transmit_cb, epilog_cb,
+ a2dp_offload_cb};
+
+} // namespace
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace dragon {
+
+class FirmwareStartupTimer {
+ public:
+ FirmwareStartupTimer() : start_time_(std::chrono::steady_clock::now()) {}
+
+ ~FirmwareStartupTimer() {
+ std::chrono::duration<double> duration =
+ std::chrono::steady_clock::now() - start_time_;
+ double s = duration.count();
+ if (s == 0) return;
+ ALOGI("Firmware configured in %.3fs", s);
+ }
+
+ private:
+ std::chrono::steady_clock::time_point start_time_;
+};
+
+bool VendorInterface::Initialize(
+ InitializeCompleteCallback initialize_complete_cb,
+ PacketReadCallback event_cb, PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb) {
+ LOG_ALWAYS_FATAL_IF(g_vendor_interface, "%s: No previous Shutdown()?",
+ __func__);
+ g_vendor_interface = new VendorInterface();
+ return g_vendor_interface->Open(initialize_complete_cb, event_cb, acl_cb,
+ sco_cb);
+}
+
+void VendorInterface::Shutdown() {
+ LOG_ALWAYS_FATAL_IF(!g_vendor_interface, "%s: No Vendor interface!",
+ __func__);
+ g_vendor_interface->Close();
+ delete g_vendor_interface;
+ g_vendor_interface = nullptr;
+}
+
+VendorInterface* VendorInterface::get() { return g_vendor_interface; }
+
+bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
+ PacketReadCallback event_cb,
+ PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb) {
+ initialize_complete_cb_ = initialize_complete_cb;
+
+ // Initialize vendor interface
+
+ lib_handle_ = dlopen(VENDOR_LIBRARY_NAME, RTLD_NOW);
+ if (!lib_handle_) {
+ ALOGE("%s unable to open %s (%s)", __func__, VENDOR_LIBRARY_NAME,
+ dlerror());
+ return false;
+ }
+
+ lib_interface_ = reinterpret_cast<bt_vendor_interface_t*>(
+ dlsym(lib_handle_, VENDOR_LIBRARY_SYMBOL_NAME));
+ if (!lib_interface_) {
+ ALOGE("%s unable to find symbol %s in %s (%s)", __func__,
+ VENDOR_LIBRARY_SYMBOL_NAME, VENDOR_LIBRARY_NAME, dlerror());
+ return false;
+ }
+
+ // Get the local BD address
+
+ uint8_t local_bda[BluetoothAddress::kBytes];
+ if (!BluetoothAddress::get_local_address(local_bda)) {
+ LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
+ }
+ int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
+ if (status) {
+ ALOGE("%s unable to initialize vendor library: %d", __func__, status);
+ return false;
+ }
+
+ ALOGD("%s vendor library loaded", __func__);
+
+ // Power on the controller
+
+ int power_state = BT_VND_PWR_ON;
+ lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+
+ // Get the UART socket(s)
+
+ int fd_list[CH_MAX] = {0};
+ int fd_count = lib_interface_->op(BT_VND_OP_USERIAL_OPEN, &fd_list);
+
+ for (int i = 0; i < fd_count; i++) {
+ if (fd_list[i] == INVALID_FD) {
+ ALOGE("%s: fd %d is invalid!", __func__, fd_list[i]);
+ return false;
+ }
+ }
+
+ event_cb_ = event_cb;
+ PacketReadCallback intercept_events = [this](const hidl_vec<uint8_t>& event) {
+ HandleIncomingEvent(event);
+ };
+
+ if (fd_count == 1) {
+ hci::H4Protocol* h4_hci =
+ new hci::H4Protocol(fd_list[0], intercept_events, acl_cb, sco_cb);
+ fd_watcher_.WatchFdForNonBlockingReads(
+ fd_list[0], [h4_hci](int fd) { h4_hci->OnDataReady(fd); });
+ hci_ = h4_hci;
+ }
+
+ // Initially, the power management is off.
+ lpm_wake_deasserted = true;
+
+ // Start configuring the firmware
+ firmware_startup_timer_ = new FirmwareStartupTimer();
+ lib_interface_->op(BT_VND_OP_FW_CFG, nullptr);
+
+ return true;
+}
+
+void VendorInterface::Close() {
+ // These callbacks may send HCI events (vendor-dependent), so make sure to
+ // StopWatching the file descriptor after this.
+ if (lib_interface_ != nullptr) {
+ bt_vendor_lpm_mode_t mode = BT_VND_LPM_DISABLE;
+ lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
+ }
+
+ fd_watcher_.StopWatchingFileDescriptors();
+
+ if (hci_ != nullptr) {
+ delete hci_;
+ hci_ = nullptr;
+ }
+
+ if (lib_interface_ != nullptr) {
+ lib_interface_->op(BT_VND_OP_USERIAL_CLOSE, nullptr);
+
+ int power_state = BT_VND_PWR_OFF;
+ lib_interface_->op(BT_VND_OP_POWER_CTRL, &power_state);
+ }
+
+ if (lib_handle_ != nullptr) {
+ dlclose(lib_handle_);
+ lib_handle_ = nullptr;
+ }
+
+ if (firmware_startup_timer_ != nullptr) {
+ delete firmware_startup_timer_;
+ firmware_startup_timer_ = nullptr;
+ }
+}
+
+size_t VendorInterface::Send(uint8_t type, const uint8_t* data, size_t length) {
+ recent_activity_flag = true;
+
+ if (lpm_wake_deasserted == true) {
+ // Restart the timer.
+ fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
+ [this]() { OnTimeout(); });
+ // Assert wake.
+ lpm_wake_deasserted = false;
+ bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_ASSERT;
+ lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
+ ALOGV("%s: Sent wake before (%02x)", __func__, data[0] | (data[1] << 8));
+ }
+
+ return hci_->Send(type, data, length);
+}
+
+void VendorInterface::OnFirmwareConfigured(uint8_t result) {
+ ALOGD("%s result: %d", __func__, result);
+
+ if (firmware_startup_timer_ != nullptr) {
+ delete firmware_startup_timer_;
+ firmware_startup_timer_ = nullptr;
+ }
+
+ if (initialize_complete_cb_ != nullptr) {
+ initialize_complete_cb_(result == 0);
+ initialize_complete_cb_ = nullptr;
+ }
+
+ lib_interface_->op(BT_VND_OP_GET_LPM_IDLE_TIMEOUT, &lpm_timeout_ms);
+ ALOGI("%s: lpm_timeout_ms %d", __func__, lpm_timeout_ms);
+
+ bt_vendor_lpm_mode_t mode = BT_VND_LPM_ENABLE;
+ lib_interface_->op(BT_VND_OP_LPM_SET_MODE, &mode);
+
+ ALOGD("%s Calling StartLowPowerWatchdog()", __func__);
+ fd_watcher_.ConfigureTimeout(std::chrono::milliseconds(lpm_timeout_ms),
+ [this]() { OnTimeout(); });
+}
+
+void VendorInterface::OnTimeout() {
+ ALOGV("%s", __func__);
+ if (recent_activity_flag == false) {
+ lpm_wake_deasserted = true;
+ bt_vendor_lpm_wake_state_t wakeState = BT_VND_LPM_WAKE_DEASSERT;
+ lib_interface_->op(BT_VND_OP_LPM_WAKE_SET_STATE, &wakeState);
+ fd_watcher_.ConfigureTimeout(std::chrono::seconds(0), []() {
+ ALOGE("Zero timeout! Should never happen.");
+ });
+ }
+ recent_activity_flag = false;
+}
+
+void VendorInterface::HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet) {
+ if (internal_command.cb != nullptr &&
+ internal_command_event_match(hci_packet)) {
+ HC_BT_HDR* bt_hdr = WrapPacketAndCopy(HCI_PACKET_TYPE_EVENT, hci_packet);
+
+ // The callbacks can send new commands, so don't zero after calling.
+ tINT_CMD_CBACK saved_cb = internal_command.cb;
+ internal_command.cb = nullptr;
+ saved_cb(bt_hdr);
+ } else {
+ event_cb_(hci_packet);
+ }
+}
+
+} // namespace dragon
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/bluetooth/vendor_interface.h b/bluetooth/vendor_interface.h
new file mode 100644
index 0000000..df7daa1
--- /dev/null
+++ b/bluetooth/vendor_interface.h
@@ -0,0 +1,76 @@
+//
+// Copyright 2016 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.
+//
+
+#pragma once
+
+#include <hidl/HidlSupport.h>
+
+#include "async_fd_watcher.h"
+#include "bt_vendor_lib.h"
+#include "hci_protocol.h"
+
+namespace android {
+namespace hardware {
+namespace bluetooth {
+namespace V1_0 {
+namespace dragon {
+
+using ::android::hardware::hidl_vec;
+using InitializeCompleteCallback = std::function<void(bool success)>;
+using PacketReadCallback = std::function<void(const hidl_vec<uint8_t>&)>;
+
+class FirmwareStartupTimer;
+
+class VendorInterface {
+ public:
+ static bool Initialize(InitializeCompleteCallback initialize_complete_cb,
+ PacketReadCallback event_cb, PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb);
+ static void Shutdown();
+ static VendorInterface* get();
+
+ size_t Send(uint8_t type, const uint8_t* data, size_t length);
+
+ void OnFirmwareConfigured(uint8_t result);
+
+ private:
+ virtual ~VendorInterface() = default;
+
+ bool Open(InitializeCompleteCallback initialize_complete_cb,
+ PacketReadCallback event_cb, PacketReadCallback acl_cb,
+ PacketReadCallback sco_cb);
+ void Close();
+
+ void OnTimeout();
+
+ void HandleIncomingEvent(const hidl_vec<uint8_t>& hci_packet);
+
+ void* lib_handle_;
+ bt_vendor_interface_t* lib_interface_;
+ async::AsyncFdWatcher fd_watcher_;
+ InitializeCompleteCallback initialize_complete_cb_;
+ hci::HciProtocol* hci_;
+
+ PacketReadCallback event_cb_;
+
+ FirmwareStartupTimer* firmware_startup_timer_;
+};
+
+} // namespace dragon
+} // namespace V1_0
+} // namespace bluetooth
+} // namespace hardware
+} // namespace android
diff --git a/device.mk b/device.mk
index 917e755..f1accca 100644
--- a/device.mk
+++ b/device.mk
@@ -127,7 +127,7 @@ PRODUCT_COPY_FILES += \
# Bluetooth HAL
PRODUCT_PACKAGES += \
libbt-vendor \
- android.hardware.bluetooth@1.0-impl
+ android.hardware.bluetooth@1.0-impl-dragon
# Copy dsp firmware to the vendor parition so it is available when hotwording
# starts
@@ -232,7 +232,6 @@ PRODUCT_PACKAGES += \
PRODUCT_PACKAGES += \
android.hardware.audio@2.0-impl \
android.hardware.audio.effect@2.0-impl \
- android.hardware.broadcastradio@1.0-impl \
android.hardware.soundtrigger@2.0-impl
PRODUCT_PACKAGES += \
diff --git a/manifest_dragon_car.xml b/manifest_dragon_car.xml
new file mode 100644
index 0000000..4d4167f
--- /dev/null
+++ b/manifest_dragon_car.xml
@@ -0,0 +1,39 @@
+<manifest version="1.0" type="device">
+ <hal format="hidl">
+ <name>android.hardware.graphics.allocator</name>
+ <transport>hwbinder</transport>
+ <impl level="generic"></impl>
+ <version>2.0</version>
+ <interface>
+ <name>IAllocator</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
+ <name>android.hardware.wifi</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>IWifi</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
+ <name>android.hardware.wifi.supplicant</name>
+ <transport>hwbinder</transport>
+ <version>1.0</version>
+ <interface>
+ <name>ISupplicant</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl">
+ <name>android.hardware.automotive.vehicle</name>
+ <transport>hwbinder</transport>
+ <version>2.1</version>
+ <interface>
+ <name>IVehicle</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+</manifest>
diff --git a/media_codecs_performance.xml b/media_codecs_performance.xml
index e1f9330..66d5d6b 100644
--- a/media_codecs_performance.xml
+++ b/media_codecs_performance.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8" ?>
-<!-- Copyright 2016 The Android Open Source Project
+<!-- Copyright 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.
@@ -14,111 +14,119 @@
limitations under the License.
-->
+<!-- Generated file for ryu using measurements between OPR1.170623.019 and OPM1.170911.002 -->
<MediaCodecs>
+ <!-- Measurements between OPR1.170623.016 and OPM1.170908.002 -->
<Encoders>
<MediaCodec name="OMX.Nvidia.h264.encoder" type="video/avc" update="true">
- <Limit name="measured-frame-rate-320x240" range="280-289" /> <!-- N=38 v93%=1.1 -->
- <!-- measured 93%:152-276 med:168 SLOW -->
- <Limit name="measured-frame-rate-720x480" range="168-205" /> <!-- N=38 v93%=1.3 -->
- <!-- measured 93%:83-139 med:90 SLOW -->
- <Limit name="measured-frame-rate-1280x720" range="89-108" /> <!-- N=38 v93%=1.3 -->
- <Limit name="measured-frame-rate-1920x1080" range="88-88" /> <!-- N=38 v93%=1.4 -->
+ <Limit name="measured-frame-rate-320x240" range="333-333" /> <!-- N=118 v98%=1.2 -->
+ <Limit name="measured-frame-rate-720x480" range="197-211" /> <!-- N=118 v98%=1.3 -->
+ <Limit name="measured-frame-rate-1280x720" range="125-125" /> <!-- N=118 v98%=1.3 -->
+ <Limit name="measured-frame-rate-1920x1080" range="73-93" /> <!-- N=118 v98%=1.4 -->
</MediaCodec>
<MediaCodec name="OMX.Nvidia.vp8.encoder" type="video/x-vnd.on2.vp8" update="true">
- <Limit name="measured-frame-rate-320x180" range="265-273" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-640x360" range="196-215" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-1280x720" range="104-114" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-1920x1080" range="67-67" /> <!-- N=38 v93%=1.1 -->
+ <Limit name="measured-frame-rate-320x180" range="304-304" /> <!-- N=118 v98%=1.1 -->
+ <Limit name="measured-frame-rate-640x360" range="216-216" /> <!-- N=118 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1280x720" range="122-123" /> <!-- N=118 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1920x1080" range="70-70" /> <!-- N=118 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.google.h263.encoder" type="video/3gpp" update="true">
- <Limit name="measured-frame-rate-176x144" range="646-653" /> <!-- N=38 v93%=1.1 -->
+ <Limit name="measured-frame-rate-176x144" range="684-684" /> <!-- N=118 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.google.h264.encoder" type="video/avc" update="true">
- <Limit name="measured-frame-rate-320x240" range="481-481" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-720x480" range="138-138" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-1280x720" range="72-75" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-1920x1080" range="36-36" /> <!-- N=38 v93%=1.1 -->
+ <Limit name="measured-frame-rate-320x240" range="555-555" /> <!-- N=118 v98%=1.2 -->
+ <Limit name="measured-frame-rate-720x480" range="155-156" /> <!-- N=118 v98%=1.1 -->
+ <Limit name="measured-frame-rate-1280x720" range="76-76" /> <!-- N=118 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1920x1080" range="36-36" /> <!-- N=118 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.google.mpeg4.encoder" type="video/mp4v-es" update="true">
- <Limit name="measured-frame-rate-176x144" range="744-744" /> <!-- N=38 v93%=1.1 -->
+ <Limit name="measured-frame-rate-176x144" range="780-780" /> <!-- N=118 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.google.vp8.encoder" type="video/x-vnd.on2.vp8" update="true">
- <Limit name="measured-frame-rate-320x180" range="139-145" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-640x360" range="85-85" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-1280x720" range="35-35" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-1920x1080" range="18-19" /> <!-- N=38 v93%=1.1 -->
+ <Limit name="measured-frame-rate-320x180" range="161-161" /> <!-- N=118 v98%=1.2 -->
+ <!-- measured 98%:51-114 med:102/102 FLAKY(mn=46.0 < 51 - 204) -->
+ <Limit name="measured-frame-rate-640x360" range="91-102" /> <!-- TWEAKED N=118 v98%=1.5 -->
+ <Limit name="measured-frame-rate-1280x720" range="36-36" /> <!-- N=118 v98%=1.0 -->
+ <Limit name="measured-frame-rate-1920x1080" range="27-27" /> <!-- N=118 v98%=1.1 -->
+ </MediaCodec>
+ <!-- Measurements between OPR1.170208.003 and OPM1.170908.002 -->
+ <MediaCodec name="OMX.google.vp9.encoder" type="video/x-vnd.on2.vp9" update="true">
+ <!-- measured 98%:117-159 med:154/154 N=70 -->
+ <Limit name="measured-frame-rate-320x180" range="154-154" /> <!-- v98%=1.2 -->
+ <!-- measured 98%:34-52 med:50/50 N=72 -->
+ <Limit name="measured-frame-rate-640x360" range="50-50" /> <!-- v98%=1.2 -->
+ <!-- measured 98%:10-13 med:12/12 N=70 -->
+ <Limit name="measured-frame-rate-1280x720" range="12-12" /> <!-- v98%=1.1 -->
</MediaCodec>
</Encoders>
<Decoders>
<MediaCodec name="OMX.Nvidia.h263.decode" type="video/3gpp" update="true">
- <Limit name="measured-frame-rate-176x144" range="1967-1967" /> <!-- N=38 v93%=1.5 -->
- <Limit name="measured-frame-rate-352x288" range="1897-1897" /> <!-- N=38 v93%=1.4 -->
+ <Limit name="measured-frame-rate-176x144" range="2053-2060" /> <!-- N=110 v98%=1.6 -->
+ <Limit name="measured-frame-rate-352x288" range="2033-2062" /> <!-- N=110 v98%=1.7 -->
</MediaCodec>
<MediaCodec name="OMX.Nvidia.h264.decode" type="video/avc" update="true">
- <Limit name="measured-frame-rate-320x240" range="1816-1816" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-720x480" range="994-995" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1280x720" range="471-471" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1920x1088" range="210-210" /> <!-- N=38 v93%=1.0 -->
+ <Limit name="measured-frame-rate-320x240" range="1956-1956" /> <!-- N=110 v98%=1.3 -->
+ <Limit name="measured-frame-rate-720x480" range="995-995" /> <!-- N=110 v98%=1.1 -->
+ <Limit name="measured-frame-rate-1280x720" range="471-471" /> <!-- N=110 v98%=1.1 -->
+ <Limit name="measured-frame-rate-1920x1080" range="212-212" /> <!-- N=110 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.Nvidia.h265.decode" type="video/hevc" update="true">
- <!-- measured 93%:1355-2968 med:1667 SLOW -->
- <Limit name="measured-frame-rate-352x288" range="1666-2005" /> <!-- N=38 v93%=1.5 -->
- <Limit name="measured-frame-rate-640x368" range="1770-1770" /> <!-- N=38 v93%=1.3 -->
- <Limit name="measured-frame-rate-720x480" range="1526-1526" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-1280x720" range="701-701" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1920x1088" range="355-355" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-3840x2160" range="89-89" /> <!-- N=38 v93%=1.0 -->
+ <!-- measured 98%:1134-3356 med:2208/2204 FLAKY(mn=1019.4 < 1102 - 4408) -->
+ <Limit name="measured-frame-rate-352x288" range="2204-2204" /> <!-- N=110 v98%=1.7 -->
+ <Limit name="measured-frame-rate-640x360" range="1912-1917" /> <!-- N=110 v98%=1.4 -->
+ <Limit name="measured-frame-rate-720x480" range="1555-1556" /> <!-- N=110 v98%=1.3 -->
+ <Limit name="measured-frame-rate-1280x720" range="704-704" /> <!-- N=110 v98%=1.1 -->
+ <Limit name="measured-frame-rate-1920x1080" range="356-356" /> <!-- N=110 v98%=1.1 -->
+ <Limit name="measured-frame-rate-3840x2160" range="89-89" /> <!-- N=110 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.Nvidia.mp4.decode" type="video/mp4v-es" update="true">
- <!-- measured 93%:1394-3077 med:1761 SLOW -->
- <Limit name="measured-frame-rate-176x144" range="1760-2072" /> <!-- N=38 v93%=1.5 -->
- <Limit name="measured-frame-rate-480x368" range="2034-2034" /> <!-- N=38 v93%=1.6 -->
+ <Limit name="measured-frame-rate-176x144" range="2031-2031" /> <!-- N=110 v98%=1.7 -->
+ <Limit name="measured-frame-rate-480x360" range="2056-2056" /> <!-- N=110 v98%=1.6 -->
</MediaCodec>
<MediaCodec name="OMX.Nvidia.vp8.decode" type="video/x-vnd.on2.vp8" update="true">
- <Limit name="measured-frame-rate-320x192" range="1718-1874" /> <!-- N=38 v93%=1.4 -->
- <Limit name="measured-frame-rate-640x368" range="1364-1364" /> <!-- N=38 v93%=1.4 -->
- <Limit name="measured-frame-rate-1280x720" range="460-460" /> <!-- N=38 v93%=1.2 -->
- <Limit name="measured-frame-rate-1920x1088" range="233-233" /> <!-- N=38 v93%=1.1 -->
+ <Limit name="measured-frame-rate-320x180" range="2043-2043" /> <!-- N=110 v98%=1.7 -->
+ <Limit name="measured-frame-rate-640x360" range="1576-1576" /> <!-- N=110 v98%=1.4 -->
+ <Limit name="measured-frame-rate-1280x720" range="462-463" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1920x1080" range="238-238" /> <!-- N=110 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.Nvidia.vp9.decode" type="video/x-vnd.on2.vp9" update="true">
- <!-- measured 93%:1107-2778 med:1305 SLOW -->
- <Limit name="measured-frame-rate-320x180" range="1305-1754" /> <!-- N=38 v93%=1.6 -->
- <Limit name="measured-frame-rate-640x360" range="1253-1284" /> <!-- N=38 v93%=1.4 -->
- <Limit name="measured-frame-rate-1280x720" range="428-428" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-1920x1080" range="246-246" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-3840x2160" range="63-64" /> <!-- N=38 v93%=1.0 -->
+ <!-- measured 98%:826-3096 med:1876/1856 FLAKY(mn=782.5 < 826 - 3712) -->
+ <Limit name="measured-frame-rate-320x180" range="1564-1856" /> <!-- TWEAKED N=110 v98%=1.9 -->
+ <Limit name="measured-frame-rate-640x360" range="1318-1319" /> <!-- N=110 v98%=1.4 -->
+ <Limit name="measured-frame-rate-1280x720" range="421-421" /> <!-- N=110 v98%=1.3 -->
+ <Limit name="measured-frame-rate-1920x1080" range="243-243" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-3840x2160" range="64-64" /> <!-- N=110 v98%=1.2 -->
</MediaCodec>
<MediaCodec name="OMX.google.h263.decoder" type="video/3gpp" update="true">
- <!-- measured 93%:704-1170 med:792 SLOW -->
- <Limit name="measured-frame-rate-176x144" range="792-908" /> <!-- N=38 v93%=1.3 -->
+ <Limit name="measured-frame-rate-176x144" range="810-810" /> <!-- N=110 v98%=1.5 -->
</MediaCodec>
<MediaCodec name="OMX.google.h264.decoder" type="video/avc" update="true">
- <Limit name="measured-frame-rate-320x240" range="478-478" /> <!-- N=38 v93%=1.3 -->
- <Limit name="measured-frame-rate-720x480" range="181-181" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1280x720" range="70-70" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1920x1080" range="31-32" /> <!-- N=38 v93%=1.0 -->
+ <Limit name="measured-frame-rate-320x240" range="493-524" /> <!-- N=110 v98%=1.5 -->
+ <Limit name="measured-frame-rate-720x480" range="181-181" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1280x720" range="67-67" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1920x1080" range="32-32" /> <!-- N=110 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.google.hevc.decoder" type="video/hevc" update="true">
- <Limit name="measured-frame-rate-352x288" range="677-685" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-640x360" range="320-320" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-720x480" range="275-275" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-1280x720" range="106-106" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1920x1080" range="49-50" /> <!-- N=38 v93%=1.0 -->
+ <Limit name="measured-frame-rate-352x288" range="635-704" /> <!-- N=110 v98%=1.5 -->
+ <Limit name="measured-frame-rate-640x360" range="344-349" /> <!-- N=110 v98%=1.4 -->
+ <Limit name="measured-frame-rate-720x480" range="293-311" /> <!-- N=110 v98%=1.4 -->
+ <Limit name="measured-frame-rate-1280x720" range="115-115" /> <!-- N=110 v98%=1.3 -->
+ <Limit name="measured-frame-rate-1920x1080" range="56-56" /> <!-- N=110 v98%=1.3 -->
</MediaCodec>
<MediaCodec name="OMX.google.mpeg4.decoder" type="video/mp4v-es" update="true">
- <Limit name="measured-frame-rate-176x144" range="881-930" /> <!-- N=38 v93%=1.4 -->
+ <Limit name="measured-frame-rate-176x144" range="862-906" /> <!-- N=110 v98%=1.5 -->
</MediaCodec>
<MediaCodec name="OMX.google.vp8.decoder" type="video/x-vnd.on2.vp8" update="true">
- <Limit name="measured-frame-rate-320x180" range="900-904" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-640x360" range="314-314" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1280x720" range="67-67" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1920x1080" range="26-27" /> <!-- N=38 v93%=1.0 -->
+ <Limit name="measured-frame-rate-320x180" range="928-928" /> <!-- N=110 v98%=1.3 -->
+ <Limit name="measured-frame-rate-640x360" range="324-325" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1280x720" range="69-69" /> <!-- N=112 v98%=1.1 (OPR1.170623.006-) -->
+ <Limit name="measured-frame-rate-1920x1080" range="27-27" /> <!-- N=110 v98%=1.1 -->
</MediaCodec>
<MediaCodec name="OMX.google.vp9.decoder" type="video/x-vnd.on2.vp9" update="true">
- <Limit name="measured-frame-rate-320x180" range="635-637" /> <!-- N=38 v93%=1.1 -->
- <Limit name="measured-frame-rate-640x360" range="315-315" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1280x720" range="91-92" /> <!-- N=38 v93%=1.0 -->
- <Limit name="measured-frame-rate-1920x1080" range="50-51" /> <!-- N=38 v93%=1.0 -->
+ <Limit name="measured-frame-rate-320x180" range="684-686" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-640x360" range="337-337" /> <!-- N=110 v98%=1.2 -->
+ <Limit name="measured-frame-rate-1280x720" range="140-146" /> <!-- N=110 v98%=1.4 -->
+ <Limit name="measured-frame-rate-1920x1080" range="84-84" /> <!-- N=110 v98%=1.3 -->
</MediaCodec>
</Decoders>
</MediaCodecs>
diff --git a/overlay/frameworks/base/core/res/res/values/config.xml b/overlay/frameworks/base/core/res/res/values/config.xml
index 1b13f00..9766de6 100644
--- a/overlay/frameworks/base/core/res/res/values/config.xml
+++ b/overlay/frameworks/base/core/res/res/values/config.xml
@@ -51,6 +51,13 @@
<!-- Enable device idle mode -->
<bool name="config_enableAutoPowerModes">true</bool>
+ <!-- If true, enables verification of the lockscreen credential in the factory reset protection
+ flow. This should be true if gatekeeper / weaver credentials can still be checked after a
+ factory reset.
+
+ dragon's gatekeeper does not preserve credentials across factory resets. -->
+ <bool name="config_enableCredentialFactoryResetProtection">false</bool>
+
<!-- Flag indicating whether the we should enable the automatic brightness in Settings.
Software implementation will be used if config_hardware_auto_brightness_available is not set -->
<bool name="config_automatic_brightness_available">true</bool>