Merge "power/stats: Add EnergyConsumerAttribution interface"
diff --git a/contexthub/1.1/default/Contexthub.cpp b/contexthub/1.1/default/Contexthub.cpp
index e7fde84..2d4fbae 100644
--- a/contexthub/1.1/default/Contexthub.cpp
+++ b/contexthub/1.1/default/Contexthub.cpp
@@ -23,10 +23,29 @@
 namespace V1_1 {
 namespace implementation {
 
+using ::android::hardware::contexthub::V1_0::Result;
+
 Return<void> Contexthub::onSettingChanged(Setting /*setting*/, SettingValue /*newValue*/) {
     return Void();
 }
 
+Return<Result> Contexthub::registerCallback(uint32_t hubId, const sp<IContexthubCallback>& cb) {
+    if (hubId == kMockHubId) {
+        mCallback = cb;
+        return Result::OK;
+    }
+    return Result::BAD_PARAMS;
+}
+
+Return<Result> Contexthub::queryApps(uint32_t hubId) {
+    if (hubId == kMockHubId && mCallback != nullptr) {
+        std::vector<HubAppInfo> nanoapps;
+        mCallback->handleAppsInfo(nanoapps);
+        return Result::OK;
+    }
+    return Result::BAD_PARAMS;
+}
+
 }  // namespace implementation
 }  // namespace V1_1
 }  // namespace contexthub
diff --git a/contexthub/1.1/default/Contexthub.h b/contexthub/1.1/default/Contexthub.h
index 1468fcf..648749e 100644
--- a/contexthub/1.1/default/Contexthub.h
+++ b/contexthub/1.1/default/Contexthub.h
@@ -27,9 +27,19 @@
 
 class Contexthub
     : public ::android::hardware::contexthub::V1_X::implementation::ContextHub<IContexthub> {
+    using Result = ::android::hardware::contexthub::V1_0::Result;
+
   public:
+    // Methods from V1_0::IContexthub
+    Return<Result> registerCallback(uint32_t hubId, const sp<IContexthubCallback>& cb) override;
+
+    Return<Result> queryApps(uint32_t hubId) override;
+
     // Methods from V1_1::IContexthub
     Return<void> onSettingChanged(Setting setting, SettingValue newValue) override;
+
+  private:
+    sp<IContexthubCallback> mCallback;
 };
 
 }  // namespace implementation
