Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
  • Loading branch information
Kelvin-FUTO committed Aug 22, 2024
2 parents 2941546 + ec19ea4 commit a95ddab
Show file tree
Hide file tree
Showing 17 changed files with 399 additions and 267 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ android {
}

dependencies {
implementation 'com.google.dagger:dagger:2.48'
annotationProcessor 'com.google.dagger:dagger-compiler:2.48'

//Core
implementation 'androidx.core:core-ktx:1.12.0'
Expand Down
35 changes: 18 additions & 17 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<!--<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS" tools:ignore="ProtectedPermissions"/>
Expand Down Expand Up @@ -50,7 +51,7 @@
android:name=".activities.MainActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
android:exported="true"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar"
android:launchMode="singleTask"
android:resizeableActivity="true"
Expand Down Expand Up @@ -152,27 +153,27 @@

<activity
android:name=".activities.SettingsActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.DeveloperActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.ExceptionActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.CaptchaActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.LoginActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.AddSourceActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:exported="true"
android:theme="@style/Theme.FutoVideo.NoActionBar">
<intent-filter>
Expand All @@ -186,44 +187,44 @@
</activity>
<activity
android:name=".activities.AddSourceOptionsActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.PolycentricHomeActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.PolycentricBackupActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.PolycentricCreateProfileActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.PolycentricProfileActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.PolycentricWhyActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.PolycentricImportProfileActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.ManageTabsActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />

<activity
android:name=".activities.QRCaptureActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
<activity
android:name=".activities.FCastGuideActivity"
android:screenOrientation="portrait"
android:screenOrientation="sensorPortrait"
android:theme="@style/Theme.FutoVideo.NoActionBar" />
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import android.app.Activity
import android.content.Context
import android.content.pm.ActivityInfo
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import com.futo.platformplayer.constructs.Event1
import com.futo.platformplayer.logging.Logger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch


class AdvancedOrientationListener(private val activity: Activity, private val lifecycleScope: CoroutineScope) {
private val sensorManager: SensorManager = activity.getSystemService(Context.SENSOR_SERVICE) as SensorManager
private val accelerometer: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
private val magnetometer: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)

private var lastOrientation: Int = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
private var lastStableOrientation: Int = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
private var lastOrientationChangeTime = 0L
private val debounceTime = 200L
private val stabilityThresholdTime = 800L
private var deviceAspectRatio: Float = 1.0f

private val gravity = FloatArray(3)
private val geomagnetic = FloatArray(3)
private val rotationMatrix = FloatArray(9)
private val orientationAngles = FloatArray(3)

val onOrientationChanged = Event1<Int>()

private val sensorListener = object : SensorEventListener {
override fun onSensorChanged(event: SensorEvent) {
when (event.sensor.type) {
Sensor.TYPE_ACCELEROMETER -> {
System.arraycopy(event.values, 0, gravity, 0, gravity.size)
}
Sensor.TYPE_MAGNETIC_FIELD -> {
System.arraycopy(event.values, 0, geomagnetic, 0, geomagnetic.size)
}
}

if (gravity.isNotEmpty() && geomagnetic.isNotEmpty()) {
val success = SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomagnetic)
if (success) {
SensorManager.getOrientation(rotationMatrix, orientationAngles)

val azimuth = Math.toDegrees(orientationAngles[0].toDouble()).toFloat()
val pitch = Math.toDegrees(orientationAngles[1].toDouble()).toFloat()
val roll = Math.toDegrees(orientationAngles[2].toDouble()).toFloat()

val newOrientation = when {
roll in -155f .. -15f && isWithinThreshold(pitch, 0f, 30.0) -> {
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
}
roll in 15f .. 155f && isWithinThreshold(pitch, 0f, 30.0) -> {
ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
}
isWithinThreshold(pitch, -90f, 30.0 * deviceAspectRatio) && roll in -15f .. 15f -> {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
}
isWithinThreshold(pitch, 90f, 30.0 * deviceAspectRatio) && roll in -15f .. 15f -> {
ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
}
else -> lastOrientation
}

//Logger.i("AdvancedOrientationListener", "newOrientation = ${newOrientation}, roll = ${roll}, pitch = ${pitch}, azimuth = ${azimuth}")

if (newOrientation != lastStableOrientation) {
val currentTime = System.currentTimeMillis()
if (currentTime - lastOrientationChangeTime > debounceTime) {
lastOrientationChangeTime = currentTime
lastStableOrientation = newOrientation

lifecycleScope.launch(Dispatchers.Main) {
delay(stabilityThresholdTime)
if (newOrientation == lastStableOrientation) {
lastOrientation = newOrientation
onOrientationChanged.emit(newOrientation)
}
}
}
}
}
}
}

override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
}

