Merge "Fix directory permission issue for modem logging"
diff --git a/fstab.hardware b/fstab.hardware
index 7d1e9ac..d2fc516 100644
--- a/fstab.hardware
+++ b/fstab.hardware
@@ -2,7 +2,7 @@
 
 #<src>                                                     <mnt_point>        <type>      <mnt_flags and options>                               <fs_mgr_flags>
 /dev/block/platform/soc/1da4000.ufshc/by-name/system       /                  ext4        ro,barrier=1                                          wait,slotselect,avb
-/dev/block/platform/soc/1da4000.ufshc/by-name/userdata     /data              ext4        errors=panic,noatime,nosuid,nodev,barrier=1,noauto_da_alloc        latemount,wait,check,formattable,fileencryption=ice:aes-256-heh,eraseblk=16777216,logicalblk=4096,quota
+/dev/block/platform/soc/1da4000.ufshc/by-name/userdata     /data              ext4        errors=panic,noatime,nosuid,nodev,barrier=1,noauto_da_alloc        latemount,wait,check,formattable,fileencryption=ice:aes-256-heh,eraseblk=16777216,logicalblk=4096,quota,reservedsize=128M
 /dev/block/platform/soc/1da4000.ufshc/by-name/misc         /misc              emmc        defaults                                              defaults
 /dev/block/platform/soc/1da4000.ufshc/by-name/modem        /firmware          vfat        ro,shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337,context=u:object_r:firmware_file:s0   wait,slotselect
 /devices/soc/a800000.ssusb/a800000.dwc3*                   auto               vfat        defaults                                              voldmanaged=usb:auto
diff --git a/power-libperfmgr/Power.cpp b/power-libperfmgr/Power.cpp
index fe60a59..6d4e374 100644
--- a/power-libperfmgr/Power.cpp
+++ b/power-libperfmgr/Power.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL)
 #define LOG_TAG "android.hardware.power@1.2-service.wahoo-libperfmgr"
 
 #include <android-base/file.h>
@@ -21,9 +22,9 @@
 #include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <utils/Log.h>
+#include <utils/Trace.h>
 
 #include "Power.h"
-
 #include "power-helper.h"
 
 /* RPM runs at 19.2Mhz. Divide by 19200 for msec */
@@ -53,6 +54,29 @@
         mSustainedPerfModeOn(false),
         mEncoderModeOn(false) {
     mInteractionHandler.Init();
+
+    std::string state = android::base::GetProperty(kPowerHalStateProp, "");
+    if (state == "VIDEO_ENCODE") {
+        ALOGI("Initialize with VIDEO_ENCODE on");
+        mHintManager->DoHint("VIDEO_ENCODE");
+        mEncoderModeOn = true;
+    } else if (state ==  "SUSTAINED_PERFORMANCE") {
+        ALOGI("Initialize with SUSTAINED_PERFORMANCE on");
+        mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+        mSustainedPerfModeOn = true;
+    } else if (state == "VR_MODE") {
+        ALOGI("Initialize with VR_MODE on");
+        mHintManager->DoHint("VR_MODE");
+        mVRModeOn = true;
+    } else if (state == "VR_SUSTAINED_PERFORMANCE") {
+        ALOGI("Initialize with SUSTAINED_PERFORMANCE and VR_MODE on");
+        mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+        mSustainedPerfModeOn = true;
+        mVRModeOn = true;
+    } else {
+        ALOGI("Initialize with default setting");
+    }
+
 }
 
 // Methods from ::android::hardware::power::V1_0::IPower follow.
@@ -74,29 +98,45 @@
             }
             break;
         case PowerHint_1_0::VIDEO_ENCODE:
+            ATRACE_BEGIN("video_encode");
             if (mVRModeOn || mSustainedPerfModeOn) {
                 ALOGV("%s: ignoring due to other active perf hints", __func__);
             } else {
                 if (data) {
                     // Hint until canceled
+                    ATRACE_INT("video_encode_lock", 1);
                     mHintManager->DoHint("VIDEO_ENCODE");
                     ALOGD("VIDEO_ENCODE ON");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "VIDEO_ENCODE")) {
+                        ALOGE("%s: could not set powerHAL state property to VIDEO_ENCODE", __func__);
+                    }
                     mEncoderModeOn = true;
                 } else {
+                    ATRACE_INT("video_encode_lock", 0);
                     mHintManager->EndHint("VIDEO_ENCODE");
                     ALOGD("VIDEO_ENCODE OFF");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "")) {
+                        ALOGE("%s: could not clear powerHAL state property", __func__);
+                    }
                     mEncoderModeOn = false;
                 }
             }