diff --git a/contexthub/1.2/Android.bp b/contexthub/1.2/Android.bp
index e819482..9722a97 100644
--- a/contexthub/1.2/Android.bp
+++ b/contexthub/1.2/Android.bp
@@ -6,6 +6,7 @@
     srcs: [
         "types.hal",
         "IContexthub.hal",
+        "IContexthubCallback.hal",
     ],
     interfaces: [
         "android.hardware.contexthub@1.0",
diff --git a/contexthub/1.2/IContexthub.hal b/contexthub/1.2/IContexthub.hal
index 819fc1d..3488b74 100644
--- a/contexthub/1.2/IContexthub.hal
+++ b/contexthub/1.2/IContexthub.hal
@@ -16,11 +16,41 @@
 
 package android.hardware.contexthub@1.2;
 
+import @1.0::Result;
 import @1.1::IContexthub;
 import @1.1::SettingValue;
+import IContexthubCallback;
 
 interface IContexthub extends @1.1::IContexthub {
     /**
+     * Register a callback for the HAL implementation to send asynchronous
+     * messages to the service from a context hub. There can be a maximum of
+     * one callback registered with the HAL. A call to this function when a
+     * callback has already been registered must override the previous
+     * registration.
+     *
+     * @param hubId    identifier for the hub
+     * @param callback an implementation of the IContextHubCallbacks
+     *
+     * @return result OK on success
+     *                BAD_VALUE if parameters are not valid
+     *
+     */
+    registerCallback_1_2(uint32_t hubId, IContexthubCallback cb) generates (Result result);
+
+    /**
+     * Send a message to a hub
+     *
+     * @param hubId identifier for hub to send message to
+     * @param msg   message to be sent
+     *
+     * @return result OK if successful, error code otherwise
+     *                BAD_VALUE if parameters are not valid
+     *                TRANSACTION_FAILED if message send failed
+     */
+    sendMessageToHub_1_2(uint32_t hubId, ContextHubMsg msg) generates (Result result);
+
+    /**
      * Notification sent by the framework to indicate that the user
      * has changed a setting.
      *
diff --git a/contexthub/1.2/IContexthubCallback.hal b/contexthub/1.2/IContexthubCallback.hal
new file mode 100644
index 0000000..0236160
--- /dev/null
+++ b/contexthub/1.2/IContexthubCallback.hal
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2020 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.contexthub@1.2;
+
+import @1.0::IContexthubCallback;
+
+interface IContexthubCallback extends @1.0::IContexthubCallback {
+    /**
+     * This callback is passed by the Contexthub service to the HAL
+     * implementation to allow the HAL to send asynchronous messages back
+     * to the service and registered clients of the ContextHub service.
+     *
+     * @param msg message that should be delivered to host app clients
+     *
+     */
+    handleClientMsg_1_2(ContextHubMsg msg);
+
+    /**
+     * This callback is passed by the Contexthub service to the HAL
+     * implementation to allow the HAL to send information about the
+     * currently loaded and active nanoapps on the hub.
+     *
+     * @param appInfo vector of HubAppinfo structure for each nanoApp
+     *                on the hub that can be enabled, disabled and
+     *                unloaded by the service. Any nanoApps that cannot
+     *                be controlled by the service must not be reported.
+     *                All nanoApps that can be controlled by the service
+     *                must be reported.
+     */
+    handleAppsInfo_1_2(vec<HubAppInfo> appInfo);
+};
diff --git a/contexthub/1.2/default/Android.bp b/contexthub/1.2/default/Android.bp
index 49b54fc..0a31325 100644
--- a/contexthub/1.2/default/Android.bp
+++ b/contexthub/1.2/default/Android.bp
@@ -41,6 +41,7 @@
     ],
     header_libs: [
         "android.hardware.contexthub@1.X-common-impl",
+        "android.hardware.contexthub@1.X-common-utils",
     ],
     vintf_fragments: ["android.hardware.contexthub@1.2.xml"],
 }
