Camera: Cleanup hardware key handling

* Fix power shutter behaviour in camcorder mode
* Disable volume change while in panorama mode, volume buttons should only
handle camera operations while in the camera
* Add camera/power/volume key shutter handling in panorama mode

On devices with a hardware camera key:
* Disable power & volume shutter features
* Volume buttons control the zoom

On devices without a hardware camera key:
* When power shutter is disabled, volume buttons control the shutter (like AOSP)
* When power shutter is enabled, volume buttons control the zoom

Change-Id: I141946d5b6f5aec8b1e9a9f99270d30295596079
diff --git a/Android.mk b/Android.mk
index 4acc5b8..a8cdcb9 100755
--- a/Android.mk
+++ b/Android.mk
@@ -25,6 +25,8 @@
         --version-name "$(version_name_package)" \
         --version-code $(version_code_package) \
 
+LOCAL_JAVA_LIBRARIES := org.lineageos.platform.internal
+
 LOCAL_PACKAGE_NAME := Snap
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_PRIVATE_PLATFORM_APIS:=true
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 0bdc60e..868a255 100755
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -2048,7 +2048,9 @@
     protected void initPowerShutter(ComboPreferences prefs) {
         String val = prefs.getString(CameraSettings.KEY_POWER_SHUTTER,
                 getResources().getString(R.string.pref_camera_power_shutter_default));
-        mPowerShutter = val.equals(CameraSettings.VALUE_ON);
+        if (!CameraUtil.hasCameraKey()) {
+            mPowerShutter = val.equals(CameraSettings.VALUE_ON);
+        }
         if (mPowerShutter /*TODO: && mShowCameraAppView*/) {
             getWindow().addPrivateFlags(
                     WindowManager.LayoutParams.PRIVATE_FLAG_PREVENT_POWER_KEY);
diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java
index abad064..273c235 100755
--- a/src/com/android/camera/CameraSettings.java
+++ b/src/com/android/camera/CameraSettings.java
@@ -1004,6 +1004,7 @@
         ListPreference cameraHdr = group.findPreference(KEY_CAMERA_HDR);
         ListPreference disMode = group.findPreference(KEY_DIS);
         ListPreference cameraHdrPlus = group.findPreference(KEY_CAMERA_HDR_PLUS);
+        ListPreference powerShutter = group.findPreference(KEY_POWER_SHUTTER);
         ListPreference videoHfrMode =
                 group.findPreference(KEY_VIDEO_HIGH_FRAME_RATE);
         ListPreference seeMoreMode = group.findPreference(KEY_SEE_MORE);
@@ -1115,6 +1116,9 @@
                 !GcamHelper.hasGcamCapture() || isFrontCamera)) {
             removePreference(group, cameraHdrPlus.getKey());
         }
+        if (powerShutter != null && CameraUtil.hasCameraKey()) {
+            removePreference(group, powerShutter.getKey());
+        }
 
         if (PersistUtil.isSaveInSdEnabled()) {
             final String CAMERA_SAVEPATH_SDCARD = "1";
diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java
index 8afc9da..3c5b165 100755
--- a/src/com/android/camera/PhotoModule.java
+++ b/src/com/android/camera/PhotoModule.java
@@ -2809,13 +2809,21 @@
             case KeyEvent.KEYCODE_VOLUME_UP:
                 if (/*TODO: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized
                     && (mUI.mMenuInitialized)) {
-                    mUI.onScaleStepResize(true);
+                    if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                        onShutterButtonFocus(true);
+                    } else {
+                        mUI.onScaleStepResize(true);
+                    }
                 }
                 return true;
             case KeyEvent.KEYCODE_VOLUME_DOWN:
                 if (/*TODO: mActivity.isInCameraApp() &&*/ mFirstTimeInitialized
                     && (mUI.mMenuInitialized)) {
-                    mUI.onScaleStepResize(false);
+                    if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                        onShutterButtonFocus(true);
+                    } else {
+                        mUI.onScaleStepResize(false);
+                    }
                 }
                 return true;
             case KeyEvent.KEYCODE_FOCUS:
@@ -2844,7 +2852,7 @@
                 return true;
             case KeyEvent.KEYCODE_POWER:
                 if (mFirstTimeInitialized && event.getRepeatCount() == 0
-                        && CameraActivity.mPowerShutter) {
+                        && CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
                     onShutterButtonFocus(true);
                 }
                 return true;
@@ -2860,6 +2868,10 @@
         switch (keyCode) {
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
+                if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()
+                        && mFirstTimeInitialized) {
+                    onShutterButtonClick();
+                }
                 return true;
             case KeyEvent.KEYCODE_FOCUS:
                 if (mFirstTimeInitialized) {
@@ -2867,7 +2879,8 @@
                 }
                 return true;
             case KeyEvent.KEYCODE_POWER:
