lmi: Commonize popup camera stuff
Change-Id: I40195b126b3f79566240f88f0b2bf55f941ccd66
This commit is contained in:
@@ -19,9 +19,6 @@ SOONG_CONFIG_XIAOMI_KONA_FOD_POS_X = 439
|
||||
SOONG_CONFIG_XIAOMI_KONA_FOD_POS_Y = 1655
|
||||
SOONG_CONFIG_XIAOMI_KONA_FOD_SIZE = 202
|
||||
|
||||
# HIDL
|
||||
DEVICE_MANIFEST_FILE += $(DEVICE_PATH)/manifest.xml
|
||||
|
||||
# Init
|
||||
TARGET_INIT_VENDOR_LIB := //$(DEVICE_PATH):init_xiaomi_lmi
|
||||
TARGET_RECOVERY_DEVICE_MODULES := init_xiaomi_lmi
|
||||
|
||||
@@ -34,14 +34,6 @@ PRODUCT_COPY_FILES += \
|
||||
$(LOCAL_PATH)/audio/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
|
||||
$(LOCAL_PATH)/audio/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml
|
||||
|
||||
# Camera
|
||||
PRODUCT_PACKAGES += \
|
||||
vendor.xiaomi.hardware.motor@1.0.vendor
|
||||
|
||||
# Device parts
|
||||
PRODUCT_PACKAGES += \
|
||||
DeviceParts
|
||||
|
||||
# Permissions
|
||||
PRODUCT_COPY_FILES += \
|
||||
frameworks/native/data/etc/android.hardware.sensor.barometer.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.sensor.barometer.xml
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="hidl">
|
||||
<name>vendor.xiaomi.hardware.motor</name>
|
||||
<transport>hwbinder</transport>
|
||||
<fqname>@1.0::IMotor/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
@@ -1,24 +0,0 @@
|
||||
//
|
||||
// Copyright (C) 2017-2021 The LineageOS Project
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
android_app {
|
||||
name: "DeviceParts",
|
||||
|
||||
srcs: ["src/**/*.java"],
|
||||
resource_dirs: ["res"],
|
||||
certificate: "platform",
|
||||
platform_apis: true,
|
||||
privileged: true,
|
||||
|
||||
static_libs: [
|
||||
"org.lineageos.settings.resources",
|
||||
"//hardware/xiaomi:vendor.xiaomi.hardware.motor-V1.0-java",
|
||||
],
|
||||
|
||||
optimize: {
|
||||
proguard_flags_files: ["proguard.flags"],
|
||||
},
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2015-2016 The CyanogenMod Project
|
||||
2017-2021 The LineageOS 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.lineageos.devicesettings"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0"
|
||||
android:sharedUserId="android.uid.system">
|
||||
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="24"
|
||||
android:targetSdkVersion="24"/>
|
||||
|
||||
<application
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/device_settings_app_name"
|
||||
android:persistent="true"
|
||||
android:theme="@style/Theme.Main">
|
||||
|
||||
<receiver android:name=".BootCompletedReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service
|
||||
android:name=".popupcamera.PopupCameraService"
|
||||
android:permission="PopupCameraService">
|
||||
</service>
|
||||
|
||||
<activity
|
||||
android:name=".popupcamera.PopupCameraSettingsActivity"
|
||||
android:label="@string/popup_title"
|
||||
android:theme="@style/Theme.Main">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.settings.action.IA_SETTINGS" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="com.android.settings.category"
|
||||
android:value="com.android.settings.category.ia.system" />
|
||||
<meta-data
|
||||
android:name="com.android.settings.icon"
|
||||
android:resource="@drawable/ic_settings_popup" />
|
||||
<meta-data
|
||||
android:name="com.android.settings.summary"
|
||||
android:resource="@string/summary_empty" />
|
||||
<meta-data
|
||||
android:name="com.android.settings.order"
|
||||
android:value="-255" />
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -1,4 +0,0 @@
|
||||
-keep class org.lineageos.devicesettings.popupcamera.* {
|
||||
*;
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?android:attr/colorControlNormal"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FFFFFFFF"
|
||||
android:pathData="M10,20L5,20v2h5v2l3,-3 -3,-3v2zM14,20v2h5v-2h-5zM12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -1.99,0.9 -1.99,2S10.9,8 12,8zM17,0L7,0C5.9,0 5,0.9 5,2v14c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,2c0,-1.1 -0.9,-2 -2,-2zM7,2h10v10.5c0,-1.67 -3.33,-2.5 -5,-2.5s-5,0.83 -5,2.5L7,2z" />
|
||||
</vector>
|
||||
@@ -1,53 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The LineageOS 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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Popup camera effect names -->
|
||||
<string-array name="popupcamera_effects_names" translatable="false">
|
||||
<item>popup_muqin_up.ogg</item>
|
||||
<item>popup_muqin_down.ogg</item>
|
||||
<item>popup_yingyan_up.ogg</item>
|
||||
<item>popup_yingyan_down.ogg</item>
|
||||
<item>popup_mofa_up.ogg</item>
|
||||
<item>popup_mofa_down.ogg</item>
|
||||
<item>popup_jijia_up.ogg</item>
|
||||
<item>popup_jijia_down.ogg</item>
|
||||
<item>popup_chilun_up.ogg</item>
|
||||
<item>popup_chilun_down.ogg</item>
|
||||
<item>popup_cangmen_up.ogg</item>
|
||||
<item>popup_cangmen_down.ogg</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="popupcamera_effects_entries">
|
||||
<item>@string/action_none</item>
|
||||
<item>@string/popup_title_muqin</item>
|
||||
<item>@string/popup_title_yingyan</item>
|
||||
<item>@string/popup_title_mofa</item>
|
||||
<item>@string/popup_title_jijia</item>
|
||||
<item>@string/popup_title_chilun</item>
|
||||
<item>@string/popup_title_cangmen</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="popupcamera_effects_values">
|
||||
<item>-1</item>
|
||||
<item>0</item>
|
||||
<item>2</item>
|
||||
<item>4</item>
|
||||
<item>6</item>
|
||||
<item>8</item>
|
||||
<item>10</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2018 The LineageOS 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.
|
||||
-->
|
||||
<resources>
|
||||
<!-- Popup camera settings -->
|
||||
<string name="popup_led_title">Visual effect</string>
|
||||
<string name="popup_led_summary">Show animation when the front camera appears and retracts</string>
|
||||
<string name="popup_title">Front camera effects</string>
|
||||
<string name="popup_title_muqin">Xylophone</string>
|
||||
<string name="popup_title_yingyan">Condor</string>
|
||||
<string name="popup_title_mofa">Magic</string>
|
||||
<string name="popup_title_jijia">Mecha</string>
|
||||
<string name="popup_title_chilun">Gearwheel</string>
|
||||
<string name="popup_title_cangmen">Cabin door</string>
|
||||
|
||||
<!-- Popup camera strings -->
|
||||
<string name="popup_camera_tip">Warning</string>
|
||||
<string name="popup_camera_takeback_failed_times_calibrate">Couldn\'t close front camera multiple times. Try calibrating the camera.</string>
|
||||
<string name="popup_camera_popup_failed_times_calibrate">Couldn\'t open front camera multiple times. Try calibrating the camera.</string>
|
||||
<string name="popup_camera_calibrate_running">Front camera cannot be used during calibration.</string>
|
||||
<string name="popup_camera_calibrate_now">Calibrate</string>
|
||||
<string name="popup_camera_calibrate_failed">Couldn\'t calibrate</string>
|
||||
<string name="popup_camera_calibrate_success">Calibrated successfully. You can open the front camera now.</string>
|
||||
<string name="stop_operate_camera_frequently">You\'re opening the front camera too frequently.</string>
|
||||
<string name="takeback_camera_front_failed">Couldn\'t close front camera. Try again.</string>
|
||||
<string name="popup_camera_front_failed">Couldn\'t open front camera. Try again.</string>
|
||||
</resources>
|
||||
@@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="popup_led_effect"
|
||||
android:summary="@string/popup_led_summary"
|
||||
android:title="@string/popup_led_title" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/popupcamera_effects_entries"
|
||||
android:entryValues="@array/popupcamera_effects_values"
|
||||
android:key="popup_sound_effect"
|
||||
android:summary="%s"
|
||||
android:title="@string/popup_title" />
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The CyanogenMod Project
|
||||
* 2017-2020 The LineageOS 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 org.lineageos.devicesettings;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import org.lineageos.devicesettings.popupcamera.PopupCameraUtils;
|
||||
|
||||
public class BootCompletedReceiver extends BroadcastReceiver {
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "DeviceParts";
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, Intent intent) {
|
||||
if (DEBUG) Log.d(TAG, "Received boot completed intent");
|
||||
PopupCameraUtils.startService(context);
|
||||
}
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The LineageOS 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 org.lineageos.devicesettings.popupcamera;
|
||||
|
||||
public class Constants {
|
||||
public static final int FREE_FALL_SENSOR_ID = 33171042;
|
||||
|
||||
public static final int CAMERA_EVENT_DELAY_TIME = 100; // ms
|
||||
public static final int MSG_CAMERA_CLOSED = 1001;
|
||||
public static final int MSG_CAMERA_OPEN = 1002;
|
||||
|
||||
public static final int MOTOR_STATUS_CALIB_ERROR = 18;
|
||||
public static final int MOTOR_STATUS_CALIB_OK = 17;
|
||||
public static final int MOTOR_STATUS_CANCELED = 20;
|
||||
public static final int MOTOR_STATUS_DROPPED = 16;
|
||||
public static final int MOTOR_STATUS_INVALID = 10;
|
||||
public static final int MOTOR_STATUS_MAX = 20;
|
||||
public static final int MOTOR_STATUS_MIN = 10;
|
||||
public static final int MOTOR_STATUS_NOT_INIT = -1;
|
||||
public static final int MOTOR_STATUS_POPUP_JAMMED = 12;
|
||||
public static final int MOTOR_STATUS_POPUP_OK = 11;
|
||||
public static final int MOTOR_STATUS_PRESSED = 15;
|
||||
public static final int MOTOR_STATUS_REQUEST_CALIB = 19;
|
||||
public static final int MOTOR_STATUS_TAKEBACK_JAMMED = 14;
|
||||
public static final int MOTOR_STATUS_TAKEBACK_OK = 13;
|
||||
|
||||
public static final String CLOSE_CAMERA_STATE = "0";
|
||||
public static final String OPEN_CAMERA_STATE = "1";
|
||||
|
||||
public static final String FRONT_CAMERA_ID = "1";
|
||||
public static final String BLUE_LED_PATH = "/sys/class/leds/blue/breath";
|
||||
public static final String RED_LED_PATH = "/sys/class/leds/red/breath";
|
||||
public static final String GREEN_LED_PATH =
|
||||
"/sys/class/leds/green/breath";
|
||||
public static final String BLUE_RIGHT_LED_PATH =
|
||||
"/sys/class/leds/blue-right/breath";
|
||||
public static final String RED_RIGHT_LED_PATH =
|
||||
"/sys/class/leds/red-right/breath";
|
||||
public static final String GREEN_RIGHT_LED_PATH =
|
||||
"/sys/class/leds/green-right/breath";
|
||||
public static final String POPUP_SOUND_PATH = "/system/media/audio/ui/";
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS 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 org.lineageos.devicesettings.popupcamera;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
public class PopupCameraPreferences {
|
||||
|
||||
private static final String TAG = "PopupCameraUtils";
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String LED_EFFECT_KEY = "popup_led_effect";
|
||||
private static final boolean LED_EFFECT_DEFAULT_VALUE = true;
|
||||
private static final String SOUND_EFFECT_KEY = "popup_sound_effect";
|
||||
private static final String SOUND_EFFECT_DEFAULT_VALUE = "0";
|
||||
private SharedPreferences mSharedPrefs;
|
||||
|
||||
public PopupCameraPreferences(Context context) {
|
||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
}
|
||||
|
||||
public String getSoundEffect() {
|
||||
return mSharedPrefs.getString(SOUND_EFFECT_KEY, SOUND_EFFECT_DEFAULT_VALUE);
|
||||
}
|
||||
|
||||
public boolean isLedAllowed() {
|
||||
return mSharedPrefs.getBoolean(LED_EFFECT_KEY, LED_EFFECT_DEFAULT_VALUE);
|
||||
}
|
||||
}
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS 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 org.lineageos.devicesettings.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;
|
||||
import android.hardware.SensorManager;
|
||||
import android.hardware.camera2.CameraManager;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.SoundPool;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Toast;
|
||||
import org.lineageos.devicesettings.R;
|
||||
import org.lineageos.devicesettings.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";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private int[] mSounds;
|
||||
private boolean mMotorBusy = false;
|
||||
private long mClosedEvent;
|
||||
private long mOpenEvent;
|
||||
|
||||
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;
|
||||
private SoundPool mSoundPool;
|
||||
|
||||
private CameraManager.AvailabilityCallback availabilityCallback =
|
||||
new CameraManager.AvailabilityCallback() {
|
||||
@Override
|
||||
public void onCameraAvailable(@NonNull String cameraId) {
|
||||
super.onCameraAvailable(cameraId);
|
||||
if (cameraId.equals(Constants.FRONT_CAMERA_ID)) {
|
||||
mClosedEvent = SystemClock.elapsedRealtime();
|
||||
if (SystemClock.elapsedRealtime() - mOpenEvent <
|
||||
Constants.CAMERA_EVENT_DELAY_TIME &&
|
||||
mHandler.hasMessages(Constants.MSG_CAMERA_OPEN)) {
|
||||
mHandler.removeMessages(Constants.MSG_CAMERA_OPEN);
|
||||
}
|
||||
mHandler.sendEmptyMessageDelayed(Constants.MSG_CAMERA_CLOSED,
|
||||
Constants.CAMERA_EVENT_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCameraUnavailable(@NonNull String cameraId) {
|
||||
super.onCameraAvailable(cameraId);
|
||||
if (cameraId.equals(Constants.FRONT_CAMERA_ID)) {
|
||||
mOpenEvent = SystemClock.elapsedRealtime();
|
||||
if (SystemClock.elapsedRealtime() - mClosedEvent <
|
||||
Constants.CAMERA_EVENT_DELAY_TIME &&
|
||||
mHandler.hasMessages(Constants.MSG_CAMERA_CLOSED)) {
|
||||
mHandler.removeMessages(Constants.MSG_CAMERA_CLOSED);
|
||||
}
|
||||
mHandler.sendEmptyMessageDelayed(Constants.MSG_CAMERA_OPEN,
|
||||
Constants.CAMERA_EVENT_DELAY_TIME);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private SensorEventListener mFreeFallListener = new SensorEventListener() {
|
||||
@Override
|
||||
public void onSensorChanged(SensorEvent event) {
|
||||
if (event.values[0] == 2.0f) {
|
||||
updateMotor(Constants.CLOSE_CAMERA_STATE);
|
||||
goBackHome();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
CameraManager cameraManager = getSystemService(CameraManager.class);
|
||||
cameraManager.registerAvailabilityCallback(availabilityCallback, null);
|
||||
mSensorManager = getSystemService(SensorManager.class);
|
||||
mFreeFallSensor =
|
||||
mSensorManager.getDefaultSensor(Constants.FREE_FALL_SENSOR_ID);
|
||||
mPopupCameraPreferences = new PopupCameraPreferences(this);
|
||||
mSoundPool =
|
||||
new SoundPool.Builder()
|
||||
.setMaxStreams(1)
|
||||
.setAudioAttributes(
|
||||
new AudioAttributes.Builder()
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
|
||||
.build())
|
||||
.build();
|
||||
String[] soundNames =
|
||||
getResources().getStringArray(R.array.popupcamera_effects_names);
|
||||
mSounds = new int[soundNames.length];
|
||||
for (int i = 0; i < soundNames.length; i++) {
|
||||
mSounds[i] =
|
||||
mSoundPool.load(Constants.POPUP_SOUND_PATH + soundNames[i], 1);
|
||||
}
|
||||
|
||||
try {
|
||||
mMotor = IMotor.getService();
|
||||
mMotorStatusCallback = new MotorStatusCallback();
|
||||
mMotor.setMotorCallback(mMotorStatusCallback);
|
||||
int status = mMotor.getMotorStatus();
|
||||
if (status == Constants.MOTOR_STATUS_POPUP_OK ||
|
||||
status == Constants.MOTOR_STATUS_POPUP_JAMMED ||
|
||||
status == Constants.MOTOR_STATUS_TAKEBACK_JAMMED) {
|
||||
mHandler.sendEmptyMessage(Constants.MSG_CAMERA_CLOSED);
|
||||
}
|
||||
} 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)
|
||||
Log.d(TAG, "Starting service");
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (DEBUG)
|
||||
Log.d(TAG, "Destroying service");
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void updateMotor(String cameraState) {
|
||||
if (mMotor == null) {
|
||||
return;
|
||||
}
|
||||
final Runnable r = () -> {
|
||||
mMotorBusy = true;
|
||||
try {
|
||||
int status = mMotor.getMotorStatus();
|
||||
if (DEBUG)
|
||||
Log.d(TAG, "updateMotor: status=" + status);
|
||||
if (cameraState.equals(Constants.OPEN_CAMERA_STATE) &&
|
||||
mMotor.getMotorStatus() == Constants.MOTOR_STATUS_TAKEBACK_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_OK) {
|
||||
lightUp();
|
||||
playSoundEffect(Constants.CLOSE_CAMERA_STATE);
|
||||
mMotor.takebackMotor(1);
|
||||
mSensorManager.unregisterListener(mFreeFallListener, mFreeFallSensor);
|
||||
} else {
|
||||
mMotorBusy = false;
|
||||
if (status == Constants.MOTOR_STATUS_REQUEST_CALIB ||
|
||||
status == Constants.MOTOR_STATUS_POPUP_JAMMED ||
|
||||
status == Constants.MOTOR_STATUS_TAKEBACK_JAMMED ||
|
||||
status == Constants.MOTOR_STATUS_CALIB_ERROR) {
|
||||
showErrorDialog();
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
// Do nothing
|
||||
}
|
||||
mHandler.postDelayed(() -> mMotorBusy = false, 1200);
|
||||
};
|
||||
|
||||
if (mMotorBusy) {
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mMotorBusy) {
|
||||
mHandler.postDelayed(this, 100);
|
||||
} else {
|
||||
mHandler.post(r);
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
} else {
|
||||
mHandler.post(r);
|
||||
}
|
||||
}
|
||||
|
||||
private void lightUp() {
|
||||
if (mPopupCameraPreferences.isLedAllowed()) {
|
||||
FileUtils.writeLine(Constants.RED_LED_PATH, "1");
|
||||
FileUtils.writeLine(Constants.GREEN_LED_PATH, "1");
|
||||
FileUtils.writeLine(Constants.BLUE_LED_PATH, "1");
|
||||
FileUtils.writeLine(Constants.RED_RIGHT_LED_PATH, "1");
|
||||
FileUtils.writeLine(Constants.GREEN_RIGHT_LED_PATH, "1");
|
||||
FileUtils.writeLine(Constants.BLUE_RIGHT_LED_PATH, "1");
|
||||
|
||||
mHandler.postDelayed(() -> {
|
||||
FileUtils.writeLine(Constants.RED_LED_PATH, "0");
|
||||
FileUtils.writeLine(Constants.GREEN_LED_PATH, "0");
|
||||
FileUtils.writeLine(Constants.BLUE_LED_PATH, "0");
|
||||
FileUtils.writeLine(Constants.RED_RIGHT_LED_PATH, "0");
|
||||
FileUtils.writeLine(Constants.GREEN_RIGHT_LED_PATH, "0");
|
||||
FileUtils.writeLine(Constants.BLUE_RIGHT_LED_PATH, "0");
|
||||
}, 2300);
|
||||
}
|
||||
}
|
||||
|
||||
private void showCalibrationResult(int status) {
|
||||
mHandler.post(() -> {
|
||||
Toast
|
||||
.makeText(PopupCameraService.this,
|
||||
status == Constants.MOTOR_STATUS_CALIB_OK
|
||||
? R.string.popup_camera_calibrate_success
|
||||
: R.string.popup_camera_calibrate_failed,
|
||||
Toast.LENGTH_LONG)
|
||||
.show();
|
||||
});
|
||||
}
|
||||
|
||||
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_times_calibrate
|
||||
: R.string.popup_camera_popup_failed_times_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) {
|
||||
if (state.equals(Constants.CLOSE_CAMERA_STATE)) {
|
||||
soundEffect++;
|
||||
}
|
||||
mSoundPool.play(mSounds[soundEffect], 1.0f, 1.0f, 0, 0, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void goBackHome() {
|
||||
Intent homeIntent = new Intent(Intent.ACTION_MAIN);
|
||||
homeIntent.addCategory(Intent.CATEGORY_HOME);
|
||||
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivityAsUser(homeIntent, null, UserHandle.CURRENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case Constants.MSG_CAMERA_CLOSED: {
|
||||
updateMotor(Constants.CLOSE_CAMERA_STATE);
|
||||
} break;
|
||||
case Constants.MSG_CAMERA_OPEN: {
|
||||
updateMotor(Constants.OPEN_CAMERA_STATE);
|
||||
} break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 The CyanogenMod Project
|
||||
* 2017 The LineageOS 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 org.lineageos.devicesettings.popupcamera;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
public class PopupCameraSettingsActivity extends PreferenceActivity {
|
||||
|
||||
private static final String TAG_POPUPCAMERA = "popupcamera";
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getFragmentManager()
|
||||
.beginTransaction()
|
||||
.replace(android.R.id.content, new PopupCameraSettingsFragment(),
|
||||
TAG_POPUPCAMERA)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The LineageOS 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 org.lineageos.devicesettings.popupcamera;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.Preference.OnPreferenceChangeListener;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import org.lineageos.devicesettings.R;
|
||||
|
||||
public class PopupCameraSettingsFragment
|
||||
extends PreferenceFragment implements OnPreferenceChangeListener {
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.popup_settings);
|
||||
getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
getActivity().onBackPressed();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 The LineageOS 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 org.lineageos.devicesettings.popupcamera;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.UserHandle;
|
||||
|
||||
public class PopupCameraUtils {
|
||||
|
||||
private static final String TAG = "PopupCameraUtils";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public static void startService(Context context) {
|
||||
context.startServiceAsUser(new Intent(context, PopupCameraService.class),
|
||||
UserHandle.CURRENT);
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The CyanogenMod 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 org.lineageos.devicesettings.utils;
|
||||
|
||||
import android.util.Log;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
||||
public final class FileUtils {
|
||||
private static final String TAG = "FileUtils";
|
||||
|
||||
private FileUtils() {
|
||||
// This class is not supposed to be instantiated
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the first line of text from the given file.
|
||||
* Reference {@link BufferedReader#readLine()} for clarification on what a
|
||||
* line is
|
||||
*
|
||||
* @return the read line contents, or null on failure
|
||||
*/
|
||||
public static String readOneLine(String fileName) {
|
||||
String line = null;
|
||||
BufferedReader reader = null;
|
||||
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(fileName), 512);
|
||||
line = reader.readLine();
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, "No such file " + fileName + " for reading", e);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not read from file " + fileName, e);
|
||||
} finally {
|
||||
try {
|
||||
if (reader != null) {
|
||||
reader.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored, not much we can do anyway
|
||||
}
|
||||
}
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given value into the given file
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
public static boolean writeLine(String fileName, String value) {
|
||||
BufferedWriter writer = null;
|
||||
|
||||
try {
|
||||
writer = new BufferedWriter(new FileWriter(fileName));
|
||||
writer.write(value);
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(TAG, "No such file " + fileName + " for writing", e);
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Could not write to file " + fileName, e);
|
||||
return false;
|
||||
} finally {
|
||||
try {
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignored, not much we can do anyway
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given file exists
|
||||
*
|
||||
* @return true if exists, false if not
|
||||
*/
|
||||
public static boolean fileExists(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given file is readable
|
||||
*
|
||||
* @return true if readable, false if not
|
||||
*/
|
||||
public static boolean isFileReadable(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
return file.exists() && file.canRead();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given file is writable
|
||||
*
|
||||
* @return true if writable, false if not
|
||||
*/
|
||||
public static boolean isFileWritable(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
return file.exists() && file.canWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an existing file
|
||||
*
|
||||
* @return true if the delete was successful, false if not
|
||||
*/
|
||||
public static boolean delete(String fileName) {
|
||||
final File file = new File(fileName);
|
||||
boolean ok = false;
|
||||
try {
|
||||
ok = file.delete();
|
||||
} catch (SecurityException e) {
|
||||
Log.w(TAG, "SecurityException trying to delete " + fileName, e);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames an existing file
|
||||
*
|
||||
* @return true if the rename was successful, false if not
|
||||
*/
|
||||
public static boolean rename(String srcPath, String dstPath) {
|
||||
final File srcFile = new File(srcPath);
|
||||
final File dstFile = new File(dstPath);
|
||||
boolean ok = false;
|
||||
try {
|
||||
ok = srcFile.renameTo(dstFile);
|
||||
} catch (SecurityException e) {
|
||||
Log.w(TAG,
|
||||
"SecurityException trying to rename " + srcPath + " to " + dstPath,
|
||||
e);
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(TAG,
|
||||
"NullPointerException trying to rename " + srcPath + " to " +
|
||||
dstPath,
|
||||
e);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
}
|
||||
@@ -346,30 +346,6 @@ vendor/firmware/lmi_tele_rohm_ois.prog
|
||||
vendor/firmware/lmi_wide_ois_ST.coeff
|
||||
vendor/firmware/lmi_wide_ois_ST.prog
|
||||
|
||||
# Camera motor
|
||||
vendor/bin/hw/vendor.xiaomi.hardware.motor@1.0-service
|
||||
vendor/etc/init/init.lmi.rc
|
||||
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 motor sound
|
||||
media/audio/ui/popup_cangmen_down.ogg
|
||||
media/audio/ui/popup_cangmen_up.ogg
|
||||
media/audio/ui/popup_chilun_down.ogg
|
||||
media/audio/ui/popup_chilun_up.ogg
|
||||
media/audio/ui/popup_jijia_down.ogg
|
||||
media/audio/ui/popup_jijia_up.ogg
|
||||
media/audio/ui/popup_mofa_down.ogg
|
||||
media/audio/ui/popup_mofa_up.ogg
|
||||
media/audio/ui/popup_muqin_down.ogg
|
||||
media/audio/ui/popup_muqin_up.ogg
|
||||
media/audio/ui/popup_yingyan_down.ogg
|
||||
media/audio/ui/popup_yingyan_up.ogg
|
||||
|
||||
# Display
|
||||
vendor/etc/qdcm_calib_data_xiaomi_j11_38_08_0a_fhd_panel.xml
|
||||
|
||||
|
||||
Reference in New Issue
Block a user