diff --git a/contexthub/1.2/default/Contexthub.cpp b/contexthub/1.2/default/Contexthub.cpp
index d7ac7bf..db0c5bc 100644
--- a/contexthub/1.2/default/Contexthub.cpp
+++ b/contexthub/1.2/default/Contexthub.cpp
@@ -23,6 +23,43 @@
 namespace V1_2 {
 namespace implementation {
 
+using ::android::hardware::contexthub::V1_0::Result;
+using ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperV1_0;
+using ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperV1_2;
+
+Return<Result> Contexthub::registerCallback(uint32_t hubId,
+                                            const sp<V1_0::IContexthubCallback>& cb) {
+    if (hubId == kMockHubId) {
+        mCallback = new IContextHubCallbackWrapperV1_0(cb);
+        return Result::OK;
+    }
+    return Result::BAD_PARAMS;
+}
+
+Return<Result> Contexthub::queryApps(uint32_t hubId) {
+    if (hubId == kMockHubId && mCallback != nullptr) {
+        std::vector<V1_2::HubAppInfo> nanoapps;
+        mCallback->handleAppsInfo(nanoapps);
+        return Result::OK;
+    }
+    return Result::BAD_PARAMS;
+}
+
+Return<Result> Contexthub::registerCallback_1_2(uint32_t hubId,
+                                                const sp<V1_2::IContexthubCallback>& cb) {
+    if (hubId == kMockHubId) {
+        mCallback = new IContextHubCallbackWrapperV1_2(cb);
+        return Result::OK;
+    }
+    return Result::BAD_PARAMS;
+}
+
+// We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS
+Return<Result> Contexthub::sendMessageToHub_1_2(uint32_t /* hubId */,
+                                                const ContextHubMsg& /* msg */) {
+    return Result::BAD_PARAMS;
+}
+
 Return<void> Contexthub::onSettingChanged(SettingV1_1 /*setting*/, SettingValue /*newValue*/) {
     return Void();
 }
diff --git a/contexthub/1.2/default/Contexthub.h b/contexthub/1.2/default/Contexthub.h
index d2f8d69..8b89824 100644
--- a/contexthub/1.2/default/Contexthub.h
+++ b/contexthub/1.2/default/Contexthub.h
@@ -16,6 +16,7 @@
 #pragma once
 
 #include "ContextHub.h"
+#include "IContextHubCallbackWrapper.h"
 
 #include <android/hardware/contexthub/1.2/IContexthub.h>
 
@@ -27,15 +28,34 @@
 
 class Contexthub
     : public ::android::hardware::contexthub::V1_X::implementation::ContextHub<IContexthub> {
+    using ContextHubMsg = ::android::hardware::contexthub::V1_2::ContextHubMsg;
+    using IContexthubCallback = ::android::hardware::contexthub::V1_2::IContexthubCallback;
+    using IContextHubCallbackWrapperBase =
+            ::android::hardware::contexthub::V1_X::implementation::IContextHubCallbackWrapperBase;
+    using Result = ::android::hardware::contexthub::V1_0::Result;
     using SettingValue = ::android::hardware::contexthub::V1_1::SettingValue;
     using SettingV1_1 = ::android::hardware::contexthub::V1_1::Setting;
 
   public:
+    // Methods from V1_0::IContexthub
+    Return<Result> registerCallback(uint32_t hubId,
+                                    const sp<V1_0::IContexthubCallback>& cb) override;
+
+    Return<Result> queryApps(uint32_t hubId) override;
+
     // Methods from V1_1::IContexthub
     Return<void> onSettingChanged(SettingV1_1 setting, SettingValue newValue) override;
 
     // Methods from V1_2::IContexthub
     Return<void> onSettingChanged_1_2(Setting setting, SettingValue newValue) override;
+
+    Return<Result> registerCallback_1_2(uint32_t hubId,
+                                        const sp<V1_2::IContexthubCallback>& cb) override;
+
+    Return<Result> sendMessageToHub_1_2(uint32_t hubId, const ContextHubMsg& msg) override;
+
+  private:
+    sp<IContextHubCallbackWrapperBase> mCallback;
 };
 
 }  // namespace implementation
diff --git a/contexthub/1.2/types.hal b/contexthub/1.2/types.hal
index 38f9f7a..e6c8acc 100644
--- a/contexthub/1.2/types.hal
+++ b/contexthub/1.2/types.hal
@@ -16,6 +16,8 @@
 
 package android.hardware.contexthub@1.2;
 
+import @1.0::ContextHubMsg;
+import @1.0::HubAppInfo;
 import @1.1::Setting;
 
 /**
@@ -32,3 +34,36 @@
     WIFI_AVAILABLE,
     AIRPLANE_MODE,
 };
+
+struct ContextHubMsg {
+    @1.0::ContextHubMsg msg_1_0;
+
+    /**
+     * The list of Android permissions that the sender of this message has at
+     * the time the message was sent.
+     *
+     * The HAL MUST drop messages to nanoapps if this list of permissions is not
+     * a superset of those of the receiving nanoapp(s).
+     *
+     * The framework MUST drop messages to host apps that don't have a superset
+     * of the permissions that the sending nanoapp is using.
+     */
+    vec<string> permissions;
+};
+
+struct HubAppInfo {
+    @1.0::HubAppInfo info_1_0;
+
+    /**
+     * The list of Android permissions used by this nanoapp. This list MUST
+     * correspond to the permissions required for an equivalent Android app to
+     * sample similar signals through the Android framework.
+     *
+     * For example, if a nanoapp used location-based signals, the permissions
+     * list MUST contains android.permission.ACCESS_FINE_LOCATION and
+     * android.permission.ACCESS_BACKGROUND_LOCATION. If it were to also list to
+     * audio data, it would require adding android.permission.RECORD_AUDIO to
+     * this list.
+     */
+    vec<string> permissions;
+};
diff --git a/contexthub/common/default/1.X/ContextHub.h b/contexthub/common/default/1.X/ContextHub.h
index 73d0631..00f74af 100644
--- a/contexthub/common/default/1.X/ContextHub.h
+++ b/contexthub/common/default/1.X/ContextHub.h
@@ -60,14 +60,6 @@
         return Void();
     }
 
