Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessibility Service Overlay MVP #329

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
13 changes: 13 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,18 @@
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>

<service
android:name=".service.AccessibilityFilterService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:label="@string/overlay_accessibility_service_label"
android:exported="true">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />

</service>
</application>
</manifest>
1 change: 0 additions & 1 deletion app/src/main/java/com/jmstudios/redmoon/Command.kt
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ enum class Command(val time: Float) {

fun getCommand(intent: Intent): Command {
val commandName = intent.getStringExtra(EXTRA_COMMAND) ?: ""
Log.i("Recieved flag: $commandName")
return valueOf(commandName)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,14 @@
package com.jmstudios.redmoon

import android.animation.Animator
import android.app.Service
import com.jmstudios.redmoon.service.AccessibilityFilterService
import com.jmstudios.redmoon.service.FilterService

class CommandAnimatorListener(
private val cmd: Command,
private val svc: FilterService)
private val cmd: Command,
private val svc: FilterService,
)
: Animator.AnimatorListener {

override fun onAnimationStart (a: Animator?) = cmd.onAnimationStart (svc)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/jmstudios/redmoon/EventBus.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,6 @@ class overlayPermissionDenied : Event
class locationAccessDenied : Event
class changeBrightnessDenied : Event

class accessibilityServiceCommand(val command: Command) : Event

data class locationService(val isSearching: Boolean, val isRunning: Boolean = true) : Event
52 changes: 37 additions & 15 deletions app/src/main/java/com/jmstudios/redmoon/Overlay.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
package com.jmstudios.redmoon

import android.content.Context
import android.content.res.Resources
import android.graphics.Canvas
import android.graphics.PixelFormat
import android.os.Build
import android.view.View
import android.view.WindowInsets
import android.view.WindowManager

import com.jmstudios.redmoon.helper.Logger
import com.jmstudios.redmoon.manager.BrightnessManager
import com.jmstudios.redmoon.manager.ScreenManager
import com.jmstudios.redmoon.receiver.OrientationChangeReceiver

import kotlin.properties.Delegates
Expand All @@ -42,7 +45,6 @@ class Overlay(context: Context) : View(context), Filter,
OrientationChangeReceiver.OnOrientationChangeListener {

private val mWindowManager = context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
private val mScreenManager = ScreenManager(context, mWindowManager)
private val mOrientationReceiver = OrientationChangeReceiver(context, this)
private val mBrightnessManager = BrightnessManager(context)

Expand Down Expand Up @@ -71,7 +73,6 @@ class Overlay(context: Context) : View(context), Filter,
}

private fun show() {
updateLayoutParams()
mWindowManager.addView(this, mLayoutParams)
mBrightnessManager.brightnessLowered = profile.lowerBrightness
mOrientationReceiver.register()
Expand All @@ -93,26 +94,47 @@ class Overlay(context: Context) : View(context), Filter,
mBrightnessManager.brightnessLowered = profile.lowerBrightness
}

private var mLayoutParams = mScreenManager.layoutParams
smichel17 marked this conversation as resolved.
Show resolved Hide resolved
get() = field.apply {
buttonBrightness = Config.buttonBacklightLevel
type = if (atLeastAPI(26)) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
}
val mLayoutParams = WindowManager.LayoutParams().apply {
buttonBrightness = Config.buttonBacklightLevel
// TODO: why is cutout always null?
// if(atLeastAPI(Build.VERSION_CODES.P)) {
// val cutout = WindowInsets.Builder().build().displayCutout
// val top = cutout?.boundingRectTop?.height() ?: 0
// val bottom = cutout?.boundingRectBottom?.height() ?: 0
// val left = cutout?.boundingRectLeft?.width() ?: 0
// val right = cutout?.boundingRectRight?.width() ?: 0
// height = Resources.getSystem().displayMetrics.heightPixels + top + bottom
// width = Resources.getSystem().displayMetrics.widthPixels + left + right
// x = -left
// y = -top
// } else {
height = Resources.getSystem().displayMetrics.heightPixels + 4000
width = Resources.getSystem().displayMetrics.widthPixels + 4000
x = -1000
y = -1000
// }
format = PixelFormat.TRANSLUCENT
type = if (isAccessibilityServiceOn(context) && atLeastAPI(Build.VERSION_CODES.M)) {
WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY
} else if (atLeastAPI(Build.VERSION_CODES.O)) {
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY
} else {
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY
}
flags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
.or(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE)
.or(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)
.or(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
}

private fun updateLayoutParams() {
mLayoutParams = mScreenManager.layoutParams
}

private fun reLayout() = mWindowManager.updateViewLayout(this, mLayoutParams)

override fun onDraw(canvas: Canvas) = canvas.drawColor(profile.filterColor)

override fun onOrientationChanged() {
updateLayoutParams()
reLayout()
}

Expand Down
7 changes: 7 additions & 0 deletions app/src/main/java/com/jmstudios/redmoon/Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
*/
package com.jmstudios.redmoon

import android.content.Context
import android.content.Intent
import android.provider.Settings
import androidx.preference.Preference
import androidx.core.content.ContextCompat
import androidx.preference.PreferenceFragmentCompat
Expand Down Expand Up @@ -60,6 +62,11 @@ var filterIsOn: Boolean = false
Config.filterIsOn = value
}

fun isAccessibilityServiceOn(context: Context?): Boolean {
val prefString = Settings.Secure.getString(context?.contentResolver, Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES)
return prefString != null && prefString.contains("com.jmstudios.redmoon.service.AccessibilityFilterService")
}

fun inActivePeriod(Log: KLog? = null): Boolean {
val now = Calendar.getInstance()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
*/
package com.jmstudios.redmoon.fragment

import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.view.ViewGroup
import android.widget.TextView
import android.widget.Toast
Expand All @@ -14,23 +16,11 @@ import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import com.google.android.material.snackbar.Snackbar
import com.jmstudios.redmoon.Command
import com.jmstudios.redmoon.*

import com.jmstudios.redmoon.Config
import com.jmstudios.redmoon.EventBus
import com.jmstudios.redmoon.filterIsOn
import com.jmstudios.redmoon.getColor
import com.jmstudios.redmoon.helper.Logger
import com.jmstudios.redmoon.helper.Permission
import com.jmstudios.redmoon.inActivePeriod
import com.jmstudios.redmoon.locationAccessDenied
import com.jmstudios.redmoon.locationChanged
import com.jmstudios.redmoon.locationService
import com.jmstudios.redmoon.pref
import com.jmstudios.redmoon.R
import com.jmstudios.redmoon.scheduleChanged
import com.jmstudios.redmoon.service.LocationUpdateService
import com.jmstudios.redmoon.useLocationChanged

import com.topjohnwu.superuser.Shell
import org.greenrobot.eventbus.Subscribe
Expand All @@ -57,6 +47,9 @@ class SettingsFragment : PreferenceFragmentCompat() {
private val rootPref: SwitchPreference
get() = pref(R.string.pref_key_use_root) as SwitchPreference

private val accessibilityServicePref: Preference
get() = pref(R.string.pref_key_use_accessibility_service) as Preference

private var mSnackbar: Snackbar? = null

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
Expand Down Expand Up @@ -121,6 +114,11 @@ class SettingsFragment : PreferenceFragmentCompat() {
return@setOnPreferenceChangeListener true
}

accessibilityServicePref.setOnPreferenceClickListener { _ ->
startActivity(Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS))
return@setOnPreferenceClickListener true
}

updatePrefs()
}

Expand Down
119 changes: 0 additions & 119 deletions app/src/main/java/com/jmstudios/redmoon/manager/ScreenManager.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.jmstudios.redmoon.service

import android.accessibilityservice.AccessibilityService
import android.animation.ValueAnimator
import android.graphics.PixelFormat
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import com.jmstudios.redmoon.*
import com.jmstudios.redmoon.helper.Logger
import org.greenrobot.eventbus.Subscribe


class AccessibilityFilterService : AccessibilityService() {
lateinit var mFilter: Overlay

override fun onAccessibilityEvent(event: AccessibilityEvent) {}
override fun onInterrupt() {}

override fun onServiceConnected() {
mFilter = Overlay(applicationContext)
(getSystemService(WINDOW_SERVICE) as WindowManager).addView(mFilter, mFilter.mLayoutParams)
mFilter.visibility = View.GONE;
EventBus.register(this)
}

override fun onDestroy() {
super.onDestroy()
(getSystemService(WINDOW_SERVICE) as WindowManager).removeView(mFilter)
EventBus.unregister(this);
AdamNiederer marked this conversation as resolved.
Show resolved Hide resolved
}

@Subscribe
fun turnOnOrOff(cmd: accessibilityServiceCommand) {
mFilter.setBackgroundColor(activeProfile.filterColor)
mFilter.visibility = if (cmd.command.turnOn) View.VISIBLE else View.GONE
}
}