Skip to content
This repository has been archived by the owner on Aug 19, 2023. It is now read-only.

Commit

Permalink
Ensure locks are reacquired when the app is updated or killed.
Browse files Browse the repository at this point in the history
  • Loading branch information
d4rken committed Oct 14, 2018
1 parent 7c714d1 commit a44d399
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 43 deletions.
38 changes: 21 additions & 17 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.thedarken.wldonate"
xmlns:android="http://schemas.android.com/apk/res/android">
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="eu.thedarken.wldonate">

<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<application
android:name="eu.thedarken.wldonate.App"
Expand All @@ -14,14 +15,15 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/BaseAppTheme.NoActionBar">
android:theme="@style/BaseAppTheme.NoActionBar"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name="eu.thedarken.wldonate.main.ui.MainActivity"
android:label="@string/app_name"
android:theme="@style/Theme.LauncherToMainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

Expand All @@ -30,31 +32,33 @@
android:enabled="true"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.PHONE_STATE"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.PHONE_STATE" />

<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />

<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>

<service android:name="eu.thedarken.wldonate.main.core.service.LockService"/>
<service android:name="eu.thedarken.wldonate.main.core.service.LockService" />

<receiver
android:name="eu.thedarken.wldonate.main.core.widget.ToggleWidgetProvider"
android:icon="@drawable/ic_launcher_splash_bulb"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
<action android:name="${applicationId}.widget.ACTION_UPDATE_WIDGET_FROM_SERVICE"/>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="${applicationId}.widget.ACTION_UPDATE_WIDGET_FROM_SERVICE" />
</intent-filter>

<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_toggle_info"/>
android:resource="@xml/widget_toggle_info" />
</receiver>

<meta-data
android:name="com.bugsnag.android.API_KEY"
android:value="${apikey_bugsnag}"/>
android:value="${apikey_bugsnag}" />
</application>
</manifest>
7 changes: 6 additions & 1 deletion app/src/main/java/eu/thedarken/wldonate/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.app.Application
import android.app.Service
import android.content.BroadcastReceiver
import android.content.Intent
import android.support.v7.app.AppCompatDelegate
import com.bugsnag.android.Bugsnag
import eu.darken.mvpbakery.injection.ComponentSource
Expand All @@ -15,6 +16,7 @@ import eu.thedarken.wldonate.common.UUIDToken
import eu.thedarken.wldonate.common.timber.BugsnagErrorHandler
import eu.thedarken.wldonate.common.timber.BugsnagTree
import eu.thedarken.wldonate.main.core.GeneralSettings
import eu.thedarken.wldonate.main.core.receiver.LockCommandReceiver
import eu.thedarken.wldonate.main.core.service.ServiceController
import eu.thedarken.wldonate.main.core.widget.WidgetController
import timber.log.Timber
Expand Down Expand Up @@ -56,7 +58,10 @@ open class App : Application(), HasManualActivityInjector, HasManualBroadcastRec
activityInjector = appComponent.activityInjector()
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Timber.d("onCreate() done!")
Timber.d("onCreate() done, requesting CHECKUP")
val checkupIntent = Intent(this, LockCommandReceiver::class.java)
checkupIntent.action = LockCommandReceiver.ACTION_CHECKUP
sendBroadcast(checkupIntent)
}

override fun activityInjector(): ManualInjector<Activity> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class GeneralSettings @Inject constructor(@ApplicationContext val context: Conte
const val PREF_KEY_SAVED_LOCKS = "core.locks.saved"
const val PREF_KEY_AUTOSTART_BOOT = "core.autostart.boot"
const val PREF_KEY_AUTOSTART_CALL = "core.autostart.call"
const val PREF_KEY_ACTIVE = "core.paused"
}