-    Return<Result> registerCallback(uint32_t hubId, const sp<IContexthubCallback>& cb) override {
-        if (hubId == kMockHubId) {
-            mCallback = cb;
-            return Result::OK;
-        }
-        return Result::BAD_PARAMS;
-    }
-
     // We don't expose any nanoapps, therefore all nanoapp-related API calls return with BAD_PARAMS
     Return<Result> sendMessageToHub(uint32_t /*hubId*/, const ContextHubMsg& /*msg*/) override {
         return Result::BAD_PARAMS;
@@ -93,19 +85,8 @@
         return Result::BAD_PARAMS;
     }
 
-    Return<Result> queryApps(uint32_t hubId) override {
-        if (hubId == kMockHubId && mCallback != nullptr) {
-            std::vector<HubAppInfo> nanoapps;
-            mCallback->handleAppsInfo(nanoapps);
-            return Result::OK;
-        }
-        return Result::BAD_PARAMS;
-    }
-
-  private:
+  protected:
     static constexpr uint32_t kMockHubId = 0;
-
-    sp<IContexthubCallback> mCallback;
 };
 
 }  // namespace implementation
diff --git a/contexthub/common/default/1.X/OWNERS b/contexthub/common/default/1.X/OWNERS
new file mode 100644
index 0000000..90c2330
--- /dev/null
+++ b/contexthub/common/default/1.X/OWNERS
@@ -0,0 +1,3 @@
+arthuri@google.com
+bduddie@google.com
+stange@google.com
diff --git a/contexthub/common/default/1.X/utils/Android.bp b/contexthub/common/default/1.X/utils/Android.bp
new file mode 100644
index 0000000..c74b647
--- /dev/null
+++ b/contexthub/common/default/1.X/utils/Android.bp
@@ -0,0 +1,30 @@
+//
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_library_headers {
+    name: "android.hardware.contexthub@1.X-common-utils",
+    vendor_available: true,
+    defaults: ["hidl_defaults"],
+    export_include_dirs: ["."],
+    shared_libs: [
+        "android.hardware.contexthub@1.0",
+        "android.hardware.contexthub@1.1",
+        "android.hardware.contexthub@1.2",
+        "libbinder",
+        "libcutils",
+        "libhidlbase",
+        "libutils",
+    ],
+}
diff --git a/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h
new file mode 100644
index 0000000..df78438
--- /dev/null
+++ b/contexthub/common/default/1.X/utils/IContextHubCallbackWrapper.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2020 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_CONTEXTHUB_V1_X_ICONTEXTHUBCALLBACKWRAPPER_H
+#define ANDROID_HARDWARE_CONTEXTHUB_V1_X_ICONTEXTHUBCALLBACKWRAPPER_H
+
+#include "android/hardware/contexthub/1.0/IContexthub.h"
+#include "android/hardware/contexthub/1.0/IContexthubCallback.h"
+#include "android/hardware/contexthub/1.0/types.h"
+#include "android/hardware/contexthub/1.2/IContexthubCallback.h"
+#include "android/hardware/contexthub/1.2/types.h"
+
+#include <utils/LightRefBase.h>
+
+#include <cassert>
+
+namespace android {
+namespace hardware {
+namespace contexthub {
+namespace V1_X {
+namespace implementation {
+
+inline V1_0::ContextHubMsg convertToOldMsg(V1_2::ContextHubMsg msg) {
+    return msg.msg_1_0;
+}
+
+inline hidl_vec<V1_0::HubAppInfo> convertToOldAppInfo(hidl_vec<V1_2::HubAppInfo> appInfos) {
+    hidl_vec<V1_0::HubAppInfo> convertedInfo(appInfos.size());
+    for (int i = 0; i < appInfos.size(); ++i) {
+        convertedInfo[i] = appInfos[i].info_1_0;
+    }
+
+    return convertedInfo;
+}
+
+/**
+ * The IContexthubCallback classes below abstract away the common logic between both the V1.0, and
+ * V1.2 versions of the Contexthub HAL callback interface. This allows users of these classes to
+ * only care about the HAL version at init time and then interact with either version of the
+ * callback without worrying about the class type by utilizing the base class.
+ */
+class IContextHubCallbackWrapperBase : public VirtualLightRefBase {
+  public:
+    virtual Return<void> handleClientMsg(V1_2::ContextHubMsg msg) = 0;
+
+    virtual Return<void> handleTxnResult(uint32_t txnId, V1_0::TransactionResult result) = 0;
+
+    virtual Return<void> handleHubEvent(V1_0::AsyncEventType evt) = 0;
+
+    virtual Return<void> handleAppAbort(uint64_t appId, uint32_t abortCode) = 0;
+
+    virtual Return<void> handleAppsInfo(hidl_vec<V1_2::HubAppInfo> appInfo) = 0;
+};
+
+template <typename T>
+class ContextHubCallbackWrapper : public IContextHubCallbackWrapperBase {
+  public:
+    ContextHubCallbackWrapper(sp<T> callback) : mCallback(callback){};
+
+    virtual Return<void> handleClientMsg(V1_2::ContextHubMsg msg) override {
+        return mCallback->handleClientMsg(convertToOldMsg(msg));
+    }
+
+    virtual Return<void> handleTxnResult(uint32_t txnId, V1_0::TransactionResult result) override {
+        return mCallback->handleTxnResult(txnId, result);
+    }
+
+    virtual Return<void> handleHubEvent(V1_0::AsyncEventType evt) override {
+        return mCallback->handleHubEvent(evt);
+    }
+
+    virtual Return<void> handleAppAbort(uint64_t appId, uint32_t abortCode) override {
+        return mCallback->handleAppAbort(appId, abortCode);
+    }
+
+    virtual Return<void> handleAppsInfo(hidl_vec<V1_2::HubAppInfo> appInfo) override {
+        return mCallback->handleAppsInfo(convertToOldAppInfo(appInfo));
+    }
+
+  protected:
+    sp<T> mCallback;
+};
+
+class IContextHubCallbackWrapperV1_0 : public ContextHubCallbackWrapper<V1_0::IContexthubCallback> {
+  public:
+    IContextHubCallbackWrapperV1_0(sp<V1_0::IContexthubCallback> callback)
+        : ContextHubCallbackWrapper(callback){};
+};
+
+class IContextHubCallbackWrapperV1_2 : public ContextHubCallbackWrapper<V1_2::IContexthubCallback> {
+  public:
+    IContextHubCallbackWrapperV1_2(sp<V1_2::IContexthubCallback> callback)
+        : ContextHubCallbackWrapper(callback){};
+
+    Return<void> handleClientMsg(V1_2::ContextHubMsg msg) override {
+        return mCallback->handleClientMsg_1_2(msg);
+    }
+
+    Return<void> handleAppsInfo(hidl_vec<V1_2::HubAppInfo> appInfo) override {
+        return mCallback->handleAppsInfo_1_2(appInfo);
+    }
+};
+
+}  // namespace implementation
+}  // namespace V1_X
+}  // namespace contexthub
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_CONTEXTHUB_V1_X_ICONTEXTHUBCALLBACKWRAPPER_H
\ No newline at end of file
diff --git a/current.txt b/current.txt
index 8623fc0..0b88a7a 100644
--- a/current.txt
+++ b/current.txt
@@ -787,6 +787,4 @@
 
 # HALs released in Android S
 # NOTE: waiting to freeze HALs until later in the release
-# NOTE: new HALs are recommended to be in AIDL
-6e64b33f1b720b66b0deb5e08dee37a99deaa94e2e9ebf7806703cabab56e21d android.hardware.contexthub@1.2::IContexthub
-3fb83f4539cab2c7bf9fdbecf7265d1c1dd6e8de9694046fe512b493c127ccea android.hardware.contexthub@1.2::types
+# NOTE: new HALs are recommended to be in AIDL
\ No newline at end of file