private fun isWithinThreshold(value: Float, target: Float, threshold: Double): Boolean {
return Math.abs(value - target) <= threshold
}

init {
sensorManager.registerListener(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_GAME)
sensorManager.registerListener(sensorListener, magnetometer, SensorManager.SENSOR_DELAY_GAME)

val metrics = activity.resources.displayMetrics
deviceAspectRatio = (metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat())
if (deviceAspectRatio == 0.0f)
deviceAspectRatio = 1.0f

lastOrientation = activity.resources.configuration.orientation
}

fun stopListening() {
sensorManager.unregisterListener(sensorListener)
}
}
46 changes: 31 additions & 15 deletions app/src/main/java/com/futo/platformplayer/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ package com.futo.platformplayer

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Context.POWER_SERVICE
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.webkit.CookieManager
import androidx.lifecycle.lifecycleScope
import com.futo.platformplayer.activities.MainActivity
Expand All @@ -23,6 +26,7 @@ import com.futo.platformplayer.states.StateBackup
import com.futo.platformplayer.states.StateCache
import com.futo.platformplayer.states.StateMeta
import com.futo.platformplayer.states.StatePayment
import com.futo.platformplayer.states.StatePlayer
import com.futo.platformplayer.states.StatePolycentric
import com.futo.platformplayer.states.StateUpdate
import com.futo.platformplayer.stores.FragmentedStorage
Expand All @@ -34,6 +38,7 @@ import com.futo.platformplayer.views.fields.FormField
import com.futo.platformplayer.views.fields.FormFieldButton
import com.futo.platformplayer.views.fields.FormFieldWarning
import com.futo.platformplayer.views.overlays.slideup.SlideUpMenuItem
import com.stripe.android.customersheet.injection.CustomerSheetViewModelModule_Companion_ContextFactory.context
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
Expand All @@ -44,6 +49,7 @@ import kotlinx.serialization.json.Json
import java.io.File
import java.time.OffsetDateTime


@Serializable
data class MenuBottomBarSetting(val id: Int, var enabled: Boolean);

