power: PowerHAL support for HIDL interfaces.

Bug: 31177288
Change-Id: I3ce5a71958f47d26855513cf7523922e80dd25d2
Signed-off-by: Ruchi Kandoi <kandoiruchi@google.com>
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index 9bbe8f9..c153184 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -53,24 +53,6 @@
      */
     public static final int WAKEFULNESS_DOZING = 3;
 
-
-    /**
-     * Power hint:
-     * Interaction: The user is interacting with the device. The corresponding data field must be
-     * the expected duration of the interaction, or 0 if unknown.
-     *
-     * Sustained Performance Mode: The corresponding data field must be Enable/Disable
-     * Sustained Performance Mode.
-     *
-     * Launch: This is specific for activity launching. The corresponding data field must be
-     * the expected duration of the required boost, or 0 if unknown.
-     *
-     * These must be kept in sync with the values in hardware/libhardware/include/hardware/power.h
-     */
-    public static final int POWER_HINT_INTERACTION = 2;
-    public static final int POWER_HINT_SUSTAINED_PERFORMANCE_MODE = 6;
-    public static final int POWER_HINT_LAUNCH = 8;
-
     public static String wakefulnessToString(int wakefulness) {
         switch (wakefulness) {
             case WAKEFULNESS_ASLEEP:
@@ -169,5 +151,9 @@
 
     public abstract void uidGone(int uid);
 
+    /**
+     * The hintId sent through this method should be in-line with the
+     * PowerHint defined in android/hardware/power/<version 1.0 & up>/IPower.h
+     */
     public abstract void powerHint(int hintId, int data);
 }
diff --git a/services/core/Android.mk b/services/core/Android.mk
index 58f2074..fedce0c 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -17,7 +17,8 @@
 LOCAL_AIDL_INCLUDES += \
     system/netd/server/binder
 
-LOCAL_JAVA_LIBRARIES := services.net telephony-common
+LOCAL_JAVA_LIBRARIES := services.net telephony-common \
+    android.hardware.power@1.0-java
 LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
 
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 028c6ac..4fa507c 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -98,6 +98,7 @@
 import android.content.pm.UserInfo;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.hardware.power.V1_0.PowerHint;
 import android.os.Binder;
 import android.os.Bundle;
 import android.os.IBinder;
@@ -1002,7 +1003,7 @@
                 curTop.task != null && mStartActivity != null &&
                 curTop.task != mStartActivity.task )) &&
                 mService.mLocalPowerManager != null) {
-            mService.mLocalPowerManager.powerHint(PowerManagerInternal.POWER_HINT_LAUNCH, 1);
+            mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 1);
             mPowerHintSent = true;
         }
     }
@@ -1010,7 +1011,7 @@
     void sendPowerHintForLaunchEndIfNeeded() {
         // Trigger launch power hint if activity is launched
         if (mPowerHintSent && mService.mLocalPowerManager != null) {
-            mService.mLocalPowerManager.powerHint(PowerManagerInternal.POWER_HINT_LAUNCH, 0);
+            mService.mLocalPowerManager.powerHint(PowerHint.LAUNCH, 0);
             mPowerHintSent = false;
         }
     }
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index b3430c6..55c28c1 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -72,6 +72,7 @@
 import android.hardware.hdmi.HdmiPlaybackClient;
 import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback;
 import android.hardware.input.InputManagerInternal;
+import android.hardware.power.V1_0.PowerHint;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.AudioSystem;
@@ -900,7 +901,7 @@
             @Override
             public void run() {
                 // send interaction hint to improve redraw performance
-                mPowerManagerInternal.powerHint(PowerManagerInternal.POWER_HINT_INTERACTION, 0);
+                mPowerManagerInternal.powerHint(PowerHint.INTERACTION, 0);
                 updateRotation(false);
             }
         };
@@ -1831,7 +1832,7 @@
                     public void onFling(int duration) {
                         if (mPowerManagerInternal != null) {
                             mPowerManagerInternal.powerHint(
-                                    PowerManagerInternal.POWER_HINT_INTERACTION, duration);
+                                    PowerHint.INTERACTION, duration);
                         }
                     }
                     @Override
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 7576cddad..706828b 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -31,6 +31,7 @@
 import android.hardware.SystemSensorManager;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
+import android.hardware.power.V1_0.PowerHint;
 import android.net.Uri;
 import android.os.BatteryManager;
 import android.os.BatteryManagerInternal;
@@ -84,7 +85,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 
-import static android.os.PowerManagerInternal.POWER_HINT_INTERACTION;
 import static android.os.PowerManagerInternal.WAKEFULNESS_ASLEEP;
 import static android.os.PowerManagerInternal.WAKEFULNESS_AWAKE;
 import static android.os.PowerManagerInternal.WAKEFULNESS_DOZING;
@@ -163,10 +163,6 @@
     // How long a partial wake lock must be held until we consider it a long wake lock.
     static final long MIN_LONG_WAKE_CHECK_INTERVAL = 60*1000;
 
-    // Power hints defined in hardware/libhardware/include/hardware/power.h.
-    private static final int POWER_HINT_LOW_POWER = 5;
-    private static final int POWER_HINT_VR_MODE = 7;
-
     // Power features defined in hardware/libhardware/include/hardware/power.h.
     private static final int POWER_FEATURE_DOUBLE_TAP_TO_WAKE = 1;
 
@@ -826,7 +822,7 @@
 
         if (mLowPowerModeEnabled != lowPowerModeEnabled) {
             mLowPowerModeEnabled = lowPowerModeEnabled;
-            powerHintInternal(POWER_HINT_LOW_POWER, lowPowerModeEnabled ? 1 : 0);
+            powerHintInternal(PowerHint.LOW_POWER, lowPowerModeEnabled ? 1 : 0);
             postAfterBootCompleted(new Runnable() {
                 @Override
                 public void run() {
@@ -1152,7 +1148,7 @@
         Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity");
         try {
             if (eventTime > mLastInteractivePowerHintTime) {
-                powerHintInternal(POWER_HINT_INTERACTION, 0);
+                powerHintInternal(PowerHint.INTERACTION, 0);
                 mLastInteractivePowerHintTime = eventTime;
             }
 
@@ -3083,7 +3079,7 @@
     private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
         @Override
         public void onVrStateChanged(boolean enabled) {
-            powerHintInternal(POWER_HINT_VR_MODE, enabled ? 1 : 0);
+            powerHintInternal(PowerHint.VR_MODE, enabled ? 1 : 0);
         }
     };
 
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 1700bca..cae8270 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -19,6 +19,7 @@
 import android.app.AppOpsManager;
 import android.content.res.Configuration;
 import android.graphics.Rect;
+import android.hardware.power.V1_0.PowerHint;
 import android.os.Binder;
 import android.os.Debug;
 import android.os.ParcelFileDescriptor;
@@ -890,7 +891,7 @@
         if (mSustainedPerformanceModeCurrent != mSustainedPerformanceModeEnabled) {
             mSustainedPerformanceModeEnabled = mSustainedPerformanceModeCurrent;
             mService.mPowerManagerInternal.powerHint(
-                    mService.mPowerManagerInternal.POWER_HINT_SUSTAINED_PERFORMANCE_MODE,
+                    PowerHint.SUSTAINED_PERFORMANCE,
                     (mSustainedPerformanceModeEnabled ? 1 : 0));
         }
 
diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk
index 9459517..ce73f34 100644
--- a/services/core/jni/Android.mk
+++ b/services/core/jni/Android.mk
@@ -65,4 +65,8 @@
     libEGL \
     libGLESv2 \
     libnetutils \
+    libhidl \
+    libhwbinder \
+    libutils \
+    android.hardware.power@1.0 \
 
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index ecdc71e..b22d5e7 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -17,6 +17,7 @@
 #define LOG_TAG "BatteryStatsService"
 //#define LOG_NDEBUG 0
 
+#include <android/hardware/power/1.0/IPower.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <jni.h>
 
@@ -26,8 +27,6 @@
 #include <cutils/log.h>
 #include <utils/misc.h>
 #include <utils/Log.h>
-#include <hardware/hardware.h>
-#include <hardware/power.h>
 #include <suspend/autosuspend.h>
 
 #include <inttypes.h>
@@ -41,6 +40,14 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::power::V1_0::IPower;
+using android::hardware::power::V1_0::PowerStatePlatformSleepState;
+using android::hardware::power::V1_0::PowerStateVoter;
+using android::hardware::power::V1_0::Status;
+using android::hardware::hidl_vec;
+
 namespace android
 {
 
@@ -49,7 +56,7 @@
 
 static bool wakeup_init = false;
 static sem_t wakeup_sem;
-extern struct power_module* gPowerModule;
+extern sp<IPower> gPowerHal;
 
 static void wakeup_callback(bool success)
 {
@@ -174,86 +181,34 @@
 }
 
 static jint getPlatformLowPowerStats(JNIEnv* env, jobject /* clazz */, jobject outBuf) {
-    int num_modes = -1;
-    char *output = (char*)env->GetDirectBufferAddress(outBuf), *offset = output;
+    char *output = (char*)env->GetDirectBufferAddress(outBuf);
+    char *offset = output;
     int remaining = (int)env->GetDirectBufferCapacity(outBuf);
-    power_state_platform_sleep_state_t *list;
-    size_t *voter_list;
     int total_added = -1;
 
     if (outBuf == NULL) {
         jniThrowException(env, "java/lang/NullPointerException", "null argument");
-        goto error;
+        return -1;
     }
 
-    if (!gPowerModule) {
-        ALOGE("%s: gPowerModule not loaded", POWER_HARDWARE_MODULE_ID);
-        goto error;
+    if (gPowerHal == nullptr) {
+        ALOGE("gPowerHal not loaded");
+        return -1;
     }
 
-    if (! (gPowerModule->get_platform_low_power_stats && gPowerModule->get_number_of_platform_modes
-       && gPowerModule->get_voter_list)) {
-        ALOGE("%s: Missing API", POWER_HARDWARE_MODULE_ID);
-        goto error;
-    }
+    gPowerHal->getPlatformLowPowerStats(
+        [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
+                Status status) {
+            if (status != Status::SUCCESS)
+                return;
+            for (size_t i = 0; i < states.size(); i++) {
+                int added;
+                const PowerStatePlatformSleepState& state = states[i];
 
-    if (gPowerModule->get_number_of_platform_modes) {
-        num_modes = gPowerModule->get_number_of_platform_modes(gPowerModule);
-    }
-
-    if (num_modes < 1) {
-        ALOGE("%s: Platform does not even have one low power mode", POWER_HARDWARE_MODULE_ID);
-        goto error;
-    }
-
-    list = (power_state_platform_sleep_state_t *)calloc(num_modes,
-        sizeof(power_state_platform_sleep_state_t));
-    if (!list) {
-        ALOGE("%s: power_state_platform_sleep_state_t allocation failed", POWER_HARDWARE_MODULE_ID);
-        goto error;
-    }
-
-    voter_list = (size_t *)calloc(num_modes, sizeof(*voter_list));
-    if (!voter_list) {
-        ALOGE("%s: voter_list allocation failed", POWER_HARDWARE_MODULE_ID);
-        goto err_free;
-    }
-
-    gPowerModule->get_voter_list(gPowerModule, voter_list);
-
-    for (int i = 0; i < num_modes; i++) {
-        list[i].voters = (power_state_voter_t *)calloc(voter_list[i],
-                         sizeof(power_state_voter_t));
-        if (!list[i].voters) {
-            ALOGE("%s: voter_t allocation failed", POWER_HARDWARE_MODULE_ID);
-            goto err_free;
-        }
-    }
-
-    if (!gPowerModule->get_platform_low_power_stats(gPowerModule, list)) {
-        for (int i = 0; i < num_modes; i++) {
-            int added;
-
-            added = snprintf(offset, remaining,
-                    "state_%d name=%s time=%" PRIu64 " count=%" PRIu64 " ",
-                    i + 1, list[i].name, list[i].residency_in_msec_since_boot,
-                    list[i].total_transitions);
-            if (added < 0) {
-                break;
-            }
-            if (added > remaining) {
-                added = remaining;
-            }
-            offset += added;
-            remaining -= added;
-            total_added += added;
-
-            for (unsigned int j = 0; j < list[i].number_of_voters; j++) {
                 added = snprintf(offset, remaining,
-                        "voter_%d name=%s time=%" PRIu64 " count=%" PRIu64 " ",
-                        j + 1, list[i].voters[j].name,
-                        list[i].voters[j].total_time_in_msec_voted_for_since_boot,
-                        list[i].voters[j].total_number_of_times_voted_since_boot);
+                    "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+                    i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
+                    state.totalTransitions);
                 if (added < 0) {
                     break;
                 }
@@ -263,27 +218,37 @@
                 offset += added;
                 remaining -= added;
                 total_added += added;
-            }
 
-            if (remaining <= 0) {
-                /* rewrite NULL character*/
-                offset--;
-                total_added--;
-                ALOGE("%s module: buffer not enough", POWER_HARDWARE_MODULE_ID);
-                break;
+                for (size_t j = 0; j < state.voters.size(); j++) {
+                    const PowerStateVoter& voter = state.voters[j];
+                    added = snprintf(offset, remaining,
+                            "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+                            j + 1, voter.name.c_str(),
+                            voter.totalTimeInMsecVotedForSinceBoot,
+                            voter.totalNumberOfTimesVotedSinceBoot);
+                    if (added < 0) {
+                        break;
+                    }
+                    if (added > remaining) {
+                        added = remaining;
+                    }
+                    offset += added;
+                    remaining -= added;
+                    total_added += added;
+                }
+
+                if (remaining <= 0) {
+                    /* rewrite NULL character*/
+                    offset--;
+                    total_added--;
+                    ALOGE("PowerHal: buffer not enough");
+                    break;
+                }
             }
         }
-    }
+    );
     *offset = 0;
     total_added += 1;
-
-err_free:
-    for (int i = 0; i < num_modes; i++) {
-        free(list[i].voters);
-    }
-    free(list);
-    free(voter_list);
-error:
     return total_added;
 }
 
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index 048ef76..b2372a3 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -18,6 +18,7 @@
 
 //#define LOG_NDEBUG 0
 
+#include <android/hardware/power/1.0/IPower.h>
 #include "JNIHelp.h"
 #include "jni.h"
 
@@ -37,6 +38,13 @@
 
 #include "com_android_server_power_PowerManagerService.h"
 
+using android::hardware::Return;
+using android::hardware::Void;
+using android::hardware::power::V1_0::IPower;
+using android::hardware::power::V1_0::PowerHint;
+using android::hardware::power::V1_0::Feature;
+using android::hardware::hidl_vec;
+
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -48,8 +56,7 @@
 // ----------------------------------------------------------------------------
 
 static jobject gPowerManagerServiceObj;
-struct power_module* gPowerModule;
-
+sp<IPower> gPowerHal;
 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
 
 // Throttling interval for user activity calls.
@@ -69,8 +76,8 @@
 
 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
     // Tell the power HAL when user activity occurs.
-    if (gPowerModule && gPowerModule->powerHint) {
-        gPowerModule->powerHint(gPowerModule, POWER_HINT_INTERACTION, NULL);
+    if (gPowerHal != nullptr) {
+        gPowerHal->powerHint(PowerHint::INTERACTION, 0);
     }
 
     if (gPowerManagerServiceObj) {
@@ -99,16 +106,13 @@
 }
 
 // ----------------------------------------------------------------------------
-
+//TODO(b/31632518)
 static void nativeInit(JNIEnv* env, jobject obj) {
     gPowerManagerServiceObj = env->NewGlobalRef(obj);
 
-    status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
-            (hw_module_t const**)&gPowerModule);
-    if (!err) {
-        gPowerModule->init(gPowerModule);
-    } else {
-        ALOGE("Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err));
+    gPowerHal = IPower::getService("power");
+    if (gPowerHal == nullptr) {
+        ALOGE("Couldn't load PowerHAL module");
     }
 }
 
@@ -123,13 +127,13 @@
 }
 
 static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
-    if (gPowerModule) {
+    if (gPowerHal != nullptr) {
         if (enable) {
             ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
-            gPowerModule->setInteractive(gPowerModule, true);
+            gPowerHal->setInteractive(true);
         } else {
             ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
-            gPowerModule->setInteractive(gPowerModule, false);
+            gPowerHal->setInteractive(false);
         }
     }
 }
@@ -145,13 +149,11 @@
 }
 
 static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) {
-    int data_param = data;
-
-    if (gPowerModule && gPowerModule->powerHint) {
+    if (gPowerHal != nullptr) {
         if(data)
-            gPowerModule->powerHint(gPowerModule, (power_hint_t)hintId, &data_param);
+            gPowerHal->powerHint((PowerHint)hintId, data);
         else {
-            gPowerModule->powerHint(gPowerModule, (power_hint_t)hintId, NULL);
+            gPowerHal->powerHint((PowerHint)hintId, 0);
         }
     }
 }
@@ -159,8 +161,8 @@
 static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
     int data_param = data;
 
-    if (gPowerModule && gPowerModule->setFeature) {
-        gPowerModule->setFeature(gPowerModule, (feature_t)featureId, data_param);
+    if (gPowerHal != nullptr) {
+        gPowerHal->setFeature((Feature)featureId, data_param ? true : false);
     }
 }
 
@@ -215,7 +217,7 @@
         gLastEventTime[i] = LLONG_MIN;
     }
     gPowerManagerServiceObj = NULL;
-    gPowerModule = NULL;
+    gPowerHal = NULL;
     return 0;
 }