private val preferences: SharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)
Expand All @@ -44,7 +45,7 @@ class GeneralSettings @Inject constructor(@ApplicationContext val context: Conte

fun getSavedLocks(): HashSet<Lock.Type> {
val lockSet = HashSet<Lock.Type>()
for (s in preferences.getStringSet(PREF_KEY_SAVED_LOCKS, HashSet<String>())) {
for (s in preferences.getStringSet(PREF_KEY_SAVED_LOCKS, HashSet<String>())!!) {
lockSet.add(Lock.Type.valueOf(s))
}
Timber.d("Loaded locks %s", lockSet)
Expand All @@ -58,6 +59,14 @@ class GeneralSettings @Inject constructor(@ApplicationContext val context: Conte
preferences.edit().putStringSet(PREF_KEY_SAVED_LOCKS, stringSet).apply()
}

fun setActive(active: Boolean) {
preferences.edit().putBoolean(PREF_KEY_ACTIVE, active).apply()
}

fun isActive(): Boolean {
return preferences.getBoolean(PREF_KEY_ACTIVE, false)
}

fun isAutostartBootEnabled(): Boolean {
return preferences.getBoolean(PREF_KEY_AUTOSTART_BOOT, false)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,20 @@
package eu.thedarken.wldonate.main.core.locks

import eu.thedarken.wldonate.AppComponent
import eu.thedarken.wldonate.main.core.GeneralSettings
import io.reactivex.Completable
import io.reactivex.subjects.BehaviorSubject
import timber.log.Timber
import javax.inject.Inject

@AppComponent.Scope
class LockController @Inject constructor(
locks: Map<@JvmSuppressWildcards Lock.Type, @JvmSuppressWildcards Lock>
locks: Map<@JvmSuppressWildcards Lock.Type, @JvmSuppressWildcards Lock>,
val settings: GeneralSettings
) {

val locksPub: BehaviorSubject<Map<Lock.Type, Lock>> = BehaviorSubject.createDefault(locks)

@Synchronized
fun toggle(lockType: Lock.Type): Completable {
return Completable.create {
val lock: Lock = locksPub.blockingFirst().get(lockType)!!
Timber.i("Toggling: %s", lock)
if (lock.isAcquired()) lock.release()
else lock.acquire()
Timber.i("New lock-state: %s.isAcquired()=%b", lock, lock.isAcquired())
notifyOfChanges()
}
}

private fun notifyOfChanges() {
locksPub.onNext(locksPub.value!!)
}
Expand All @@ -33,16 +23,19 @@ class LockController @Inject constructor(
fun acquireExclusive(desired: Collection<Lock.Type>): Completable {
Timber.i("Acquiring %s", desired)
return locksPub.firstOrError()
.map {
it.forEach {
.map { lockMap ->
lockMap.forEach {
if (desired.contains(it.key)) {
it.value.acquire()
} else {
it.value.release()
}
}
}
.doOnSuccess { notifyOfChanges() }
.doOnSuccess {
settings.setActive(!desired.isEmpty())
notifyOfChanges()
}
.ignoreElement()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@ import javax.inject.Inject

class LockCommandReceiver : BroadcastReceiver() {
companion object {
@JvmStatic val ACTION_STOP = "eu.thedarken.wldonate.actions.RELEASE_LOCKS"
@JvmStatic val ACTION_TOGGLE = "eu.thedarken.wldonate.actions.TOGGLE_LOCKS"
@JvmStatic
val ACTION_STOP = "eu.thedarken.wldonate.actions.RELEASE_LOCKS"
@JvmStatic
val ACTION_TOGGLE = "eu.thedarken.wldonate.actions.TOGGLE_LOCKS"
@JvmStatic
val ACTION_CHECKUP = "eu.thedarken.wldonate.actions.CHECKUP"
}

@Inject lateinit var lockController: LockController
@Inject lateinit var settings: GeneralSettings
@Inject
lateinit var lockController: LockController
@Inject
lateinit var settings: GeneralSettings

override fun onReceive(context: Context, intent: Intent) {
Timber.v("onReceive(%s, %s)", context, intent)
Expand All @@ -37,16 +43,16 @@ class LockCommandReceiver : BroadcastReceiver() {
return
}

if (intent.action!! == ACTION_STOP) {
if (intent.action == ACTION_STOP) {
Timber.i("Stop request")
releaseAll()
} else if (intent.action!! == ACTION_TOGGLE) {
} else if (intent.action == ACTION_TOGGLE) {
Timber.i("Toggle request.")
toggle()
} else if (intent.action!! == Intent.ACTION_BOOT_COMPLETED && settings.isAutostartBootEnabled() && !settings.isAutostartCallEnabled()) {
} else if (intent.action == Intent.ACTION_BOOT_COMPLETED && settings.isAutostartBootEnabled() && !settings.isAutostartCallEnabled()) {
Timber.i("Reboot, restoring locks...")
acquireSaved()
} else if (intent.action!! == TelephonyManager.ACTION_PHONE_STATE_CHANGED && settings.isAutostartCallEnabled()) {
} else if (intent.action == TelephonyManager.ACTION_PHONE_STATE_CHANGED && settings.isAutostartCallEnabled()) {
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
if (TelephonyManager.EXTRA_STATE_RINGING == state || TelephonyManager.EXTRA_STATE_OFFHOOK == state) {
Timber.i("Call incoming...")
Expand All @@ -55,6 +61,13 @@ class LockCommandReceiver : BroadcastReceiver() {
Timber.i("Call ended, stopping it...")
releaseAll()
}
} else if (intent.action == Intent.ACTION_MY_PACKAGE_REPLACED && settings.isActive()) {
Timber.i("An update happened and we were previously active!")
acquireSaved()
} else if (intent.action == ACTION_CHECKUP) {
Timber.i("Self check, should we be active? -> ${settings.isActive()}")
if (settings.isActive()) acquireSaved()
else releaseAll()
}
}

Expand Down

0 comments on commit a44d399

Please sign in to comment.