-                if (CameraActivity.mPowerShutter && mFirstTimeInitialized) {
+                if (CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()
+                        && mFirstTimeInitialized) {
                     onShutterButtonClick();
                 }
                 return true;
diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java
index df43610..e713c72 100644
--- a/src/com/android/camera/VideoModule.java
+++ b/src/com/android/camera/VideoModule.java
@@ -1385,26 +1385,42 @@
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_VOLUME_UP:
-                mUI.onScaleStepResize(true);
+                if (event.getRepeatCount() == 0 && !CameraActivity.mPowerShutter &&
+                        !CameraUtil.hasCameraKey()) {
+                    mUI.clickShutter();
+                } else {
+                    mUI.onScaleStepResize(true);
+                }
                 return true;
             case KeyEvent.KEYCODE_VOLUME_DOWN:
-                mUI.onScaleStepResize(false);
+                if (event.getRepeatCount() == 0 && !CameraActivity.mPowerShutter &&
+                        !CameraUtil.hasCameraKey()) {
+                    mUI.clickShutter();
+                } else {
+                    mUI.onScaleStepResize(false);
+                }
                 return true;
             case KeyEvent.KEYCODE_CAMERA:
                 if (event.getRepeatCount() == 0) {
                     mUI.clickShutter();
-                    return true;
                 }
-                break;
+                return true;
             case KeyEvent.KEYCODE_DPAD_CENTER:
                 if (event.getRepeatCount() == 0) {
                     mUI.clickShutter();
+                }
+                return true;
+            case KeyEvent.KEYCODE_POWER:
+                if (event.getRepeatCount() == 0 && CameraActivity.mPowerShutter &&
+                        !CameraUtil.hasCameraKey()) {
+                    mUI.clickShutter();
+                }
+                return true;
+            case KeyEvent.KEYCODE_MENU:
+                if (mMediaRecorderRecording) {
                     return true;
                 }
                 break;
-            case KeyEvent.KEYCODE_MENU:
-                if (mMediaRecorderRecording) return true;
-                break;
         }
         return false;
     }
@@ -1413,14 +1429,21 @@
     public boolean onKeyUp(int keyCode, KeyEvent event) {
         switch (keyCode) {
             case KeyEvent.KEYCODE_VOLUME_UP:
+                if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                    mUI.pressShutter(false);
+                }
+                return true;
             case KeyEvent.KEYCODE_VOLUME_DOWN:
+                if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                    mUI.pressShutter(false);
+                }
                 return true;
             case KeyEvent.KEYCODE_CAMERA:
                 mUI.pressShutter(false);
                 return true;
             case KeyEvent.KEYCODE_POWER:
-                if (CameraActivity.mPowerShutter) {
-                    onShutterButtonClick();
+                if (CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                    mUI.pressShutter(false);
                 }
                 return true;
         }
diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java
index 0aab8f8..65e18a1 100644
--- a/src/com/android/camera/WideAnglePanoramaModule.java
+++ b/src/com/android/camera/WideAnglePanoramaModule.java
@@ -310,6 +310,9 @@
         CameraSettings.upgradeGlobalPreferences(mPreferences.getGlobal(), activity);
         mLocationManager = new LocationManager(mActivity, null);
 
+        // Power shutter
+        mActivity.initPowerShutter(mPreferences);
+
         mMainHandler = new Handler() {
             @Override
             public void handleMessage(Message msg) {
@@ -943,6 +946,10 @@
         }
         mUI.showPreviewCover();
         releaseCamera();
+
+        // Load the power shutter
+        mActivity.initPowerShutter(mPreferences);
+
         synchronized (mRendererLock) {
             mCameraTexture = null;
 
@@ -1235,14 +1242,38 @@
     public void onActivityResult(int requestCode, int resultCode, Intent data) {
     }
 
-
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_VOLUME_UP:
+            case KeyEvent.KEYCODE_VOLUME_DOWN:
+                return true;
+            case KeyEvent.KEYCODE_CAMERA:
+                if (event.getRepeatCount() == 0) {
+                    onShutterButtonClick();
+                }
+                return true;
+            case KeyEvent.KEYCODE_POWER:
+                return true;
+        }
         return false;
     }
 
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_VOLUME_UP:
+            case KeyEvent.KEYCODE_VOLUME_DOWN:
+                if (!CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                    onShutterButtonClick();
+                }
+                return true;
+            case KeyEvent.KEYCODE_POWER:
+                if (CameraActivity.mPowerShutter && !CameraUtil.hasCameraKey()) {
+                    onShutterButtonClick();
+                }
+                return true;
+        }
         return false;
     }
 
diff --git a/src/com/android/camera/util/CameraUtil.java b/src/com/android/camera/util/CameraUtil.java
index 09c9277..3b34519 100755
--- a/src/com/android/camera/util/CameraUtil.java
+++ b/src/com/android/camera/util/CameraUtil.java
@@ -144,6 +144,9 @@
     public static final String TRUE = "true";
     public static final String FALSE = "false";
 
+    // Hardware camera key mask
+    private static final int KEY_MASK_CAMERA = 0x20;
+
     private static final Class<?>[] CTOR_SIGNATURE =
             new Class[] {CaptureRequest.class, CameraMetadataNative.class, boolean.class, int.class};
 
@@ -191,6 +194,10 @@
         return (supported != null) && supported.contains(SCENE_MODE_HDR);
     }
 
+    public static boolean hasCameraKey() {
+        return (sDeviceKeysPresent & KEY_MASK_CAMERA) != 0;
+    }
+
     public static boolean isMeteringAreaSupported(Parameters params) {
         return params.getMaxNumMeteringAreas() > 0;
     }
@@ -216,6 +223,9 @@
     private static float sPixelDensity = 1;
     private static ImageFileNamer sImageFileNamer;
 
+    // Get available hardware keys
+    private static int sDeviceKeysPresent;
+
     private CameraUtil() {
     }
 
@@ -227,6 +237,8 @@
         sPixelDensity = metrics.density;
         sImageFileNamer = new ImageFileNamer(
                 context.getString(R.string.image_file_name_format));
+        sDeviceKeysPresent = context.getResources().getInteger(
+                org.lineageos.platform.internal.R.integer.config_deviceHardwareKeys);
     }
 
     public static int dpToPixel(int dp) {