Expand All @@ -57,7 +63,7 @@ class Settings : FragmentedStorageFileJson() {
@Transient
val onTabsChanged = Event0();

@FormField(R.string.manage_polycentric_identity, FieldForm.BUTTON, R.string.manage_your_polycentric_identity, -6)
@FormField(R.string.manage_polycentric_identity, FieldForm.BUTTON, R.string.manage_your_polycentric_identity, -7)
@FormFieldButton(R.drawable.ic_person)
fun managePolycentricIdentity() {
SettingsActivity.getActivity()?.let {
Expand All @@ -73,7 +79,7 @@ class Settings : FragmentedStorageFileJson() {
}
}

@FormField(R.string.show_faq, FieldForm.BUTTON, R.string.get_answers_to_common_questions, -5)
@FormField(R.string.show_faq, FieldForm.BUTTON, R.string.get_answers_to_common_questions, -6)
@FormFieldButton(R.drawable.ic_quiz)
fun openFAQ() {
try {
Expand All @@ -83,7 +89,7 @@ class Settings : FragmentedStorageFileJson() {
//Ignored
}
}
@FormField(R.string.show_issues, FieldForm.BUTTON, R.string.a_list_of_user_reported_and_self_reported_issues, -4)
@FormField(R.string.show_issues, FieldForm.BUTTON, R.string.a_list_of_user_reported_and_self_reported_issues, -5)
@FormFieldButton(R.drawable.ic_data_alert)
fun openIssues() {
try {
Expand Down Expand Up @@ -115,7 +121,7 @@ class Settings : FragmentedStorageFileJson() {
}
}*/

@FormField(R.string.manage_tabs, FieldForm.BUTTON, R.string.change_tabs_visible_on_the_home_screen, -3)
@FormField(R.string.manage_tabs, FieldForm.BUTTON, R.string.change_tabs_visible_on_the_home_screen, -4)
@FormFieldButton(R.drawable.ic_tabs)
fun manageTabs() {
try {
Expand All @@ -129,7 +135,7 @@ class Settings : FragmentedStorageFileJson() {



@FormField(R.string.import_data, FieldForm.BUTTON, R.string.import_data_description, -2)
@FormField(R.string.import_data, FieldForm.BUTTON, R.string.import_data_description, -3)
@FormFieldButton(R.drawable.ic_move_up)
fun import() {
val act = SettingsActivity.getActivity() ?: return;
Expand All @@ -138,7 +144,7 @@ class Settings : FragmentedStorageFileJson() {
act.startActivity(intent);
}

@FormField(R.string.link_handling, FieldForm.BUTTON, R.string.allow_grayjay_to_handle_links, -1)
@FormField(R.string.link_handling, FieldForm.BUTTON, R.string.allow_grayjay_to_handle_links, -2)
@FormFieldButton(R.drawable.ic_link)
fun manageLinks() {
try {
Expand All @@ -148,6 +154,24 @@ class Settings : FragmentedStorageFileJson() {
}
}

/*@FormField(R.string.disable_battery_optimization, FieldForm.BUTTON, R.string.click_to_go_to_battery_optimization_settings_disabling_battery_optimization_will_prevent_the_os_from_killing_media_sessions, -1)
@FormFieldButton(R.drawable.battery_full_24px)
fun ignoreBatteryOptimization() {
SettingsActivity.getActivity()?.let {
val intent = Intent()
val packageName = it.packageName
val pm = it.getSystemService(POWER_SERVICE) as PowerManager;
if (!pm.isIgnoringBatteryOptimizations(packageName)) {
intent.setAction(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
intent.setData(Uri.parse("package:$packageName"))
it.startActivity(intent)
UIDialogs.toast(it, "Please ignore battery optimizations for Grayjay")
} else {
UIDialogs.toast(it, "Battery optimizations already disabled for Grayjay")
}
}
}*/

@FormField(R.string.language, "group", -1, 0)
var language = LanguageSettings();
@Serializable
Expand Down Expand Up @@ -393,15 +417,7 @@ class Settings : FragmentedStorageFileJson() {
@DropdownFieldOptionsId(R.array.system_enabled_disabled_array)
var autoRotate: Int = 2;

fun isAutoRotate() = autoRotate == 1 || (autoRotate == 2 && StateApp.instance.getCurrentSystemAutoRotate());

@FormField(R.string.auto_rotate_dead_zone, FieldForm.DROPDOWN, R.string.this_prevents_the_device_from_rotating_within_the_given_amount_of_degrees, 6)
@DropdownFieldOptionsId(R.array.auto_rotate_dead_zone)
var autoRotateDeadZone: Int = 0;

fun getAutoRotateDeadZoneDegrees(): Int {
return autoRotateDeadZone * 5;
}
fun isAutoRotate() = (autoRotate == 1 && !StatePlayer.instance.rotationLock) || (autoRotate == 2 && StateApp.instance.getCurrentSystemAutoRotate() && !StatePlayer.instance.rotationLock);

@FormField(R.string.background_behavior, FieldForm.DROPDOWN, -1, 7)
@DropdownFieldOptionsId(R.array.player_background_behavior)
Expand Down
Loading

0 comments on commit a95ddab

Please sign in to comment.