From 027a842a5836d5e4e27cfb3c97882a5bd18f1652 Mon Sep 17 00:00:00 2001 From: jhenrique09 Date: Wed, 27 Nov 2019 05:52:23 +0000 Subject: [PATCH] davinci: parts: Implement popup motor calibration Co-authored-by: Arian Change-Id: If1f6c757cbf521fd27f7124284f40ea602f53ba8 --- parts/AndroidManifest.xml | 3 +- parts/res/values/strings.xml | 9 ++ parts/res/values/styles.xml | 3 + .../settings/popupcamera/Constants.java | 12 +- .../popupcamera/PopupCameraService.java | 135 +++++++++++++++++- proprietary-files.txt | 6 +- sepolicy/vendor/hal_motor_default.te | 6 +- 7 files changed, 160 insertions(+), 14 deletions(-) diff --git a/parts/AndroidManifest.xml b/parts/AndroidManifest.xml index 33f323d..ad5474d 100644 --- a/parts/AndroidManifest.xml +++ b/parts/AndroidManifest.xml @@ -1,7 +1,7 @@ + Warning + Couldn\'t close front camera. Try calibrating the motor. + Couldn\'t open front camera. Try calibrating the motor. + Front camera cannot be used during calibration. + Calibrate + Couldn\'t calibrate + Calibrated successfully. You can open the front camera now. diff --git a/parts/res/values/styles.xml b/parts/res/values/styles.xml index e98b9f6..73b3ea7 100644 --- a/parts/res/values/styles.xml +++ b/parts/res/values/styles.xml @@ -70,4 +70,7 @@ 0.072727273 + + diff --git a/parts/src/org/lineageos/settings/popupcamera/Constants.java b/parts/src/org/lineageos/settings/popupcamera/Constants.java index 339cd07..9554e8e 100644 --- a/parts/src/org/lineageos/settings/popupcamera/Constants.java +++ b/parts/src/org/lineageos/settings/popupcamera/Constants.java @@ -23,10 +23,14 @@ public class Constants { public static final int MSG_CAMERA_CLOSED = 1001; public static final int MSG_CAMERA_OPEN = 1002; - public static final int MOTOR_STATUS_POPUP = 11; - public static final int MOTOR_STATUS_POPUP_JAM = 12; - public static final int MOTOR_STATUS_TAKEBACK = 13; - public static final int MOTOR_STATUS_TAKEBACK_JAM = 14; + public static final int MOTOR_STATUS_POPUP_OK = 11; + public static final int MOTOR_STATUS_POPUP_JAMMED = 12; + public static final int MOTOR_STATUS_TAKEBACK_OK = 13; + public static final int MOTOR_STATUS_TAKEBACK_JAMMED = 14; + public static final int MOTOR_STATUS_PRESSED = 15; + public static final int MOTOR_STATUS_CALIB_OK = 17; + public static final int MOTOR_STATUS_CALIB_ERROR = 18; + public static final int MOTOR_STATUS_REQUEST_CALIB = 19; public static final String CLOSE_CAMERA_STATE = "0"; public static final String OPEN_CAMERA_STATE = "1"; diff --git a/parts/src/org/lineageos/settings/popupcamera/PopupCameraService.java b/parts/src/org/lineageos/settings/popupcamera/PopupCameraService.java index 40a9228..4e69c7d 100644 --- a/parts/src/org/lineageos/settings/popupcamera/PopupCameraService.java +++ b/parts/src/org/lineageos/settings/popupcamera/PopupCameraService.java @@ -17,8 +17,11 @@ package org.lineageos.settings.popupcamera; import android.annotation.NonNull; +import android.app.AlertDialog; import android.app.Service; +import android.content.DialogInterface; import android.content.Intent; +import android.content.res.Resources; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; @@ -33,11 +36,14 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.util.Log; +import android.view.WindowManager; import org.lineageos.settings.R; import org.lineageos.settings.utils.FileUtils; import vendor.xiaomi.hardware.motor.V1_0.IMotor; +import vendor.xiaomi.hardware.motor.V1_0.IMotorCallback; +import vendor.xiaomi.hardware.motor.V1_0.MotorEvent; public class PopupCameraService extends Service implements Handler.Callback { private static final String TAG = "PopupCameraService"; @@ -50,6 +56,10 @@ public class PopupCameraService extends Service implements Handler.Callback { private Handler mHandler = new Handler(this); private IMotor mMotor = null; + private IMotorCallback mMotorStatusCallback; + private boolean mMotorCalibrating = false; + private boolean mErrorDialogShowing; + private final Object mLock = new Object(); private PopupCameraPreferences mPopupCameraPreferences; private SensorManager mSensorManager; private Sensor mFreeFallSensor; @@ -127,15 +137,55 @@ public class PopupCameraService extends Service implements Handler.Callback { try { mMotor = IMotor.getService(); int status = mMotor.getMotorStatus(); - if (status == Constants.MOTOR_STATUS_POPUP || status == Constants.MOTOR_STATUS_POPUP_JAM - || status == Constants.MOTOR_STATUS_TAKEBACK_JAM) { + if (status == Constants.MOTOR_STATUS_POPUP_OK + || status == Constants.MOTOR_STATUS_TAKEBACK_JAMMED) { mMotor.takebackMotor(1); } + mMotorStatusCallback = new MotorStatusCallback(); + mMotor.setMotorCallback(mMotorStatusCallback); } catch (RemoteException e) { // Do nothing } } + private final class MotorStatusCallback extends IMotorCallback.Stub { + public MotorStatusCallback() {} + + @Override + public void onNotify(MotorEvent event) { + int status = event.vaalue; + int cookie = event.cookie; + if (DEBUG) + Log.d(TAG, "onNotify: cookie=" + cookie + ", status=" + status); + synchronized (mLock) { + if (status == Constants.MOTOR_STATUS_CALIB_OK + || status == Constants.MOTOR_STATUS_CALIB_ERROR) { + mMotorCalibrating = false; + showCalibrationResult(status); + } else if (status == Constants.MOTOR_STATUS_PRESSED) { + updateMotor(Constants.CLOSE_CAMERA_STATE); + goBackHome(); + } else if (status == Constants.MOTOR_STATUS_POPUP_JAMMED + || status == Constants.MOTOR_STATUS_TAKEBACK_JAMMED) { + showErrorDialog(); + } + } + } + } + + private void calibrateMotor() { + synchronized (mLock) { + if (mMotorCalibrating || mMotor == null) + return; + try { + mMotorCalibrating = true; + mMotor.calibration(); + } catch (RemoteException e) { + // Do nothing + } + } + } + @Override public int onStartCommand(Intent intent, int flags, int startId) { if (DEBUG) @@ -161,25 +211,38 @@ public class PopupCameraService extends Service implements Handler.Callback { } final Runnable r = () -> { mMotorBusy = true; - mHandler.postDelayed(() -> mMotorBusy = false, 1200); try { + int status = mMotor.getMotorStatus(); + if (DEBUG) + Log.d(TAG, "updateMotor: status=" + status + ", cameraState=" + cameraState); if (cameraState.equals(Constants.OPEN_CAMERA_STATE) - && mMotor.getMotorStatus() == Constants.MOTOR_STATUS_TAKEBACK) { + && (status == Constants.MOTOR_STATUS_TAKEBACK_OK + || status == Constants.MOTOR_STATUS_CALIB_OK)) { lightUp(); playSoundEffect(Constants.OPEN_CAMERA_STATE); mMotor.popupMotor(1); mSensorManager.registerListener( mFreeFallListener, mFreeFallSensor, SensorManager.SENSOR_DELAY_NORMAL); } else if (cameraState.equals(Constants.CLOSE_CAMERA_STATE) - && mMotor.getMotorStatus() == Constants.MOTOR_STATUS_POPUP) { + && status == Constants.MOTOR_STATUS_POPUP_OK) { lightUp(); playSoundEffect(Constants.CLOSE_CAMERA_STATE); mMotor.takebackMotor(1); mSensorManager.unregisterListener(mFreeFallListener, mFreeFallSensor); + } else { + mMotorBusy = false; + if (status == Constants.MOTOR_STATUS_POPUP_JAMMED + || status == Constants.MOTOR_STATUS_TAKEBACK_JAMMED + || status == Constants.MOTOR_STATUS_CALIB_ERROR + || status == Constants.MOTOR_STATUS_REQUEST_CALIB) { + showErrorDialog(); + } + return; } } catch (RemoteException e) { // Do nothing } + mHandler.postDelayed(() -> mMotorBusy = false, 1200); }; if (mMotorBusy) { @@ -210,6 +273,68 @@ public class PopupCameraService extends Service implements Handler.Callback { } } + private void showCalibrationResult(int status) { + if (mErrorDialogShowing) { + return; + } + mErrorDialogShowing = true; + mHandler.post(() -> { + Resources res = getResources(); + int dialogMessageResId = mMotorCalibrating + ? R.string.popup_camera_calibrate_running + : (status == Constants.MOTOR_STATUS_CALIB_OK + ? R.string.popup_camera_calibrate_success + : R.string.popup_camera_calibrate_failed); + AlertDialog.Builder alertDialogBuilder = + new AlertDialog.Builder(this, R.style.SystemAlertDialogTheme); + alertDialogBuilder.setMessage(res.getString(dialogMessageResId)); + alertDialogBuilder.setPositiveButton(android.R.string.ok, null); + AlertDialog alertDialog = alertDialogBuilder.create(); + alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG); + alertDialog.setCancelable(false); + alertDialog.setCanceledOnTouchOutside(false); + alertDialog.show(); + alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + mErrorDialogShowing = false; + } + }); + }); + } + + private void showErrorDialog() { + if (mErrorDialogShowing) { + return; + } + mErrorDialogShowing = true; + goBackHome(); + mHandler.post(() -> { + Resources res = getResources(); + String cameraState = "-1"; + int dialogMessageResId = cameraState.equals(Constants.CLOSE_CAMERA_STATE) + ? R.string.popup_camera_takeback_failed_calibrate + : R.string.popup_camera_popup_failed_calibrate; + AlertDialog alertDialog = + new AlertDialog.Builder(this, R.style.SystemAlertDialogTheme) + .setTitle(res.getString(R.string.popup_camera_tip)) + .setMessage(res.getString(dialogMessageResId)) + .setPositiveButton(res.getString(R.string.popup_camera_calibrate_now), + (dialog, which) -> calibrateMotor()) + .setNegativeButton(res.getString(android.R.string.cancel), null) + .create(); + alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); + alertDialog.setCanceledOnTouchOutside(false); + alertDialog.show(); + alertDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialogInterface) { + mErrorDialogShowing = false; + } + }); + }); + } + private void playSoundEffect(String state) { int soundEffect = Integer.parseInt(mPopupCameraPreferences.getSoundEffect()); if (soundEffect != -1) { diff --git a/proprietary-files.txt b/proprietary-files.txt index 8ccd288..6ef9245 100644 --- a/proprietary-files.txt +++ b/proprietary-files.txt @@ -131,8 +131,6 @@ vendor/lib64/libmialgo_sd.so vendor/lib64/libmialgo_utils.so vendor/lib64/libmialgoengine.so vendor/lib64/libmibokeh_712.so -vendor/lib64/libmivendor_module_hall.so -vendor/lib64/libmivendor_module_motor.so vendor/lib64/libmmcamera_faceproc2.so vendor/lib64/libmmcamera_faceproc.so vendor/lib64/libmpbase.so @@ -272,7 +270,11 @@ vendor/firmware/CAMERA_ICP.elf # Camera motor vendor/bin/hw/vendor.xiaomi.hardware.motor@1.0-service +vendor/etc/step_motor/mi_camera_config.xml vendor/lib64/hw/vendor.xiaomi.hardware.motor@1.0-impl.so +vendor/lib64/libmivendor_module_calibration.so +vendor/lib64/libmivendor_module_hall.so +vendor/lib64/libmivendor_module_motor.so vendor/lib64/mi.motor.daemon.so # Camera (popup sound effects) diff --git a/sepolicy/vendor/hal_motor_default.te b/sepolicy/vendor/hal_motor_default.te index 7595068..dffd6aa 100644 --- a/sepolicy/vendor/hal_motor_default.te +++ b/sepolicy/vendor/hal_motor_default.te @@ -7,6 +7,8 @@ hal_server_domain(hal_motor_default, hal_motor) binder_call(hal_motor_client, hal_motor_server) +binder_call(hal_motor_default, system_app) + type hal_motor_default_exec, exec_type, vendor_file_type, file_type; init_daemon_domain(hal_motor_default) @@ -16,8 +18,8 @@ allow hal_motor_client hal_motor_hwservice_xiaomi:hwservice_manager find; allow hal_motor_default hall_device:chr_file rw_file_perms; allow hal_motor_default motor_device:chr_file rw_file_perms; -allow hal_motor_default persist_sensors_file:dir search; -allow hal_motor_default persist_sensors_file:file r_file_perms; +allow hal_motor_default persist_sensors_file:dir rw_dir_perms; +allow hal_motor_default persist_sensors_file:file rw_file_perms; allow hal_motor_default mnt_vendor_file:dir { search };