+            ATRACE_END();
             break;
         case PowerHint_1_0::SUSTAINED_PERFORMANCE:
             if (data && !mSustainedPerfModeOn) {
                 ALOGD("SUSTAINED_PERFORMANCE ON");
                 if (!mVRModeOn) { // Sustained mode only.
                     mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "SUSTAINED_PERFORMANCE")) {
+                        ALOGE("%s: could not set powerHAL state property to SUSTAINED_PERFORMANCE", __func__);
+                    }
                 } else { // Sustained + VR mode.
                     mHintManager->EndHint("VR_MODE");
                     mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "VR_SUSTAINED_PERFORMANCE")) {
+                        ALOGE("%s: could not set powerHAL state property to VR_SUSTAINED_PERFORMANCE", __func__);
+                    }
                 }
                 mSustainedPerfModeOn = true;
             } else if (!data && mSustainedPerfModeOn) {
@@ -105,6 +145,13 @@
                 mHintManager->EndHint("SUSTAINED_PERFORMANCE");
                 if (mVRModeOn) { // Switch back to VR Mode.
                     mHintManager->DoHint("VR_MODE");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "VR_MODE")) {
+                        ALOGE("%s: could not set powerHAL state property to VR_MODE", __func__);
+                    }
+                } else {
+                    if (!android::base::SetProperty(kPowerHalStateProp, "")) {
+                        ALOGE("%s: could not clear powerHAL state property", __func__);
+                    }
                 }
                 mSustainedPerfModeOn = false;
             }
@@ -114,9 +161,15 @@
                 ALOGD("VR_MODE ON");
                 if (!mSustainedPerfModeOn) { // VR mode only.
                     mHintManager->DoHint("VR_MODE");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "VR_MODE")) {
+                        ALOGE("%s: could not set powerHAL state property to VR_MODE", __func__);
+                    }
                 } else { // Sustained + VR mode.
                     mHintManager->EndHint("SUSTAINED_PERFORMANCE");
                     mHintManager->DoHint("VR_SUSTAINED_PERFORMANCE");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "VR_SUSTAINED_PERFORMANCE")) {
+                        ALOGE("%s: could not set powerHAL state property to VR_SUSTAINED_PERFORMANCE", __func__);
+                    }
                 }
                 mVRModeOn = true;
             } else if (!data && mVRModeOn) {
@@ -125,23 +178,40 @@
                 mHintManager->EndHint("VR_MODE");
                 if (mSustainedPerfModeOn) { // Switch back to sustained Mode.
                     mHintManager->DoHint("SUSTAINED_PERFORMANCE");
+                    if (!android::base::SetProperty(kPowerHalStateProp, "SUSTAINED_PERFORMANCE")) {
+                        ALOGE("%s: could not set powerHAL state property to SUSTAINED_PERFORMANCE", __func__);
+                    }
+                } else {
+                    if (!android::base::SetProperty(kPowerHalStateProp, "")) {
+                        ALOGE("%s: could not clear powerHAL state property", __func__);
+                    }
                 }
                 mVRModeOn = false;
             }
             break;
         case PowerHint_1_0::LAUNCH:
+            ATRACE_BEGIN("launch");
             if (mVRModeOn || mSustainedPerfModeOn) {
                 ALOGV("%s: ignoring due to other active perf hints", __func__);
             } else {
                 if (data) {
                     // Hint until canceled
+                    ATRACE_INT("launch_lock", 1);
+                    if (mEncoderModeOn) {
+                        mHintManager->EndHint("VIDEO_ENCODE");
+                    }
                     mHintManager->DoHint("LAUNCH");
                     ALOGD("LAUNCH ON");
                 } else {
+                    ATRACE_INT("launch_lock", 0);
                     mHintManager->EndHint("LAUNCH");
+                    if (mEncoderModeOn) {
+                        mHintManager->DoHint("VIDEO_ENCODE");
+                    }
                     ALOGD("LAUNCH OFF");
                 }
             }
+            ATRACE_END();
             break;
         default:
             break;
