mirror of
https://github.com/chararomandroid/android_device_samsung_a20
synced 2026-08-22 04:05:31 -04:00
unversal7885: SamsungParts: Convert to Kotlin
This commit is contained in:
parent
3eeab18801
commit
e3848cdb11
60 changed files with 1657 additions and 2217 deletions
|
|
@ -1,7 +1,6 @@
|
|||
android_app {
|
||||
name: "SamsungParts",
|
||||
srcs: [
|
||||
"src/**/*.java",
|
||||
"src/**/*.kt",
|
||||
],
|
||||
platform_apis: true,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Java_com_eurekateam_samsungextras_interfaces_Battery_getChargeSysfs
|
|||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_eurekateam_samsungextras_interfaces_Battery_setFastCharge(JNIEnv *env, __unused jclass obj,
|
||||
Java_com_eurekateam_samsungextras_interfaces_Battery_setFastCharge(JNIEnv *env, __unused jobject obj,
|
||||
jint enable) {
|
||||
android::sp<IBattery> service = IBattery::getService();
|
||||
if (enable == 1){
|
||||
|
|
@ -52,9 +52,7 @@ jclass obj) {
|
|||
}
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_eurekateam_samsungextras_interfaces_Battery_getGeneralBatteryStats(JNIEnv *env,
|
||||
__unused
|
||||
jclass obj, jint id) {
|
||||
Java_com_eurekateam_samsungextras_interfaces_Battery_getGeneralBatteryStats(JNIEnv *env,__unused jobject obj, jint id) {
|
||||
/**
|
||||
* id:
|
||||
* 1 = BATTERY_CAPACITY_MAX
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ using android::sp;
|
|||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_com_eurekateam_samsungextras_interfaces_Flashlight_setFlash(JNIEnv *env, __unused jclass obj,
|
||||
Java_com_eurekateam_samsungextras_interfaces_Flashlight_setFlash(JNIEnv *env, __unused jobject obj,
|
||||
jint value) {
|
||||
android::sp<IFlashlight> service = IFlashlight::getService();
|
||||
service->setFlashlightEnable(Enable::ENABLE);
|
||||
|
|
@ -55,14 +55,10 @@ Java_com_eurekateam_samsungextras_interfaces_Flashlight_setFlash(JNIEnv *env, __
|
|||
}
|
||||
extern "C"
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_eurekateam_samsungextras_interfaces_Flashlight_getFlash(JNIEnv *env, jclass clazz,
|
||||
Java_com_eurekateam_samsungextras_interfaces_Flashlight_getFlash(JNIEnv *env, jobject clazz,
|
||||
jint isA10) {
|
||||
android::sp<IFlashlight> service = IFlashlight::getService();
|
||||
int ret;
|
||||
if(isA10 == 1) {
|
||||
ret = service->readFlashlightstats(Device::A10);
|
||||
}else{
|
||||
ret = service->readFlashlightstats(Device::NOTA10);
|
||||
}
|
||||
ret = service->readFlashlightstats(Device::A10);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -23,7 +23,8 @@
|
|||
android:paddingStart="?android:attr/listPreferredItemPaddingStart"
|
||||
android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
|
||||
android:background="?android:attr/activatedBackgroundIndicator"
|
||||
android:clipToPadding="false">
|
||||
android:clipToPadding="false"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@android:id/icon_frame"
|
||||
|
|
@ -45,7 +46,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingTop="16dp"
|
||||
|
|
@ -127,11 +128,11 @@
|
|||
android:id="@+id/seekbar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginEnd="3dp"
|
||||
android:layout_toEndOf="@id/minus"
|
||||
android:layout_toStartOf="@id/plus"
|
||||
android:layout_centerVertical="true" />
|
||||
android:layout_centerVertical="true"
|
||||
android:orientation="horizontal" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
|
|
|
|||
|
|
@ -34,10 +34,9 @@
|
|||
android:ellipsize="end"
|
||||
android:textAppearance="@android:style/TextAppearance.Material.Title"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:textAlignment="viewStart"
|
||||
android:text="@string/switch_bar_on" />
|
||||
|
||||
<Switch
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@android:id/switch_widget"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
<SwitchPreference
|
||||
android:key="dolby_pref"
|
||||
android:title="@string/dolby_title"
|
||||
android:icon="@drawable/dolby"
|
||||
android:icon="@drawable/ic_speaker_cleaner_icon"
|
||||
android:summary="@string/dolby_summary"/>
|
||||
|
||||
<ListPreference
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
import com.eurekateam.samsungextras.interfaces.GPU;
|
||||
|
||||
|
||||
public class BootReceiver extends BroadcastReceiver {
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
|
||||
if (context != null) {
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
boolean fpsenabled = sharedPrefs.getBoolean(DeviceSettings.PREF_KEY_FPS_INFO, false);
|
||||
if (fpsenabled) {
|
||||
context.startService(new Intent(context, FPSInfoService.class));
|
||||
}
|
||||
boolean gpuenabled = sharedPrefs.getBoolean(DeviceSettings.PREF_GPUEXYNOS, false);
|
||||
if (!gpuenabled){
|
||||
GPU.setGPU(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.eurekateam.samsungextras.interfaces.GPU
|
||||
|
||||
class BootReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action.equals(Intent.ACTION_BOOT_COMPLETED, ignoreCase = true)) {
|
||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val fpsenabled = sharedPrefs.getBoolean(DeviceSettings.PREF_KEY_FPS_INFO, false)
|
||||
if (fpsenabled) {
|
||||
context.startService(Intent(context, FPSInfoService::class.java))
|
||||
}
|
||||
val gpuenabled = sharedPrefs.getBoolean(DeviceSettings.PREF_GPUEXYNOS, true)
|
||||
if (gpuenabled) {
|
||||
GPU.GPU = 1
|
||||
}else{
|
||||
GPU.GPU = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.eurekateam.samsungextras.battery.BatteryActivity;
|
||||
import com.eurekateam.samsungextras.flashlight.FlashLightActivity;
|
||||
import com.eurekateam.samsungextras.interfaces.GPU;
|
||||
import com.eurekateam.samsungextras.interfaces.SELinux;
|
||||
import com.eurekateam.samsungextras.speaker.ClearSpeakerActivity;
|
||||
|
||||
public class DeviceSettings extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
public static final String PREF_KEY_FPS_INFO = "fps_info";
|
||||
private static final String PREF_CLEAR_SPEAKER = "clear_speaker_settings";
|
||||
private static final String PREF_FLASHLIGHT = "flashlight_settings";
|
||||
public static final String PREF_GPUEXYNOS = "gpuexynos_settings";
|
||||
private static final String PREF_SELINUX = "selinux_settings";
|
||||
public static final String PREF_BATTERY = "battery_settings";
|
||||
|
||||
public DeviceSettings() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
System.loadLibrary("samsungparts_jni");
|
||||
setPreferencesFromResource(R.xml.preferences_samsung_parts, rootKey);
|
||||
Context mContext = this.getContext();
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
Preference mClearSpeakerPref = findPreference(PREF_CLEAR_SPEAKER);
|
||||
assert mClearSpeakerPref != null;
|
||||
mClearSpeakerPref.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(getActivity().getApplicationContext(), ClearSpeakerActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
|
||||
SwitchPreference mFpsInfo = findPreference(PREF_KEY_FPS_INFO);
|
||||
assert mFpsInfo != null;
|
||||
mFpsInfo.setChecked(prefs.getBoolean(PREF_KEY_FPS_INFO, false));
|
||||
mFpsInfo.setOnPreferenceChangeListener(this);
|
||||
|
||||
SwitchPreference mGPUExynos = findPreference(PREF_GPUEXYNOS);
|
||||
assert mGPUExynos != null;
|
||||
mGPUExynos.setChecked(GPU.getGPU() == 1);
|
||||
mGPUExynos.setOnPreferenceChangeListener(this);
|
||||
|
||||
Preference mSELinux = findPreference(PREF_SELINUX);
|
||||
assert mSELinux != null;
|
||||
mSELinux.setOnPreferenceClickListener(preference -> {
|
||||
Toast.makeText(getContext(), SELinux.getSELinux() == 1 ?
|
||||
"SELinux is in enforcing state." :
|
||||
"SELinux is in permissive state.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
});
|
||||
|
||||
Preference mFlashLight = findPreference(PREF_FLASHLIGHT);
|
||||
assert mFlashLight != null;
|
||||
mFlashLight.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(getActivity().getApplicationContext(), FlashLightActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
Preference mFastCharge = findPreference(PREF_BATTERY);
|
||||
assert mFastCharge != null;
|
||||
mFastCharge.setOnPreferenceClickListener(preference -> {
|
||||
Intent intent = new Intent(getActivity().getApplicationContext(), BatteryActivity.class);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object value) {
|
||||
final String key = preference.getKey();
|
||||
switch (key) {
|
||||
case PREF_KEY_FPS_INFO:
|
||||
boolean fps_enabled = (Boolean) value;
|
||||
Intent fpsinfo = new Intent(this.getContext(), FPSInfoService.class);
|
||||
if (fps_enabled) {
|
||||
this.getContext().startService(fpsinfo);
|
||||
} else {
|
||||
this.getContext().stopService(fpsinfo);
|
||||
}
|
||||
break;
|
||||
case PREF_GPUEXYNOS:
|
||||
boolean gpu_enabled = (Boolean) value;
|
||||
GPU.setGPU(gpu_enabled ? 1 : 0);
|
||||
Toast.makeText(getContext(), gpu_enabled ? "GPU Throttling is now enabled."
|
||||
: "GPU Throttling is now disabled.",
|
||||
Toast.LENGTH_SHORT).show();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragment
|
||||
import androidx.preference.PreferenceManager
|
||||
import androidx.preference.SwitchPreference
|
||||
import com.eurekateam.samsungextras.battery.BatteryActivity
|
||||
import com.eurekateam.samsungextras.flashlight.FlashLightActivity
|
||||
import com.eurekateam.samsungextras.interfaces.GPU.GPU
|
||||
import com.eurekateam.samsungextras.interfaces.SELinux.SELinux
|
||||
import com.eurekateam.samsungextras.speaker.ClearSpeakerActivity
|
||||
|
||||
class DeviceSettings : PreferenceFragment(), Preference.OnPreferenceChangeListener {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
System.loadLibrary("samsungparts_jni")
|
||||
setPreferencesFromResource(R.xml.preferences_samsung_parts, rootKey)
|
||||
val mContext = this.context
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||
val mClearSpeakerPref = findPreference<Preference>(PREF_CLEAR_SPEAKER)!!
|
||||
mClearSpeakerPref.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
val intent = Intent(activity.applicationContext, ClearSpeakerActivity::class.java)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
val mFpsInfo = findPreference<SwitchPreference>(PREF_KEY_FPS_INFO)!!
|
||||
mFpsInfo.isChecked = prefs.getBoolean(PREF_KEY_FPS_INFO, false)
|
||||
mFpsInfo.onPreferenceChangeListener = this
|
||||
val mGPUExynos = findPreference<SwitchPreference>(PREF_GPUEXYNOS)!!
|
||||
mGPUExynos.isChecked = GPU == 1
|
||||
mGPUExynos.onPreferenceChangeListener = this
|
||||
val mSELinux = findPreference<Preference>(PREF_SELINUX)!!
|
||||
mSELinux.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
Toast.makeText(
|
||||
context,
|
||||
if (SELinux == 1) "SELinux is in enforcing state." else "SELinux is in permissive state.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
true
|
||||
}
|
||||
val mFlashLight = findPreference<Preference>(PREF_FLASHLIGHT)!!
|
||||
mFlashLight.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
val intent = Intent(activity.applicationContext, FlashLightActivity::class.java)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
val mFastCharge = findPreference<Preference>(PREF_BATTERY)!!
|
||||
mFastCharge.onPreferenceClickListener =
|
||||
Preference.OnPreferenceClickListener {
|
||||
val intent = Intent(activity.applicationContext, BatteryActivity::class.java)
|
||||
startActivity(intent)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, value: Any): Boolean {
|
||||
when (preference.key) {
|
||||
PREF_KEY_FPS_INFO -> {
|
||||
val fps_enabled = value as Boolean
|
||||
val fpsinfo = Intent(this.context, FPSInfoService::class.java)
|
||||
if (fps_enabled) {
|
||||
this.context.startService(fpsinfo)
|
||||
} else {
|
||||
this.context.stopService(fpsinfo)
|
||||
}
|
||||
}
|
||||
PREF_GPUEXYNOS -> {
|
||||
val gpu_enabled = value as Boolean
|
||||
GPU = if (gpu_enabled) 1 else 0
|
||||
Toast.makeText(
|
||||
context,
|
||||
if (gpu_enabled) "GPU Throttling is now enabled." else "GPU Throttling is now disabled.",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PREF_KEY_FPS_INFO = "fps_info"
|
||||
private const val PREF_CLEAR_SPEAKER = "clear_speaker_settings"
|
||||
private const val PREF_FLASHLIGHT = "flashlight_settings"
|
||||
const val PREF_GPUEXYNOS = "gpuexynos_settings"
|
||||
private const val PREF_SELINUX = "selinux_settings"
|
||||
const val PREF_BATTERY = "battery_settings"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
public class DeviceSettingsActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
|
||||
DeviceSettings mDeviceSettingsFragment;
|
||||
if (fragment == null) {
|
||||
mDeviceSettingsFragment = new DeviceSettings();
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(android.R.id.content, mDeviceSettingsFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import com.android.internal.R.id.content
|
||||
import com.android.internal.R.id.home
|
||||
|
||||
class DeviceSettingsActivity : Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
val fragment = fragmentManager.findFragmentById(content)
|
||||
val mDeviceSettingsFragment: DeviceSettings
|
||||
if (fragment == null) {
|
||||
mDeviceSettingsFragment = DeviceSettings()
|
||||
fragmentManager.beginTransaction()
|
||||
.add(content, mDeviceSettingsFragment)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == home) {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
package com.eurekateam.samsungextras;
|
||||
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
|
||||
import com.eurekateam.samsungextras.dolby.DolbyCore;
|
||||
|
||||
public class DolbyTile extends TileService {
|
||||
private boolean isRunning;
|
||||
DolbyCore dolbyCore = new DolbyCore();
|
||||
@Override
|
||||
public void onStartListening() {
|
||||
super.onStartListening();
|
||||
isRunning = dolbyCore.isRunning();
|
||||
updateTile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
if (isRunning) {
|
||||
dolbyCore.stopDolbyEffect();
|
||||
}else{
|
||||
dolbyCore.justStartOnly();
|
||||
}
|
||||
isRunning = !isRunning;
|
||||
updateTile();
|
||||
}
|
||||
private void updateTile() {
|
||||
final Tile tile = getQsTile();
|
||||
tile.setState(isRunning ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
|
||||
tile.updateTile();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.eurekateam.samsungextras
|
||||
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import com.eurekateam.samsungextras.dolby.DolbyCore
|
||||
|
||||
class DolbyTile : TileService() {
|
||||
private var isRunning = false
|
||||
private var dolbyCore = DolbyCore()
|
||||
override fun onStartListening() {
|
||||
super.onStartListening()
|
||||
isRunning = dolbyCore.isRunning()
|
||||
updateTile()
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
if (isRunning) {
|
||||
dolbyCore.stopDolbyEffect()
|
||||
} else {
|
||||
dolbyCore.justStartOnly()
|
||||
}
|
||||
isRunning = !isRunning
|
||||
updateTile()
|
||||
}
|
||||
|
||||
private fun updateTile() {
|
||||
val tile = qsTile
|
||||
tile.state =
|
||||
if (isRunning) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
|
||||
tile.updateTile()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,282 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.service.dreams.DreamService;
|
||||
import android.service.dreams.IDreamManager;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class FPSInfoService extends Service {
|
||||
private View mView;
|
||||
private Thread mCurFPSThread;
|
||||
private static SurfaceFlingerFPS surfaceFlingerFPS;
|
||||
private final String TAG = "FPSInfoService";
|
||||
private String mFps = null;
|
||||
|
||||
private IDreamManager mDreamManager;
|
||||
|
||||
private class FPSView extends View {
|
||||
private final Paint mOnlinePaint;
|
||||
private final float mAscent;
|
||||
private int mMaxWidth = 0;
|
||||
|
||||
private int mNeededWidth;
|
||||
private int mNeededHeight;
|
||||
|
||||
private boolean mDataAvail;
|
||||
|
||||
private final Handler mCurFPSHandler = new Handler(Looper.getMainLooper()) {
|
||||
public void handleMessage(Message msg) {
|
||||
if (msg.obj == null || msg.what != 1) {
|
||||
return;
|
||||
}
|
||||
String msgData = (String) msg.obj;
|
||||
mFps = msgData + " FPS";
|
||||
mDataAvail = true;
|
||||
updateDisplay();
|
||||
}
|
||||
};
|
||||
|
||||
FPSView(Context c) {
|
||||
super(c);
|
||||
float density = c.getResources().getDisplayMetrics().density;
|
||||
int paddingPx = Math.round(5 * density);
|
||||
setPadding(paddingPx, paddingPx, paddingPx, paddingPx);
|
||||
setBackgroundColor(Color.argb(0x60, 0, 0, 0));
|
||||
|
||||
final int textSize = Math.round(12 * density);
|
||||
|
||||
Typeface typeface = Typeface.create("monospace", Typeface.NORMAL);
|
||||
|
||||
mOnlinePaint = new Paint();
|
||||
mOnlinePaint.setTypeface(typeface);
|
||||
mOnlinePaint.setAntiAlias(true);
|
||||
mOnlinePaint.setTextSize(textSize);
|
||||
mOnlinePaint.setColor(Color.WHITE);
|
||||
mOnlinePaint.setShadowLayer(5.0f, 0.0f, 0.0f, Color.BLACK);
|
||||
|
||||
mAscent = mOnlinePaint.ascent();
|
||||
mOnlinePaint.descent();
|
||||
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mCurFPSHandler.removeMessages(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setMeasuredDimension(resolveSize(mNeededWidth, widthMeasureSpec),
|
||||
resolveSize(mNeededHeight, heightMeasureSpec));
|
||||
}
|
||||
|
||||
private String getFPSInfoString() {
|
||||
return mFps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
if (!mDataAvail) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int LEFT = getWidth() - 1;
|
||||
|
||||
int y = mPaddingTop - (int) mAscent;
|
||||
|
||||
String s = getFPSInfoString();
|
||||
canvas.drawText(s, LEFT - mPaddingLeft - mMaxWidth,
|
||||
y - 1, mOnlinePaint);
|
||||
}
|
||||
|
||||
void updateDisplay() {
|
||||
if (!mDataAvail) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOnlinePaint != null) {
|
||||
mMaxWidth = (int) mOnlinePaint.measureText(mFps);
|
||||
}
|
||||
|
||||
int neededWidth = mPaddingLeft + mPaddingRight + mMaxWidth;
|
||||
int neededHeight = mPaddingTop + mPaddingBottom + 40;
|
||||
if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
|
||||
mNeededWidth = neededWidth;
|
||||
mNeededHeight = neededHeight;
|
||||
requestLayout();
|
||||
} else {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public Handler getHandler() {
|
||||
return mCurFPSHandler;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thead to monitor fps
|
||||
*/
|
||||
protected static class CurFPSThread extends Thread {
|
||||
private boolean mInterrupt = false;
|
||||
private final Handler mHandler;
|
||||
|
||||
public CurFPSThread(Handler handler) {
|
||||
mHandler = handler;
|
||||
}
|
||||
|
||||
public void interrupt() {
|
||||
mInterrupt = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
while (!mInterrupt) {
|
||||
sleep(500);
|
||||
new StringBuilder();
|
||||
String fpsVal = String.valueOf(Math.round(surfaceFlingerFPS.getFps()));
|
||||
mHandler.sendMessage(mHandler.obtainMessage(1, fpsVal));
|
||||
}
|
||||
} catch (InterruptedException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
mView = new FPSView(this);
|
||||
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
|
||||
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
params.y = 50;
|
||||
params.gravity = Gravity.START | Gravity.TOP;
|
||||
params.setTitle("FPS Info");
|
||||
surfaceFlingerFPS = SurfaceFlingerFPS.getInstance();
|
||||
startThread();
|
||||
|
||||
mDreamManager = IDreamManager.Stub.asInterface(
|
||||
ServiceManager.checkService(DreamService.DREAM_SERVICE));
|
||||
IntentFilter screenStateFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
|
||||
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
registerReceiver(mScreenStateReceiver, screenStateFilter);
|
||||
|
||||
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
wm.addView(mView, params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
stopThread();
|
||||
((WindowManager) getSystemService(WINDOW_SERVICE)).removeView(mView);
|
||||
mView = null;
|
||||
unregisterReceiver(mScreenStateReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
private final BroadcastReceiver mScreenStateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
|
||||
Log.d(TAG, "ACTION_SCREEN_ON " + isDozeMode());
|
||||
if (!isDozeMode()) {
|
||||
startThread();
|
||||
mView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
Log.d(TAG, "ACTION_SCREEN_OFF");
|
||||
mView.setVisibility(View.GONE);
|
||||
stopThread();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Find is the device is in doze mode
|
||||
* @return true if device is in doze mode, else false
|
||||
*/
|
||||
private boolean isDozeMode() {
|
||||
try {
|
||||
if (mDreamManager != null && mDreamManager.isDreaming()) {
|
||||
return true;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void startThread() {
|
||||
Log.d(TAG, "started CurFPSThread");
|
||||
mCurFPSThread = new CurFPSThread(mView.getHandler());
|
||||
surfaceFlingerFPS.start();
|
||||
mCurFPSThread.start();
|
||||
}
|
||||
|
||||
private void stopThread() {
|
||||
if (mCurFPSThread != null && mCurFPSThread.isAlive()) {
|
||||
Log.d(TAG, "stopping CurFPSThread");
|
||||
surfaceFlingerFPS.stop();
|
||||
mCurFPSThread.interrupt();
|
||||
try {
|
||||
mCurFPSThread.join();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mCurFPSThread = null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* Copyright (C) 2020 The Xiaomi-SM6250 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 com.eurekateam.samsungextras
|
||||
|
||||
import android.app.Service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.*
|
||||
import android.os.*
|
||||
import android.service.dreams.DreamService
|
||||
import android.service.dreams.IDreamManager
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
open class FPSInfoService : Service() {
|
||||
private var mView: View? = null
|
||||
private var mCurFPSThread: Thread? = null
|
||||
private val TAG = "FPSInfoService"
|
||||
private var fPSInfoString: String? = null
|
||||
private var mDreamManager: IDreamManager? = null
|
||||
|
||||
private inner class FPSView(c: Context) : View(c) {
|
||||
private val mOnlinePaint: Paint?
|
||||
private val mAscent: Float
|
||||
private var mMaxWidth = 0
|
||||
private var mNeededWidth = 0
|
||||
private var mNeededHeight = 0
|
||||
private var mDataAvail = false
|
||||
private val mCurFPSHandler: Handler = object : Handler(Looper.getMainLooper()) {
|
||||
override fun handleMessage(msg: Message) {
|
||||
if (msg.obj == null || msg.what != 1) {
|
||||
return
|
||||
}
|
||||
val msgData = msg.obj as String
|
||||
fPSInfoString = "$msgData FPS"
|
||||
mDataAvail = true
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
mCurFPSHandler.removeMessages(1)
|
||||
}
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
setMeasuredDimension(
|
||||
resolveSize(mNeededWidth, widthMeasureSpec),
|
||||
resolveSize(mNeededHeight, heightMeasureSpec)
|
||||
)
|
||||
}
|
||||
|
||||
public override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
if (!mDataAvail) {
|
||||
return
|
||||
}
|
||||
val LEFT = width - 1
|
||||
val y = mPaddingTop - mAscent.toInt()
|
||||
val s = fPSInfoString
|
||||
canvas.drawText(
|
||||
s, (LEFT - mPaddingLeft - mMaxWidth).toFloat(), (
|
||||
y - 1).toFloat(), mOnlinePaint
|
||||
)
|
||||
}
|
||||
|
||||
fun updateDisplay() {
|
||||
if (!mDataAvail) {
|
||||
return
|
||||
}
|
||||
if (mOnlinePaint != null) {
|
||||
mMaxWidth = mOnlinePaint.measureText(fPSInfoString).toInt()
|
||||
}
|
||||
val neededWidth = mPaddingLeft + mPaddingRight + mMaxWidth
|
||||
val neededHeight = mPaddingTop + mPaddingBottom + 40
|
||||
if (neededWidth != mNeededWidth || neededHeight != mNeededHeight) {
|
||||
mNeededWidth = neededWidth
|
||||
mNeededHeight = neededHeight
|
||||
requestLayout()
|
||||
} else {
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun getHandler(): Handler {
|
||||
return mCurFPSHandler
|
||||
}
|
||||
|
||||
init {
|
||||
val density = c.resources.displayMetrics.density
|
||||
val paddingPx = (5 * density).roundToInt()
|
||||
setPadding(paddingPx, paddingPx, paddingPx, paddingPx)
|
||||
setBackgroundColor(Color.argb(0x60, 0, 0, 0))
|
||||
val textSize = (12 * density).roundToInt()
|
||||
val typeface = Typeface.create("monospace", Typeface.NORMAL)
|
||||
mOnlinePaint = Paint()
|
||||
mOnlinePaint.typeface = typeface
|
||||
mOnlinePaint.isAntiAlias = true
|
||||
mOnlinePaint.textSize = textSize.toFloat()
|
||||
mOnlinePaint.color = Color.WHITE
|
||||
mOnlinePaint.setShadowLayer(5.0f, 0.0f, 0.0f, Color.BLACK)
|
||||
mAscent = mOnlinePaint.ascent()
|
||||
mOnlinePaint.descent()
|
||||
updateDisplay()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thead to monitor fps
|
||||
*/
|
||||
protected class CurFPSThread(private val mHandler: Handler) : Thread() {
|
||||
private var mInterrupt = false
|
||||
override fun interrupt() {
|
||||
mInterrupt = true
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
while (!mInterrupt) {
|
||||
sleep(500)
|
||||
StringBuilder()
|
||||
val fpsVal = surfaceFlingerFPS?.fps?.roundToInt().toString()
|
||||
mHandler.sendMessage(mHandler.obtainMessage(1, fpsVal))
|
||||
}
|
||||
} catch (ignored: InterruptedException) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
mView = FPSView(this)
|
||||
val params = WindowManager.LayoutParams(
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT,
|
||||
WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY,
|
||||
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
|
||||
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
|
||||
PixelFormat.TRANSLUCENT
|
||||
)
|
||||
params.y = 50
|
||||
params.gravity = Gravity.START or Gravity.TOP
|
||||
params.title = "FPS Info"
|
||||
surfaceFlingerFPS = SurfaceFlingerFPS.instance
|
||||
startThread()
|
||||
mDreamManager = IDreamManager.Stub.asInterface(
|
||||
ServiceManager.checkService(DreamService.DREAM_SERVICE)
|
||||
)
|
||||
val screenStateFilter = IntentFilter(Intent.ACTION_SCREEN_ON)
|
||||
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||
registerReceiver(mScreenStateReceiver, screenStateFilter)
|
||||
val wm = getSystemService(WINDOW_SERVICE) as WindowManager
|
||||
wm.addView(mView, params)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
stopThread()
|
||||
(getSystemService(WINDOW_SERVICE) as WindowManager).removeView(mView)
|
||||
mView = null
|
||||
unregisterReceiver(mScreenStateReceiver)
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
private val mScreenStateReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
if (intent.action == Intent.ACTION_SCREEN_ON) {
|
||||
Log.d(TAG, "ACTION_SCREEN_ON $isDozeMode")
|
||||
if (!isDozeMode) {
|
||||
startThread()
|
||||
mView!!.visibility = View.VISIBLE
|
||||
}
|
||||
} else if (intent.action == Intent.ACTION_SCREEN_OFF) {
|
||||
Log.d(TAG, "ACTION_SCREEN_OFF")
|
||||
mView!!.visibility = View.GONE
|
||||
stopThread()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find is the device is in doze mode
|
||||
* @return true if device is in doze mode, else false
|
||||
*/
|
||||
private val isDozeMode: Boolean
|
||||
get() {
|
||||
try {
|
||||
if (mDreamManager != null && mDreamManager!!.isDreaming) {
|
||||
return true
|
||||
}
|
||||
} catch (e: RemoteException) {
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun startThread() {
|
||||
Log.d(TAG, "started CurFPSThread")
|
||||
mCurFPSThread = CurFPSThread(mView!!.handler)
|
||||
surfaceFlingerFPS!!.start()
|
||||
mCurFPSThread?.start()
|
||||
}
|
||||
|
||||
private fun stopThread() {
|
||||
if (mCurFPSThread != null && mCurFPSThread!!.isAlive) {
|
||||
Log.d(TAG, "stopping CurFPSThread")
|
||||
surfaceFlingerFPS!!.stop()
|
||||
mCurFPSThread!!.interrupt()
|
||||
try {
|
||||
mCurFPSThread!!.join()
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
mCurFPSThread = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private var surfaceFlingerFPS: SurfaceFlingerFPS? = null
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Xiaomi-SM6250 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 com.eurekateam.samsungextras;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Intent;
|
||||
import android.service.quicksettings.Tile;
|
||||
import android.service.quicksettings.TileService;
|
||||
|
||||
// TODO: Add FPS drawables
|
||||
public class FPSTileService extends TileService {
|
||||
|
||||
private boolean isShowing = false;
|
||||
|
||||
public FPSTileService() { }
|
||||
|
||||
@Override
|
||||
public void onStartListening() {
|
||||
super.onStartListening();
|
||||
ActivityManager manager =
|
||||
(ActivityManager) getSystemService(ACTIVITY_SERVICE);
|
||||
for (ActivityManager.RunningServiceInfo service :
|
||||
manager.getRunningServices(Integer.MAX_VALUE)) {
|
||||
if (FPSInfoService.class.getName().equals(
|
||||
service.service.getClassName())) {
|
||||
isShowing = true;
|
||||
}
|
||||
}
|
||||
updateTile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
Intent fpsinfo = new Intent(this, FPSInfoService.class);
|
||||
if (!isShowing)
|
||||
this.startService(fpsinfo);
|
||||
else
|
||||
this.stopService(fpsinfo);
|
||||
isShowing = !isShowing;
|
||||
updateTile();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update tile
|
||||
*/
|
||||
private void updateTile() {
|
||||
final Tile tile = getQsTile();
|
||||
tile.setState(isShowing ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
|
||||
tile.updateTile();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Xiaomi-SM6250 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 com.eurekateam.samsungextras
|
||||
|
||||
import android.app.ActivityManager
|
||||
import android.content.Intent
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
|
||||
// TODO: Add FPS drawables
|
||||
class FPSTileService : TileService() {
|
||||
private var isShowing = false
|
||||
override fun onStartListening() {
|
||||
super.onStartListening()
|
||||
val manager = getSystemService(ACTIVITY_SERVICE) as ActivityManager
|
||||
for (service in manager.getRunningServices(Int.MAX_VALUE)) {
|
||||
if (FPSInfoService::class.java.name ==
|
||||
service.service.className
|
||||
) {
|
||||
isShowing = true
|
||||
}
|
||||
}
|
||||
updateTile()
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
val fpsinfo = Intent(this, FPSInfoService::class.java)
|
||||
if (!isShowing) startService(fpsinfo) else stopService(fpsinfo)
|
||||
isShowing = !isShowing
|
||||
updateTile()
|
||||
}
|
||||
|
||||
private fun updateTile() {
|
||||
val tile = qsTile
|
||||
tile.state =
|
||||
if (isShowing) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
|
||||
tile.updateTile()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
package com.eurekateam.samsungextras;
|
||||
|
||||
public class GlobalConstants {
|
||||
/**
|
||||
* Global Variables
|
||||
*/
|
||||
public static final String FLASHLIGHT_SYSFS = "/sys/class/camera/flash/" +
|
||||
"torch_brightness_lvl";
|
||||
public static final String FLASHLIGHT_SYSFS_ENABLE = "/sys/class/camera/" +
|
||||
"flash/torch_brightness_lvl_enable";
|
||||
public static final String TMU_SYSFS = "/sys/devices/platform/11500000.mali/tmu";
|
||||
public static final String TAG = "SamsungExtras";
|
||||
public static final String FASTCHARGE_SYSFS = "/sys/class/sec/switch/afc_disable";
|
||||
public static final String CHARGE_DISABLE_SYSFS = "/sys/devices/platform/battery/" +
|
||||
"power_supply/battery/batt_slate_mode";
|
||||
public static final String BATTERY_CAPACITY_MAX_SYSFS = "/sys/devices/platform/battery/"
|
||||
+ "power_supply/battery/charge_full";
|
||||
public static final String BATTERY_TEMP_SYSFS = "/sys/devices/platform/battery/"
|
||||
+ "power_supply/battery/batt_temp";
|
||||
public static final String BATTERY_CAPACITY_CURRENT_SYSFS = "/sys/devices/platform/battery/"
|
||||
+ "power_supply/battery/capacity";
|
||||
public static final String BATTERY_CURRENT_SYSFS = "/sys/devices/platform/battery/"
|
||||
+ "power_supply/battery/current_now";
|
||||
public static final String BATTERY_TIME_TO_FULL_SYSFS = "/sys/devices/platform/battery/"
|
||||
+ "power_supply/battery/time_to_full_now";
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.eurekateam.samsungextras
|
||||
|
||||
object GlobalConstants {
|
||||
/**
|
||||
* Global Variables
|
||||
*/
|
||||
const val FLASHLIGHT_SYSFS = "/sys/class/camera/flash/" +
|
||||
"torch_brightness_lvl"
|
||||
const val TAG = "SamsungExtras"
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package com.eurekateam.samsungextras;
|
||||
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.service.quicksettings.TileService;
|
||||
|
||||
public class SamsungPartsTile extends TileService {
|
||||
@Override
|
||||
public void onClick() {
|
||||
try {
|
||||
Intent intent = new Intent(this, DeviceSettingsActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
startActivityAndCollapse(intent);
|
||||
} catch (ActivityNotFoundException ignored) {
|
||||
// At this point, the app is most likely hidden and set to only open from Settings
|
||||
Intent intent = new Intent(this, DeviceSettings.class);
|
||||
startActivityAndCollapse(intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.eurekateam.samsungextras
|
||||
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.service.quicksettings.TileService
|
||||
|
||||
class SamsungPartsTile : TileService() {
|
||||
override fun onClick() {
|
||||
try {
|
||||
val intent = Intent(this, DeviceSettingsActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
startActivityAndCollapse(intent)
|
||||
} catch (ignored: ActivityNotFoundException) {
|
||||
// At this point, the app is most likely hidden and set to only open from Settings
|
||||
val intent = Intent(this, DeviceSettings::class.java)
|
||||
startActivityAndCollapse(intent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -15,25 +15,20 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.eurekateam.samsungextras;
|
||||
package com.eurekateam.samsungextras
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.preference.PreferenceManager
|
||||
|
||||
import androidx.preference.PreferenceManager;
|
||||
|
||||
public class Startup extends BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
public void onReceive(final Context context, final Intent bootintent) {
|
||||
boolean enabled;
|
||||
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
enabled = sharedPrefs.getBoolean(DeviceSettings.PREF_KEY_FPS_INFO, false);
|
||||
class Startup : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, bootintent: Intent) {
|
||||
val enabled: Boolean
|
||||
val sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
enabled = sharedPrefs.getBoolean(DeviceSettings.PREF_KEY_FPS_INFO, false)
|
||||
if (enabled) {
|
||||
context.startService(new Intent(context, FPSInfoService.class));
|
||||
context.startService(Intent(context, FPSInfoService::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
package com.eurekateam.samsungextras;
|
||||
|
||||
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.ServiceManager;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Samsung Electronics Co. Ltd
|
||||
* This Class is based on Samsung's OneUI 3.1
|
||||
* /system/frameworks/gamesdk.jar
|
||||
*/
|
||||
public class SurfaceFlingerFPS {
|
||||
private double mFps;
|
||||
private final Object mLock;
|
||||
private long mPrevFPSCheckStartTime;
|
||||
private int mPrevFlipCount;
|
||||
private double mPrevFps;
|
||||
public boolean running;
|
||||
private long mPrevPrevCheckStartTime;
|
||||
private int mPrevPrevFlipCount;
|
||||
private volatile boolean mSkipUpdate;
|
||||
private volatile boolean mStopThread;
|
||||
private ThreadGetFlip mThread;
|
||||
|
||||
private SurfaceFlingerFPS() {
|
||||
this.mThread = null;
|
||||
this.mStopThread = false;
|
||||
this.mSkipUpdate = false;
|
||||
this.mLock = new Object();
|
||||
this.mFps = 0.0d;
|
||||
this.mPrevFps = 0.0d;
|
||||
this.mPrevFlipCount = 0;
|
||||
this.mPrevFPSCheckStartTime = 0;
|
||||
this.mPrevPrevFlipCount = 0;
|
||||
this.mPrevPrevCheckStartTime = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the thread
|
||||
*/
|
||||
public void start() {
|
||||
synchronized (this) {
|
||||
if (this.mThread == null || this.mStopThread) {
|
||||
this.mStopThread = false;
|
||||
ThreadGetFlip threadGetFlip = new ThreadGetFlip();
|
||||
this.mThread = threadGetFlip;
|
||||
threadGetFlip.start();
|
||||
running = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the thread
|
||||
*/
|
||||
public void stop() {
|
||||
synchronized (this) {
|
||||
this.mStopThread = true;
|
||||
if (this.mThread != null) {
|
||||
this.mThread.interrupt();
|
||||
}
|
||||
this.mThread = null;
|
||||
running = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the fps monitor is able to start
|
||||
* @return true if able to start, else false
|
||||
*/
|
||||
private boolean isAvailable() {
|
||||
return this.mStopThread || this.mThread == null;
|
||||
}
|
||||
|
||||
private void updateCurrentFps() {
|
||||
try {
|
||||
synchronized (this.mLock) {
|
||||
this.mSkipUpdate = true;
|
||||
long curTime = System.currentTimeMillis();
|
||||
int curFlipCount = getFlipCount();
|
||||
if (curTime - this.mPrevFPSCheckStartTime < 200) {
|
||||
this.mFps = ((double) (curFlipCount - this.mPrevPrevFlipCount)) / (((double) (curTime - this.mPrevPrevCheckStartTime)) / 1000.0d);
|
||||
} else {
|
||||
this.mFps = ((double) (curFlipCount - this.mPrevFlipCount)) / (((double) (curTime - this.mPrevFPSCheckStartTime)) / 1000.0d);
|
||||
}
|
||||
if (this.mFps < 1.0d) {
|
||||
this.mFps = this.mPrevFps;
|
||||
}
|
||||
this.mPrevFlipCount = curFlipCount;
|
||||
this.mPrevFPSCheckStartTime = curTime;
|
||||
this.mPrevFps = this.mFps;
|
||||
this.mSkipUpdate = false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fps value from internal thread
|
||||
* @return fps value in Double
|
||||
*/
|
||||
public double getFps() {
|
||||
if (isAvailable()) {
|
||||
return -999.0d;
|
||||
}
|
||||
updateCurrentFps();
|
||||
return this.mFps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flip count from SurfaceFlinger Service
|
||||
* @return flip count
|
||||
*/
|
||||
private int getFlipCount() {
|
||||
int flipCount = -1;
|
||||
try {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
try {
|
||||
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
|
||||
data.writeInterfaceToken("android.ui.ISurfaceComposer");
|
||||
if (surfaceFlinger != null && surfaceFlinger.transact(1013, data, reply, 0)) {
|
||||
flipCount = reply.readInt();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
} catch (Exception e2) {
|
||||
e2.printStackTrace();
|
||||
}
|
||||
return flipCount;
|
||||
}
|
||||
|
||||
/* access modifiers changed from: private */
|
||||
|
||||
public void updateFlipCountRecord() {
|
||||
try {
|
||||
synchronized (this.mLock) {
|
||||
this.mPrevPrevCheckStartTime = this.mPrevFPSCheckStartTime;
|
||||
this.mPrevPrevFlipCount = this.mPrevFlipCount;
|
||||
this.mPrevFPSCheckStartTime = System.currentTimeMillis();
|
||||
this.mPrevFlipCount = getFlipCount();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/* access modifiers changed from: private */
|
||||
/* loaded from: classes.dex */
|
||||
public class ThreadGetFlip extends Thread {
|
||||
private ThreadGetFlip() {
|
||||
}
|
||||
|
||||
@Override // java.lang.Thread, java.lang.Runnable
|
||||
public void run() {
|
||||
while (!SurfaceFlingerFPS.this.mStopThread) {
|
||||
if (!SurfaceFlingerFPS.this.mSkipUpdate) {
|
||||
SurfaceFlingerFPS.this.updateFlipCountRecord();
|
||||
try {
|
||||
Thread.sleep(300);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an instance of this class
|
||||
* @return new instance
|
||||
*/
|
||||
public static SurfaceFlingerFPS getInstance(){
|
||||
return new SurfaceFlingerFPS();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
package com.eurekateam.samsungextras
|
||||
|
||||
import android.os.Parcel
|
||||
import android.os.ServiceManager
|
||||
|
||||
/*
|
||||
* Copyright (C) 2020-2021 Samsung Electronics Co. Ltd
|
||||
* This Class is based on Samsung's OneUI 3.1
|
||||
* /system/frameworks/gamesdk.jar
|
||||
*/
|
||||
class SurfaceFlingerFPS private constructor() {
|
||||
private var mFps: Double
|
||||
private val mLock: Any = Any()
|
||||
private var mPrevFPSCheckStartTime: Long
|
||||
private var mPrevFlipCount: Int
|
||||
private var mPrevFps: Double
|
||||
private var running = false
|
||||
private var mPrevPrevCheckStartTime: Long
|
||||
private var mPrevPrevFlipCount: Int
|
||||
|
||||
@Volatile
|
||||
private var mSkipUpdate = false
|
||||
|
||||
@Volatile
|
||||
private var mStopThread = false
|
||||
private var mThread: ThreadGetFlip? = null
|
||||
|
||||
/**
|
||||
* Starts the thread
|
||||
*/
|
||||
fun start() {
|
||||
synchronized(this) {
|
||||
if (mThread == null || mStopThread) {
|
||||
mStopThread = false
|
||||
val threadGetFlip = ThreadGetFlip()
|
||||
mThread = threadGetFlip
|
||||
threadGetFlip.start()
|
||||
running = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the thread
|
||||
*/
|
||||
fun stop() {
|
||||
synchronized(this) {
|
||||
mStopThread = true
|
||||
if (mThread != null) {
|
||||
mThread!!.interrupt()
|
||||
}
|
||||
mThread = null
|
||||
running = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the fps monitor is able to start
|
||||
* @return true if able to start, else false
|
||||
*/
|
||||
private val isAvailable: Boolean
|
||||
get() = mStopThread || mThread == null
|
||||
|
||||
private fun updateCurrentFps() {
|
||||
try {
|
||||
synchronized(mLock) {
|
||||
mSkipUpdate = true
|
||||
val curTime = System.currentTimeMillis()
|
||||
val curFlipCount = flipCount
|
||||
mFps = if (curTime - mPrevFPSCheckStartTime < 200) {
|
||||
(curFlipCount - mPrevPrevFlipCount).toDouble() / ((curTime - mPrevPrevCheckStartTime).toDouble() / 1000.0)
|
||||
} else {
|
||||
(curFlipCount - mPrevFlipCount).toDouble() / ((curTime - mPrevFPSCheckStartTime).toDouble() / 1000.0)
|
||||
}
|
||||
if (mFps < 1.0) {
|
||||
mFps = mPrevFps
|
||||
}
|
||||
mPrevFlipCount = curFlipCount
|
||||
mPrevFPSCheckStartTime = curTime
|
||||
mPrevFps = mFps
|
||||
mSkipUpdate = false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fps value from internal thread
|
||||
* @return fps value in Double
|
||||
*/
|
||||
val fps: Double
|
||||
get() {
|
||||
if (isAvailable) {
|
||||
return -999.0
|
||||
}
|
||||
updateCurrentFps()
|
||||
return mFps
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the flip count from SurfaceFlinger Service
|
||||
* @return flip count
|
||||
*/
|
||||
private val flipCount: Int
|
||||
get() {
|
||||
var flipCount = -1
|
||||
try {
|
||||
val data = Parcel.obtain()
|
||||
val reply = Parcel.obtain()
|
||||
try {
|
||||
val surfaceFlinger = ServiceManager.getService("SurfaceFlinger")
|
||||
data.writeInterfaceToken("android.ui.ISurfaceComposer")
|
||||
if (surfaceFlinger != null && surfaceFlinger.transact(1013, data, reply, 0)) {
|
||||
flipCount = reply.readInt()
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
data.recycle()
|
||||
reply.recycle()
|
||||
} catch (e2: Exception) {
|
||||
e2.printStackTrace()
|
||||
}
|
||||
return flipCount
|
||||
}
|
||||
|
||||
/* access modifiers changed from: private */
|
||||
fun updateFlipCountRecord() {
|
||||
try {
|
||||
synchronized(mLock) {
|
||||
mPrevPrevCheckStartTime = mPrevFPSCheckStartTime
|
||||
mPrevPrevFlipCount = mPrevFlipCount
|
||||
mPrevFPSCheckStartTime = System.currentTimeMillis()
|
||||
mPrevFlipCount = flipCount
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
/* access modifiers changed from: private */ /* loaded from: classes.dex */
|
||||
inner class ThreadGetFlip : Thread() {
|
||||
// java.lang.Thread, java.lang.Runnable
|
||||
override fun run() {
|
||||
while (!mStopThread) {
|
||||
if (!mSkipUpdate) {
|
||||
updateFlipCountRecord()
|
||||
try {
|
||||
sleep(300)
|
||||
} catch (e: InterruptedException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Gets an instance of this class
|
||||
* @return new instance
|
||||
*/
|
||||
val instance: SurfaceFlingerFPS
|
||||
get() = SurfaceFlingerFPS()
|
||||
}
|
||||
|
||||
init {
|
||||
mFps = 0.0
|
||||
mPrevFps = 0.0
|
||||
mPrevFlipCount = 0
|
||||
mPrevFPSCheckStartTime = 0
|
||||
mPrevPrevFlipCount = 0
|
||||
mPrevPrevCheckStartTime = 0
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.battery;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
public class BatteryActivity extends FragmentActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
|
||||
BatteryFragment batteryFragment;
|
||||
if (fragment == null) {
|
||||
batteryFragment = new BatteryFragment();
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(android.R.id.content, batteryFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.battery
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.android.internal.R.id.content
|
||||
import com.android.internal.R.id.home
|
||||
|
||||
class BatteryActivity : FragmentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
val fragment = fragmentManager.findFragmentById(content)
|
||||
val batteryFragment: BatteryFragment
|
||||
if (fragment == null) {
|
||||
batteryFragment = BatteryFragment()
|
||||
fragmentManager.beginTransaction()
|
||||
.add(content, batteryFragment)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == home) {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.battery;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.eurekateam.samsungextras.R;
|
||||
import com.eurekateam.samsungextras.interfaces.Battery;
|
||||
|
||||
public class BatteryFragment extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
private static final String PREF_FASTCHARGE = "fastcharge_pref";
|
||||
private static final String PREF_CHARGE = "charge_pref";
|
||||
private static final String BATTERY_INFO = "battery_info";
|
||||
private SwitchPreference mFastChargePref;
|
||||
private SwitchPreference mChargePref;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.battery_settings);
|
||||
mFastChargePref = findPreference(PREF_FASTCHARGE);
|
||||
assert mFastChargePref != null;
|
||||
mFastChargePref.setOnPreferenceChangeListener(this);
|
||||
mFastChargePref.setChecked(Battery.getChargeSysfs() == 0);
|
||||
mChargePref = findPreference(PREF_CHARGE);
|
||||
assert mChargePref != null;
|
||||
mChargePref.setOnPreferenceChangeListener(this);
|
||||
mChargePref.setChecked(Battery.getFastChargeSysfs() == 0);
|
||||
ListPreference mBatteryInfo = findPreference(BATTERY_INFO);
|
||||
CharSequence[] items = {
|
||||
Battery.getGeneralBatteryStats(1) + " mAh",
|
||||
Battery.getGeneralBatteryStats(2) + " %",
|
||||
Battery.getGeneralBatteryStats(3) + " mAh" ,
|
||||
Battery.getGeneralBatteryStats(6) + " mAh",
|
||||
Battery.getGeneralBatteryStats(4) == 1
|
||||
? "Charging" : "Discharging",
|
||||
Battery.getGeneralBatteryStats(5) + " \u2103",
|
||||
};
|
||||
assert mBatteryInfo != null;
|
||||
mBatteryInfo.setEntryValues(items);
|
||||
mBatteryInfo.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
Toast.makeText(getContext(), (String) newValue, Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == mChargePref) {
|
||||
Boolean value = (Boolean) newValue;
|
||||
Battery.setChargeSysfs(value ? 0 : 1 );
|
||||
mChargePref.setChecked(Battery.getChargeSysfs() == 0);
|
||||
return true;
|
||||
}else if (preference == mFastChargePref){
|
||||
Boolean value = (Boolean) newValue;
|
||||
Battery.setFastCharge(value ? 0 : 1 );
|
||||
mFastChargePref.setChecked(Battery.getFastChargeSysfs() == 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.battery
|
||||
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragment
|
||||
import androidx.preference.SwitchPreference
|
||||
import com.eurekateam.samsungextras.R
|
||||
import com.eurekateam.samsungextras.interfaces.Battery
|
||||
|
||||
class BatteryFragment : PreferenceFragment(), Preference.OnPreferenceChangeListener {
|
||||
private var mFastChargePref: SwitchPreference? = null
|
||||
private var mChargePref: SwitchPreference? = null
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.battery_settings)
|
||||
mFastChargePref = findPreference(PREF_FASTCHARGE)
|
||||
assert(mFastChargePref != null)
|
||||
mFastChargePref!!.onPreferenceChangeListener = this
|
||||
mFastChargePref!!.isChecked = Battery.chargeSysfs == 0
|
||||
mChargePref = findPreference(PREF_CHARGE)
|
||||
assert(mChargePref != null)
|
||||
mChargePref!!.onPreferenceChangeListener = this
|
||||
mChargePref!!.isChecked = Battery.fastChargeSysfs == 0
|
||||
val mBatteryInfo = findPreference<ListPreference>(BATTERY_INFO)
|
||||
val items = arrayOf<CharSequence>(
|
||||
Battery.getGeneralBatteryStats(1).toString() + " mAh",
|
||||
Battery.getGeneralBatteryStats(2).toString() + " %",
|
||||
Battery.getGeneralBatteryStats(3).toString() + " mAh",
|
||||
Battery.getGeneralBatteryStats(6).toString() + " mAh",
|
||||
if (Battery.getGeneralBatteryStats(4) == 1) "Charging" else "Discharging",
|
||||
Battery.getGeneralBatteryStats(5).toString() + " \u2103"
|
||||
)
|
||||
assert(mBatteryInfo != null)
|
||||
mBatteryInfo!!.entryValues = items
|
||||
mBatteryInfo.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any? ->
|
||||
Toast.makeText(
|
||||
context, newValue as String?, Toast.LENGTH_SHORT
|
||||
).show()
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
if (preference === mChargePref) {
|
||||
val value = newValue as Boolean
|
||||
Battery.chargeSysfs = if (value) 0 else 1
|
||||
mChargePref!!.isChecked = Battery.chargeSysfs == 0
|
||||
return true
|
||||
} else if (preference === mFastChargePref) {
|
||||
val value = newValue as Boolean
|
||||
Battery.setFastCharge(if (value) 0 else 1)
|
||||
mFastChargePref!!.isChecked =
|
||||
Battery.fastChargeSysfs == 0
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREF_FASTCHARGE = "fastcharge_pref"
|
||||
private const val PREF_CHARGE = "charge_pref"
|
||||
private const val BATTERY_INFO = "battery_info"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.dolby;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
public class DolbyActivity extends FragmentActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
|
||||
DolbyFragment dolbyFragment;
|
||||
if (fragment == null) {
|
||||
dolbyFragment = new DolbyFragment();
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(android.R.id.content, dolbyFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.dolby
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.android.internal.R.id.content
|
||||
import com.android.internal.R.id.home
|
||||
|
||||
class DolbyActivity : FragmentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
val fragment = fragmentManager.findFragmentById(content)
|
||||
val dolbyFragment: DolbyFragment
|
||||
if (fragment == null) {
|
||||
dolbyFragment = DolbyFragment()
|
||||
fragmentManager.beginTransaction()
|
||||
.add(content, dolbyFragment)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == home) {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,12 +4,14 @@ import android.media.audiofx.AudioEffect
|
|||
import java.util.*
|
||||
|
||||
class DolbyCore {
|
||||
private var currentProfile : Int = -1
|
||||
private val audioEffect = AudioEffect(
|
||||
EFFECT_TYPE_DAP, AudioEffect.EFFECT_TYPE_NULL, 0, 0
|
||||
)
|
||||
fun startDolbyEffect(PROFILE: Int){
|
||||
audioEffect.setParameter(EFFECT_PARAM_EFF_ENAB, 1)
|
||||
audioEffect.setParameter(EFFECT_PARAM_PROFILE, PROFILE)
|
||||
currentProfile = PROFILE
|
||||
audioEffect.enabled = true
|
||||
}
|
||||
fun stopDolbyEffect(){
|
||||
|
|
@ -22,6 +24,9 @@ class DolbyCore {
|
|||
audioEffect.enabled = true
|
||||
}
|
||||
|
||||
fun currentState(): Int{
|
||||
return currentProfile
|
||||
}
|
||||
companion object {
|
||||
|
||||
private val EFFECT_TYPE_DAP = UUID.fromString("46d279d9-9be7-453d-9d7c-ef937f675587")
|
||||
|
|
|
|||
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.dolby;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.eurekateam.samsungextras.R;
|
||||
|
||||
public class DolbyFragment extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
private static final String PREF_DOLBY = "dolby_pref";
|
||||
private static final String DOLBY_MODES = "dolby_modes";
|
||||
ListPreference DolbyModesPreference;
|
||||
SwitchPreference DolbyEnablePreference;
|
||||
DolbyCore dolbyCore = new DolbyCore();
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.dolby_settings);
|
||||
DolbyModesPreference = findPreference(DOLBY_MODES);
|
||||
DolbyEnablePreference = findPreference(PREF_DOLBY);
|
||||
assert DolbyEnablePreference != null;
|
||||
DolbyEnablePreference.setChecked(dolbyCore.isRunning());
|
||||
DolbyEnablePreference.setOnPreferenceChangeListener(this);
|
||||
CharSequence[] items = {
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9"
|
||||
};
|
||||
DolbyModesPreference.setEntryValues(items);
|
||||
DolbyModesPreference.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
switch (Integer.parseInt((String) newValue)){
|
||||
case 1:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_AUTO);
|
||||
break;
|
||||
case 2:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_GAME);
|
||||
break;
|
||||
case 3:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_GAME_1);
|
||||
break;
|
||||
case 4:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_GAME_2);
|
||||
break;
|
||||
case 5:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_MOVIE);
|
||||
break;
|
||||
case 6:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_MUSIC);
|
||||
break;
|
||||
case 7:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_OFF);
|
||||
break;
|
||||
case 8:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_VOICE);
|
||||
break;
|
||||
case 9:
|
||||
dolbyCore.startDolbyEffect(DolbyCore.PROFILE_SPACIAL_AUDIO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == DolbyEnablePreference) {
|
||||
Boolean value = (Boolean) newValue;
|
||||
if(value){
|
||||
dolbyCore.justStartOnly();
|
||||
}else{
|
||||
dolbyCore.stopDolbyEffect();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.dolby
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.ListPreference
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragment
|
||||
import androidx.preference.SwitchPreference
|
||||
import com.eurekateam.samsungextras.R
|
||||
|
||||
class DolbyFragment : PreferenceFragment(), Preference.OnPreferenceChangeListener {
|
||||
private var DolbyModesPreference: ListPreference? = null
|
||||
private var DolbyEnablePreference: SwitchPreference? = null
|
||||
private var dolbyCore = DolbyCore()
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.dolby_settings)
|
||||
DolbyModesPreference = findPreference(DOLBY_MODES)
|
||||
DolbyEnablePreference = findPreference(PREF_DOLBY)
|
||||
assert(DolbyEnablePreference != null)
|
||||
DolbyEnablePreference!!.isChecked = dolbyCore.isRunning()
|
||||
DolbyEnablePreference!!.onPreferenceChangeListener = this
|
||||
val items = arrayOf<CharSequence>(
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9"
|
||||
)
|
||||
DolbyModesPreference!!.entryValues = items
|
||||
DolbyModesPreference!!.onPreferenceChangeListener =
|
||||
Preference.OnPreferenceChangeListener { _: Preference?, newValue: Any ->
|
||||
when ((newValue as String?)?.toInt()) {
|
||||
1 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_AUTO)
|
||||
2 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_GAME)
|
||||
3 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_GAME_1)
|
||||
4 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_GAME_2)
|
||||
5 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_MOVIE)
|
||||
6 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_MUSIC)
|
||||
7 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_OFF)
|
||||
8 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_VOICE)
|
||||
9 -> dolbyCore.startDolbyEffect(DolbyCore.PROFILE_SPACIAL_AUDIO)
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
if (preference === DolbyEnablePreference) {
|
||||
val value = newValue as Boolean
|
||||
if (value) {
|
||||
dolbyCore.justStartOnly()
|
||||
} else {
|
||||
dolbyCore.stopDolbyEffect()
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREF_DOLBY = "dolby_pref"
|
||||
private const val DOLBY_MODES = "dolby_modes"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.flashlight;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
public class FlashLightActivity extends FragmentActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
|
||||
FlashLightFragment flashLightFragment;
|
||||
if (fragment == null) {
|
||||
flashLightFragment = new FlashLightFragment();
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(android.R.id.content, flashLightFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.flashlight
|
||||
|
||||
import android.R.id.content
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import com.android.internal.R.id.home
|
||||
|
||||
class FlashLightActivity : FragmentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
val fragment = fragmentManager.findFragmentById(content)
|
||||
val flashLightFragment: FlashLightFragment
|
||||
if (fragment == null) {
|
||||
flashLightFragment = FlashLightFragment()
|
||||
fragmentManager.beginTransaction()
|
||||
.add(content, flashLightFragment)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == home) {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.flashlight;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
|
||||
import com.eurekateam.samsungextras.GlobalConstants;
|
||||
import com.eurekateam.samsungextras.R;
|
||||
import com.eurekateam.samsungextras.interfaces.Flashlight;
|
||||
import com.eurekateam.samsungextras.preferences.CustomSeekBarPreference;
|
||||
import com.eurekateam.samsungextras.utils.FileUtilsWrapper;
|
||||
import com.eurekateam.samsungextras.utils.SystemProperties;
|
||||
|
||||
public class FlashLightFragment extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
private static final String PREF_FLASHLIGHT = "flashlight_pref";
|
||||
private CustomSeekBarPreference mFlashLightPref;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.flashlight_settings);
|
||||
mFlashLightPref = findPreference(PREF_FLASHLIGHT);
|
||||
assert mFlashLightPref != null;
|
||||
mFlashLightPref.setOnPreferenceChangeListener(this);
|
||||
if (!FileUtilsWrapper.fileExists(GlobalConstants.FLASHLIGHT_SYSFS)){
|
||||
mFlashLightPref.setEnabled(false);
|
||||
}
|
||||
mFlashLightPref.setMax(10);
|
||||
mFlashLightPref.setMin(1);
|
||||
boolean isa10 = SystemProperties.read("ro.product.device").equals("a10");
|
||||
mFlashLightPref.setValue(Flashlight.getFlash(isa10 ? 1 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == mFlashLightPref) {
|
||||
Integer value = (Integer) newValue;
|
||||
Flashlight.setFlash(value);
|
||||
mFlashLightPref.setValue(value, true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.flashlight
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragment
|
||||
import com.eurekateam.samsungextras.GlobalConstants
|
||||
import com.eurekateam.samsungextras.R
|
||||
import com.eurekateam.samsungextras.interfaces.Flashlight
|
||||
import com.eurekateam.samsungextras.preferences.CustomSeekBarPreference
|
||||
import com.eurekateam.samsungextras.utils.SystemProperties
|
||||
import java.io.File
|
||||
|
||||
class FlashLightFragment : PreferenceFragment(), Preference.OnPreferenceChangeListener {
|
||||
private var mFlashLightPref: CustomSeekBarPreference? = null
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.flashlight_settings)
|
||||
mFlashLightPref = findPreference(PREF_FLASHLIGHT)
|
||||
assert(mFlashLightPref != null)
|
||||
mFlashLightPref!!.onPreferenceChangeListener = this
|
||||
if (!File(GlobalConstants.FLASHLIGHT_SYSFS).exists()) {
|
||||
mFlashLightPref!!.isEnabled = false
|
||||
}
|
||||
mFlashLightPref!!.setMax(10)
|
||||
mFlashLightPref!!.setMin(1)
|
||||
val isa10 = SystemProperties.read("ro.product.device") == "a10"
|
||||
mFlashLightPref!!.value = Flashlight.getFlash(if (isa10) 1 else 0)
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
if (preference === mFlashLightPref) {
|
||||
val value = newValue as Int
|
||||
Flashlight.setFlash(value)
|
||||
mFlashLightPref!!.setValue(value, true)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PREF_FLASHLIGHT = "flashlight_pref"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
package com.eurekateam.samsungextras.interfaces;
|
||||
|
||||
public class Battery {
|
||||
public static native void setChargeSysfs(int enable);
|
||||
public static native int getChargeSysfs();
|
||||
public static native void setFastCharge(int enable);
|
||||
public static native int getFastChargeSysfs();
|
||||
public static native int getGeneralBatteryStats(int id);
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.eurekateam.samsungextras.interfaces
|
||||
|
||||
object Battery {
|
||||
var chargeSysfs: Int
|
||||
external get
|
||||
external set
|
||||
|
||||
external fun setFastCharge(enable: Int)
|
||||
val fastChargeSysfs: Int
|
||||
external get
|
||||
|
||||
external fun getGeneralBatteryStats(id: Int): Int
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
package com.eurekateam.samsungextras.interfaces;
|
||||
|
||||
public class Flashlight {
|
||||
public static native void setFlash(int value);
|
||||
public static native int getFlash(int isA10);
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.eurekateam.samsungextras.interfaces
|
||||
|
||||
object Flashlight {
|
||||
external fun setFlash(value: Int)
|
||||
external fun getFlash(isA10: Int): Int
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
package com.eurekateam.samsungextras.interfaces;
|
||||
|
||||
public class GPU {
|
||||
public static native void setGPU(int enable);
|
||||
public static native int getGPU();
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.eurekateam.samsungextras.interfaces
|
||||
|
||||
object GPU {
|
||||
var GPU: Int
|
||||
external get
|
||||
external set
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package com.eurekateam.samsungextras.interfaces;
|
||||
|
||||
public class SELinux {
|
||||
public static native int getSELinux();
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.eurekateam.samsungextras.interfaces
|
||||
|
||||
object SELinux {
|
||||
val SELinux: Int
|
||||
external get
|
||||
}
|
||||
|
|
@ -1,328 +0,0 @@
|
|||
package com.eurekateam.samsungextras.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.PorterDuff;
|
||||
import androidx.core.content.res.TypedArrayUtils;
|
||||
import androidx.preference.*;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.eurekateam.samsungextras.R;
|
||||
|
||||
public class CustomSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener,
|
||||
View.OnClickListener, View.OnLongClickListener {
|
||||
protected final String TAG = getClass().getName();
|
||||
private static final String APP_NS = "http://schemas.android.com/apk/res-auto";
|
||||
protected static final String ANDROIDNS = "http://schemas.android.com/apk/res/android";
|
||||
|
||||
protected int mInterval = 1;
|
||||
protected boolean mShowSign = false;
|
||||
protected String mUnits = "";
|
||||
protected boolean mContinuousUpdates = false;
|
||||
|
||||
protected int mMinValue = 1;
|
||||
protected int mMaxValue = 256;
|
||||
protected boolean mDefaultValueExists = false;
|
||||
protected int mDefaultValue;
|
||||
|
||||
protected int mValue;
|
||||
|
||||
protected TextView mValueTextView;
|
||||
protected ImageView mResetImageView;
|
||||
protected ImageView mMinusImageView;
|
||||
protected ImageView mPlusImageView;
|
||||
protected SeekBar mSeekBar;
|
||||
|
||||
protected boolean mTrackingTouch = false;
|
||||
protected int mTrackingValue;
|
||||
|
||||
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomSeekBarPreference);
|
||||
try {
|
||||
mShowSign = a.getBoolean(R.styleable.CustomSeekBarPreference_showSign, mShowSign);
|
||||
String units = a.getString(R.styleable.CustomSeekBarPreference_units);
|
||||
if (units != null)
|
||||
mUnits = " " + units;
|
||||
mContinuousUpdates = a.getBoolean(R.styleable.CustomSeekBarPreference_continuousUpdates, mContinuousUpdates);
|
||||
} finally {
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
try {
|
||||
String newInterval = attrs.getAttributeValue(APP_NS, "interval");
|
||||
if (newInterval != null)
|
||||
mInterval = Integer.parseInt(newInterval);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Invalid interval value", e);
|
||||
}
|
||||
mMinValue = attrs.getAttributeIntValue(APP_NS, "min", mMinValue);
|
||||
mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", mMaxValue);
|
||||
if (mMaxValue < mMinValue)
|
||||
mMaxValue = mMinValue;
|
||||
String defaultValue = attrs.getAttributeValue(ANDROIDNS, "defaultValue");
|
||||
mDefaultValueExists = defaultValue != null && !defaultValue.isEmpty();
|
||||
if (mDefaultValueExists) {
|
||||
mDefaultValue = getLimitedValue(Integer.parseInt(defaultValue));
|
||||
mValue = mDefaultValue;
|
||||
} else {
|
||||
mValue = mMinValue;
|
||||
}
|
||||
|
||||
mSeekBar = new SeekBar(context, attrs);
|
||||
setLayoutResource(R.layout.preference_custom_seekbar);
|
||||
}
|
||||
|
||||
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
this(context, attrs, defStyleAttr, 0);
|
||||
}
|
||||
|
||||
public CustomSeekBarPreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, TypedArrayUtils.getAttr(context,
|
||||
androidx.preference.R.attr.preferenceStyle,
|
||||
android.R.attr.preferenceStyle));
|
||||
}
|
||||
|
||||
public CustomSeekBarPreference(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
try
|
||||
{
|
||||
// move our seekbar to the new view we've been given
|
||||
ViewParent oldContainer = mSeekBar.getParent();
|
||||
ViewGroup newContainer = (ViewGroup) holder.findViewById(R.id.seekbar);
|
||||
if (oldContainer != newContainer) {
|
||||
// remove the seekbar from the old view
|
||||
if (oldContainer != null) {
|
||||
((ViewGroup) oldContainer).removeView(mSeekBar);
|
||||
}
|
||||
// remove the existing seekbar (there may not be one) and add ours
|
||||
newContainer.removeAllViews();
|
||||
newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
Log.e(TAG, "Error binding view: " + ex.toString());
|
||||
}
|
||||
|
||||
mSeekBar.setMax(getSeekValue(mMaxValue));
|
||||
mSeekBar.setProgress(getSeekValue(mValue));
|
||||
mSeekBar.setEnabled(isEnabled());
|
||||
|
||||
mValueTextView = (TextView) holder.findViewById(R.id.value);
|
||||
mResetImageView = (ImageView) holder.findViewById(R.id.reset);
|
||||
mMinusImageView = (ImageView) holder.findViewById(R.id.minus);
|
||||
mPlusImageView = (ImageView) holder.findViewById(R.id.plus);
|
||||
|
||||
updateValueViews();
|
||||
|
||||
mSeekBar.setOnSeekBarChangeListener(this);
|
||||
mResetImageView.setOnClickListener(this);
|
||||
mMinusImageView.setOnClickListener(this);
|
||||
mPlusImageView.setOnClickListener(this);
|
||||
mResetImageView.setOnLongClickListener(this);
|
||||
mMinusImageView.setOnLongClickListener(this);
|
||||
mPlusImageView.setOnLongClickListener(this);
|
||||
}
|
||||
|
||||
protected int getLimitedValue(int v) {
|
||||
return v < mMinValue ? mMinValue : (v > mMaxValue ? mMaxValue : v);
|
||||
}
|
||||
|
||||
protected int getSeekValue(int v) {
|
||||
return 0 - Math.floorDiv(mMinValue - v, mInterval);
|
||||
}
|
||||
|
||||
protected String getTextValue(int v) {
|
||||
return (mShowSign && v > 0 ? "+" : "") + String.valueOf(v) + mUnits;
|
||||
}
|
||||
|
||||
protected void updateValueViews() {
|
||||
if (mValueTextView != null) {
|
||||
mValueTextView.setText(getContext().getString(R.string.custom_seekbar_value,
|
||||
(!mTrackingTouch || mContinuousUpdates ? getTextValue(mValue) +
|
||||
(mDefaultValueExists && mValue == mDefaultValue ? " (" +
|
||||
getContext().getString(R.string.custom_seekbar_default_value) + ")" : "")
|
||||
: getTextValue(mTrackingValue))));
|
||||
}
|
||||
if (mResetImageView != null) {
|
||||
if (!mDefaultValueExists || mValue == mDefaultValue || mTrackingTouch)
|
||||
mResetImageView.setVisibility(View.INVISIBLE);
|
||||
else
|
||||
mResetImageView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
if (mMinusImageView != null) {
|
||||
if (mValue == mMinValue || mTrackingTouch) {
|
||||
mMinusImageView.setClickable(false);
|
||||
mMinusImageView.setColorFilter(getContext().getColor(R.color.disabled_text_color),
|
||||
PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
mMinusImageView.setClickable(true);
|
||||
mMinusImageView.clearColorFilter();
|
||||
}
|
||||
}
|
||||
if (mPlusImageView != null) {
|
||||
if (mValue == mMaxValue || mTrackingTouch) {
|
||||
mPlusImageView.setClickable(false);
|
||||
mPlusImageView.setColorFilter(getContext().getColor(R.color.disabled_text_color), PorterDuff.Mode.MULTIPLY);
|
||||
} else {
|
||||
mPlusImageView.setClickable(true);
|
||||
mPlusImageView.clearColorFilter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void changeValue(int newValue) {
|
||||
// for subclasses
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
int newValue = getLimitedValue(mMinValue + (progress * mInterval));
|
||||
if (mTrackingTouch && !mContinuousUpdates) {
|
||||
mTrackingValue = newValue;
|
||||
updateValueViews();
|
||||
} else if (mValue != newValue) {
|
||||
// change rejected, revert to the previous value
|
||||
if (!callChangeListener(newValue)) {
|
||||
mSeekBar.setProgress(getSeekValue(mValue));
|
||||
return;
|
||||
}
|
||||
// change accepted, store it
|
||||
changeValue(newValue);
|
||||
persistInt(newValue);
|
||||
|
||||
mValue = newValue;
|
||||
updateValueViews();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
mTrackingValue = mValue;
|
||||
mTrackingTouch = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
mTrackingTouch = false;
|
||||
if (!mContinuousUpdates)
|
||||
onProgressChanged(mSeekBar, getSeekValue(mTrackingValue), false);
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.reset) {
|
||||
Toast.makeText(getContext(), getContext().getString(R.string.custom_seekbar_default_value_to_set, getTextValue(mDefaultValue)),
|
||||
Toast.LENGTH_LONG).show();
|
||||
} else if (id == R.id.minus) {
|
||||
setValue(mValue - mInterval, true);
|
||||
} else if (id == R.id.plus) {
|
||||
setValue(mValue + mInterval, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
int id = v.getId();
|
||||
if (id == R.id.reset) {
|
||||
setValue(mDefaultValue, true);
|
||||
//Toast.makeText(getContext(), getContext().getString(R.string.custom_seekbar_default_value_is_set),
|
||||
// Toast.LENGTH_LONG).show();
|
||||
} else if (id == R.id.minus) {
|
||||
setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue < mValue * 2 ? Math.floorDiv(mMaxValue + mMinValue, 2) : mMinValue, true);
|
||||
} else if (id == R.id.plus) {
|
||||
setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue > mValue * 2 ? -1 * Math.floorDiv(-1 * (mMaxValue + mMinValue), 2) : mMaxValue, true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// dont need too much shit about initial and default values
|
||||
// its all done in constructor already
|
||||
|
||||
@Override
|
||||
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
|
||||
if (restoreValue)
|
||||
mValue = getPersistedInt(mValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultValue(Object defaultValue) {
|
||||
if (defaultValue instanceof Integer)
|
||||
setDefaultValue((Integer) defaultValue, mSeekBar != null);
|
||||
else
|
||||
setDefaultValue(defaultValue == null ? (String) null : defaultValue.toString(), mSeekBar != null);
|
||||
}
|
||||
|
||||
public void setDefaultValue(int newValue, boolean update) {
|
||||
newValue = getLimitedValue(newValue);
|
||||
if (!mDefaultValueExists || mDefaultValue != newValue) {
|
||||
mDefaultValueExists = true;
|
||||
mDefaultValue = newValue;
|
||||
if (update)
|
||||
updateValueViews();
|
||||
}
|
||||
}
|
||||
|
||||
public void setDefaultValue(String newValue, boolean update) {
|
||||
if (mDefaultValueExists && (newValue == null || newValue.isEmpty())) {
|
||||
mDefaultValueExists = false;
|
||||
if (update)
|
||||
updateValueViews();
|
||||
} else if (newValue != null && !newValue.isEmpty()) {
|
||||
setDefaultValue(Integer.parseInt(newValue), update);
|
||||
}
|
||||
}
|
||||
|
||||
public void setMax(int max) {
|
||||
mMaxValue = max;
|
||||
mSeekBar.setMax(mMaxValue - mMinValue);
|
||||
}
|
||||
|
||||
public void setMin(int min) {
|
||||
mMinValue = min;
|
||||
mSeekBar.setMax(mMaxValue - mMinValue);
|
||||
}
|
||||
|
||||
public void setValue(int newValue) {
|
||||
mValue = getLimitedValue(newValue);
|
||||
if (mSeekBar != null) mSeekBar.setProgress(getSeekValue(mValue));
|
||||
}
|
||||
|
||||
public void setValue(int newValue, boolean update) {
|
||||
newValue = getLimitedValue(newValue);
|
||||
if (mValue != newValue) {
|
||||
if (update)
|
||||
mSeekBar.setProgress(getSeekValue(newValue));
|
||||
else
|
||||
mValue = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
public int getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
// need some methods here to set/get other attrs at runtime,
|
||||
// but who really need this ...
|
||||
|
||||
public void refresh(int newValue) {
|
||||
// this will ...
|
||||
setValue(newValue, mSeekBar != null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,323 @@
|
|||
package com.eurekateam.samsungextras.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.PorterDuff
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.View.OnLongClickListener
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.SeekBar
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.core.content.res.TypedArrayUtils
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import androidx.preference.R
|
||||
|
||||
open class CustomSeekBarPreference @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = TypedArrayUtils.getAttr(
|
||||
context,
|
||||
R.attr.preferenceStyle,
|
||||
android.R.attr.preferenceStyle
|
||||
), defStyleRes: Int = 0
|
||||
) : Preference(context, attrs, defStyleAttr, defStyleRes), OnSeekBarChangeListener,
|
||||
View.OnClickListener, OnLongClickListener {
|
||||
private val TAG: String = javaClass.name
|
||||
private var mInterval = 1
|
||||
private var mShowSign = false
|
||||
private var mUnits = ""
|
||||
private var mContinuousUpdates = false
|
||||
private var mMinValue = 1
|
||||
private var mMaxValue = 256
|
||||
private var mDefaultValueExists: Boolean
|
||||
private var mDefaultValue = 0
|
||||
private var mValue = 0
|
||||
private var mValueTextView: TextView? = null
|
||||
private var mResetImageView: ImageView? = null
|
||||
private var mMinusImageView: ImageView? = null
|
||||
private var mPlusImageView: ImageView? = null
|
||||
private var mSeekBar: SeekBar
|
||||
private var mTrackingTouch = false
|
||||
private var mTrackingValue = 0
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
super.onBindViewHolder(holder)
|
||||
try {
|
||||
// move our seekbar to the new view we've been given
|
||||
val oldContainer = mSeekBar.parent
|
||||
val newContainer =
|
||||
holder.findViewById(com.eurekateam.samsungextras.R.id.seekbar) as ViewGroup
|
||||
if (oldContainer !== newContainer) {
|
||||
// remove the seekbar from the old view
|
||||
if (oldContainer != null) {
|
||||
(oldContainer as ViewGroup).removeView(mSeekBar)
|
||||
}
|
||||
// remove the existing seekbar (there may not be one) and add ours
|
||||
newContainer.removeAllViews()
|
||||
newContainer.addView(
|
||||
mSeekBar, ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
Log.e(TAG, "Error binding view: $ex")
|
||||
}
|
||||
mSeekBar.max = getSeekValue(mMaxValue)
|
||||
mSeekBar.progress = getSeekValue(mValue)
|
||||
mSeekBar.isEnabled = isEnabled
|
||||
mValueTextView = holder.findViewById(com.eurekateam.samsungextras.R.id.value) as TextView
|
||||
mResetImageView = holder.findViewById(com.eurekateam.samsungextras.R.id.reset) as ImageView
|
||||
mMinusImageView = holder.findViewById(com.eurekateam.samsungextras.R.id.minus) as ImageView
|
||||
mPlusImageView = holder.findViewById(com.eurekateam.samsungextras.R.id.plus) as ImageView
|
||||
updateValueViews()
|
||||
mSeekBar.setOnSeekBarChangeListener(this)
|
||||
mResetImageView!!.setOnClickListener(this)
|
||||
mMinusImageView!!.setOnClickListener(this)
|
||||
mPlusImageView!!.setOnClickListener(this)
|
||||
mResetImageView!!.onLongClickListener = this
|
||||
mMinusImageView!!.onLongClickListener = this
|
||||
mPlusImageView!!.onLongClickListener = this
|
||||
}
|
||||
|
||||
private fun getLimitedValue(v: Int): Int {
|
||||
return if (v < mMinValue) mMinValue else v.coerceAtMost(mMaxValue)
|
||||
}
|
||||
|
||||
private fun getSeekValue(v: Int): Int {
|
||||
return -Math.floorDiv(mMinValue - v, mInterval)
|
||||
}
|
||||
|
||||
private fun getTextValue(v: Int): String {
|
||||
return (if (mShowSign && v > 0) "+" else "") + v + mUnits
|
||||
}
|
||||
|
||||
private fun updateValueViews() {
|
||||
if (mValueTextView != null) {
|
||||
mValueTextView!!.text = context.getString(
|
||||
com.eurekateam.samsungextras.R.string.custom_seekbar_value,
|
||||
if (!mTrackingTouch || mContinuousUpdates) getTextValue(mValue) +
|
||||
(if (mDefaultValueExists && mValue == mDefaultValue) " (" +
|
||||
context.getString(com.eurekateam.samsungextras.R.string.custom_seekbar_default_value) + ")" else "") else getTextValue(
|
||||
mTrackingValue
|
||||
)
|
||||
)
|
||||
}
|
||||
if (mResetImageView != null) {
|
||||
if (!mDefaultValueExists || mValue == mDefaultValue || mTrackingTouch) mResetImageView!!.visibility =
|
||||
View.INVISIBLE else mResetImageView!!.visibility = View.VISIBLE
|
||||
}
|
||||
if (mMinusImageView != null) {
|
||||
if (mValue == mMinValue || mTrackingTouch) {
|
||||
mMinusImageView!!.isClickable = false
|
||||
mMinusImageView!!.setColorFilter(
|
||||
context.getColor(com.eurekateam.samsungextras.R.color.disabled_text_color),
|
||||
PorterDuff.Mode.MULTIPLY
|
||||
)
|
||||
} else {
|
||||
mMinusImageView!!.isClickable = true
|
||||
mMinusImageView!!.clearColorFilter()
|
||||
}
|
||||
}
|
||||
if (mPlusImageView != null) {
|
||||
if (mValue == mMaxValue || mTrackingTouch) {
|
||||
mPlusImageView!!.isClickable = false
|
||||
mPlusImageView!!.setColorFilter(
|
||||
context.getColor(com.eurekateam.samsungextras.R.color.disabled_text_color),
|
||||
PorterDuff.Mode.MULTIPLY
|
||||
)
|
||||
} else {
|
||||
mPlusImageView!!.isClickable = true
|
||||
mPlusImageView!!.clearColorFilter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun changeValue() {
|
||||
// for subclasses
|
||||
}
|
||||
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
val newValue = getLimitedValue(mMinValue + progress * mInterval)
|
||||
if (mTrackingTouch && !mContinuousUpdates) {
|
||||
mTrackingValue = newValue
|
||||
updateValueViews()
|
||||
} else if (mValue != newValue) {
|
||||
// change rejected, revert to the previous value
|
||||
if (!callChangeListener(newValue)) {
|
||||
mSeekBar.progress = getSeekValue(mValue)
|
||||
return
|
||||
}
|
||||
// change accepted, store it
|
||||
changeValue()
|
||||
persistInt(newValue)
|
||||
mValue = newValue
|
||||
updateValueViews()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||
mTrackingValue = mValue
|
||||
mTrackingTouch = true
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
mTrackingTouch = false
|
||||
if (!mContinuousUpdates) onProgressChanged(mSeekBar, getSeekValue(mTrackingValue), false)
|
||||
notifyChanged()
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
com.eurekateam.samsungextras.R.id.reset -> {
|
||||
Toast.makeText(
|
||||
context,
|
||||
context.getString(
|
||||
com.eurekateam.samsungextras.R.string.custom_seekbar_default_value_to_set,
|
||||
getTextValue(mDefaultValue)
|
||||
),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
}
|
||||
com.eurekateam.samsungextras.R.id.minus -> {
|
||||
setValue(mValue - mInterval, true)
|
||||
}
|
||||
com.eurekateam.samsungextras.R.id.plus -> {
|
||||
setValue(mValue + mInterval, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLongClick(v: View): Boolean {
|
||||
when (v.id) {
|
||||
com.eurekateam.samsungextras.R.id.reset -> {
|
||||
setValue(mDefaultValue, true)
|
||||
}
|
||||
com.eurekateam.samsungextras.R.id.minus -> {
|
||||
setValue(
|
||||
if (mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue < mValue * 2) Math.floorDiv(
|
||||
mMaxValue + mMinValue,
|
||||
2
|
||||
) else mMinValue, true
|
||||
)
|
||||
}
|
||||
com.eurekateam.samsungextras.R.id.plus -> {
|
||||
setValue(
|
||||
if (mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue > mValue * 2) -1 * Math.floorDiv(
|
||||
-1 * (mMaxValue + mMinValue),
|
||||
2
|
||||
) else mMaxValue, true
|
||||
)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// dont need too much shit about initial and default values
|
||||
// its all done in constructor already
|
||||
override fun onSetInitialValue(restoreValue: Boolean, defaultValue: Any) {
|
||||
if (restoreValue) mValue = getPersistedInt(mValue)
|
||||
}
|
||||
|
||||
override fun setDefaultValue(defaultValue: Any) {
|
||||
if (defaultValue is Int) setDefaultValue(
|
||||
defaultValue,
|
||||
true
|
||||
) else setDefaultValue(
|
||||
defaultValue.toString(), true
|
||||
)
|
||||
}
|
||||
|
||||
private fun setDefaultValue(newValue: Int, update: Boolean) {
|
||||
var newValue = newValue
|
||||
newValue = getLimitedValue(newValue)
|
||||
if (!mDefaultValueExists || mDefaultValue != newValue) {
|
||||
mDefaultValueExists = true
|
||||
mDefaultValue = newValue
|
||||
if (update) updateValueViews()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setDefaultValue(newValue: String?, update: Boolean) {
|
||||
if (mDefaultValueExists && (newValue == null || newValue.isEmpty())) {
|
||||
mDefaultValueExists = false
|
||||
if (update) updateValueViews()
|
||||
} else if (newValue != null && newValue.isNotEmpty()) {
|
||||
setDefaultValue(newValue.toInt(), update)
|
||||
}
|
||||
}
|
||||
|
||||
fun setMax(max: Int) {
|
||||
mMaxValue = max
|
||||
mSeekBar.max = mMaxValue - mMinValue
|
||||
}
|
||||
|
||||
fun setMin(min: Int) {
|
||||
mMinValue = min
|
||||
mSeekBar.max = mMaxValue - mMinValue
|
||||
}
|
||||
|
||||
fun setValue(newValue: Int, update: Boolean) {
|
||||
var newValue = newValue
|
||||
newValue = getLimitedValue(newValue)
|
||||
if (mValue != newValue) {
|
||||
if (update) mSeekBar.progress = getSeekValue(newValue) else mValue = newValue
|
||||
}
|
||||
}
|
||||
|
||||
// need some methods here to set/get other attrs at runtime,
|
||||
var value: Int
|
||||
get() = mValue
|
||||
set(newValue) {
|
||||
mValue = getLimitedValue(newValue)
|
||||
mSeekBar.progress = getSeekValue(mValue)
|
||||
}
|
||||
|
||||
// but who really need this ...
|
||||
companion object {
|
||||
private const val APP_NS = "http://schemas.android.com/apk/res-auto"
|
||||
protected const val ANDROIDNS = "http://schemas.android.com/apk/res/android"
|
||||
}
|
||||
|
||||
init {
|
||||
val a = context.obtainStyledAttributes(
|
||||
attrs,
|
||||
com.eurekateam.samsungextras.R.styleable.CustomSeekBarPreference
|
||||
)
|
||||
try {
|
||||
mShowSign = a.getBoolean(
|
||||
com.eurekateam.samsungextras.R.styleable.CustomSeekBarPreference_showSign,
|
||||
mShowSign
|
||||
)
|
||||
val units =
|
||||
a.getString(com.eurekateam.samsungextras.R.styleable.CustomSeekBarPreference_units)
|
||||
if (units != null) mUnits = " $units"
|
||||
mContinuousUpdates = a.getBoolean(
|
||||
com.eurekateam.samsungextras.R.styleable.CustomSeekBarPreference_continuousUpdates,
|
||||
mContinuousUpdates
|
||||
)
|
||||
} finally {
|
||||
a.recycle()
|
||||
}
|
||||
try {
|
||||
val newInterval = attrs!!.getAttributeValue(APP_NS, "interval")
|
||||
if (newInterval != null) mInterval = newInterval.toInt()
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Invalid interval value", e)
|
||||
}
|
||||
mMinValue = attrs!!.getAttributeIntValue(APP_NS, "min", mMinValue)
|
||||
mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", mMaxValue)
|
||||
if (mMaxValue < mMinValue) mMaxValue = mMinValue
|
||||
val defaultValue = attrs.getAttributeValue(ANDROIDNS, "defaultValue")
|
||||
mDefaultValueExists = defaultValue != null && defaultValue.isNotEmpty()
|
||||
if (mDefaultValueExists) {
|
||||
mDefaultValue = getLimitedValue(defaultValue!!.toInt())
|
||||
mValue = mDefaultValue
|
||||
} else {
|
||||
mValue = mMinValue
|
||||
}
|
||||
mSeekBar = SeekBar(context, attrs)
|
||||
layoutResource = com.eurekateam.samsungextras.R.layout.preference_custom_seekbar
|
||||
}
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
package com.eurekateam.samsungextras.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.eurekateam.samsungextras.preferences.SecureSettingsStore;
|
||||
|
||||
public class SecureSettingCustomSeekBarPreference extends com.eurekateam.samsungextras.preferences.CustomSeekBarPreference {
|
||||
|
||||
public SecureSettingCustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingCustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingCustomSeekBarPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingCustomSeekBarPreference(Context context) {
|
||||
super(context);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 AICP
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.preference.ListPreference;
|
||||
|
||||
public class SecureSettingListPreference extends ListPreference {
|
||||
private boolean mAutoSummary = false;
|
||||
|
||||
public SecureSettingListPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingListPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingListPreference(Context context) {
|
||||
super(context);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(String value) {
|
||||
super.setValue(value);
|
||||
if (mAutoSummary || TextUtils.isEmpty(getSummary())) {
|
||||
setSummary(getEntry(), true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSummary(CharSequence summary) {
|
||||
setSummary(summary, false);
|
||||
}
|
||||
|
||||
private void setSummary(CharSequence summary, boolean autoSummary) {
|
||||
mAutoSummary = autoSummary;
|
||||
super.setSummary(summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
|
||||
// This is what default ListPreference implementation is doing without respecting
|
||||
// real default value:
|
||||
//setValue(restoreValue ? getPersistedString(mValue) : (String) defaultValue);
|
||||
// Instead, we better do
|
||||
setValue(restoreValue ? getPersistedString((String) defaultValue) : (String) defaultValue);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2014 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 com.eurekateam.samsungextras.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.Settings;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
public class SecureSettingSwitchPreference extends SwitchPreference {
|
||||
public SecureSettingSwitchPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingSwitchPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
public SecureSettingSwitchPreference(Context context) {
|
||||
super(context);
|
||||
setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean persistBoolean(boolean value) {
|
||||
if (shouldPersist()) {
|
||||
if (value == getPersistedBoolean(!value)) {
|
||||
// It's already there, so the same as persisting
|
||||
return true;
|
||||
}
|
||||
Settings.Secure.putInt(getContext().getContentResolver(), getKey(), value ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean getPersistedBoolean(boolean defaultReturnValue) {
|
||||
if (!shouldPersist()) {
|
||||
return defaultReturnValue;
|
||||
}
|
||||
return Settings.Secure.getInt(getContext().getContentResolver(),
|
||||
getKey(), defaultReturnValue ? 1 : 0) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
|
||||
setChecked(Settings.Secure.getString(getContext().getContentResolver(), getKey()) != null ? getPersistedBoolean(isChecked())
|
||||
: (Boolean) defaultValue);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2017 AICP
|
||||
* Copyright (C) 2018 CarbonROM
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.preferences;
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.preference.PreferenceDataStore;
|
||||
import android.provider.Settings;
|
||||
|
||||
public class SecureSettingsStore extends androidx.preference.PreferenceDataStore
|
||||
implements PreferenceDataStore {
|
||||
|
||||
private final ContentResolver mContentResolver;
|
||||
|
||||
public SecureSettingsStore(ContentResolver contentResolver) {
|
||||
mContentResolver = contentResolver;
|
||||
}
|
||||
|
||||
public boolean getBoolean(String key, boolean defValue) {
|
||||
return getInt(key, defValue ? 1 : 0) != 0;
|
||||
}
|
||||
|
||||
public float getFloat(String key, float defValue) {
|
||||
return Settings.Secure.getFloat(mContentResolver, key, defValue);
|
||||
}
|
||||
|
||||
public int getInt(String key, int defValue) {
|
||||
return Settings.Secure.getInt(mContentResolver, key, defValue);
|
||||
}
|
||||
|
||||
public long getLong(String key, long defValue) {
|
||||
return Settings.Secure.getLong(mContentResolver, key, defValue);
|
||||
}
|
||||
|
||||
public String getString(String key, String defValue) {
|
||||
String result = Settings.Secure.getString(mContentResolver, key);
|
||||
return result == null ? defValue : result;
|
||||
}
|
||||
|
||||
public void putBoolean(String key, boolean value) {
|
||||
putInt(key, value ? 1 : 0);
|
||||
}
|
||||
|
||||
public void putFloat(String key, float value) {
|
||||
Settings.Secure.putFloat(mContentResolver, key, value);
|
||||
}
|
||||
|
||||
public void putInt(String key, int value) {
|
||||
Settings.Secure.putInt(mContentResolver, key, value);
|
||||
}
|
||||
|
||||
public void putLong(String key, long value) {
|
||||
Settings.Secure.putLong(mContentResolver, key, value);
|
||||
}
|
||||
|
||||
public void putString(String key, String value) {
|
||||
Settings.Secure.putString(mContentResolver, key, value);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.speaker;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.view.MenuItem;
|
||||
|
||||
public class ClearSpeakerActivity extends FragmentActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
Fragment fragment = getFragmentManager().findFragmentById(android.R.id.content);
|
||||
ClearSpeakerFragment clearSpeakerFragment;
|
||||
if (fragment == null) {
|
||||
clearSpeakerFragment = new ClearSpeakerFragment();
|
||||
getFragmentManager().beginTransaction()
|
||||
.add(android.R.id.content, clearSpeakerFragment)
|
||||
.commit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (item.getItemId() == android.R.id.home) {
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.speaker
|
||||
|
||||
import android.R.id.content
|
||||
import android.R.id.home
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
|
||||
class ClearSpeakerActivity : FragmentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
actionBar.setDisplayHomeAsUpEnabled(true)
|
||||
val fragment = fragmentManager.findFragmentById(content)
|
||||
val clearSpeakerFragment: ClearSpeakerFragment
|
||||
if (fragment == null) {
|
||||
clearSpeakerFragment = ClearSpeakerFragment()
|
||||
fragmentManager.beginTransaction()
|
||||
.add(content, clearSpeakerFragment)
|
||||
.commit()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == home) {
|
||||
finish()
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.speaker;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.AssetFileDescriptor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.preference.Preference;
|
||||
import androidx.preference.PreferenceFragment;
|
||||
import androidx.preference.SwitchPreference;
|
||||
|
||||
import com.eurekateam.samsungextras.R;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ClearSpeakerFragment extends PreferenceFragment implements
|
||||
Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String TAG = ClearSpeakerFragment.class.getSimpleName();
|
||||
|
||||
private static final String PREF_CLEAR_SPEAKER = "clear_speaker_pref";
|
||||
|
||||
private AudioManager mAudioManager;
|
||||
private Handler mHandler;
|
||||
private MediaPlayer mMediaPlayer;
|
||||
private SwitchPreference mClearSpeakerPref;
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.clear_speaker_settings);
|
||||
|
||||
mClearSpeakerPref = findPreference(PREF_CLEAR_SPEAKER);
|
||||
mClearSpeakerPref.setOnPreferenceChangeListener(this);
|
||||
|
||||
mHandler = new Handler();
|
||||
mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == mClearSpeakerPref) {
|
||||
boolean value = (Boolean) newValue;
|
||||
if (value) {
|
||||
if (startPlaying()) {
|
||||
mHandler.removeCallbacksAndMessages(null);
|
||||
mHandler.postDelayed(this::stopPlaying, 30000);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
stopPlaying();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start playing speaker-clearing audio
|
||||
* @return true on success, else false
|
||||
*/
|
||||
public boolean startPlaying() {
|
||||
mAudioManager.setParameters("status_earpiece_clean=on");
|
||||
mMediaPlayer = new MediaPlayer();
|
||||
getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
|
||||
mMediaPlayer.setLooping(true);
|
||||
try {
|
||||
try (AssetFileDescriptor file = getResources().openRawResourceFd(R.raw.clear_speaker_sound)) {
|
||||
mMediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
|
||||
}
|
||||
mClearSpeakerPref.setEnabled(false);
|
||||
mMediaPlayer.setVolume(1.0f, 1.0f);
|
||||
mMediaPlayer.prepare();
|
||||
mMediaPlayer.start();
|
||||
} catch (IOException ioe) {
|
||||
Log.e(TAG, "Failed to play speaker clean sound!", ioe);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops and invalidates
|
||||
*/
|
||||
public void stopPlaying() {
|
||||
if (mMediaPlayer != null) {
|
||||
mMediaPlayer.stop();
|
||||
mMediaPlayer.reset();
|
||||
mMediaPlayer.release();
|
||||
}
|
||||
mAudioManager.setParameters("status_earpiece_clean=off");
|
||||
mClearSpeakerPref.setEnabled(true);
|
||||
mClearSpeakerPref.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (C) 2020 Paranoid Android
|
||||
*
|
||||
* 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 com.eurekateam.samsungextras.speaker
|
||||
|
||||
import android.content.Context
|
||||
import android.media.AudioManager
|
||||
import android.media.MediaPlayer
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.util.Log
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragment
|
||||
import androidx.preference.SwitchPreference
|
||||
import com.eurekateam.samsungextras.R
|
||||
import java.io.IOException
|
||||
|
||||
class ClearSpeakerFragment : PreferenceFragment(), Preference.OnPreferenceChangeListener {
|
||||
private var mAudioManager: AudioManager? = null
|
||||
private var mHandler: Handler? = null
|
||||
private var mMediaPlayer: MediaPlayer? = null
|
||||
private var mClearSpeakerPref: SwitchPreference? = null
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.clear_speaker_settings)
|
||||
mClearSpeakerPref = findPreference(PREF_CLEAR_SPEAKER)
|
||||
mClearSpeakerPref!!.onPreferenceChangeListener = this
|
||||
mHandler = Handler(Looper.getMainLooper())
|
||||
mAudioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
}
|
||||
|
||||
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
|
||||
if (preference === mClearSpeakerPref) {
|
||||
val value = newValue as Boolean
|
||||
if (value) {
|
||||
if (startPlaying()) {
|
||||
mHandler!!.removeCallbacksAndMessages(null)
|
||||
mHandler!!.postDelayed({ stopPlaying() }, 30000)
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
stopPlaying()
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
/**
|
||||
* Start playing speaker-clearing audio
|
||||
* @return true on success, else false
|
||||
*/
|
||||
private fun startPlaying(): Boolean {
|
||||
mAudioManager!!.setParameters("status_earpiece_clean=on")
|
||||
mMediaPlayer = MediaPlayer()
|
||||
activity.volumeControlStream = AudioManager.STREAM_MUSIC
|
||||
mMediaPlayer!!.setAudioStreamType(AudioManager.STREAM_MUSIC)
|
||||
mMediaPlayer!!.isLooping = true
|
||||
try {
|
||||
resources.openRawResourceFd(R.raw.clear_speaker_sound).use { file ->
|
||||
mMediaPlayer!!.setDataSource(
|
||||
file.fileDescriptor,
|
||||
file.startOffset,
|
||||
file.length
|
||||
)
|
||||
}
|
||||
mClearSpeakerPref!!.isEnabled = false
|
||||
mMediaPlayer!!.setVolume(1.0f, 1.0f)
|
||||
mMediaPlayer!!.prepare()
|
||||
mMediaPlayer!!.start()
|
||||
} catch (ioe: IOException) {
|
||||
Log.e(TAG, "Failed to play speaker clean sound!", ioe)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops and invalidates
|
||||
*/
|
||||
private fun stopPlaying() {
|
||||
if (mMediaPlayer != null) {
|
||||
mMediaPlayer!!.stop()
|
||||
mMediaPlayer!!.reset()
|
||||
mMediaPlayer!!.release()
|
||||
}
|
||||
mAudioManager!!.setParameters("status_earpiece_clean=off")
|
||||
mClearSpeakerPref!!.isEnabled = true
|
||||
mClearSpeakerPref!!.isChecked = false
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = ClearSpeakerFragment::class.java.simpleName
|
||||
private const val PREF_CLEAR_SPEAKER = "clear_speaker_pref"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
package com.eurekateam.samsungextras.utils;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import android.os.FileUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public final class FileUtilsWrapper {
|
||||
private static final String TAG = "FileUtils";
|
||||
|
||||
/**
|
||||
* Reads the first line of text from the given file.
|
||||
* Reference {@link FileUtils} for clarification on what a line is
|
||||
*
|
||||
*/
|
||||
public static String readOneLine(String fileName){
|
||||
try {
|
||||
return FileUtils.readTextFile(new File(fileName),0,null)
|
||||
.replaceAll("[\n]","");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given value into the given file
|
||||
*
|
||||
*/
|
||||
public static void writeLine(String fileName, String value){
|
||||
try {
|
||||
FileUtils.stringToFile(fileName,value);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,75 +0,0 @@
|
|||
package com.eurekateam.samsungextras.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.eurekateam.samsungextras.GlobalConstants;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
public class SystemProperties {
|
||||
|
||||
/**
|
||||
* To read a prop using getprop
|
||||
* @param propName the prop name to get
|
||||
* @return the prop's value, empty string is not found
|
||||
*/
|
||||
public static String read(String propName) {
|
||||
Process process = null;
|
||||
BufferedReader bufferedReader = null;
|
||||
|
||||
String TAG = GlobalConstants.TAG;
|
||||
try {
|
||||
String GETPROP_EXECUTABLE_PATH = "/system/bin/getprop";
|
||||
process = new ProcessBuilder().command(GETPROP_EXECUTABLE_PATH, propName).redirectErrorStream(true).start();
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line = bufferedReader.readLine();
|
||||
if (line == null){
|
||||
line = ""; //prop not set
|
||||
}
|
||||
Log.i(TAG,"read System Property: " + propName + "=" + line);
|
||||
return line;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG,"Failed to read System Property " + propName,e);
|
||||
return "";
|
||||
} finally{
|
||||
if (bufferedReader != null){
|
||||
try {
|
||||
bufferedReader.close();
|
||||
} catch (IOException ignored) {}
|
||||
}
|
||||
if (process != null){
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The status of SELinux on the device
|
||||
* true: enforcing, false: permissive
|
||||
*/
|
||||
public static boolean getenforce() {
|
||||
Process process = null;
|
||||
BufferedReader bufferedReader;
|
||||
String TAG = GlobalConstants.TAG;
|
||||
try {
|
||||
String GETENFORCE_EXECUTABLE_PATH = "/system/bin/getenforce";
|
||||
process = new ProcessBuilder().command(GETENFORCE_EXECUTABLE_PATH).redirectErrorStream(true).start();
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
String line = bufferedReader.readLine();
|
||||
if (line == null) {
|
||||
line = ""; //prop not set
|
||||
}
|
||||
Log.i(TAG, "Getenforce: " + line);
|
||||
return line.equals("Enforcing");
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Getenforce failed", e);
|
||||
} finally {
|
||||
if (process != null) {
|
||||
process.destroy();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.eurekateam.samsungextras.utils
|
||||
|
||||
import android.util.Log
|
||||
import com.eurekateam.samsungextras.GlobalConstants
|
||||
import java.io.BufferedReader
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
|
||||
object SystemProperties {
|
||||
/**
|
||||
* To read a prop using getprop
|
||||
* @param propName the prop name to get
|
||||
* @return the prop's value, empty string is not found
|
||||
*/
|
||||
fun read(propName: String): String {
|
||||
var process: Process? = null
|
||||
var bufferedReader: BufferedReader? = null
|
||||
val TAG = GlobalConstants.TAG
|
||||
return try {
|
||||
val GETPROP_EXECUTABLE_PATH = "/system/bin/getprop"
|
||||
process = ProcessBuilder().command(GETPROP_EXECUTABLE_PATH, propName)
|
||||
.redirectErrorStream(true).start()
|
||||
bufferedReader = BufferedReader(InputStreamReader(process.inputStream))
|
||||
var line = bufferedReader.readLine()
|
||||
if (line == null) {
|
||||
line = "" //prop not set
|
||||
}
|
||||
Log.i(TAG, "read System Property: $propName=$line")
|
||||
line
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Failed to read System Property $propName", e)
|
||||
""
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
try {
|
||||
bufferedReader.close()
|
||||
} catch (ignored: IOException) {
|
||||
}
|
||||
}
|
||||
process?.destroy()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue