Merge "camera: Correct 'availableSessionKeys' version"
diff --git a/authsecret/1.0/Android.bp b/authsecret/1.0/Android.bp
new file mode 100644
index 0000000..9cde99a
--- /dev/null
+++ b/authsecret/1.0/Android.bp
@@ -0,0 +1,17 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.authsecret@1.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "IAuthSecret.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ gen_java: true,
+}
+
diff --git a/authsecret/1.0/IAuthSecret.hal b/authsecret/1.0/IAuthSecret.hal
new file mode 100644
index 0000000..d2cb5da
--- /dev/null
+++ b/authsecret/1.0/IAuthSecret.hal
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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.hardware.authsecret@1.0;
+
+/**
+ * This security HAL allows vendor components to be cryptographically tied to
+ * the primary user's credential. For example, security hardware could require
+ * proof that the credential is known before applying updates.
+ *
+ * This HAL is optional so does not require an implementation on device.
+ */
+interface IAuthSecret {
+ /**
+ * When the primary user correctly enters their credential, this method is
+ * passed a secret derived from that credential to prove that their
+ * credential is known.
+ *
+ * The first time this is called, the secret must be used to provision state
+ * that depends on the primary user's credential. The same secret is passed
+ * on each call until a factory reset after which there must be a new
+ * secret.
+ *
+ * The secret must be at lesat 16 bytes.
+ *
+ * @param secret blob derived from the primary user's credential.
+ */
+ primaryUserCredential(vec<uint8_t> secret);
+
+ /**
+ * Called from recovery during factory reset. The secret is now lost and can
+ * no longer be derived. Any data linked to the secret must be destroyed and
+ * any dependence on the secret must be removed.
+ */
+ factoryReset();
+};
diff --git a/authsecret/1.0/default/Android.bp b/authsecret/1.0/default/Android.bp
new file mode 100644
index 0000000..5c3234f
--- /dev/null
+++ b/authsecret/1.0/default/Android.bp
@@ -0,0 +1,21 @@
+cc_binary {
+ name: "android.hardware.authsecret@1.0-service",
+ init_rc: ["android.hardware.authsecret@1.0-service.rc"],
+ relative_install_path: "hw",
+ vendor: true,
+ srcs: [
+ "service.cpp",
+ "AuthSecret.cpp",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ shared_libs: [
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ "android.hardware.authsecret@1.0",
+ ],
+}
diff --git a/authsecret/1.0/default/AuthSecret.cpp b/authsecret/1.0/default/AuthSecret.cpp
new file mode 100644
index 0000000..46a3ec1
--- /dev/null
+++ b/authsecret/1.0/default/AuthSecret.cpp
@@ -0,0 +1,47 @@
+#include "AuthSecret.h"
+
+namespace android {
+namespace hardware {
+namespace authsecret {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::authsecret::V1_0::IAuthSecret follow.
+Return<void> AuthSecret::primaryUserCredential(const hidl_vec<uint8_t>& secret) {
+ (void)secret;
+
+ // To create a dependency on the credential, it is recommended to derive a
+ // different value from the provided secret for each purpose e.g.
+ //
+ // purpose1_secret = hash( "purpose1" || secret )
+ // purpose2_secret = hash( "purpose2" || secret )
+ //
+ // The derived values can then be used as cryptographic keys or stored
+ // securely for comparison in a future call.
+ //
+ // For example, a security module might require that the credential has been
+ // entered before it applies any updates. This can be achieved by storing a
+ // derived value in the module and only applying updates when the same
+ // derived value is presented again.
+ //
+ // This implementation does nothing.
+
+ return Void();
+}
+
+Return<void> AuthSecret::factoryReset() {
+ // Clear all dependency on the secret.
+ //
+ // With the example of updating a security module, the stored value must be
+ // cleared so that the new primary user enrolled as the approver of updates.
+ //
+ // This implementation does nothing as there is no dependence on the secret.
+
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace authsecret
+} // namespace hardware
+} // namespace android
diff --git a/authsecret/1.0/default/AuthSecret.h b/authsecret/1.0/default/AuthSecret.h
new file mode 100644
index 0000000..edb49b8
--- /dev/null
+++ b/authsecret/1.0/default/AuthSecret.h
@@ -0,0 +1,36 @@
+#ifndef ANDROID_HARDWARE_AUTHSECRET_V1_0_AUTHSECRET_H
+#define ANDROID_HARDWARE_AUTHSECRET_V1_0_AUTHSECRET_H
+
+#include <android/hardware/authsecret/1.0/IAuthSecret.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace authsecret {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct AuthSecret : public IAuthSecret {
+ // Methods from ::android::hardware::authsecret::V1_0::IAuthSecret follow.
+ Return<void> primaryUserCredential(const hidl_vec<uint8_t>& secret) override;
+ Return<void> factoryReset() override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace authsecret
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_AUTHSECRET_V1_0_AUTHSECRET_H
diff --git a/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
new file mode 100644
index 0000000..e82da7e
--- /dev/null
+++ b/authsecret/1.0/default/android.hardware.authsecret@1.0-service.rc
@@ -0,0 +1,4 @@
+service vendor.authsecret-1-0 /vendor/bin/hw/android.hardware.authsecret@1.0-service
+ class hal
+ user system
+ group system
diff --git a/authsecret/1.0/default/service.cpp b/authsecret/1.0/default/service.cpp
new file mode 100644
index 0000000..4acd16c
--- /dev/null
+++ b/authsecret/1.0/default/service.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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.authsecret@1.0-service"
+
+#include <android/hardware/authsecret/1.0/IAuthSecret.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "AuthSecret.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::authsecret::V1_0::IAuthSecret;
+using android::hardware::authsecret::V1_0::implementation::AuthSecret;
+using android::sp;
+using android::status_t;
+using android::OK;
+
+int main() {
+ configureRpcThreadpool(1, true);
+
+ sp<IAuthSecret> authSecret = new AuthSecret;
+ status_t status = authSecret->registerAsService();
+ LOG_ALWAYS_FATAL_IF(status != OK, "Could not register IAuthSecret");
+
+ joinRpcThreadpool();
+ return 0;
+}
diff --git a/authsecret/1.0/vts/functional/Android.bp b/authsecret/1.0/vts/functional/Android.bp
new file mode 100644
index 0000000..de9f560
--- /dev/null
+++ b/authsecret/1.0/vts/functional/Android.bp
@@ -0,0 +1,22 @@
+//
+// Copyright (C) 2018 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_test {
+ name: "VtsHalAuthSecretV1_0TargetTest",
+ defaults: ["VtsHalTargetTestDefaults"],
+ srcs: ["VtsHalAuthSecretV1_0TargetTest.cpp"],
+ static_libs: ["android.hardware.authsecret@1.0"],
+}
diff --git a/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
new file mode 100644
index 0000000..b0cbd91
--- /dev/null
+++ b/authsecret/1.0/vts/functional/VtsHalAuthSecretV1_0TargetTest.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2018 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 <android/hardware/authsecret/1.0/IAuthSecret.h>
+
+#include <VtsHalHidlTargetTestBase.h>
+
+using ::android::hardware::hidl_vec;
+using ::android::hardware::authsecret::V1_0::IAuthSecret;
+using ::android::sp;
+
+/**
+ * There is no expected behaviour that can be tested so these tests check the
+ * HAL doesn't crash with different execution orders.
+ */
+struct AuthSecretHidlTest : public ::testing::VtsHalHidlTargetTestBase {
+ virtual void SetUp() override {
+ authsecret = ::testing::VtsHalHidlTargetTestBase::getService<IAuthSecret>();
+ ASSERT_NE(authsecret, nullptr);
+ authsecret->factoryReset();
+ }
+
+ sp<IAuthSecret> authsecret;
+};
+
+/* Provision the primary user with a secret. */
+TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredential) {
+ hidl_vec<uint8_t> secret{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
+ authsecret->primaryUserCredential(secret);
+}
+
+/* Provision the primary user with a large secret. */
+TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialWithLargeSecret) {
+ hidl_vec<uint8_t> secret{89, 233, 52, 29, 130, 210, 229, 170, 124, 102, 56, 238, 198,
+ 199, 246, 152, 185, 123, 155, 215, 29, 252, 30, 70, 118, 29,
+ 149, 36, 222, 203, 163, 7, 72, 56, 247, 19, 198, 76, 71,
+ 37, 120, 201, 220, 70, 150, 18, 23, 22, 236, 57, 184, 86,
+ 190, 122, 210, 207, 74, 51, 222, 157, 74, 196, 86, 208};
+ authsecret->primaryUserCredential(secret);
+}
+
+/* Provision the primary user with a secret and pass the secret again. */
+TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgain) {
+ hidl_vec<uint8_t> secret{64, 2, 3, 0, 5, 6, 7, 172, 9, 10, 11, 255, 13, 14, 15, 83};
+ authsecret->primaryUserCredential(secret);
+ authsecret->primaryUserCredential(secret);
+}
+
+/* Provision the primary user with a secret and pass the secret again repeatedly. */
+TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndPassAgainMultipleTimes) {
+ hidl_vec<uint8_t> secret{1, 2, 34, 4, 5, 6, 7, 8, 9, 105, 11, 12, 13, 184, 15, 16};
+ authsecret->primaryUserCredential(secret);
+ constexpr int N = 5;
+ for (int i = 0; i < N; ++i) {
+ authsecret->primaryUserCredential(secret);
+ }
+}
+
+/* Factory reset before provisioning the primary user with a secret. */
+TEST_F(AuthSecretHidlTest, factoryResetWithoutProvisioningPrimaryUserCredential) {
+ authsecret->factoryReset();
+}
+
+/* Provision the primary user with a secret then factory reset. */
+TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialAndFactoryReset) {
+ hidl_vec<uint8_t> secret{1, 24, 124, 240, 5, 6, 7, 8, 9, 13, 11, 12, 189, 14, 195, 16};
+ authsecret->primaryUserCredential(secret);
+ authsecret->factoryReset();
+}
+
+/* Provision the primary differently after factory reset. */
+TEST_F(AuthSecretHidlTest, provisionPrimaryUserCredentialDifferentlyAfterFactoryReset) {
+ {
+ hidl_vec<uint8_t> secret1{19, 0, 65, 20, 65, 12, 7, 8, 9, 13, 29, 12, 189, 32, 195, 16};
+ authsecret->primaryUserCredential(secret1);
+ }
+
+ authsecret->factoryReset();
+
+ {
+ hidl_vec<uint8_t> secret2{61, 93, 124, 240, 5, 0, 7, 201, 9, 129, 11, 12, 0, 14, 0, 16};
+ authsecret->primaryUserCredential(secret2);
+ }
+}
diff --git a/automotive/audiocontrol/1.0/Android.bp b/automotive/audiocontrol/1.0/Android.bp
new file mode 100644
index 0000000..a967049
--- /dev/null
+++ b/automotive/audiocontrol/1.0/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.automotive.audiocontrol@1.0",
+ root: "android.hardware",
+ vndk: {
+ enabled: true,
+ },
+ srcs: [
+ "types.hal",
+ "IAudioControl.hal",
+ "IAudioControlCallback.hal",
+ ],
+ interfaces: [
+ "android.hidl.base@1.0",
+ ],
+ types: [
+ "AudioResult",
+ "ContextNumber",
+ ],
+ gen_java: true,
+}
+
diff --git a/automotive/audiocontrol/1.0/IAudioControl.hal b/automotive/audiocontrol/1.0/IAudioControl.hal
new file mode 100644
index 0000000..fe9ea8e
--- /dev/null
+++ b/automotive/audiocontrol/1.0/IAudioControl.hal
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol@1.0;
+
+import IAudioControlCallback;
+
+
+/**
+ * Interacts with the car's audio subsystem to manage audio sources and volumes
+ */
+interface IAudioControl {
+
+ /**
+ * Registers the required callback object so that we can be notified when the state
+ * of the car's audio system changes. This call must be made when the interface is
+ * initialized.
+ */
+ setCallback(IAudioControlCallback notificationObject)
+ generates (AudioResult result);
+
+
+ /**
+ * Called at startup once per context to get the mapping from ContextNumber to
+ * busAddress. This lets the car tell the framework to which physical output stream
+ * each context should be routed.
+ *
+ * For every context, a valid bus number (0 - num busses-1) must be returned. If an
+ * unrecognized contextNumber is encountered, then -1 shall be returned.
+ *
+ * Any context for which an invalid busNumber is returned must be routed to bus 0.
+ */
+ getBusForContext(uint32_t contextNumber)
+ generates (int32_t busNumber);
+
+
+ /**
+ * Control the right/left balance setting of the car speakers.
+ *
+ * This is intended to shift the speaker volume toward the right (+) or left (-) side of
+ * the car. 0.0 means "centered". +1.0 means fully right. -1.0 means fully left.
+ *
+ * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1
+ * range.
+ */
+ oneway setBalanceTowardRight(float value);
+
+
+ /**
+ * Control the fore/aft fade setting of the car speakers.
+ *
+ * This is intended to shift the speaker volume toward the front (+) or back (-) of the car.
+ * 0.0 means "centered". +1.0 means fully forward. -1.0 means fully rearward.
+ *
+ * A value outside the range -1 to 1 must be clamped by the implementation to the -1 to 1
+ * range.
+ */
+ oneway setFadeTowardFront(float value);
+};
+
diff --git a/automotive/audiocontrol/1.0/IAudioControlCallback.hal b/automotive/audiocontrol/1.0/IAudioControlCallback.hal
new file mode 100644
index 0000000..f5c227e
--- /dev/null
+++ b/automotive/audiocontrol/1.0/IAudioControlCallback.hal
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol@1.0;
+
+
+/**
+ * Implemented on client (framework) side to receive asynchronous updates from the car.
+ */
+interface IAudioControlCallback {
+
+ /**
+ * When the HAL makes this call, any apps currently playing must be asked to
+ * temporarily suspend playback (via an AudioManager::AUDIOFOCUS_LOSS_TRANSIENT event).
+ *
+ * This is only a suggestion. Apps may be slow to react or even ignore this message
+ * entirely. Enforcement, if necessary, must be done at the AudioHAL level as the
+ * samples are delivered. In most instances, this is the way a car should ask for
+ * quiet if it needs it for some important situation, such as warning alarms or chimes.
+ */
+ oneway suggestPausePlayers();
+
+
+ /**
+ * When the HAL makes this case, any apps currently playing must be asked to stop
+ * playing (via an AudioManager::AUDIOFOCUS_LOSS event). Once stopped, the apps must
+ * not resume their playback.
+ *
+ * It should be noted that not all apps or sound sources honor this request, but this
+ * at least gives an app the chance to do the right thing.
+ * Because it premanently stops media, this call is expected to be used only rarely.
+ * Perhaps in the event of an E-call, where resuming music might be undesirable assuming
+ * the driver is now dealing with whatever the emergency is?
+ */
+ oneway suggestStopPlayers();
+
+
+ /**
+ * Receives calls from the HAL when Android should resume normal operations. If the previous
+ * action was a requestPausePlayers, then things that were paused must be told they may
+ * resume.
+ */
+ oneway resumePlayers();
+};
diff --git a/automotive/audiocontrol/1.0/default/Android.bp b/automotive/audiocontrol/1.0/default/Android.bp
new file mode 100644
index 0000000..614c58b
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/Android.bp
@@ -0,0 +1,40 @@
+// 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_binary {
+ name: "android.hardware.automotive.audiocontrol@1.0-service",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ relative_install_path: "hw",
+ srcs: [
+ "AudioControl.cpp",
+ "AudioControlCallback.cpp",
+ "service.cpp"
+ ],
+ init_rc: ["android.hardware.automotive.audiocontrol@1.0-service.rc"],
+
+ shared_libs: [
+ "android.hardware.automotive.audiocontrol@1.0",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libutils",
+ ],
+
+ cflags: [
+ "-DLOG_TAG=\"AudCntrlDrv\"",
+ "-O0",
+ "-g",
+ ],
+}
diff --git a/automotive/audiocontrol/1.0/default/AudioControl.cpp b/automotive/audiocontrol/1.0/default/AudioControl.cpp
new file mode 100644
index 0000000..419225d
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/AudioControl.cpp
@@ -0,0 +1,86 @@
+#include "AudioControl.h"
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+namespace V1_0 {
+namespace implementation {
+
+
+// This is the static map we're using to associate a ContextNumber with a
+// bus number from the audio_policy_configuration.xml setup. Every valid context needs
+// to be mapped to a bus address that actually exists in the platforms configuration.
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a)) // Would be nice if this were common...
+static int sContextToBusMap[] = {
+ -1, // INVALID
+ 0, // MUSIC_CONTEXT
+ 1, // NAVIGATION_CONTEXT
+ 2, // VOICE_COMMAND_CONTEXT
+ 3, // CALL_RING_CONTEXT
+ 4, // CALL_CONTEXT
+ 5, // ALARM_CONTEXT
+ 6, // NOTIFICATION_CONTEXT
+ 7, // SYSTEM_SOUND_CONTEXT
+};
+static const unsigned sContextMapSize = ARRAY_SIZE(sContextToBusMap);
+static const unsigned sContextCount = sContextMapSize - 1; // Less one for the INVALID entry
+static const unsigned sContextNumberMax = sContextCount; // contextNumber is counted from 1
+
+
+AudioControl::AudioControl() {
+};
+
+
+// Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControl follow.
+Return<AudioResult> AudioControl::setCallback(const sp<IAudioControlCallback>& notificationObject) {
+ // Hang onto the provided callback object for future use
+ callback = notificationObject;
+
+ return AudioResult::OK;
+}
+
+
+Return<int32_t> AudioControl::getBusForContext(uint32_t contextNumber) {
+ if (contextNumber > sContextNumberMax) {
+ ALOGE("Unexpected context number %d (max expected is %d)", contextNumber, sContextCount);
+ return -1;
+ } else {
+ return sContextToBusMap[contextNumber];
+ }
+}
+
+
+Return<void> AudioControl::setBalanceTowardRight(float value) {
+ // For completeness, lets bounds check the input...
+ if ((value > 1.0f) || (value < -1.0f)) {
+ ALOGE("Balance value out of range -1 to 1 at %0.2f", value);
+ } else {
+ // Just log in this default mock implementation
+ ALOGI("Balance set to %0.2f", value);
+ }
+ return Void();
+}
+
+
+Return<void> AudioControl::setFadeTowardFront(float value) {
+ // For completeness, lets bounds check the input...
+ if ((value > 1.0f) || (value < -1.0f)) {
+ ALOGE("Fader value out of range -1 to 1 at %0.2f", value);
+ } else {
+ // Just log in this default mock implementation
+ ALOGI("Fader set to %0.2f", value);
+ }
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/audiocontrol/1.0/default/AudioControl.h b/automotive/audiocontrol/1.0/default/AudioControl.h
new file mode 100644
index 0000000..3383875
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/AudioControl.h
@@ -0,0 +1,45 @@
+#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROL_H
+#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROL_H
+
+#include <android/hardware/automotive/audiocontrol/1.0/IAudioControl.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct AudioControl : public IAudioControl {
+public:
+ // Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControl follow.
+ Return<AudioResult> setCallback(const sp<IAudioControlCallback>& notificationObject) override;
+ Return<int32_t> getBusForContext(uint32_t contextNumber) override;
+ Return<void> setBalanceTowardRight(float value) override;
+ Return<void> setFadeTowardFront(float value) override;
+
+ // Implementation details
+ AudioControl();
+
+private:
+ sp<IAudioControlCallback> callback;
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROL_H
diff --git a/automotive/audiocontrol/1.0/default/AudioControlCallback.cpp b/automotive/audiocontrol/1.0/default/AudioControlCallback.cpp
new file mode 100644
index 0000000..ea79cad
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/AudioControlCallback.cpp
@@ -0,0 +1,31 @@
+#include "AudioControlCallback.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+namespace V1_0 {
+namespace implementation {
+
+// Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControlCallback follow.
+Return<void> AudioControlCallback::suggestPausePlayers() {
+ // TODO implement in framework (this is called by the HAL implementation when needed)
+ return Void();
+}
+
+Return<void> AudioControlCallback::suggestStopPlayers() {
+ // TODO implement in framework (this is called by the HAL implementation when needed)
+ return Void();
+}
+
+Return<void> AudioControlCallback::resumePlayers() {
+ // TODO implement in framework (this is called by the HAL implementation when needed)
+ return Void();
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/audiocontrol/1.0/default/AudioControlCallback.h b/automotive/audiocontrol/1.0/default/AudioControlCallback.h
new file mode 100644
index 0000000..1054548
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/AudioControlCallback.h
@@ -0,0 +1,41 @@
+#ifndef ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROLCALLBACK_H
+#define ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROLCALLBACK_H
+
+#include <android/hardware/automotive/audiocontrol/1.0/IAudioControlCallback.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace audiocontrol {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+// TODO: Move this into packages/services/Car...
+struct AudioControlCallback : public IAudioControlCallback {
+ // Methods from ::android::hardware::automotive::audiocontrol::V1_0::IAudioControlCallback follow.
+ Return<void> suggestPausePlayers() override;
+ Return<void> suggestStopPlayers() override;
+ Return<void> resumePlayers() override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace audiocontrol
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_AUTOMOTIVE_AUDIOCONTROL_V1_0_AUDIOCONTROLCALLBACK_H
diff --git a/automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc b/automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc
new file mode 100644
index 0000000..79edad6
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/android.hardware.automotive.audiocontrol@1.0-service.rc
@@ -0,0 +1,4 @@
+service vendor.evs-hal-mock /vendor/bin/hw/android.hardware.automotive.audiocontrol@1.0-service
+ class hal
+ user audioserver
+ group system
diff --git a/automotive/audiocontrol/1.0/default/service.cpp b/automotive/audiocontrol/1.0/default/service.cpp
new file mode 100644
index 0000000..a033fd9
--- /dev/null
+++ b/automotive/audiocontrol/1.0/default/service.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+#include <unistd.h>
+
+#include <hidl/HidlTransportSupport.h>
+#include <log/log.h>
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+
+#include "AudioControl.h"
+
+
+// libhidl:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::automotive::audiocontrol::V1_0::IAudioControl;
+
+// The namespace in which all our implementation code lives
+using namespace android::hardware::automotive::audiocontrol::V1_0::implementation;
+using namespace android;
+
+
+// Main service entry point
+int main() {
+ // Create an instance of our service class
+ android::sp<IAudioControl> service = new AudioControl();
+ configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+ if (service->registerAsService() != OK) {
+ ALOGE("registerAsService failed");
+ return 1;
+ }
+
+ // Join (forever) the thread pool we created for the service above
+ joinRpcThreadpool();
+
+ // We don't ever actually expect to return, so return an error if we do get here
+ return 2;
+}
\ No newline at end of file
diff --git a/automotive/audiocontrol/1.0/types.hal b/automotive/audiocontrol/1.0/types.hal
new file mode 100644
index 0000000..6301d3a
--- /dev/null
+++ b/automotive/audiocontrol/1.0/types.hal
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.automotive.audiocontrol@1.0;
+
+
+/**
+ * Predefined flags to identifying audio contexts
+ */
+enum ContextNumber : uint32_t {
+ INVALID = 0, /* Shouldn't be used */
+
+ // Sounds from Android (counting from 1 coincidentally lets us match AudioAttributes usages)
+ MUSIC, /* Music playback */
+ NAVIGATION, /* Navigation directions */
+ VOICE_COMMAND, /* Voice command session */
+ CALL_RING, /* Voice call ringing */
+ CALL, /* Voice call */
+ ALARM, /* Alarm sound from Android */
+ NOTIFICATION, /* Notifications */
+ SYSTEM_SOUND, /* User interaction sounds (button clicks, etc) */
+};
+
+
+/** Error codes used in AudioControl HAL interface. */
+enum AudioResult : uint32_t {
+ OK = 0,
+ NOT_AVAILABLE,
+ INVALID_ARGUMENT,
+ UNDERLYING_SERVICE_ERROR,
+};
diff --git a/automotive/evs/1.0/default/Android.bp b/automotive/evs/1.0/default/Android.bp
index 2574e86..7286478 100644
--- a/automotive/evs/1.0/default/Android.bp
+++ b/automotive/evs/1.0/default/Android.bp
@@ -13,7 +13,6 @@
shared_libs: [
"android.hardware.automotive.evs@1.0",
- "libui",
"libbase",
"libbinder",
"libcutils",
@@ -21,6 +20,7 @@
"libhidlbase",
"libhidltransport",
"liblog",
+ "libui",
"libutils",
],
diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp
index 7ab2387..ffe012e 100644
--- a/automotive/vehicle/2.0/Android.bp
+++ b/automotive/vehicle/2.0/Android.bp
@@ -42,19 +42,6 @@
"VehicleAreaSeat",
"VehicleAreaWindow",
"VehicleAreaZone",
- "VehicleAudioContextFlag",
- "VehicleAudioExtFocusFlag",
- "VehicleAudioFocusIndex",
- "VehicleAudioFocusRequest",
- "VehicleAudioFocusState",
- "VehicleAudioHwVariantConfigFlag",
- "VehicleAudioRoutingPolicyIndex",
- "VehicleAudioStream",
- "VehicleAudioStreamFlag",
- "VehicleAudioVolumeCapabilityFlag",
- "VehicleAudioVolumeIndex",
- "VehicleAudioVolumeLimitIndex",
- "VehicleAudioVolumeState",
"VehicleDisplay",
"VehicleDrivingStatus",
"VehicleGear",
diff --git a/automotive/vehicle/2.0/default/Android.bp b/automotive/vehicle/2.0/default/Android.bp
index 1690163..6a254a5 100644
--- a/automotive/vehicle/2.0/default/Android.bp
+++ b/automotive/vehicle/2.0/default/Android.bp
@@ -46,6 +46,7 @@
"common/src/VehicleObjectPool.cpp",
"common/src/VehiclePropertyStore.cpp",
"common/src/VehicleUtils.cpp",
+ "common/src/VmsUtils.cpp",
],
local_include_dirs: ["common/include/vhal_v2_0"],
export_include_dirs: ["common/include"],
@@ -93,6 +94,7 @@
"tests/VehicleHalManager_test.cpp",
"tests/VehicleObjectPool_test.cpp",
"tests/VehiclePropConfigIndex_test.cpp",
+ "tests/VmsUtils_test.cpp",
],
header_libs: ["libbase_headers"],
}
diff --git a/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
new file mode 100644
index 0000000..9e32bb5
--- /dev/null
+++ b/automotive/vehicle/2.0/default/common/include/vhal_v2_0/VmsUtils.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2018 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_automotive_vehicle_V2_0_VmsUtils_H_
+#define android_hardware_automotive_vehicle_V2_0_VmsUtils_H_
+
+#include <memory>
+#include <string>
+
+#include <android/hardware/automotive/vehicle/2.0/types.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace vms {
+
+// VmsUtils are a set of abstractions for creating and parsing Vehicle Property
+// updates to VehicleProperty::VEHICLE_MAP_SERVICE. The format for parsing a
+// VehiclePropValue update with a VMS message is specified in the Vehicle HIDL.
+//
+// This interface is meant for use by HAL clients of VMS; corresponding
+// functionality is also provided by VMS in the embedded car service.
+
+// A VmsLayer is comprised of a type, subtype, and version.
+struct VmsLayer {
+ VmsLayer(int type, int subtype, int version) : type(type), subtype(subtype), version(version) {}
+ int type;
+ int subtype;
+ int version;
+};
+
+struct VmsLayerAndPublisher {
+ VmsLayer layer;
+ int publisher_id;
+};
+
+// A VmsAssociatedLayer is used by subscribers to specify which publisher IDs
+// are acceptable for a given layer.
+struct VmsAssociatedLayer {
+ VmsLayer layer;
+ std::vector<int> publisher_ids;
+};
+
+// A VmsLayerOffering refers to a single layer that can be published, along with
+// its dependencies. Dependencies can be empty.
+struct VmsLayerOffering {
+ VmsLayerOffering(VmsLayer layer, std::vector<VmsLayer> dependencies)
+ : layer(layer), dependencies(dependencies) {}
+ VmsLayerOffering(VmsLayer layer) : layer(layer), dependencies() {}
+ VmsLayer layer;
+ std::vector<VmsLayer> dependencies;
+};
+
+// A VmsSubscriptionsState is delivered in response to a
+// VmsMessageType.SUBSCRIPTIONS_REQUEST or on the first SUBSCRIBE or last
+// UNSUBSCRIBE for a layer. It indicates which layers or associated_layers are
+// currently being subscribed to in the system.
+struct VmsSubscriptionsState {
+ int sequence_number;
+ std::vector<VmsLayer> layers;
+ std::vector<VmsAssociatedLayer> associated_layers;
+};
+
+struct VmsAvailabilityState {
+ int sequence_number;
+ std::vector<VmsAssociatedLayer> associated_layers;
+};
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.SUBSCRIBE, specifying to the VMS service
+// which layer to subscribe to.
+std::unique_ptr<VehiclePropValue> createSubscribeMessage(const VmsLayer& layer);
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.SUBSCRIBE_TO_PUBLISHER, specifying to the VMS service
+// which layer and publisher_id to subscribe to.
+std::unique_ptr<VehiclePropValue> createSubscribeToPublisherMessage(
+ const VmsLayerAndPublisher& layer);
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.UNSUBSCRIBE, specifying to the VMS service
+// which layer to unsubscribe from.
+std::unique_ptr<VehiclePropValue> createUnsubscribeMessage(const VmsLayer& layer);
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER, specifying to the VMS service
+// which layer and publisher_id to unsubscribe from.
+std::unique_ptr<VehiclePropValue> createUnsubscribeToPublisherMessage(
+ const VmsLayerAndPublisher& layer);
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.OFFERING, specifying to the VMS service which layers are being
+// offered and their dependencies, if any.
+std::unique_ptr<VehiclePropValue> createOfferingMessage(
+ const std::vector<VmsLayerOffering>& offering);
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.AVAILABILITY_REQUEST.
+std::unique_ptr<VehiclePropValue> createAvailabilityRequest();
+
+// Creates a VehiclePropValue containing a message of type
+// VmsMessageType.AVAILABILITY_REQUEST.
+std::unique_ptr<VehiclePropValue> createSubscriptionsRequest();
+
+// Creates a VehiclePropValue containing a message of type VmsMessageType.DATA.
+// Returns a nullptr if the byte string in bytes is empty.
+//
+// For example, to build a VehiclePropMessage containing a proto, the caller
+// should convert the proto to a byte string using the SerializeToString proto
+// API, then use this inteface to build the VehicleProperty.
+std::unique_ptr<VehiclePropValue> createDataMessage(const std::string& bytes);
+
+// Returns true if the VehiclePropValue pointed to by value contains a valid Vms
+// message, i.e. the VehicleProperty, VehicleArea, and VmsMessageType are all
+// valid. Note: If the VmsMessageType enum is extended, this function will
+// return false for any new message types added.
+bool isValidVmsMessage(const VehiclePropValue& value);
+
+// Returns the message type. Expects that the VehiclePropValue contains a valid
+// Vms message, as verified by isValidVmsMessage.
+VmsMessageType parseMessageType(const VehiclePropValue& value);
+
+// Constructs a string byte array from a message of type VmsMessageType.DATA.
+// Returns an empty string if the message type doesn't match or if the
+// VehiclePropValue does not contain a byte array.
+//
+// A proto message can then be constructed by passing the result of this
+// function to ParseFromString.
+std::string parseData(const VehiclePropValue& value);
+
+// TODO(aditin): Need to implement additional parsing functions per message
+// type.
+
+} // namespace vms
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
+
+#endif // android_hardware_automotive_vehicle_V2_0_VmsUtils_H_
diff --git a/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
new file mode 100644
index 0000000..abf425f
--- /dev/null
+++ b/automotive/vehicle/2.0/default/common/src/VmsUtils.cpp
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2018 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 "VmsUtils.h"
+
+#include <common/include/vhal_v2_0/VehicleUtils.h>
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace vms {
+
+static constexpr int kMessageIndex = toInt(VmsBaseMessageIntegerValuesIndex::MESSAGE_TYPE);
+static constexpr int kMessageTypeSize = 1;
+static constexpr int kLayerNumberSize = 1;
+static constexpr int kLayerSize = 3;
+static constexpr int kLayerAndPublisherSize = 4;
+
+// TODO(aditin): We should extend the VmsMessageType enum to include a first and
+// last, which would prevent breakages in this API. However, for all of the
+// functions in this module, we only need to guarantee that the message type is
+// between SUBSCRIBE and DATA.
+static constexpr int kFirstMessageType = toInt(VmsMessageType::SUBSCRIBE);
+static constexpr int kLastMessageType = toInt(VmsMessageType::DATA);
+
+std::unique_ptr<VehiclePropValue> createBaseVmsMessage(size_t message_size) {
+ auto result = createVehiclePropValue(VehiclePropertyType::INT32, message_size);
+ result->prop = toInt(VehicleProperty::VEHICLE_MAP_SERVICE);
+ result->areaId = toInt(VehicleArea::GLOBAL);
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createSubscribeMessage(const VmsLayer& layer) {
+ auto result = createBaseVmsMessage(kMessageTypeSize + kLayerSize);
+ result->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIBE), layer.type,
+ layer.subtype, layer.version};
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createSubscribeToPublisherMessage(
+ const VmsLayerAndPublisher& layer_publisher) {
+ auto result = createBaseVmsMessage(kMessageTypeSize + kLayerAndPublisherSize);
+ result->value.int32Values = hidl_vec<int32_t>{
+ toInt(VmsMessageType::SUBSCRIBE_TO_PUBLISHER), layer_publisher.layer.type,
+ layer_publisher.layer.subtype, layer_publisher.layer.version, layer_publisher.publisher_id};
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createUnsubscribeMessage(const VmsLayer& layer) {
+ auto result = createBaseVmsMessage(kMessageTypeSize + kLayerSize);
+ result->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::UNSUBSCRIBE), layer.type,
+ layer.subtype, layer.version};
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createUnsubscribeToPublisherMessage(
+ const VmsLayerAndPublisher& layer_publisher) {
+ auto result = createBaseVmsMessage(kMessageTypeSize + kLayerAndPublisherSize);
+ result->value.int32Values = hidl_vec<int32_t>{
+ toInt(VmsMessageType::UNSUBSCRIBE_TO_PUBLISHER), layer_publisher.layer.type,
+ layer_publisher.layer.subtype, layer_publisher.layer.version, layer_publisher.publisher_id};
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createOfferingMessage(
+ const std::vector<VmsLayerOffering>& offering) {
+ int message_size = kMessageTypeSize + kLayerNumberSize;
+ for (const auto& offer : offering) {
+ message_size += kLayerNumberSize + (1 + offer.dependencies.size()) * kLayerSize;
+ }
+ auto result = createBaseVmsMessage(message_size);
+
+ std::vector<int32_t> offers = {toInt(VmsMessageType::OFFERING),
+ static_cast<int>(offering.size())};
+ for (const auto& offer : offering) {
+ std::vector<int32_t> layer_vector = {offer.layer.type, offer.layer.subtype,
+ offer.layer.version,
+ static_cast<int32_t>(offer.dependencies.size())};
+ for (const auto& dependency : offer.dependencies) {
+ std::vector<int32_t> dependency_layer = {dependency.type, dependency.subtype,
+ dependency.version};
+ layer_vector.insert(layer_vector.end(), dependency_layer.begin(),
+ dependency_layer.end());
+ }
+ offers.insert(offers.end(), layer_vector.begin(), layer_vector.end());
+ }
+ result->value.int32Values = offers;
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createAvailabilityRequest() {
+ auto result = createBaseVmsMessage(kMessageTypeSize);
+ result->value.int32Values = hidl_vec<int32_t>{
+ toInt(VmsMessageType::AVAILABILITY_REQUEST),
+ };
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createSubscriptionsRequest() {
+ auto result = createBaseVmsMessage(kMessageTypeSize);
+ result->value.int32Values = hidl_vec<int32_t>{
+ toInt(VmsMessageType::SUBSCRIPTIONS_REQUEST),
+ };
+ return result;
+}
+
+std::unique_ptr<VehiclePropValue> createDataMessage(const std::string& bytes) {
+ auto result = createBaseVmsMessage(kMessageTypeSize);
+ result->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::DATA)};
+ result->value.bytes = std::vector<uint8_t>(bytes.begin(), bytes.end());
+ return result;
+}
+
+bool verifyPropertyAndArea(const VehiclePropValue& value) {
+ return (value.prop == toInt(VehicleProperty::VEHICLE_MAP_SERVICE) &&
+ value.areaId == toInt(VehicleArea::GLOBAL));
+}
+
+bool verifyMessageType(const VehiclePropValue& value) {
+ return (value.value.int32Values.size() > 0 &&
+ value.value.int32Values[kMessageIndex] >= kFirstMessageType &&
+ value.value.int32Values[kMessageIndex] <= kLastMessageType);
+}
+
+bool isValidVmsMessage(const VehiclePropValue& value) {
+ return (verifyPropertyAndArea(value) && verifyMessageType(value));
+}
+
+VmsMessageType parseMessageType(const VehiclePropValue& value) {
+ return static_cast<VmsMessageType>(value.value.int32Values[kMessageIndex]);
+}
+
+std::string parseData(const VehiclePropValue& value) {
+ if (isValidVmsMessage(value) && parseMessageType(value) == VmsMessageType::DATA &&
+ value.value.bytes.size() > 0) {
+ return std::string(value.value.bytes.begin(), value.value.bytes.end());
+ } else {
+ return std::string();
+ }
+}
+
+} // namespace vms
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
new file mode 100644
index 0000000..c102ce8
--- /dev/null
+++ b/automotive/vehicle/2.0/default/tests/VmsUtils_test.cpp
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2018 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 <android/hardware/automotive/vehicle/2.0/IVehicle.h>
+#include <gtest/gtest.h>
+
+#include "VehicleHalTestUtils.h"
+#include "vhal_v2_0/VmsUtils.h"
+
+namespace android {
+namespace hardware {
+namespace automotive {
+namespace vehicle {
+namespace V2_0 {
+namespace vms {
+
+namespace {
+
+TEST(VmsUtilsTest, subscribeMessage) {
+ VmsLayer layer(1, 0, 2);
+ auto message = createSubscribeMessage(layer);
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x4ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::SUBSCRIBE);
+
+ // Layer
+ EXPECT_EQ(message->value.int32Values[1], 1);
+ EXPECT_EQ(message->value.int32Values[2], 0);
+ EXPECT_EQ(message->value.int32Values[3], 2);
+}
+
+TEST(VmsUtilsTest, unsubscribeMessage) {
+ VmsLayer layer(1, 0, 2);
+ auto message = createUnsubscribeMessage(layer);
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x4ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::UNSUBSCRIBE);
+
+ // Layer
+ EXPECT_EQ(message->value.int32Values[1], 1);
+ EXPECT_EQ(message->value.int32Values[2], 0);
+ EXPECT_EQ(message->value.int32Values[3], 2);
+}
+
+TEST(VmsUtilsTest, singleOfferingMessage) {
+ std::vector<VmsLayerOffering> offering = {VmsLayerOffering(VmsLayer(1, 0, 2))};
+ auto message = createOfferingMessage(offering);
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x6ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::OFFERING);
+
+ // Number of layer offerings
+ EXPECT_EQ(message->value.int32Values[1], 1);
+
+ // Layer
+ EXPECT_EQ(message->value.int32Values[2], 1);
+ EXPECT_EQ(message->value.int32Values[3], 0);
+ EXPECT_EQ(message->value.int32Values[4], 2);
+
+ // Number of dependencies
+ EXPECT_EQ(message->value.int32Values[5], 0);
+}
+
+TEST(VmsUtilsTest, offeringWithDependencies) {
+ VmsLayer layer(1, 0, 2);
+ std::vector<VmsLayer> dependencies = {VmsLayer(2, 0, 2)};
+ std::vector<VmsLayerOffering> offering = {VmsLayerOffering(layer, dependencies)};
+ auto message = createOfferingMessage(offering);
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x9ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::OFFERING);
+
+ // Number of layer offerings
+ EXPECT_EQ(message->value.int32Values[1], 1);
+
+ // Layer
+ EXPECT_EQ(message->value.int32Values[2], 1);
+ EXPECT_EQ(message->value.int32Values[3], 0);
+ EXPECT_EQ(message->value.int32Values[4], 2);
+
+ // Number of dependencies
+ EXPECT_EQ(message->value.int32Values[5], 1);
+
+ // Dependency 1
+ EXPECT_EQ(message->value.int32Values[6], 2);
+ EXPECT_EQ(message->value.int32Values[7], 0);
+ EXPECT_EQ(message->value.int32Values[8], 2);
+}
+
+TEST(VmsUtilsTest, availabilityMessage) {
+ auto message = createAvailabilityRequest();
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x1ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::AVAILABILITY_REQUEST);
+}
+
+TEST(VmsUtilsTest, subscriptionsMessage) {
+ auto message = createSubscriptionsRequest();
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x1ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::SUBSCRIPTIONS_REQUEST);
+}
+
+TEST(VmsUtilsTest, dataMessage) {
+ std::string bytes = "aaa";
+ auto message = createDataMessage(bytes);
+ ASSERT_NE(message, nullptr);
+ EXPECT_TRUE(isValidVmsMessage(*message));
+ EXPECT_EQ(message->prop, toInt(VehicleProperty::VEHICLE_MAP_SERVICE));
+ EXPECT_EQ(message->areaId, toInt(VehicleArea::GLOBAL));
+ EXPECT_EQ(message->value.int32Values.size(), 0x1ul);
+ EXPECT_EQ(parseMessageType(*message), VmsMessageType::DATA);
+ EXPECT_EQ(message->value.bytes.size(), bytes.size());
+ EXPECT_EQ(memcmp(message->value.bytes.data(), bytes.data(), bytes.size()), 0);
+}
+
+TEST(VmsUtilsTest, emptyMessageInvalid) {
+ VehiclePropValue empty_prop;
+ EXPECT_FALSE(isValidVmsMessage(empty_prop));
+}
+
+TEST(VmsUtilsTest, invalidMessageType) {
+ VmsLayer layer(1, 0, 2);
+ auto message = createSubscribeMessage(layer);
+ message->value.int32Values[0] = 0;
+
+ EXPECT_FALSE(isValidVmsMessage(*message));
+}
+
+TEST(VmsUtilsTest, parseDataMessage) {
+ std::string bytes = "aaa";
+ auto message = createDataMessage(bytes);
+ auto data_str = parseData(*message);
+ ASSERT_FALSE(data_str.empty());
+ EXPECT_EQ(data_str, bytes);
+}
+
+TEST(VmsUtilsTest, parseInvalidDataMessage) {
+ VmsLayer layer(1, 0, 2);
+ auto message = createSubscribeMessage(layer);
+ auto data_str = parseData(*message);
+ EXPECT_TRUE(data_str.empty());
+}
+
+} // namespace
+
+} // namespace vms
+} // namespace V2_0
+} // namespace vehicle
+} // namespace automotive
+} // namespace hardware
+} // namespace android
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 8e1b164..7e42781 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -906,346 +906,6 @@
| VehicleArea:GLOBAL),
/**
- * Represents audio focus state of Android side. Note that car's audio
- * module must own audio focus and grant audio focus to Android side when
- * requested by Android side. The focus has both per stream characteristics
- * and global characteristics.
- *
- * Focus request (get of this property) must take the following form with indices defined
- * by VehicleAudioFocusIndex:
- * int32Values[0]: VehicleAudioFocusRequest type
- * int32Values[1]: bit flags of streams requested by this focus request.
- * There can be up to 32 streams.
- * int32Values[2]: External focus state flags. For request, only flag like
- * VehicleAudioExtFocusFlag#PLAY_ONLY_FLAG or
- * VehicleAudioExtFocusFlag#MUTE_MEDIA_FLAG can be
- * used.
- * VehicleAudioExtFocusFlag#PLAY_ONLY_FLAG is for case
- * like radio where android side app still needs to hold
- * focus but playback is done outside Android.
- * VehicleAudioExtFocusFlag#MUTE_MEDIA_FLAG is for
- * muting media channel including radio.
- * VehicleAudioExtFocusFlag#PLAY_ONLY_FLAG can be set
- * even if android side releases focus (request type
- * REQUEST_RELEASE). In that case, audio module must
- * maintain mute state until user's explicit action to
- * play some media.
- * int32Values[3]: Audio contexts wishing to be active. Use combination of
- * flags from VehicleAudioContextFlag.
- * This can be used as a hint to adjust audio policy or
- * other policy decision.
- * Note that there can be multiple context active at the
- * same time. And android can send the same focus request
- * type gain due to change in audio contexts.
- * Note that each focus request can request multiple streams that is
- * expected to be used for the current request. But focus request itself
- * is global behavior as GAIN or GAIN_TRANSIENT expects all sounds played
- * by car's audio module to stop. Note that stream already allocated to
- * android before this focus request must not be affected by focus
- * request.
- *
- * Focus response (set and subscription callback for this property) must
- * take the following form with indices defined by VehicleAudioFocusIndex:
- * int32Values[0]: VehicleAudioFocusState type
- * int32Values[1]: bit flags of streams allowed.
- * int32Values[2]: External focus state: bit flags of currently active
- * audio focus in car side (outside Android). Active
- * audio focus does not necessarily mean currently
- * playing, but represents the state of having focus or
- * waiting for focus (pause state).
- * One or combination of flags from
- * VehicleAudioExtFocusFlag.
- * 0 means no active audio focus holder outside Android.
- * The state must have following values for each
- * VehicleAudioFocusState:
- * GAIN: VehicleAudioExtFocusFlag#PLAY_ONLY_FLAG
- * when radio is active in Android side. Otherwise,
- * VehicleAudioExtFocusFlag#NONE_FLAG.
- * GAIN_TRANSIENT: Can be
- * VehicleAudioExtFocusFlag#PERMANENT_FLAG or
- * VehicleAudioExtFocusFlag#TRANSIENT_FLAG if android
- * side has requested
- * REQUEST_GAIN_TRANSIENT_MAY_DUCK and car side is
- * ducking. Otherwise
- * VehicleAudioExtFocusFlag#NONE_FLAG.
- * LOSS: VehicleAudioExtFocusFlag#NONE_FLAG when no focus
- * is active in car side.
- * VehicleAudioExtFocusFlag#PERMANENT_FLAG when car
- * side is playing something permanent.
- * LOSS_TRANSIENT: must always be
- * VehicleAudioExtFocusFlag#PERMANENT_FLAG
- * int32Values[3]: Audio context(s) allowed to be active. When responding positively to a
- * focus request from Android, the request's original context must be
- * repeated here. When taking focus away, or denying a request, the
- * rejected or stopped context would have its corresponding bit cleared.
- *
- * A focus response must be sent per each focus request even if there is
- * no change in focus state. This can happen in case like focus request
- * only involving context change where android side still needs matching
- * focus response to confirm that audio module has made necessary changes.
- *
- * If car does not support AUDIO_FOCUS, focus is assumed to be granted
- * always.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- AUDIO_FOCUS = (
- 0x0900
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * A property to allow external component to control audio focus. Depending on
- * H/W architecture, audio HAL may need to control audio focus while vehicle
- * HAL is still interacting with upper layer. In such case, audio HAL may set
- * this property and vehicle HAL may use this property value to decide
- * response sent through AUDIO_FOCUS property.
- * Data format is the same as AUDIO_FOCUS property.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- AUDIO_FOCUS_EXT_SYNC = (
- 0x0910
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Property to control audio volume of each audio context.
- *
- * VehiclePropConfig
- * configArray[0] : bit flags of all supported audio contexts from
- * VehicleAudioContextFlag. If this is 0, audio volume
- * is controlled per physical stream.
- * configArray[1] : flags defined in VehicleAudioVolumeCapabilityFlag to
- * represent audio module's capability.
- * configArray[2..3] : reserved
- * configArray[4..N+3] : maximum values for each audio context, where N is
- * the number of audio contexts provided in
- * configArray[0], minimum value is always 0 which
- * indicates mute state.
- *
- * Data type looks like:
- * int32Values[0] : audio context as defined in VehicleAudioContextFlag.
- * If only physical stream is supported
- * (configArray[0] == 0), this must represent physical
- * stream number.
- * int32Values[1] : volume level, valid range is 0 (mute) to max level
- * defined in the config.
- * int32Values[2] : One of VehicleAudioVolumeState.
- *
- * HAL implementations must check the incoming value of audio context
- * field in get call to return the right volume.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @config_flags all audio contexts supported.
- */
- AUDIO_VOLUME = (
- 0x0901
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Property to allow audio volume sync from external components like audio HAL.
- * Some vehicle HAL implementation may get volume control from audio HAL and in such
- * case, setting AUDIO_VOLUME_EXT_SYNC property may trigger event in AUDIO_VOLUME property.
- * Data format for this property is the same as AUDIO_VOLUME property.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @config_flags all audio contexts supported.
- */
- AUDIO_VOLUME_EXT_SYNC = (
- 0x0911
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Property for handling volume limit set by user. This limits maximum
- * volume that can be set per each context or physical stream.
- *
- * VehiclePropConfig
- * configArray[0] : bit flags of all supported audio contexts. If this is
- * 0, audio volume is controlled per physical stream.
- * configArray[1] : flags defined in VehicleAudioVolumeCapabilityFlag
- * to represent audio module's capability.
- *
- * Data type looks like:
- * int32Values[0] : audio context as defined in VehicleAudioContextFlag.
- * If only physical stream is supported
- * (configArray[0] == 0), this must represent physical
- * stream number.
- * int32Values[1] : maximum volume set to the stream. If there is no
- * restriction, this value must be equal to
- * AUDIO_VOLUME's max value.
- *
- * If car does not support this feature, this property must not be
- * populated by HAL.
- * HAL implementations must check the incoming value of audio context
- * field in get call to return the right volume.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @config_flags all audio contexts supported.
- */
- AUDIO_VOLUME_LIMIT = (
- 0x0902
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Property to share audio routing policy of android side. This property is
- * set at startup to pass audio policy in android side down to
- * vehicle HAL and car audio module.
- *
- * int32Values[0] : audio stream where the audio for the application
- * context must be routed by default. Note that this is
- * the default setting from system, but each app may
- * still use different audio stream for whatever reason.
- * int32Values[1] : All audio contexts that must be sent through the
- * physical stream. Flag is defined in
- * VehicleAudioContextFlag.
-
- * Setting of this property must be done for all available physical streams
- * based on audio H/W variant information acquired from AUDIO_HW_VARIANT
- * property.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:WRITE
- */
- AUDIO_ROUTING_POLICY = (
- 0x0903
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Property to return audio H/W variant type used in this car. This is a
- * zero based index into the set of audio routing policies defined in
- * R.array.audioRoutingPolicy on CarService, which may be overlaid to
- * support multiple variants. If this property does not exist, the default
- * audio policy must be used.
- *
- * @change_mode VehiclePropertyChangeMode:STATIC
- * @access VehiclePropertyAccess:READ
- * @config_flags Additional info on audio H/W. Must use
- * VehicleAudioHwVariantConfigFlag for this.
- */
- AUDIO_HW_VARIANT = (
- 0x0904
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32
- | VehicleArea:GLOBAL),
-
- /**
- * Property to pass hint on external audio routing. When android side
- * request focus with VehicleAudioExtFocusflag, this
- * property must be set before setting AUDIO_FOCUS property as a hint for
- * external audio source routing.
- * Note that setting this property alone must not trigger any change.
- * Audio routing must be changed only when AUDIO_FOCUS property is set.
- * Note that this property allows passing custom value as long as it is
- * defined in VehiclePropConfig#configString. This allows supporting
- * non-standard routing options through this property.
- * It is recommended to use separate name space for custom property to
- * prevent conflict in future android releases.
- * Enabling each external routing option is done by enabling each bit flag
- * for the routing.
- * This property can support up to 128 external routings.
- * To give full flexibility, there is no standard definition for each bit
- * flag and assigning each bit flag to specific routing type is decided by
- * VehiclePropConfig#configString. VehiclePropConfig#configString has
- * format of each entry separated by ',' and each entry has format of
- * bitFlagPositon:typeString[:physicalStreamNumber].
- * bitFlagPosition: represents which bit flag will be set to enable this
- * routing. 0 means LSB in int32Values[0]. 31 will be MSB in
- * int32Values[0]. 127 will MSB in int32Values[3].
- * typeString: string representation of external routing. Some types are
- * already defined in AUDIO_EXT_ROUTING_SOURCE_* and use them first
- * before adding something custom. Applications will find each routing
- * using this string.
- * physicalStreamNumber: This part is optional and represents physical
- * stream to android which will be disabled when this routing is enabled.
- * If not specified, this routing must not affect physical streams to
- * android.
- * As an example, let's assume a system with two physical streams, 0 for
- * media and 1 for nav guidance. And let's assume external routing option
- * of am fm radio, external navigation guidance, satellite radio, and one
- * custom. Let's assume that radio and satellite replaces physical stream 0
- * and external navigation replaces physical stream 1. And bit flag will be
- * assigned in the order listed above. This configuration will look like
- * this in config_string:
- * "0:RADIO_AM_FM:0,1:EXT_NAV_GUIDANCE:1,2:RADIO_SATELLITE:0,3:com.test.SOMETHING_CUSTOM"
- * When android requests RADIO_AM_FM, int32Values[0] will be set to 0x1.
- * When android requests RADIO_SATELLITE + EXT_NAV_GUIDANCE, int32Values[0]
- * will be set to 0x2|0x4.
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- * @config_string List of all avaiable external source in the system.
- */
- AUDIO_EXT_ROUTING_HINT = (
- 0x0905
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Represents state of audio stream. Audio HAL should set this when a stream is starting or
- * ending. Car service can request focus for audio played without focus. If such feature
- * is not required, this property does not need to be implemented.
- * Car service only monitors setting of this property. It is up to each vehicle HAL
- * implementation to add necessary action but default implementation will be doing nothing on
- * this propery's set from audio HAL.
- * Actual streaming of data should be done only after getting focus for the given stream from
- * car audio module. Focus can be already granted when stream is started. Focus state can be
- * monitored by monitoring AUDIO_FOCUS property. If car does not support
- * AUDIO_FOCUS property, there is no need to monitor focus as focus is assumed to be
- * granted always.
- * Data has the following format:
- * int32_array[0] : vehicle_audio_stream_state, 0: stopped, 1: started
- * int32_array[1] : stream number like 0, 1, 2, ...
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- AUDIO_STREAM_STATE = (
- 0x0906
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:INT32_VEC
- | VehicleArea:GLOBAL),
-
- /**
- * Property to control car specific audio parameters. Each parameter is defined as string key-
- * value pair.
- * set and event notification can pass multiple parameters using the
- * following format:
- * key1=value1;key2=value2;...
- * get call can request multiple parameters using the following format:
- * key1;key2;...
- * Response for get call has the same format as set.
- *
- * VehiclePropConfig
- * configString: give list of all supported keys with ; as separator. For example:
- * key1;key2;...
- *
- * @change_mode VehiclePropertyChangeMode:ON_CHANGE
- * @access VehiclePropertyAccess:READ_WRITE
- */
- AUDIO_PARAMETERS = (
- 0x907
- | VehiclePropertyGroup:SYSTEM
- | VehiclePropertyType:STRING
- | VehicleArea:GLOBAL),
-
- /**
* Property to control power state of application processor
*
* It is assumed that AP's power state is controller by separate power
@@ -2243,256 +1903,6 @@
VEHICLE_RADIO_PRESET_MIN_VALUE = 1,
};
-enum VehicleAudioFocusRequest : int32_t {
- REQUEST_GAIN = 0x1,
- REQUEST_GAIN_TRANSIENT = 0x2,
- REQUEST_GAIN_TRANSIENT_MAY_DUCK = 0x3,
- /**
- * This is for the case where android side plays sound like UI feedback
- * and car side does not need to duck existing playback as long as
- * requested stream is available.
- */
- REQUEST_GAIN_TRANSIENT_NO_DUCK = 0x4,
- REQUEST_RELEASE = 0x5,
-};
-
-enum VehicleAudioFocusState : int32_t {
- /**
- * Android side has permanent focus and can play allowed streams.
- */
- STATE_GAIN = 0x1,
-
- /**
- * Android side has transient focus and can play allowed streams.
- */
- STATE_GAIN_TRANSIENT = 0x2,
-
- /**
- * Car audio module is playing guidance kind of sound outside Android.
- * Android side can still play through allowed streams with ducking.
- */
- STATE_LOSS_TRANSIENT_CAN_DUCK = 0x3,
-
- /**
- * Car audio module is playing transient sound outside Android. Android side
- * must stop playing any sounds.
- */
- STATE_LOSS_TRANSIENT = 0x4,
-
- /**
- * Android side has lost focus and cannot play any sound.
- */
- STATE_LOSS = 0x5,
-
- /**
- * car audio module is playing safety critical sound, and Android side cannot
- * request focus until the current state is finished. car audio module
- * restore it to the previous state when it can allow Android to play.
- */
- STATE_LOSS_TRANSIENT_EXLCUSIVE = 0x6,
-};
-
-/**
- * Flags to represent multiple streams by combining these.
- */
-enum VehicleAudioStreamFlag : int32_t {
- STREAM0_FLAG = (0x1 << 0),
- STREAM1_FLAG = (0x1 << 1),
- STREAM2_FLAG = (0x1 << 2),
-};
-
-/**
- * Represents stream number (always 0 to N -1 where N is max number of streams).
- * Can be used for audio related property expecting one stream.
- */
-enum VehicleAudioStream : int32_t {
- STREAM0 = 0,
- STREAM1 = 1,
-};
-
-/**
- * Flag to represent external focus state (outside Android).
- */
-enum VehicleAudioExtFocusFlag : int32_t {
- /**
- * No external focus holder.
- */
- NONE_FLAG = 0x0,
-
- /**
- * Car side (outside Android) has component holding GAIN kind of focus state.
- */
- PERMANENT_FLAG = 0x1,
-
- /**
- * Car side (outside Android) has component holding GAIN_TRANSIENT kind of
- * focus state.
- */
- TRANSIENT_FLAG = 0x2,
-
- /**
- * Car side is expected to play something while focus is held by Android side.
- * One example can be radio attached in car side. But Android's radio app
- * still must have focus, and Android side must be in GAIN state, but
- * media stream will not be allocated to Android side and car side can play
- * radio any time while this flag is active.
- */
- PLAY_ONLY_FLAG = 0x4,
-
- /**
- * Car side must mute any media including radio. This can be used with any
- * focus request including GAIN* and RELEASE.
- */
- MUTE_MEDIA_FLAG = 0x8,
-};
-
-/**
- * Index in int32Values for VehicleProperty#AUDIO_FOCUS property.
- */
-enum VehicleAudioFocusIndex : int32_t {
- FOCUS = 0,
- STREAMS = 1,
- EXTERNAL_FOCUS_STATE = 2,
- AUDIO_CONTEXTS = 3,
-};
-
-/**
- * Flags to tell the current audio context.
- */
-enum VehicleAudioContextFlag : int32_t {
- /** Music playback is currently active. */
- MUSIC_FLAG = 0x1,
-
- /** Navigation is currently running. */
- NAVIGATION_FLAG = 0x2,
-
- /** Voice command session is currently running. */
- VOICE_COMMAND_FLAG = 0x4,
-
- /** Voice call is currently active. */
- CALL_FLAG = 0x8,
-
- /**
- * Alarm is active.
- * This must be only used in VehicleProperty#AUDIO_ROUTING_POLICY.
- */
- ALARM_FLAG = 0x10,
-
- /**
- * Notification sound is active.
- * This must be only used in VehicleProperty#AUDIO_ROUTING_POLICY.
- */
- NOTIFICATION_FLAG = 0x20,
-
- /**
- * Context unknown. Only used for VehicleProperty#AUDIO_ROUTING_POLICY to
- * represent default stream for unknown contents.
- */
- UNKNOWN_FLAG = 0x40,
-
- /** Safety alert / warning is played. */
- SAFETY_ALERT_FLAG = 0x80,
-
- /** CD / DVD kind of audio is played */
- CD_ROM_FLAG = 0x100,
-
- /** Aux audio input is played */
- AUX_AUDIO_FLAG = 0x200,
-
- /** system sound like UI feedback */
- SYSTEM_SOUND_FLAG = 0x400,
-
- /** Radio is played */
- RADIO_FLAG = 0x800,
-
- /** Ext source is played. This is for tagging generic ext sources. */
- EXT_SOURCE_FLAG = 0x1000,
-
- /** The phone ring tone is played */
- RINGTONE_FLAG = 0x2000
-};
-
-/**
- * flags to represent capability of audio volume property.
- * used in configArray[1] of VehiclePropConfig.
- */
-enum VehicleAudioVolumeCapabilityFlag : int32_t {
- /**
- * External audio module or vehicle hal has persistent storage to keep the
- * volume level. When this is set, the audio volume level for each context
- * will be retrieved from the property when the system starts up.
- * And external audio module is also expected to adjust volume automatically
- * whenever there is an audio context change.
- * When this flag is not set, android side will assume that there is no
- * persistent storage and the value stored in the android side will be used to
- * initialize the volume level, and android side will set volume level
- * of each physical stream whenever there is an audio context change.
- */
- PERSISTENT_STORAGE = 0x1,
-
- /**
- * [DEPRECATED]
- * When this flag is set, the H/W can support only single master volume for
- * all streams. There is no way to set volume level differently for each stream
- * or context.
- */
- MASTER_VOLUME_ONLY = 0x2,
-};
-
-/**
- * enum to represent audio volume state.
- */
-enum VehicleAudioVolumeState : int32_t {
- STATE_OK = 0,
-
- /**
- * Audio volume has reached volume limit set in
- * VehicleProperty#AUDIO_VOLUME_LIMIT and user's request to increase volume
- * further is not allowed.
- */
- STATE_LIMIT_REACHED = 1,
-};
-
-/**
- * Index in int32Values for VehicleProperty#AUDIO_VOLUME property.
- */
-enum VehicleAudioVolumeIndex : int32_t {
- STREAM = 0,
- VOLUME = 1,
- STATE = 2,
-};
-
-/**
- * Index in int32Values for VehicleProperty#AUDIO_VOLUME_LIMIT property.
- */
-enum VehicleAudioVolumeLimitIndex : int32_t {
- STREAM = 0,
- MAX_VOLUME = 1,
-};
-
-/**
- * Index in int32Values for VehicleProperty#AUDIO_ROUTING_POLICY property.
- */
-enum VehicleAudioRoutingPolicyIndex : int32_t {
- STREAM = 0,
- CONTEXTS = 1,
-};
-
-/**
- * Flag to be used in VehiclePropConfig#configFlags for
- * VehicleProperty#AUDIO_HW_VARIANT.
- */
-enum VehicleAudioHwVariantConfigFlag : int32_t {
- /**
- * Flag to tell that radio is internal to android and radio must
- * be treated like other android stream like media.
- * When this flag is not set or AUDIO_HW_VARIANT does not exist,
- * radio is treated as external module. This may affect audio focus
- * handling as well.
- */
- INTERNAL_RADIO_FLAG = 0x1,
-};
-
enum VehicleApPowerStateConfigFlag : int32_t /* NOTE: type is guessed */ {
/**
* AP can enter deep sleep state. If not set, AP will always shutdown from
diff --git a/broadcastradio/1.2/default/BroadcastRadio.cpp b/broadcastradio/1.2/default/BroadcastRadio.cpp
index 5164e47..74f6589 100644
--- a/broadcastradio/1.2/default/BroadcastRadio.cpp
+++ b/broadcastradio/1.2/default/BroadcastRadio.cpp
@@ -107,7 +107,7 @@
prop10.numTuners = 1;
prop10.numAudioSources = 1;
prop10.supportsCapture = false;
- prop11.supportsBackgroundScanning = false;
+ prop11.supportsBackgroundScanning = true;
prop11.supportedProgramTypes = hidl_vec<uint32_t>({
static_cast<uint32_t>(ProgramType::AM), static_cast<uint32_t>(ProgramType::FM),
static_cast<uint32_t>(ProgramType::AM_HD), static_cast<uint32_t>(ProgramType::FM_HD),
diff --git a/broadcastradio/2.0/Android.bp b/broadcastradio/2.0/Android.bp
index 7409005..2434fdc 100644
--- a/broadcastradio/2.0/Android.bp
+++ b/broadcastradio/2.0/Android.bp
@@ -8,7 +8,7 @@
},
srcs: [
"types.hal",
- "IAnnouncementObserver.hal",
+ "IAnnouncementListener.hal",
"IBroadcastRadio.hal",
"ICloseHandle.hal",
"ITunerCallback.hal",
diff --git a/broadcastradio/2.0/IAnnouncementObserver.hal b/broadcastradio/2.0/IAnnouncementListener.hal
similarity index 85%
rename from broadcastradio/2.0/IAnnouncementObserver.hal
rename to broadcastradio/2.0/IAnnouncementListener.hal
index c91e29a..1b4960c 100644
--- a/broadcastradio/2.0/IAnnouncementObserver.hal
+++ b/broadcastradio/2.0/IAnnouncementListener.hal
@@ -16,11 +16,11 @@
package android.hardware.broadcastradio@2.0;
/**
- * Callback interface for announcement observer.
+ * Callback interface for announcement listener.
*
- * For typical configuration, the observer is a broadcast radio service.
+ * For typical configuration, the listener is a broadcast radio service.
*/
-interface IAnnouncementObserver {
+interface IAnnouncementListener {
/**
* Called whenever announcement list has changed.
*
diff --git a/broadcastradio/2.0/IBroadcastRadio.hal b/broadcastradio/2.0/IBroadcastRadio.hal
index 7578f44..bedc362 100644
--- a/broadcastradio/2.0/IBroadcastRadio.hal
+++ b/broadcastradio/2.0/IBroadcastRadio.hal
@@ -15,7 +15,7 @@
package android.hardware.broadcastradio@2.0;
-import IAnnouncementObserver;
+import IAnnouncementListener;
import ICloseHandle;
import ITunerCallback;
import ITunerSession;
@@ -104,7 +104,7 @@
getImage(uint32_t id) generates (vec<uint8_t> image);
/**
- * Registers announcement observer.
+ * Registers announcement listener.
*
* If there is at least one observer registered, HAL implementation must
* notify about announcements even if no sessions are active.
@@ -113,15 +113,15 @@
* automatically.
*
* @param enabled The list of announcement types to watch for.
- * @param cb The callback interface.
+ * @param listener The listener interface.
* @return result OK in case of success.
* NOT_SUPPORTED if the tuner doesn't support announcements.
* @return closeHandle A handle to unregister observer,
* nullptr if result was not OK.
*/
- registerAnnouncementObserver(
+ registerAnnouncementListener(
vec<AnnouncementType> enabled,
- IAnnouncementObserver cb
+ IAnnouncementListener listener
) generates (
Result result,
ICloseHandle closeHandle
diff --git a/broadcastradio/2.0/default/BroadcastRadio.cpp b/broadcastradio/2.0/default/BroadcastRadio.cpp
index d16aaff..aa5afad 100644
--- a/broadcastradio/2.0/default/BroadcastRadio.cpp
+++ b/broadcastradio/2.0/default/BroadcastRadio.cpp
@@ -141,9 +141,9 @@
return {};
}
-Return<void> BroadcastRadio::registerAnnouncementObserver(
- const hidl_vec<AnnouncementType>& enabled, const sp<IAnnouncementObserver>& /* cb */,
- registerAnnouncementObserver_cb _hidl_cb) {
+Return<void> BroadcastRadio::registerAnnouncementListener(
+ const hidl_vec<AnnouncementType>& enabled, const sp<IAnnouncementListener>& /* listener */,
+ registerAnnouncementListener_cb _hidl_cb) {
ALOGV("%s(%s)", __func__, toString(enabled).c_str());
_hidl_cb(Result::NOT_SUPPORTED, nullptr);
diff --git a/broadcastradio/2.0/default/BroadcastRadio.h b/broadcastradio/2.0/default/BroadcastRadio.h
index 7904946..8c14d9e 100644
--- a/broadcastradio/2.0/default/BroadcastRadio.h
+++ b/broadcastradio/2.0/default/BroadcastRadio.h
@@ -36,9 +36,9 @@
Return<void> getDabRegionConfig(getDabRegionConfig_cb _hidl_cb);
Return<void> openSession(const sp<ITunerCallback>& callback, openSession_cb _hidl_cb) override;
Return<void> getImage(uint32_t id, getImage_cb _hidl_cb);
- Return<void> registerAnnouncementObserver(const hidl_vec<AnnouncementType>& enabled,
- const sp<IAnnouncementObserver>& cb,
- registerAnnouncementObserver_cb _hidl_cb);
+ Return<void> registerAnnouncementListener(const hidl_vec<AnnouncementType>& enabled,
+ const sp<IAnnouncementListener>& listener,
+ registerAnnouncementListener_cb _hidl_cb);
std::reference_wrapper<const VirtualRadio> mVirtualRadio;
Properties mProperties;
diff --git a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
index 1111478..8d9d622 100644
--- a/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
+++ b/broadcastradio/2.0/vts/functional/VtsHalBroadcastradioV2_0TargetTest.cpp
@@ -90,7 +90,7 @@
utils::ProgramInfoSet mProgramList;
};
-struct AnnouncementObserverMock : public IAnnouncementObserver {
+struct AnnouncementListenerMock : public IAnnouncementListener {
MOCK_METHOD1(onListUpdated, Return<void>(const hidl_vec<Announcement>&));
};
@@ -702,15 +702,15 @@
}
/**
- * Test announcement observer registration.
+ * Test announcement listener registration.
*
* Verifies that:
- * - registerAnnouncementObserver either succeeds or returns NOT_SUPPORTED;
+ * - registerAnnouncementListener either succeeds or returns NOT_SUPPORTED;
* - if it succeeds, it returns a valid close handle (which is a nullptr otherwise);
* - closing handle does not crash.
*/
-TEST_F(BroadcastRadioHalTest, AnnouncementObserverRegistration) {
- sp<AnnouncementObserverMock> observer = new AnnouncementObserverMock();
+TEST_F(BroadcastRadioHalTest, AnnouncementListenerRegistration) {
+ sp<AnnouncementListenerMock> listener = new AnnouncementListenerMock();
Result halResult = Result::UNKNOWN_ERROR;
sp<ICloseHandle> closeHandle = nullptr;
@@ -720,7 +720,7 @@
};
auto hidlResult =
- mModule->registerAnnouncementObserver({AnnouncementType::EMERGENCY}, observer, cb);
+ mModule->registerAnnouncementListener({AnnouncementType::EMERGENCY}, listener, cb);
ASSERT_TRUE(hidlResult.isOk());
if (halResult == Result::NOT_SUPPORTED) {
diff --git a/compatibility_matrices/Android.mk b/compatibility_matrices/Android.mk
new file mode 100644
index 0000000..2a01480
--- /dev/null
+++ b/compatibility_matrices/Android.mk
@@ -0,0 +1,138 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+# Install all compatibility_matrix.*.xml to /system/etc/vintf
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.legacy.xml
+LOCAL_MODULE_STEM := compatibility_matrix.legacy.xml
+LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.1.xml
+LOCAL_MODULE_STEM := compatibility_matrix.1.xml
+LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.2.xml
+LOCAL_MODULE_STEM := compatibility_matrix.2.xml
+LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
+include $(BUILD_PREBUILT)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.current.xml
+LOCAL_MODULE_STEM := compatibility_matrix.current.xml
+LOCAL_SRC_FILES := $(LOCAL_MODULE_STEM)
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
+include $(BUILD_PREBUILT)
+
+# Framework Compatibility Matrix without HALs
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.empty.xml
+LOCAL_MODULE_STEM := compatibility_matrix.empty.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/vintf
+
+GEN := $(local-generated-sources-dir)/$(LOCAL_MODULE_STEM)
+
+$(GEN): PRIVATE_FLAGS :=
+
+ifeq (true,$(BOARD_AVB_ENABLE))
+$(GEN): $(AVBTOOL)
+# INTERNAL_AVB_SYSTEM_SIGNING_ARGS consists of BOARD_AVB_SYSTEM_KEY_PATH and
+# BOARD_AVB_SYSTEM_ALGORITHM. We should add the dependency of key path, which
+# is a file, here.
+$(GEN): $(BOARD_AVB_SYSTEM_KEY_PATH)
+# Use deferred assignment (=) instead of immediate assignment (:=).
+# Otherwise, cannot get INTERNAL_AVB_SYSTEM_SIGNING_ARGS.
+$(GEN): FRAMEWORK_VBMETA_VERSION = $$("$(AVBTOOL)" add_hashtree_footer \
+ --print_required_libavb_version \
+ $(INTERNAL_AVB_SYSTEM_SIGNING_ARGS) \
+ $(BOARD_AVB_SYSTEM_ADD_HASHTREE_FOOTER_ARGS))
+else
+$(GEN): FRAMEWORK_VBMETA_VERSION := 0.0
+endif
+
+# Specify kernel versions that the current framework supports. These versions,
+# along with kernel configurations, are written to the framework compatibility
+# matrix.
+$(GEN): KERNEL_VERSIONS := 3.18 4.4 4.9
+
+# Specify the location of android-base*.cfg files.
+$(GEN): KERNEL_CONFIG_DATA := kernel/configs
+
+$(GEN): $(foreach version,$(KERNEL_VERSIONS),\
+ $(wildcard $(KERNEL_CONFIG_DATA)/android-$(version)/android-base*.cfg))
+$(GEN): PRIVATE_FLAGS += $(foreach version,$(KERNEL_VERSIONS),\
+ --kernel=$(version):$(call normalize-path-list,\
+ $(wildcard $(KERNEL_CONFIG_DATA)/android-$(version)/android-base*.cfg)))
+
+$(GEN): $(LOCAL_PATH)/compatibility_matrix.empty.xml $(HOST_OUT_EXECUTABLES)/assemble_vintf
+ POLICYVERS=$(POLICYVERS) \
+ BOARD_SEPOLICY_VERS=$(BOARD_SEPOLICY_VERS) \
+ FRAMEWORK_VBMETA_VERSION=$(FRAMEWORK_VBMETA_VERSION) \
+ $(HOST_OUT_EXECUTABLES)/assemble_vintf \
+ -i $< -o $@ $(PRIVATE_FLAGS)
+LOCAL_PREBUILT_MODULE_FILE := $(GEN)
+include $(BUILD_PREBUILT)
+
+# Framework Compatibility Matrix
+include $(CLEAR_VARS)
+LOCAL_MODULE := framework_compatibility_matrix.xml
+LOCAL_MODULE_STEM := compatibility_matrix.xml
+LOCAL_MODULE_CLASS := ETC
+LOCAL_MODULE_PATH := $(TARGET_OUT)
+
+LOCAL_REQUIRED_MODULES := \
+ framework_compatibility_matrix.legacy.xml \
+ framework_compatibility_matrix.1.xml \
+ framework_compatibility_matrix.2.xml \
+ framework_compatibility_matrix.current.xml \
+ framework_compatibility_matrix.empty.xml
+
+GEN := $(local-generated-sources-dir)/compatibility_matrix.xml
+
+$(GEN): PRIVATE_FLAGS :=
+
+ifdef BUILT_VENDOR_MANIFEST
+$(GEN): $(BUILT_VENDOR_MANIFEST)
+$(GEN): PRIVATE_FLAGS += -c "$(BUILT_VENDOR_MANIFEST)"
+endif
+
+MATRIX_SRC_FILES := $(call module-installed-files,$(LOCAL_REQUIRED_MODULES))
+$(GEN): PRIVATE_MATRIX_SRC_FILES := $(MATRIX_SRC_FILES)
+$(GEN): $(MATRIX_SRC_FILES) $(HOST_OUT_EXECUTABLES)/assemble_vintf
+ PRODUCT_ENFORCE_VINTF_MANIFEST=$(PRODUCT_ENFORCE_VINTF_MANIFEST) \
+ $(HOST_OUT_EXECUTABLES)/assemble_vintf \
+ -i $(call normalize-path-list,$(PRIVATE_MATRIX_SRC_FILES)) \
+ -o $@ $(PRIVATE_FLAGS)
+
+MATRIX_SRC_FILES :=
+
+LOCAL_PREBUILT_MODULE_FILE := $(GEN)
+include $(BUILD_PREBUILT)
+BUILT_SYSTEM_COMPATIBILITY_MATRIX := $(LOCAL_BUILT_MODULE)
diff --git a/compatibility_matrix.1.xml b/compatibility_matrices/compatibility_matrix.1.xml
similarity index 100%
rename from compatibility_matrix.1.xml
rename to compatibility_matrices/compatibility_matrix.1.xml
diff --git a/compatibility_matrix.2.xml b/compatibility_matrices/compatibility_matrix.2.xml
similarity index 100%
rename from compatibility_matrix.2.xml
rename to compatibility_matrices/compatibility_matrix.2.xml
diff --git a/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
similarity index 97%
rename from compatibility_matrix.current.xml
rename to compatibility_matrices/compatibility_matrix.current.xml
index 9287d67..1aaef1e 100644
--- a/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -16,6 +16,14 @@
</interface>
</hal>
<hal format="hidl" optional="true">
+ <name>android.hardware.authsecret</name>
+ <version>1.0</version>
+ <interface>
+ <name>IAuthSecret</name>
+ <instance>default</instance>
+ </interface>
+ </hal>
+ <hal format="hidl" optional="true">
<name>android.hardware.automotive.evs</name>
<version>1.0</version>
<interface>
diff --git a/compatibility_matrices/compatibility_matrix.empty.xml b/compatibility_matrices/compatibility_matrix.empty.xml
new file mode 100644
index 0000000..216f5f1
--- /dev/null
+++ b/compatibility_matrices/compatibility_matrix.empty.xml
@@ -0,0 +1 @@
+<compatibility-matrix version="1.0" type="framework" />
diff --git a/compatibility_matrix.legacy.xml b/compatibility_matrices/compatibility_matrix.legacy.xml
similarity index 100%
rename from compatibility_matrix.legacy.xml
rename to compatibility_matrices/compatibility_matrix.legacy.xml
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 9968f41..ed2ecbb 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -1,10 +1,15 @@
cc_library_shared {
name: "android.hardware.graphics.allocator@2.0-impl",
defaults: ["hidl_defaults"],
- proprietary: true,
+ vendor: true,
relative_install_path: "hw",
- srcs: ["Gralloc.cpp", "Gralloc0Allocator.cpp", "Gralloc1Allocator.cpp"],
- cppflags: ["-Wall", "-Wextra"],
+ srcs: ["passthrough.cpp"],
+ static_libs: [
+ "android.hardware.graphics.allocator@2.0-passthrough",
+ ],
+ header_libs: [
+ "android.hardware.graphics.allocator@2.0-hal",
+ ],
shared_libs: [
"android.hardware.graphics.allocator@2.0",
"libbase",
@@ -15,9 +20,6 @@
"liblog",
"libutils",
],
- header_libs: [
- "libgrallocmapperincludes",
- ],
}
cc_binary {
@@ -36,13 +38,3 @@
"libutils",
],
}
-
-cc_library_static {
- name: "libgralloc1-adapter",
- defaults: ["hidl_defaults"],
- srcs: ["gralloc1-adapter.cpp", "Gralloc1On0Adapter.cpp"],
- include_dirs: ["system/core/libsync/include"],
- cflags: ["-Wall", "-Wextra"],
- export_include_dirs: ["."],
- whole_static_libs: ["libgrallocusage"],
-}
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
deleted file mode 100644
index 273d3f5..0000000
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 "GrallocPassthrough"
-
-#include "Gralloc.h"
-#include "Gralloc0Allocator.h"
-#include "Gralloc1Allocator.h"
-
-#include <log/log.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace implementation {
-
-IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
- const hw_module_t* module = nullptr;
- int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
- if (err) {
- ALOGE("failed to get gralloc module");
- return nullptr;
- }
-
- uint8_t major = (module->module_api_version >> 8) & 0xff;
- switch (major) {
- case 1:
- return new Gralloc1Allocator(module);
- case 0:
- return new Gralloc0Allocator(module);
- default:
- ALOGE("unknown gralloc module major version %d", major);
- return nullptr;
- }
-}
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc.h b/graphics/allocator/2.0/default/Gralloc.h
deleted file mode 100644
index c79eeaa..0000000
--- a/graphics/allocator/2.0/default/Gralloc.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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_GRAPHICS_ALLOCATOR_V2_0_GRALLOC_H
-#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC_H
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace implementation {
-
-extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* name);
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC_H
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.cpp b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
deleted file mode 100644
index 3b62bb3..0000000
--- a/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * 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 "Gralloc0Allocator"
-
-#include "Gralloc0Allocator.h"
-#include "GrallocBufferDescriptor.h"
-
-#include <vector>
-
-#include <string.h>
-
-#include <log/log.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace implementation {
-
-using android::hardware::graphics::mapper::V2_0::implementation::
- grallocDecodeBufferDescriptor;
-
-Gralloc0Allocator::Gralloc0Allocator(const hw_module_t* module) {
- int result = gralloc_open(module, &mDevice);
- if (result) {
- LOG_ALWAYS_FATAL("failed to open gralloc0 device: %s",
- strerror(-result));
- }
-}
-
-Gralloc0Allocator::~Gralloc0Allocator() {
- gralloc_close(mDevice);
-}
-
-Return<void> Gralloc0Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
- char buf[4096] = {};
- if (mDevice->dump) {
- mDevice->dump(mDevice, buf, sizeof(buf));
- buf[sizeof(buf) - 1] = '\0';
- }
-
- hidl_cb(hidl_string(buf));
-
- return Void();
-}
-
-Return<void> Gralloc0Allocator::allocate(const BufferDescriptor& descriptor,
- uint32_t count, allocate_cb hidl_cb) {
- IMapper::BufferDescriptorInfo descriptorInfo;
- if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
- hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
- return Void();
- }
-
- Error error = Error::NONE;
- uint32_t stride = 0;
- std::vector<hidl_handle> buffers;
- buffers.reserve(count);
-
- // allocate the buffers
- for (uint32_t i = 0; i < count; i++) {
- buffer_handle_t tmpBuffer;
- uint32_t tmpStride;
- error = allocateOne(descriptorInfo, &tmpBuffer, &tmpStride);
- if (error != Error::NONE) {
- break;
- }
-
- if (stride == 0) {
- stride = tmpStride;
- } else if (stride != tmpStride) {
- // non-uniform strides
- mDevice->free(mDevice, tmpBuffer);
- stride = 0;
- error = Error::UNSUPPORTED;
- break;
- }
-
- buffers.emplace_back(hidl_handle(tmpBuffer));
- }
-
- // return the buffers
- hidl_vec<hidl_handle> hidl_buffers;
- if (error == Error::NONE) {
- hidl_buffers.setToExternal(buffers.data(), buffers.size());
- }
- hidl_cb(error, stride, hidl_buffers);
-
- // free the buffers
- for (const auto& buffer : buffers) {
- mDevice->free(mDevice, buffer.getNativeHandle());
- }
-
- return Void();
-}
-
-Error Gralloc0Allocator::allocateOne(const IMapper::BufferDescriptorInfo& info,
- buffer_handle_t* outBuffer,
- uint32_t* outStride) {
- if (info.layerCount > 1 || (info.usage >> 32) != 0) {
- return Error::BAD_VALUE;
- }
-
- buffer_handle_t buffer = nullptr;
- int stride = 0;
- int result = mDevice->alloc(mDevice, info.width, info.height,
- static_cast<int>(info.format), info.usage,
- &buffer, &stride);
- if (result) {
- switch (result) {
- case -EINVAL:
- return Error::BAD_VALUE;
- default:
- return Error::NO_RESOURCES;
- }
- }
-
- *outBuffer = buffer;
- *outStride = stride;
-
- return Error::NONE;
-}
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.h b/graphics/allocator/2.0/default/Gralloc0Allocator.h
deleted file mode 100644
index 0e90527..0000000
--- a/graphics/allocator/2.0/default/Gralloc0Allocator.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
-#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <hardware/gralloc.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace implementation {
-
-using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
-using android::hardware::graphics::mapper::V2_0::Error;
-
-class Gralloc0Allocator : public IAllocator {
- public:
- Gralloc0Allocator(const hw_module_t* module);
- virtual ~Gralloc0Allocator();
-
- // IAllocator interface
- Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
- Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
- allocate_cb hidl_cb) override;
-
- private:
- Error allocateOne(const IMapper::BufferDescriptorInfo& info,
- buffer_handle_t* outBuffer, uint32_t* outStride);
-
- alloc_device_t* mDevice;
-};
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.cpp b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
deleted file mode 100644
index 6cbb791..0000000
--- a/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * 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 "Gralloc1Allocator"
-
-#include "Gralloc1Allocator.h"
-#include "GrallocBufferDescriptor.h"
-
-#include <vector>
-
-#include <string.h>
-
-#include <log/log.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace implementation {
-
-using android::hardware::graphics::common::V1_0::BufferUsage;
-using android::hardware::graphics::mapper::V2_0::implementation::
- grallocDecodeBufferDescriptor;
-
-Gralloc1Allocator::Gralloc1Allocator(const hw_module_t* module)
- : mDevice(nullptr), mCapabilities(), mDispatch() {
- int result = gralloc1_open(module, &mDevice);
- if (result) {
- LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
- strerror(-result));
- }
-
- initCapabilities();
- initDispatch();
-}
-
-Gralloc1Allocator::~Gralloc1Allocator() {
- gralloc1_close(mDevice);
-}
-
-void Gralloc1Allocator::initCapabilities() {
- uint32_t count = 0;
- mDevice->getCapabilities(mDevice, &count, nullptr);
-
- std::vector<int32_t> capabilities(count);
- mDevice->getCapabilities(mDevice, &count, capabilities.data());
- capabilities.resize(count);
-
- for (auto capability : capabilities) {
- if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) {
- mCapabilities.layeredBuffers = true;
- break;
- }
- }
-}
-
-template <typename T>
-void Gralloc1Allocator::initDispatch(gralloc1_function_descriptor_t desc,
- T* outPfn) {
- auto pfn = mDevice->getFunction(mDevice, desc);
- if (!pfn) {
- LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
- }
-
- *outPfn = reinterpret_cast<T>(pfn);
-}
-
-void Gralloc1Allocator::initDispatch() {
- initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
- initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
- &mDispatch.createDescriptor);
- initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
- &mDispatch.destroyDescriptor);
- initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
- initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
- if (mCapabilities.layeredBuffers) {
- initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
- &mDispatch.setLayerCount);
- }
- initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
- &mDispatch.setConsumerUsage);
- initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
- &mDispatch.setProducerUsage);
- initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
- initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
- initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
-}
-
-Return<void> Gralloc1Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
- uint32_t len = 0;
- mDispatch.dump(mDevice, &len, nullptr);
-
- std::vector<char> buf(len + 1);
- mDispatch.dump(mDevice, &len, buf.data());
- buf.resize(len + 1);
- buf[len] = '\0';
-
- hidl_string reply;
- reply.setToExternal(buf.data(), len);
- hidl_cb(reply);
-
- return Void();
-}
-
-Return<void> Gralloc1Allocator::allocate(const BufferDescriptor& descriptor,
- uint32_t count, allocate_cb hidl_cb) {
- IMapper::BufferDescriptorInfo descriptorInfo;
- if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
- hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
- return Void();
- }
-
- gralloc1_buffer_descriptor_t desc;
- Error error = createDescriptor(descriptorInfo, &desc);
- if (error != Error::NONE) {
- hidl_cb(error, 0, hidl_vec<hidl_handle>());
- return Void();
- }
-
- uint32_t stride = 0;
- std::vector<hidl_handle> buffers;
- buffers.reserve(count);
-
- // allocate the buffers
- for (uint32_t i = 0; i < count; i++) {
- buffer_handle_t tmpBuffer;
- uint32_t tmpStride;
- error = allocateOne(desc, &tmpBuffer, &tmpStride);
- if (error != Error::NONE) {
- break;
- }
-
- if (stride == 0) {
- stride = tmpStride;
- } else if (stride != tmpStride) {
- // non-uniform strides
- mDispatch.release(mDevice, tmpBuffer);
- stride = 0;
- error = Error::UNSUPPORTED;
- break;
- }
-
- buffers.emplace_back(hidl_handle(tmpBuffer));
- }
-
- mDispatch.destroyDescriptor(mDevice, desc);
-
- // return the buffers
- hidl_vec<hidl_handle> hidl_buffers;
- if (error == Error::NONE) {
- hidl_buffers.setToExternal(buffers.data(), buffers.size());
- }
- hidl_cb(error, stride, hidl_buffers);
-
- // free the buffers
- for (const auto& buffer : buffers) {
- mDispatch.release(mDevice, buffer.getNativeHandle());
- }
-
- return Void();
-}
-
-Error Gralloc1Allocator::toError(int32_t error) {
- switch (error) {
- case GRALLOC1_ERROR_NONE:
- return Error::NONE;
- case GRALLOC1_ERROR_BAD_DESCRIPTOR:
- return Error::BAD_DESCRIPTOR;
- case GRALLOC1_ERROR_BAD_HANDLE:
- return Error::BAD_BUFFER;
- case GRALLOC1_ERROR_BAD_VALUE:
- return Error::BAD_VALUE;
- case GRALLOC1_ERROR_NOT_SHARED:
- return Error::NONE; // this is fine
- case GRALLOC1_ERROR_NO_RESOURCES:
- return Error::NO_RESOURCES;
- case GRALLOC1_ERROR_UNDEFINED:
- case GRALLOC1_ERROR_UNSUPPORTED:
- default:
- return Error::UNSUPPORTED;
- }
-}
-
-uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
- // this is potentially broken as we have no idea which private flags
- // should be filtered out
- uint64_t producerUsage =
- usage &
- ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
- BufferUsage::GPU_DATA_BUFFER);
-
- switch (usage & BufferUsage::CPU_WRITE_MASK) {
- case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
- producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
- break;
- case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN):
- producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
- break;
- default:
- break;
- }
-
- switch (usage & BufferUsage::CPU_READ_MASK) {
- case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
- producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
- break;
- case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
- producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
- break;
- default:
- break;
- }
-
- // BufferUsage::GPU_DATA_BUFFER is always filtered out
-
- return producerUsage;
-}
-
-uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
- // this is potentially broken as we have no idea which private flags
- // should be filtered out
- uint64_t consumerUsage =
- usage &
- ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
- BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::GPU_DATA_BUFFER);
-
- switch (usage & BufferUsage::CPU_READ_MASK) {
- case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
- consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
- break;
- case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
- consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
- break;
- default:
- break;
- }
-
- // BufferUsage::SENSOR_DIRECT_DATA is always filtered out
-
- if (usage & BufferUsage::GPU_DATA_BUFFER) {
- consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
- }
-
- return consumerUsage;
-}
-
-Error Gralloc1Allocator::createDescriptor(
- const IMapper::BufferDescriptorInfo& info,
- gralloc1_buffer_descriptor_t* outDescriptor) {
- gralloc1_buffer_descriptor_t descriptor;
-
- int32_t error = mDispatch.createDescriptor(mDevice, &descriptor);
-
- if (error == GRALLOC1_ERROR_NONE) {
- error = mDispatch.setDimensions(mDevice, descriptor, info.width,
- info.height);
- }
- if (error == GRALLOC1_ERROR_NONE) {
- error = mDispatch.setFormat(mDevice, descriptor,
- static_cast<int32_t>(info.format));
- }
- if (error == GRALLOC1_ERROR_NONE) {
- if (mCapabilities.layeredBuffers) {
- error =
- mDispatch.setLayerCount(mDevice, descriptor, info.layerCount);
- } else if (info.layerCount > 1) {
- error = GRALLOC1_ERROR_UNSUPPORTED;
- }
- }
- if (error == GRALLOC1_ERROR_NONE) {
- error = mDispatch.setProducerUsage(mDevice, descriptor,
- toProducerUsage(info.usage));
- }
- if (error == GRALLOC1_ERROR_NONE) {
- error = mDispatch.setConsumerUsage(mDevice, descriptor,
- toConsumerUsage(info.usage));
- }
-
- if (error == GRALLOC1_ERROR_NONE) {
- *outDescriptor = descriptor;
- } else {
- mDispatch.destroyDescriptor(mDevice, descriptor);
- }
-
- return toError(error);
-}
-
-Error Gralloc1Allocator::allocateOne(gralloc1_buffer_descriptor_t descriptor,
- buffer_handle_t* outBuffer,
- uint32_t* outStride) {
- buffer_handle_t buffer = nullptr;
- int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
- if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
- return toError(error);
- }
-
- uint32_t stride = 0;
- error = mDispatch.getStride(mDevice, buffer, &stride);
- if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
- mDispatch.release(mDevice, buffer);
- return toError(error);
- }
-
- *outBuffer = buffer;
- *outStride = stride;
-
- return Error::NONE;
-}
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.h b/graphics/allocator/2.0/default/Gralloc1Allocator.h
deleted file mode 100644
index 7b5a966..0000000
--- a/graphics/allocator/2.0/default/Gralloc1Allocator.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
-#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <hardware/gralloc1.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace implementation {
-
-using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
-using android::hardware::graphics::mapper::V2_0::Error;
-
-class Gralloc1Allocator : public IAllocator {
- public:
- Gralloc1Allocator(const hw_module_t* module);
- virtual ~Gralloc1Allocator();
-
- // IAllocator interface
- Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
- Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
- allocate_cb hidl_cb) override;
-
- private:
- void initCapabilities();
-
- template <typename T>
- void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
- void initDispatch();
-
- static Error toError(int32_t error);
- static uint64_t toProducerUsage(uint64_t usage);
- static uint64_t toConsumerUsage(uint64_t usage);
-
- Error createDescriptor(const IMapper::BufferDescriptorInfo& info,
- gralloc1_buffer_descriptor_t* outDescriptor);
- Error allocateOne(gralloc1_buffer_descriptor_t descriptor,
- buffer_handle_t* outBuffer, uint32_t* outStride);
-
- gralloc1_device_t* mDevice;
-
- struct {
- bool layeredBuffers;
- } mCapabilities;
-
- struct {
- GRALLOC1_PFN_DUMP dump;
- GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
- GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
- GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
- GRALLOC1_PFN_SET_FORMAT setFormat;
- GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
- GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
- GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
- GRALLOC1_PFN_GET_STRIDE getStride;
- GRALLOC1_PFN_ALLOCATE allocate;
- GRALLOC1_PFN_RELEASE release;
- } mDispatch;
-};
-
-} // namespace implementation
-} // namespace V2_0
-} // namespace allocator
-} // namespace graphics
-} // namespace hardware
-} // namespace android
-
-#endif // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
diff --git a/graphics/allocator/2.0/default/passthrough.cpp b/graphics/allocator/2.0/default/passthrough.cpp
new file mode 100644
index 0000000..132cab3
--- /dev/null
+++ b/graphics/allocator/2.0/default/passthrough.cpp
@@ -0,0 +1,25 @@
+/*
+ * 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 <allocator-passthrough/2.0/GrallocLoader.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+
+using android::hardware::graphics::allocator::V2_0::IAllocator;
+using android::hardware::graphics::allocator::V2_0::passthrough::GrallocLoader;
+
+extern "C" IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
+ return GrallocLoader::load();
+}
diff --git a/graphics/allocator/2.0/default/service.cpp b/graphics/allocator/2.0/default/service.cpp
index 99f462c..bc0539a 100644
--- a/graphics/allocator/2.0/default/service.cpp
+++ b/graphics/allocator/2.0/default/service.cpp
@@ -20,8 +20,8 @@
#include <hidl/LegacySupport.h>
-using android::hardware::graphics::allocator::V2_0::IAllocator;
using android::hardware::defaultPassthroughServiceImplementation;
+using android::hardware::graphics::allocator::V2_0::IAllocator;
int main() {
return defaultPassthroughServiceImplementation<IAllocator>(4);
diff --git a/graphics/allocator/2.0/utils/OWNERS b/graphics/allocator/2.0/utils/OWNERS
new file mode 100644
index 0000000..3aa5fa1
--- /dev/null
+++ b/graphics/allocator/2.0/utils/OWNERS
@@ -0,0 +1,4 @@
+# Graphics team
+jessehall@google.com
+olv@google.com
+stoza@google.com
diff --git a/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp b/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp
new file mode 100644
index 0000000..9cb53e3
--- /dev/null
+++ b/graphics/allocator/2.0/utils/gralloc1-adapter/Android.bp
@@ -0,0 +1,10 @@
+cc_library_static {
+ name: "libgralloc1-adapter",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ srcs: ["gralloc1-adapter.cpp", "Gralloc1On0Adapter.cpp"],
+ include_dirs: ["system/core/libsync/include"],
+ export_include_dirs: ["."],
+ whole_static_libs: ["libgrallocusage"],
+ shared_libs: ["libhardware", "liblog"],
+}
diff --git a/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp b/graphics/allocator/2.0/utils/gralloc1-adapter/Gralloc1On0Adapter.cpp
similarity index 99%
rename from graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
rename to graphics/allocator/2.0/utils/gralloc1-adapter/Gralloc1On0Adapter.cpp
index 041ce77..b7ed58c 100644
--- a/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
+++ b/graphics/allocator/2.0/utils/gralloc1-adapter/Gralloc1On0Adapter.cpp
@@ -29,6 +29,7 @@
#include <sync/sync.h>
#include <inttypes.h>
+#include <unistd.h>
template <typename PFN, typename T>
static gralloc1_function_pointer_t asFP(T function)
diff --git a/graphics/allocator/2.0/default/Gralloc1On0Adapter.h b/graphics/allocator/2.0/utils/gralloc1-adapter/Gralloc1On0Adapter.h
similarity index 100%
rename from graphics/allocator/2.0/default/Gralloc1On0Adapter.h
rename to graphics/allocator/2.0/utils/gralloc1-adapter/Gralloc1On0Adapter.h
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.cpp b/graphics/allocator/2.0/utils/gralloc1-adapter/gralloc1-adapter.cpp
similarity index 100%
rename from graphics/allocator/2.0/default/gralloc1-adapter.cpp
rename to graphics/allocator/2.0/utils/gralloc1-adapter/gralloc1-adapter.cpp
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.h b/graphics/allocator/2.0/utils/gralloc1-adapter/gralloc1-adapter.h
similarity index 100%
rename from graphics/allocator/2.0/default/gralloc1-adapter.h
rename to graphics/allocator/2.0/utils/gralloc1-adapter/gralloc1-adapter.h
diff --git a/graphics/allocator/2.0/utils/hal/Android.bp b/graphics/allocator/2.0/utils/hal/Android.bp
new file mode 100644
index 0000000..ac642ce
--- /dev/null
+++ b/graphics/allocator/2.0/utils/hal/Android.bp
@@ -0,0 +1,14 @@
+cc_library_headers {
+ name: "android.hardware.graphics.allocator@2.0-hal",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ shared_libs: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
+ ],
+ export_shared_lib_headers: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
+ ],
+ export_include_dirs: ["include"],
+}
diff --git a/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h b/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h
new file mode 100644
index 0000000..2f3022e
--- /dev/null
+++ b/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/Allocator.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2018 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
+
+#ifndef LOG_TAG
+#warning "Allocator.h included without LOG_TAG"
+#endif
+
+#include <memory>
+
+#include <allocator-hal/2.0/AllocatorHal.h>
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace hal {
+
+using mapper::V2_0::BufferDescriptor;
+using mapper::V2_0::Error;
+
+namespace detail {
+
+// AllocatorImpl implements IAllocator on top of AllocatorHal
+template <typename IALLOCATOR, typename ALLOCATOR_HAL>
+class AllocatorImpl : public IALLOCATOR {
+ public:
+ bool init(std::unique_ptr<ALLOCATOR_HAL> hal) {
+ mHal = std::move(hal);
+ return true;
+ }
+
+ // IAllocator 2.0 interface
+ Return<void> dumpDebugInfo(IAllocator::dumpDebugInfo_cb hidl_cb) override {
+ hidl_cb(mHal->dumpDebugInfo());
+ return Void();
+ }
+
+ Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+ IAllocator::allocate_cb hidl_cb) override {
+ uint32_t stride;
+ std::vector<const native_handle_t*> buffers;
+ Error error = mHal->allocateBuffers(descriptor, count, &stride, &buffers);
+ if (error != Error::NONE) {
+ hidl_cb(error, 0, hidl_vec<hidl_handle>());
+ return Void();
+ }
+
+ hidl_vec<hidl_handle> hidlBuffers(buffers.cbegin(), buffers.cend());
+ hidl_cb(Error::NONE, stride, hidlBuffers);
+
+ // free the local handles
+ mHal->freeBuffers(buffers);
+
+ return Void();
+ }
+
+ protected:
+ std::unique_ptr<ALLOCATOR_HAL> mHal;
+};
+
+} // namespace detail
+
+using Allocator = detail::AllocatorImpl<IAllocator, AllocatorHal>;
+
+} // namespace hal
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/AllocatorHal.h b/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/AllocatorHal.h
new file mode 100644
index 0000000..dec377a
--- /dev/null
+++ b/graphics/allocator/2.0/utils/hal/include/allocator-hal/2.0/AllocatorHal.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2018 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 <string>
+#include <vector>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace hal {
+
+using mapper::V2_0::BufferDescriptor;
+using mapper::V2_0::Error;
+
+class AllocatorHal {
+ public:
+ virtual ~AllocatorHal() = default;
+
+ // dump the debug information
+ virtual std::string dumpDebugInfo() = 0;
+
+ // allocate buffers
+ virtual Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count,
+ uint32_t* outStride,
+ std::vector<const native_handle_t*>* outBuffers) = 0;
+
+ // free buffers
+ virtual void freeBuffers(const std::vector<const native_handle_t*>& buffers) = 0;
+};
+
+} // namespace hal
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/passthrough/Android.bp b/graphics/allocator/2.0/utils/passthrough/Android.bp
new file mode 100644
index 0000000..b956565
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/Android.bp
@@ -0,0 +1,29 @@
+cc_library_static {
+ name: "android.hardware.graphics.allocator@2.0-passthrough",
+ defaults: ["hidl_defaults"],
+ vendor: true,
+ srcs: [
+ "Gralloc0Hal.cpp",
+ "Gralloc1Hal.cpp",
+ "GrallocLoader.cpp",
+ ],
+ shared_libs: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
+ "libhardware",
+ ],
+ export_shared_lib_headers: [
+ "android.hardware.graphics.allocator@2.0",
+ "android.hardware.graphics.mapper@2.0",
+ "libhardware",
+ ],
+ header_libs: [
+ "android.hardware.graphics.allocator@2.0-hal",
+ "libgrallocmapperincludes",
+ ],
+ export_header_lib_headers: [
+ "android.hardware.graphics.allocator@2.0-hal",
+ ],
+ export_include_dirs: ["include"],
+ cflags: ["-DLOG_TAG=\"AllocatorHal\""],
+}
diff --git a/graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp b/graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp
new file mode 100644
index 0000000..8edb7dc
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/Gralloc0Hal.cpp
@@ -0,0 +1,141 @@
+/*
+ * 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 <allocator-passthrough/2.0/Gralloc0Hal.h>
+
+#include <string.h>
+
+#include <GrallocBufferDescriptor.h>
+#include <hardware/gralloc.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace passthrough {
+
+using mapper::V2_0::implementation::grallocDecodeBufferDescriptor;
+
+Gralloc0Hal::~Gralloc0Hal() {
+ if (mDevice) {
+ gralloc_close(mDevice);
+ }
+}
+
+bool Gralloc0Hal::initWithModule(const hw_module_t* module) {
+ int result = gralloc_open(module, &mDevice);
+ if (result) {
+ ALOGE("failed to open gralloc0 device: %s", strerror(-result));
+ mDevice = nullptr;
+ return false;
+ }
+
+ return true;
+}
+
+std::string Gralloc0Hal::dumpDebugInfo() {
+ char buf[4096] = {};
+ if (mDevice->dump) {
+ mDevice->dump(mDevice, buf, sizeof(buf));
+ buf[sizeof(buf) - 1] = '\0';
+ }
+
+ return buf;
+}
+
+Error Gralloc0Hal::allocateBuffers(const BufferDescriptor& descriptor, uint32_t count,
+ uint32_t* outStride,
+ std::vector<const native_handle_t*>* outBuffers) {
+ mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo;
+ if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+ return Error::BAD_DESCRIPTOR;
+ }
+
+ Error error = Error::NONE;
+ uint32_t stride = 0;
+ std::vector<const native_handle_t*> buffers;
+ buffers.reserve(count);
+
+ // allocate the buffers
+ for (uint32_t i = 0; i < count; i++) {
+ const native_handle_t* tmpBuffer;
+ uint32_t tmpStride;
+ error = allocateOneBuffer(descriptorInfo, &tmpBuffer, &tmpStride);
+ if (error != Error::NONE) {
+ break;
+ }
+
+ buffers.push_back(tmpBuffer);
+
+ if (stride == 0) {
+ stride = tmpStride;
+ } else if (stride != tmpStride) {
+ // non-uniform strides
+ error = Error::UNSUPPORTED;
+ break;
+ }
+ }
+
+ if (error != Error::NONE) {
+ freeBuffers(buffers);
+ return error;
+ }
+
+ *outStride = stride;
+ *outBuffers = std::move(buffers);
+
+ return Error::NONE;
+}
+
+void Gralloc0Hal::freeBuffers(const std::vector<const native_handle_t*>& buffers) {
+ for (auto buffer : buffers) {
+ int result = mDevice->free(mDevice, buffer);
+ if (result != 0) {
+ ALOGE("failed to free buffer %p: %d", buffer, result);
+ }
+ }
+}
+
+Error Gralloc0Hal::allocateOneBuffer(const mapper::V2_0::IMapper::BufferDescriptorInfo& info,
+ const native_handle_t** outBuffer, uint32_t* outStride) {
+ if (info.layerCount > 1 || (info.usage >> 32) != 0) {
+ return Error::BAD_VALUE;
+ }
+
+ const native_handle_t* buffer = nullptr;
+ int stride = 0;
+ int result = mDevice->alloc(mDevice, info.width, info.height, static_cast<int>(info.format),
+ info.usage, &buffer, &stride);
+ switch (result) {
+ case 0:
+ *outBuffer = buffer;
+ *outStride = stride;
+ return Error::NONE;
+ case -EINVAL:
+ return Error::BAD_VALUE;
+ default:
+ return Error::NO_RESOURCES;
+ }
+}
+
+} // namespace passthrough
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp b/graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp
new file mode 100644
index 0000000..e343ecd
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/Gralloc1Hal.cpp
@@ -0,0 +1,323 @@
+/*
+ * 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 <allocator-passthrough/2.0/Gralloc1Hal.h>
+
+#include <string.h>
+
+#include <GrallocBufferDescriptor.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace passthrough {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using mapper::V2_0::implementation::grallocDecodeBufferDescriptor;
+
+Gralloc1Hal::~Gralloc1Hal() {
+ if (mDevice) {
+ gralloc1_close(mDevice);
+ }
+}
+
+bool Gralloc1Hal::initWithModule(const hw_module_t* module) {
+ int result = gralloc1_open(module, &mDevice);
+ if (result) {
+ ALOGE("failed to open gralloc1 device: %s", strerror(-result));
+ mDevice = nullptr;
+ return false;
+ }
+
+ initCapabilities();
+ if (!initDispatch()) {
+ gralloc1_close(mDevice);
+ mDevice = nullptr;
+ return false;
+ }
+
+ return true;
+}
+
+void Gralloc1Hal::initCapabilities() {
+ uint32_t count = 0;
+ mDevice->getCapabilities(mDevice, &count, nullptr);
+
+ std::vector<int32_t> capabilities(count);
+ mDevice->getCapabilities(mDevice, &count, capabilities.data());
+ capabilities.resize(count);
+
+ for (auto capability : capabilities) {
+ if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) {
+ mCapabilities.layeredBuffers = true;
+ break;
+ }
+ }
+}
+
+gralloc1_function_pointer_t Gralloc1Hal::getDispatchFunction(
+ gralloc1_function_descriptor_t desc) const {
+ auto pfn = mDevice->getFunction(mDevice, desc);
+ if (!pfn) {
+ ALOGE("failed to get gralloc1 function %d", desc);
+ return nullptr;
+ }
+ return pfn;
+}
+
+bool Gralloc1Hal::initDispatch() {
+ if (!initDispatchFunction(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR, &mDispatch.createDescriptor) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR, &mDispatch.destroyDescriptor) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE, &mDispatch.setConsumerUsage) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE, &mDispatch.setProducerUsage) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate) ||
+ !initDispatchFunction(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release)) {
+ return false;
+ }
+
+ if (mCapabilities.layeredBuffers) {
+ if (!initDispatchFunction(GRALLOC1_FUNCTION_SET_LAYER_COUNT, &mDispatch.setLayerCount)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+std::string Gralloc1Hal::dumpDebugInfo() {
+ uint32_t len = 0;
+ mDispatch.dump(mDevice, &len, nullptr);
+
+ std::vector<char> buf(len + 1);
+ mDispatch.dump(mDevice, &len, buf.data());
+ buf.resize(len + 1);
+ buf[len] = '\0';
+
+ return buf.data();
+}
+
+Error Gralloc1Hal::allocateBuffers(const BufferDescriptor& descriptor, uint32_t count,
+ uint32_t* outStride,
+ std::vector<const native_handle_t*>* outBuffers) {
+ mapper::V2_0::IMapper::BufferDescriptorInfo descriptorInfo;
+ if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+ return Error::BAD_DESCRIPTOR;
+ }
+
+ gralloc1_buffer_descriptor_t desc;
+ Error error = createDescriptor(descriptorInfo, &desc);
+ if (error != Error::NONE) {
+ return error;
+ }
+
+ uint32_t stride = 0;
+ std::vector<const native_handle_t*> buffers;
+ buffers.reserve(count);
+
+ // allocate the buffers
+ for (uint32_t i = 0; i < count; i++) {
+ const native_handle_t* tmpBuffer;
+ uint32_t tmpStride;
+ error = allocateOneBuffer(desc, &tmpBuffer, &tmpStride);
+ if (error != Error::NONE) {
+ break;
+ }
+
+ buffers.push_back(tmpBuffer);
+
+ if (stride == 0) {
+ stride = tmpStride;
+ } else if (stride != tmpStride) {
+ // non-uniform strides
+ error = Error::UNSUPPORTED;
+ break;
+ }
+ }
+
+ mDispatch.destroyDescriptor(mDevice, desc);
+
+ if (error != Error::NONE) {
+ freeBuffers(buffers);
+ return error;
+ }
+
+ *outStride = stride;
+ *outBuffers = std::move(buffers);
+
+ return Error::NONE;
+}
+
+void Gralloc1Hal::freeBuffers(const std::vector<const native_handle_t*>& buffers) {
+ for (auto buffer : buffers) {
+ int32_t error = mDispatch.release(mDevice, buffer);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("failed to free buffer %p: %d", buffer, error);
+ }
+ }
+}
+
+Error Gralloc1Hal::toError(int32_t error) {
+ switch (error) {
+ case GRALLOC1_ERROR_NONE:
+ return Error::NONE;
+ case GRALLOC1_ERROR_BAD_DESCRIPTOR:
+ return Error::BAD_DESCRIPTOR;
+ case GRALLOC1_ERROR_BAD_HANDLE:
+ return Error::BAD_BUFFER;
+ case GRALLOC1_ERROR_BAD_VALUE:
+ return Error::BAD_VALUE;
+ case GRALLOC1_ERROR_NOT_SHARED:
+ return Error::NONE; // this is fine
+ case GRALLOC1_ERROR_NO_RESOURCES:
+ return Error::NO_RESOURCES;
+ case GRALLOC1_ERROR_UNDEFINED:
+ case GRALLOC1_ERROR_UNSUPPORTED:
+ default:
+ return Error::UNSUPPORTED;
+ }
+}
+
+uint64_t Gralloc1Hal::toProducerUsage(uint64_t usage) {
+ // this is potentially broken as we have no idea which private flags
+ // should be filtered out
+ uint64_t producerUsage =
+ usage & ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
+ BufferUsage::GPU_DATA_BUFFER);
+
+ switch (usage & BufferUsage::CPU_WRITE_MASK) {
+ case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+ break;
+ case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
+ break;
+ default:
+ break;
+ }
+
+ switch (usage & BufferUsage::CPU_READ_MASK) {
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
+ break;
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+ producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
+ break;
+ default:
+ break;
+ }
+
+ // BufferUsage::GPU_DATA_BUFFER is always filtered out
+
+ return producerUsage;
+}
+
+uint64_t Gralloc1Hal::toConsumerUsage(uint64_t usage) {
+ // this is potentially broken as we have no idea which private flags
+ // should be filtered out
+ uint64_t consumerUsage =
+ usage &
+ ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
+ BufferUsage::SENSOR_DIRECT_DATA | BufferUsage::GPU_DATA_BUFFER);
+
+ switch (usage & BufferUsage::CPU_READ_MASK) {
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+ consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
+ break;
+ case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+ consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
+ break;
+ default:
+ break;
+ }
+
+ // BufferUsage::SENSOR_DIRECT_DATA is always filtered out
+
+ if (usage & BufferUsage::GPU_DATA_BUFFER) {
+ consumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
+ }
+
+ return consumerUsage;
+}
+
+Error Gralloc1Hal::createDescriptor(const mapper::V2_0::IMapper::BufferDescriptorInfo& info,
+ gralloc1_buffer_descriptor_t* outDescriptor) {
+ gralloc1_buffer_descriptor_t descriptor;
+
+ int32_t error = mDispatch.createDescriptor(mDevice, &descriptor);
+
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setDimensions(mDevice, descriptor, info.width, info.height);
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setFormat(mDevice, descriptor, static_cast<int32_t>(info.format));
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ if (mCapabilities.layeredBuffers) {
+ error = mDispatch.setLayerCount(mDevice, descriptor, info.layerCount);
+ } else if (info.layerCount > 1) {
+ error = GRALLOC1_ERROR_UNSUPPORTED;
+ }
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setProducerUsage(mDevice, descriptor, toProducerUsage(info.usage));
+ }
+ if (error == GRALLOC1_ERROR_NONE) {
+ error = mDispatch.setConsumerUsage(mDevice, descriptor, toConsumerUsage(info.usage));
+ }
+
+ if (error == GRALLOC1_ERROR_NONE) {
+ *outDescriptor = descriptor;
+ } else {
+ mDispatch.destroyDescriptor(mDevice, descriptor);
+ }
+
+ return toError(error);
+}
+
+Error Gralloc1Hal::allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor,
+ const native_handle_t** outBuffer, uint32_t* outStride) {
+ const native_handle_t* buffer = nullptr;
+ int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
+ if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
+ return toError(error);
+ }
+
+ uint32_t stride = 0;
+ error = mDispatch.getStride(mDevice, buffer, &stride);
+ if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
+ mDispatch.release(mDevice, buffer);
+ return toError(error);
+ }
+
+ *outBuffer = buffer;
+ *outStride = stride;
+
+ return Error::NONE;
+}
+
+} // namespace passthrough
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp b/graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp
new file mode 100644
index 0000000..dae7a78
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/GrallocLoader.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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.
+ * 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 <allocator-passthrough/2.0/GrallocLoader.h>
+
+#include <allocator-hal/2.0/Allocator.h>
+#include <allocator-hal/2.0/AllocatorHal.h>
+#include <allocator-passthrough/2.0/Gralloc0Hal.h>
+#include <allocator-passthrough/2.0/Gralloc1Hal.h>
+#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace passthrough {
+
+const hw_module_t* GrallocLoader::loadModule() {
+ const hw_module_t* module;
+ int error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+ if (error) {
+ ALOGE("failed to get gralloc module");
+ return nullptr;
+ }
+
+ return module;
+}
+
+int GrallocLoader::getModuleMajorApiVersion(const hw_module_t* module) {
+ return (module->module_api_version >> 8) & 0xff;
+}
+
+std::unique_ptr<hal::AllocatorHal> GrallocLoader::createHal(const hw_module_t* module) {
+ int major = getModuleMajorApiVersion(module);
+ switch (major) {
+ case 1: {
+ auto hal = std::make_unique<Gralloc1Hal>();
+ return hal->initWithModule(module) ? std::move(hal) : nullptr;
+ }
+ case 0: {
+ auto hal = std::make_unique<Gralloc0Hal>();
+ return hal->initWithModule(module) ? std::move(hal) : nullptr;
+ }
+ default:
+ ALOGE("unknown gralloc module major version %d", major);
+ return nullptr;
+ }
+}
+
+IAllocator* GrallocLoader::createAllocator(std::unique_ptr<hal::AllocatorHal> hal) {
+ auto allocator = std::make_unique<hal::Allocator>();
+ return allocator->init(std::move(hal)) ? allocator.release() : nullptr;
+}
+
+} // namespace passthrough
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.h
new file mode 100644
index 0000000..8f433b0
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc0Hal.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 <allocator-hal/2.0/AllocatorHal.h>
+
+struct alloc_device_t;
+struct hw_module_t;
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace passthrough {
+
+using mapper::V2_0::BufferDescriptor;
+using mapper::V2_0::Error;
+
+class Gralloc0Hal : public virtual hal::AllocatorHal {
+ public:
+ ~Gralloc0Hal();
+ bool initWithModule(const hw_module_t* module);
+
+ std::string dumpDebugInfo() override;
+
+ Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, uint32_t* outStride,
+ std::vector<const native_handle_t*>* outBuffers) override;
+
+ void freeBuffers(const std::vector<const native_handle_t*>& buffers) override;
+
+ protected:
+ Error allocateOneBuffer(const mapper::V2_0::IMapper::BufferDescriptorInfo& info,
+ const native_handle_t** outBuffer, uint32_t* outStride);
+
+ alloc_device_t* mDevice = nullptr;
+};
+
+} // namespace passthrough
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h
new file mode 100644
index 0000000..3126e91
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/Gralloc1Hal.h
@@ -0,0 +1,96 @@
+/*
+ * 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 <allocator-hal/2.0/AllocatorHal.h>
+#include <hardware/gralloc1.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace passthrough {
+
+using mapper::V2_0::BufferDescriptor;
+using mapper::V2_0::Error;
+
+class Gralloc1Hal : public virtual hal::AllocatorHal {
+ public:
+ ~Gralloc1Hal();
+ bool initWithModule(const hw_module_t* module);
+
+ std::string dumpDebugInfo() override;
+
+ Error allocateBuffers(const BufferDescriptor& descriptor, uint32_t count, uint32_t* outStride,
+ std::vector<const native_handle_t*>* outBuffers) override;
+
+ void freeBuffers(const std::vector<const native_handle_t*>& buffers) override;
+
+ protected:
+ template <typename T>
+ bool initDispatchFunction(gralloc1_function_descriptor_t desc, T* outPfn) {
+ auto pfn = getDispatchFunction(desc);
+ if (pfn) {
+ *outPfn = reinterpret_cast<T>(pfn);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ gralloc1_function_pointer_t getDispatchFunction(gralloc1_function_descriptor_t desc) const;
+
+ virtual void initCapabilities();
+ virtual bool initDispatch();
+
+ static Error toError(int32_t error);
+ static uint64_t toProducerUsage(uint64_t usage);
+ static uint64_t toConsumerUsage(uint64_t usage);
+
+ Error createDescriptor(const mapper::V2_0::IMapper::BufferDescriptorInfo& info,
+ gralloc1_buffer_descriptor_t* outDescriptor);
+
+ Error allocateOneBuffer(gralloc1_buffer_descriptor_t descriptor,
+ const native_handle_t** outBuffer, uint32_t* outStride);
+
+ gralloc1_device_t* mDevice = nullptr;
+
+ struct {
+ bool layeredBuffers;
+ } mCapabilities = {};
+
+ struct {
+ GRALLOC1_PFN_DUMP dump;
+ GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
+ GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
+ GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
+ GRALLOC1_PFN_SET_FORMAT setFormat;
+ GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
+ GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
+ GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
+ GRALLOC1_PFN_GET_STRIDE getStride;
+ GRALLOC1_PFN_ALLOCATE allocate;
+ GRALLOC1_PFN_RELEASE release;
+ } mDispatch = {};
+};
+
+} // namespace passthrough
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h
new file mode 100644
index 0000000..a0b9503
--- /dev/null
+++ b/graphics/allocator/2.0/utils/passthrough/include/allocator-passthrough/2.0/GrallocLoader.h
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ * 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 <memory>
+
+#include <allocator-hal/2.0/AllocatorHal.h>
+
+struct hw_module_t;
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace passthrough {
+
+class GrallocLoader {
+ public:
+ static IAllocator* load() {
+ const hw_module_t* module = loadModule();
+ if (!module) {
+ return nullptr;
+ }
+ auto hal = createHal(module);
+ if (!hal) {
+ return nullptr;
+ }
+ return createAllocator(std::move(hal));
+ }
+
+ // load the gralloc module
+ static const hw_module_t* loadModule();
+
+ // return the major api version of the module
+ static int getModuleMajorApiVersion(const hw_module_t* module);
+
+ // create an AllocatorHal instance
+ static std::unique_ptr<hal::AllocatorHal> createHal(const hw_module_t* module);
+
+ // create an IAllocator instance
+ static IAllocator* createAllocator(std::unique_ptr<hal::AllocatorHal> hal);
+};
+
+} // namespace passthrough
+} // namespace V2_0
+} // namespace allocator
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index 4e6dd4f..8aa9af0 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -299,10 +299,17 @@
Error err = mHal.createLayer(display, &layer);
if (err == Error::NONE) {
std::lock_guard<std::mutex> lock(mDisplayDataMutex);
-
auto dpy = mDisplayData.find(display);
- auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
- ly->second.Buffers.resize(bufferSlotCount);
+ // The display entry may have already been removed by onHotplug.
+ if (dpy != mDisplayData.end()) {
+ auto ly = dpy->second.Layers.emplace(layer, LayerBuffers()).first;
+ ly->second.Buffers.resize(bufferSlotCount);
+ } else {
+ err = Error::BAD_DISPLAY;
+ // Note: We do not destroy the layer on this error as the hotplug
+ // disconnect invalidates the display id. The implementation should
+ // ensure all layers for the display are destroyed.
+ }
}
hidl_cb(err, layer);
@@ -316,7 +323,10 @@
std::lock_guard<std::mutex> lock(mDisplayDataMutex);
auto dpy = mDisplayData.find(display);
- dpy->second.Layers.erase(layer);
+ // The display entry may have already been removed by onHotplug.
+ if (dpy != mDisplayData.end()) {
+ dpy->second.Layers.erase(layer);
+ }
}
return err;
diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp
index 1080df1..97704bf 100644
--- a/health/2.0/Android.bp
+++ b/health/2.0/Android.bp
@@ -17,6 +17,9 @@
],
types: [
"Result",
+ "DiskStats",
+ "StorageAttribute",
+ "StorageInfo",
],
gen_java: true,
}
diff --git a/health/2.0/IHealth.hal b/health/2.0/IHealth.hal
index 3e10701..a33bb15 100644
--- a/health/2.0/IHealth.hal
+++ b/health/2.0/IHealth.hal
@@ -137,4 +137,27 @@
* @return value charge status, or UNKNOWN if not successful.
*/
getChargeStatus() generates (Result result, BatteryStatus value);
+
+ /**
+ * Get storage info.
+ *
+ * @return result SUCCESS if successful,
+ * NOT_SUPPORTED if this property is not supported,
+ * UNKNOWN other errors.
+ * @return value vector of StorageInfo structs, to be ignored if result is not
+ * SUCCESS.
+ */
+ getStorageInfo() generates (Result result, vec<StorageInfo> value);
+
+ /**
+ * Gets disk statistics (number of reads/writes processed, number of I/O
+ * operations in flight etc).
+ *
+ * @return result SUCCESS if successful,
+ * NOT_SUPPORTED if this property is not supported,
+ * UNKNOWN other errors.
+ * @return value vector of disk statistics, to be ignored if result is not SUCCESS.
+ * The mapping is index 0->sda, 1->sdb and so on.
+ */
+ getDiskStats() generates (Result result, vec<DiskStats> value);
};
diff --git a/health/2.0/default/Health.cpp b/health/2.0/default/Health.cpp
index 4710c90..96f6d70 100644
--- a/health/2.0/default/Health.cpp
+++ b/health/2.0/default/Health.cpp
@@ -1,3 +1,18 @@
+/*
+ * Copyright (C) 2018 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.health@2.0-impl"
#include <android-base/logging.h>
@@ -160,6 +175,30 @@
return Void();
}
+Return<void> Health::getStorageInfo(getStorageInfo_cb _hidl_cb) {
+ std::vector<struct StorageInfo> info;
+ get_storage_info(info);
+ hidl_vec<struct StorageInfo> info_vec(info);
+ if (!info.size()) {
+ _hidl_cb(Result::NOT_SUPPORTED, info_vec);
+ } else {
+ _hidl_cb(Result::SUCCESS, info_vec);
+ }
+ return Void();
+}
+
+Return<void> Health::getDiskStats(getDiskStats_cb _hidl_cb) {
+ std::vector<struct DiskStats> stats;
+ get_disk_stats(stats);
+ hidl_vec<struct DiskStats> stats_vec(stats);
+ if (!stats.size()) {
+ _hidl_cb(Result::NOT_SUPPORTED, stats_vec);
+ } else {
+ _hidl_cb(Result::SUCCESS, stats_vec);
+ }
+ return Void();
+}
+
void Health::serviceDied(uint64_t /* cookie */, const wp<IBase>& who) {
(void)unregisterCallbackInternal(who.promote());
}
diff --git a/health/2.0/default/include/health2/Health.h b/health/2.0/default/include/health2/Health.h
index ab42ae7..41ba9e9 100644
--- a/health/2.0/default/include/health2/Health.h
+++ b/health/2.0/default/include/health2/Health.h
@@ -9,6 +9,12 @@
#include <healthd/BatteryMonitor.h>
#include <hidl/Status.h>
+using android::hardware::health::V2_0::StorageInfo;
+using android::hardware::health::V2_0::DiskStats;
+
+void get_storage_info(std::vector<struct StorageInfo>& info);
+void get_disk_stats(std::vector<struct DiskStats>& stats);
+
namespace android {
namespace hardware {
namespace health {
@@ -44,6 +50,8 @@
Return<void> getCapacity(getCapacity_cb _hidl_cb) override;
Return<void> getEnergyCounter(getEnergyCounter_cb _hidl_cb) override;
Return<void> getChargeStatus(getChargeStatus_cb _hidl_cb) override;
+ Return<void> getStorageInfo(getStorageInfo_cb _hidl_cb) override;
+ Return<void> getDiskStats(getDiskStats_cb _hidl_cb) override;
// Methods from ::android::hidl::base::V1_0::IBase follow.
Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
diff --git a/health/2.0/libstoragehealthdefault/Android.bp b/health/2.0/libstoragehealthdefault/Android.bp
new file mode 100644
index 0000000..986e1ef
--- /dev/null
+++ b/health/2.0/libstoragehealthdefault/Android.bp
@@ -0,0 +1,11 @@
+// Copyright 2018 The Android Open Source Project
+
+cc_library_static {
+ srcs: ["StorageHealthDefault.cpp"],
+ name: "libhealthstoragedefault",
+ vendor_available: true,
+ cflags: ["-Werror"],
+ shared_libs: [
+ "android.hardware.health@2.0",
+ ],
+}
diff --git a/health/2.0/libstoragehealthdefault/StorageHealthDefault.cpp b/health/2.0/libstoragehealthdefault/StorageHealthDefault.cpp
new file mode 100644
index 0000000..aba6cc3
--- /dev/null
+++ b/health/2.0/libstoragehealthdefault/StorageHealthDefault.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2018 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 "include/StorageHealthDefault.h"
+
+void get_storage_info(std::vector<struct StorageInfo>&) {
+ // Use defaults.
+}
+
+void get_disk_stats(std::vector<struct DiskStats>&) {
+ // Use defaults
+}
diff --git a/health/2.0/libstoragehealthdefault/include/StorageHealthDefault.h b/health/2.0/libstoragehealthdefault/include/StorageHealthDefault.h
new file mode 100644
index 0000000..85eb210
--- /dev/null
+++ b/health/2.0/libstoragehealthdefault/include/StorageHealthDefault.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2018 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_HEALTH_V2_0_STORAGE_HEALTH_H
+#define ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
+
+#include <android/hardware/health/2.0/types.h>
+
+using android::hardware::health::V2_0::StorageInfo;
+using android::hardware::health::V2_0::DiskStats;
+
+/*
+ * Get storage information.
+ */
+void get_storage_info(std::vector<struct StorageInfo>& info);
+
+/*
+ * Get disk statistics.
+ */
+void get_disk_stats(std::vector<struct DiskStats>& stats);
+
+#endif // ANDROID_HARDWARE_HEALTH_V2_0_STORAGE_HEALTH_H
diff --git a/health/2.0/types.hal b/health/2.0/types.hal
index 8c6d88f..4e7a081 100644
--- a/health/2.0/types.hal
+++ b/health/2.0/types.hal
@@ -26,3 +26,101 @@
NOT_FOUND,
CALLBACK_DIED,
};
+
+/*
+ * Identification attributes for a storage device.
+ */
+struct StorageAttribute {
+ /**
+ * Set to true if internal storage
+ */
+ bool isInternal;
+ /**
+ * Set to true if this is the boot device.
+ */
+ bool isBootDevice;
+ /**
+ * Name of the storage device.
+ */
+ string name;
+};
+
+/*
+ * Information on storage device including life time estimates, end of life
+ * information and other attributes.
+ */
+struct StorageInfo {
+ /**
+ * Attributes of the storage device whose info is contained by the struct.
+ */
+ StorageAttribute attr;
+ /**
+ * pre-eol (end of life) information. Follows JEDEC standard No.84-B50.
+ */
+ uint16_t eol;
+ /**
+ * device life time estimation (type A). Follows JEDEC standard No.84-B50.
+ */
+ uint16_t lifetimeA;
+ /**
+ * device life time estimation (type B). Follows JEDEC standard No.84-B50.
+ */
+ uint16_t lifetimeB;
+ /**
+ * version string
+ */
+ string version;
+};
+/*
+ * Disk statistics since boot.
+ */
+struct DiskStats {
+ /**
+ * Number of reads processed.
+ */
+ uint64_t reads;
+ /**
+ * number of read I/Os merged with in-queue I/Os.
+ */
+ uint64_t readMerges;
+ /**
+ * number of sectors read.
+ */
+ uint64_t readSectors;
+ /**
+ * total wait time for read requests.
+ */
+ uint64_t readTicks;
+ /**
+ * number of writes processed.
+ */
+ uint64_t writes;
+ /**
+ * number of writes merged with in-queue I/Os.
+ */
+ uint64_t writeMerges;
+ /**
+ * number of sectors written.
+ */
+ uint64_t writeSectors;
+ /**
+ * total wait time for write requests.
+ */
+ uint64_t writeTicks;
+ /**
+ * number of I/Os currently in flight.
+ */
+ uint64_t ioInFlight;
+ /**
+ * total time this block device has been active.
+ */
+ uint64_t ioTicks;
+ /**
+ * total wait time for all requests.
+ */
+ uint64_t ioInQueue;
+ /**
+ * Attributes of the memory device.
+ */
+ StorageAttribute attr;
+};
diff --git a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
index bf8548c..b2c6160 100644
--- a/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
+++ b/health/2.0/vts/functional/VtsHalHealthV2_0TargetTest.cpp
@@ -180,6 +180,29 @@
return AssertionFailure() << "Result is not SUCCESS or NOT_SUPPORTED: " << toString(res);
}
+bool verifyStorageInfo(const hidl_vec<struct StorageInfo>& info) {
+ for (size_t i = 0; i < info.size(); i++) {
+ if (!(0 <= info[i].eol && info[i].eol <= 3 && 0 <= info[i].lifetimeA &&
+ info[i].lifetimeA <= 0x0B && 0 <= info[i].lifetimeB && info[i].lifetimeB <= 0x0B)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool verifyDiskStats(const hidl_vec<struct DiskStats>& stats) {
+ for (size_t i = 0; i < stats.size(); i++) {
+ if (!(stats[i].reads > 0 && stats[i].readMerges > 0 && stats[i].readSectors > 0 &&
+ stats[i].readTicks > 0 && stats[i].writes > 0 && stats[i].writeMerges > 0 &&
+ stats[i].writeSectors > 0 && stats[i].writeTicks > 0 && stats[i].ioTicks > 0)) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
TEST_F(HealthHidlTest, Properties) {
EXPECT_OK(mHealth->getChargeCounter([](auto result, auto value) {
EXPECT_VALID_OR_UNSUPPORTED_PROP(result, std::to_string(value), value > 0);
@@ -202,6 +225,12 @@
value == BatteryStatus::CHARGING || value == BatteryStatus::DISCHARGING ||
value == BatteryStatus::NOT_CHARGING || value == BatteryStatus::FULL);
}));
+ EXPECT_OK(mHealth->getStorageInfo([](auto result, auto& value) {
+ EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), (verifyStorageInfo(value)));
+ }));
+ EXPECT_OK(mHealth->getDiskStats([](auto result, auto& value) {
+ EXPECT_VALID_OR_UNSUPPORTED_PROP(result, toString(value), verifyDiskStats(value));
+ }));
}
} // namespace V2_0
diff --git a/keymaster/4.0/types.hal b/keymaster/4.0/types.hal
index 0c890bd..fcc51fd 100644
--- a/keymaster/4.0/types.hal
+++ b/keymaster/4.0/types.hal
@@ -136,6 +136,51 @@
* if device is still on-body (requires secure
* on-body sensor. */
+ /**
+ * TRUSTED_USER_PRESENCE_REQUIRED is an optional feature that specifies that this key must be
+ * unusable except when the user has provided proof of physical presence. Proof of physical
+ * presence must be a signal that cannot be triggered by an attacker who doesn't have one of:
+ *
+ * a) Physical control of the device or
+ *
+ * b) Control of the secure environment that holds the key.
+ *
+ * For instance, proof of user identity may be considered proof of presence if it meets the
+ * requirements. However, proof of identity established in one security domain (e.g. TEE) does
+ * not constitute proof of presence in another security domain (e.g. StrongBox), and no
+ * mechanism analogous to the authentication token is defined for communicating proof of
+ * presence across security domains.
+ *
+ * Some examples:
+ *
+ * A hardware button hardwired to a pin on a StrongBox device in such a way that nothing
+ * other than a button press can trigger the signal constitutes proof of physical presence
+ * for StrongBox keys.
+ *
+ * Fingerprint authentication provides proof of presence (and identity) for TEE keys if the
+ * TEE has exclusive control of the fingerprint scanner and performs fingerprint matching.
+ *
+ * Password authentication does not provide proof of presence to either TEE or StrongBox,
+ * even if TEE or StrongBox does the password matching, because password input is handled by
+ * the non-secure world, which means an attacker who has compromised Android can spoof
+ * password authentication.
+ *
+ * Note that no mechanism is defined for delivering proof of presence to Keymaster,
+ * except perhaps as implied by an auth token. This means that Keymaster must be able to check
+ * proof of presence some other way. Further, the proof of presence must be performed between
+ * begin() and the first call to update() or finish(). If the first update() or the finish()
+ * call is made without proof of presence, the keymaster method must return
+ * ErrorCode::PROOF_OF_PRESENCE_REQUIRED and abort the operation. The caller must delay the
+ * update() or finish() call until proof of presence has been provided, which means the caller
+ * must also have some mechanism for verifying that the proof has been provided.
+ *
+ * Only one operation requiring TUP may be in flight at a time. If begin() has already been
+ * called on one key with TRUSTED_USER_PRESENCE_REQUIRED, and another begin() comes in for that
+ * key or another with TRUSTED_USER_PRESENCE_REQUIRED, Keymaster must return
+ * ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED.
+ */
+ TRUSTED_USER_PRESENCE_REQUIRED = TagType:BOOL | 507,
+
/* Application access control */
APPLICATION_ID = TagType:BYTES | 601, /* Byte string identifying the authorized application. */
@@ -381,6 +426,8 @@
CANNOT_ATTEST_IDS = -66,
ROLLBACK_RESISTANCE_UNAVAILABLE = -67,
HARDWARE_TYPE_UNAVAILABLE = -68,
+ PROOF_OF_PRESENCE_REQUIRED = -69,
+ CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = -70,
UNIMPLEMENTED = -100,
VERSION_MISMATCH = -101,
diff --git a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
index c8858de..060d904 100644
--- a/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
+++ b/keymaster/4.0/vts/functional/keymaster_hidl_hal_test.cpp
@@ -75,6 +75,7 @@
case Tag::ALLOW_WHILE_ON_BODY:
case Tag::ROLLBACK_RESISTANCE:
case Tag::RESET_SINCE_ID_ROTATION:
+ case Tag::TRUSTED_USER_PRESENCE_REQUIRED:
return true;
/* Integer tags */
diff --git a/radio/1.2/IRadioIndication.hal b/radio/1.2/IRadioIndication.hal
index 4aae74d..e87bb5b 100644
--- a/radio/1.2/IRadioIndication.hal
+++ b/radio/1.2/IRadioIndication.hal
@@ -37,4 +37,13 @@
* the device
*/
oneway simSlotsStatusChanged(RadioIndicationType type, vec<SimSlotStatus> slotStatus);
+
+ /**
+ * Request all of the current cell information known to the radio.
+ * Same information as returned by getCellInfoList() in 1.0::IRadio.
+ *
+ * @param type Type of radio indication
+ * @param records Current cell information known to radio
+ */
+ oneway cellInfoList_1_2(RadioIndicationType type, vec<CellInfo> records);
};
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index adba054..8d9cfc6 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -387,7 +387,8 @@
std::tie(legacy_status, legacy_logger_feature_set) =
legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
- return {createWifiStatusFromLegacyError(legacy_status), 0};
+ // some devices don't support querying logger feature set
+ legacy_logger_feature_set = 0;
}
uint32_t hidl_caps;
if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(