@@ -283,59 +353,99 @@
 
     switch(hint) {
         case PowerHint_1_2::AUDIO_LOW_LATENCY:
+            ATRACE_BEGIN("audio_low_latency");
             if (data) {
                 // Hint until canceled
+                ATRACE_INT("audio_low_latency_lock", 1);
                 mHintManager->DoHint("AUDIO_LOW_LATENCY");
                 ALOGD("AUDIO LOW LATENCY ON");
             } else {
+                ATRACE_INT("audio_low_latency_lock", 0);
                 mHintManager->EndHint("AUDIO_LOW_LATENCY");
                 ALOGD("AUDIO LOW LATENCY OFF");
             }
+            ATRACE_END();
             break;
         case PowerHint_1_2::AUDIO_STREAMING:
+            ATRACE_BEGIN("audio_streaming");
             if (data) {
                 // Hint until canceled
+                ATRACE_INT("audio_streaming_lock", 1);
                 mHintManager->DoHint("AUDIO_STREAMING");
                 ALOGD("AUDIO LOW LATENCY ON");
             } else {
+                ATRACE_INT("audio_streaming_lock", 0);
                 mHintManager->EndHint("AUDIO_STREAMING");
                 ALOGD("AUDIO LOW LATENCY OFF");
             }
+            ATRACE_END();
             break;
         case PowerHint_1_2::CAMERA_LAUNCH:
+            ATRACE_BEGIN("camera_launch");
             if (data > 0) {
+                ATRACE_INT("camera_launch_lock", 1);
+                // If Encoder hint is on, cancel it first and do camera hint
+                if (mEncoderModeOn) {
+                    mHintManager->EndHint("VIDEO_ENCODE");
+                }
                 mHintManager->DoHint("CAMERA_LAUNCH", std::chrono::milliseconds(data));
                 ALOGD("CAMERA LAUNCH ON: %d MS", data);
                 // boosts 2.5s for launching
                 mHintManager->DoHint("LAUNCH", std::chrono::milliseconds(2500));
             } else if (data == 0) {
+                ATRACE_INT("camera_launch_lock", 0);
                 mHintManager->EndHint("CAMERA_LAUNCH");
+                // If Encoder hint is on, recover it
+                if (mEncoderModeOn) {
+                    mHintManager->DoHint("VIDEO_ENCODE");
+                }
                 ALOGD("CAMERA LAUNCH OFF");
             } else {
                 ALOGE("CAMERA LAUNCH INVALID DATA: %d", data);
             }
+            ATRACE_END();
             break;
         case PowerHint_1_2::CAMERA_STREAMING:
+            ATRACE_BEGIN("camera_streaming");
             if (data > 0) {
+                ATRACE_INT("camera_streaming_lock", 1);
+                if (mEncoderModeOn) {
+                    mHintManager->EndHint("VIDEO_ENCODE");
+                }
                 mHintManager->DoHint("CAMERA_STREAMING", std::chrono::milliseconds(data));
                 ALOGD("CAMERA STREAMING ON: %d MS", data);
             } else if (data == 0) {
+                ATRACE_INT("camera_streaming_lock", 0);
                 mHintManager->EndHint("CAMERA_STREAMING");
+                if (mEncoderModeOn) {
+                    mHintManager->DoHint("VIDEO_ENCODE");
+                }
                 ALOGD("CAMERA STREAMING OFF");
             } else {
                 ALOGE("CAMERA STREAMING INVALID DATA: %d", data);
             }
+            ATRACE_END();
             break;
         case PowerHint_1_2::CAMERA_SHOT:
+            ATRACE_BEGIN("camera_shot");
             if (data > 0) {
+                ATRACE_INT("camera_shot_lock", 1);
+                if (mEncoderModeOn) {
+                    mHintManager->EndHint("VIDEO_ENCODE");
+                }
                 mHintManager->DoHint("CAMERA_SHOT", std::chrono::milliseconds(data));
                 ALOGD("CAMERA SHOT ON: %d MS", data);
             } else if (data == 0) {
+                ATRACE_INT("camera_shot_lock", 0);
                 mHintManager->EndHint("CAMERA_SHOT");
+                if (mEncoderModeOn) {
+                    mHintManager->DoHint("VIDEO_ENCODE");
+                }
                 ALOGD("CAMERA SHOT OFF");
             } else {
                 ALOGE("CAMERA SHOT INVALID DATA: %d", data);
             }
+            ATRACE_END();
             break;
         default:
             return powerHint(static_cast<PowerHint_1_0>(hint), data);
diff --git a/power-libperfmgr/Power.h b/power-libperfmgr/Power.h
index 2d84fa5..1b301c8 100644
--- a/power-libperfmgr/Power.h
+++ b/power-libperfmgr/Power.h
@@ -22,6 +22,7 @@
 #include <android/hardware/power/1.2/IPower.h>
 #include <hidl/MQDescriptor.h>
 #include <hidl/Status.h>
+#include <perfmgr/HintManager.h>
 
 #include "InteractionHandler.h"
 
@@ -40,6 +41,8 @@
 using PowerHint_1_2 = ::android::hardware::power::V1_2::PowerHint;
 using ::android::perfmgr::HintManager;
 
+constexpr char kPowerHalStateProp[] = "vendor.powerhal.state";
+
 struct Power : public IPower {
     // Methods from ::android::hardware::power::V1_0::IPower follow.
 
@@ -60,9 +63,10 @@
     // Methods from ::android::hidl::base::V1_0::IBase follow.
 
  private:
+    static bool isSupportedGovernor();
+
     std::shared_ptr<HintManager> mHintManager;
     InteractionHandler mInteractionHandler;
-    static bool isSupportedGovernor();
     std::atomic<bool> mVRModeOn;
     std::atomic<bool> mSustainedPerfModeOn;
     std::atomic<bool> mEncoderModeOn;
diff --git a/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc b/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc
index 65c43b6..06df36a 100644
--- a/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc
+++ b/power-libperfmgr/android.hardware.power@1.2-service.wahoo-libperfmgr.rc
@@ -2,3 +2,13 @@
     class hal
     user system
     group system
+
+# restart powerHAL when framework died
+on property:init.svc.zygote=restarting
+   setprop vendor.powerhal.state 0
+   restart vendor.power-hal-1-2
+
+# restart powerHAL when cameraHAL died
+on property:init.svc.vendor.camera-provider-2-4=restarting && property:vendor.powerhal.state=VIDEO_ENCODE
+   setprop vendor.powerhal.state 0
+   restart vendor.power-hal-1-2
diff --git a/power-libperfmgr/service.cpp b/power-libperfmgr/service.cpp
index 77fb139..c128f95 100644
--- a/power-libperfmgr/service.cpp
+++ b/power-libperfmgr/service.cpp
@@ -33,35 +33,27 @@
 using android::hardware::power::V1_2::IPower;
 using android::hardware::power::V1_2::implementation::Power;
 
-int main() {
+int main(int /* argc */, char** /* argv */) {
+    ALOGI("Power HAL Service 1.2 for Wahoo is starting");
 
-    status_t status;
-    android::sp<IPower> service = nullptr;
-
-    ALOGI("Power HAL Service 1.2 for Wahoo is starting.");
-
-    service = new Power();
+    android::sp<IPower> service = new Power();
     if (service == nullptr) {
         ALOGE("Can not create an instance of Power HAL Iface, exiting.");
-
-        goto shutdown;
+        return 1;
     }
 
     configureRpcThreadpool(1, true /*callerWillJoin*/);
 
-    status = service->registerAsService();
+    status_t status = service->registerAsService();
     if (status != OK) {
-        ALOGE("Could not register service for Power HAL Iface (%d).", status);
-        goto shutdown;
+        ALOGE("Could not register service for Power HAL Iface (%d), exiting.", status);
+        return 1;
     }
 
     ALOGI("Power Service is ready");
     joinRpcThreadpool();
-    //Should not pass this line
 
-shutdown:
     // In normal operation, we don't expect the thread pool to exit
-
     ALOGE("Power Service is shutting down");
     return 1;
 }
diff --git a/sepolicy/vendor/hal_power_default.te b/sepolicy/vendor/hal_power_default.te
index 3794e32..4800943 100644
--- a/sepolicy/vendor/hal_power_default.te
+++ b/sepolicy/vendor/hal_power_default.te
@@ -11,3 +11,6 @@
 allow hal_power_default sysfs_msm_subsys:file w_file_perms;
 allow hal_power_default sysfs_devices_system_cpu:file w_file_perms;
 allow hal_power_default latency_device:chr_file w_file_perms;
+
+# To get/set powerhal state property
+set_prop(hal_power_default, power_prop)
diff --git a/sepolicy/vendor/property.te b/sepolicy/vendor/property.te
index 9f38fab..3082241 100644
--- a/sepolicy/vendor/property.te
+++ b/sepolicy/vendor/property.te
@@ -15,3 +15,4 @@
 type sys_time_prop, property_type;
 type atfwd_start_prop, property_type;
 type bluetooth_log_prop, property_type;
+type power_prop, property_type;
diff --git a/sepolicy/vendor/property_contexts b/sepolicy/vendor/property_contexts
index d698bf3..bce1fda 100644
--- a/sepolicy/vendor/property_contexts
+++ b/sepolicy/vendor/property_contexts
@@ -24,3 +24,4 @@
 sys.time.set               u:object_r:sys_time_prop:s0
 persist.radio.atfwd.start  u:object_r:atfwd_start_prop:s0
 sys.logger.bluetooth       u:object_r:bluetooth_log_prop:s0
+vendor.powerhal.state      u:object_r:power_prop:s0