Skip to content

Commit

Permalink
[Fix] Acquire wifi and wake lock for file jobs.
Browse files Browse the repository at this point in the history
Fixes: #1031
  • Loading branch information
zhanghai committed Sep 21, 2023
1 parent 38fa9e1 commit f7d5056
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,14 @@ import me.zhanghai.android.files.provider.common.PosixFileModeBit
import me.zhanghai.android.files.provider.common.PosixGroup
import me.zhanghai.android.files.provider.common.PosixUser
import me.zhanghai.android.files.util.ForegroundNotificationManager
import me.zhanghai.android.files.util.WakeWifiLock
import me.zhanghai.android.files.util.removeFirst
import java.util.concurrent.Executors
import java.util.concurrent.Future

class FileJobService : Service() {
private lateinit var wakeWifiLock: WakeWifiLock

internal lateinit var notificationManager: ForegroundNotificationManager
private set

Expand All @@ -31,6 +34,7 @@ class FileJobService : Service() {
override fun onCreate() {
super.onCreate()

wakeWifiLock = WakeWifiLock(FileJobService::class.java.simpleName)
notificationManager = ForegroundNotificationManager(this)
instance = this

Expand All @@ -39,27 +43,32 @@ class FileJobService : Service() {
}
}

override fun onBind(intent: Intent): IBinder? = null

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = START_STICKY

private val jobCount: Int
get() = synchronized(runningJobs) { runningJobs.size }

private fun startJob(job: FileJob) {
// Synchronize on runningJobs to prevent a job from removing itself before being added.
synchronized(runningJobs) {
val future = executorService.submit {
job.runOn(this)
synchronized(runningJobs) { runningJobs.remove(job) }
synchronized(runningJobs) {
runningJobs.remove(job)
updateWakeWifiLockLocked()
}
}
runningJobs[job] = future
updateWakeWifiLockLocked()
}
}

override fun onBind(intent: Intent): IBinder? = null

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int = START_STICKY

private val jobCount: Int
get() = synchronized(runningJobs) { runningJobs.size }

private fun cancelJob(id: Int) {
synchronized(runningJobs) {
runningJobs.removeFirst { it.key.id == id }?.value?.cancel(true)
updateWakeWifiLockLocked()
}
}

Expand All @@ -72,9 +81,16 @@ class FileJobService : Service() {
while (runningJobs.isNotEmpty()) {
runningJobs.removeFirst().value.cancel(true)
}
updateWakeWifiLockLocked()
}
}

// Synchronize on runningJobs to avoid the potential race condition that the lock is
// acquired after all jobs are finished in a very short time.
private fun updateWakeWifiLockLocked() {
wakeWifiLock.isAcquired = jobCount > 0
}

companion object {
private var instance: FileJobService? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import me.zhanghai.android.files.compat.mainExecutorCompat
import me.zhanghai.android.files.settings.Settings
import me.zhanghai.android.files.util.WakeWifiLock
import me.zhanghai.android.files.util.showToast
import me.zhanghai.android.files.util.valueCompat
import java.util.concurrent.Executors
Expand All @@ -26,7 +27,7 @@ class FtpServerService : Service() {
_stateLiveData.value = value
}

private lateinit var wakeLock: FtpServerWakeLock
private lateinit var wakeWifiLock: WakeWifiLock

private lateinit var notification: FtpServerNotification

Expand All @@ -37,7 +38,7 @@ class FtpServerService : Service() {
override fun onCreate() {
super.onCreate()

wakeLock = FtpServerWakeLock()
wakeWifiLock = WakeWifiLock(FtpServerService::class.java.simpleName)
notification = FtpServerNotification(this)
executeStart()
}
Expand All @@ -57,7 +58,7 @@ class FtpServerService : Service() {
if (state == State.STARTING || state == State.RUNNING) {
return
}
wakeLock.acquire()
wakeWifiLock.isAcquired = true
notification.startForeground()
state = State.STARTING
executorService.execute { doStart() }
Expand All @@ -67,7 +68,7 @@ class FtpServerService : Service() {
state = State.STOPPED
showToast(exception.toString())
notification.stopForeground()
wakeLock.release()
wakeWifiLock.isAcquired = false
stopSelf()
}

Expand All @@ -78,7 +79,7 @@ class FtpServerService : Service() {
state = State.STOPPING
executorService.execute { doStop() }
notification.stopForeground()
wakeLock.release()
wakeWifiLock.isAcquired = false
}

@WorkerThread
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,32 @@
* All Rights Reserved.
*/

package me.zhanghai.android.files.ftpserver
package me.zhanghai.android.files.util

import android.net.wifi.WifiManager
import android.os.PowerManager
import me.zhanghai.android.files.app.powerManager
import me.zhanghai.android.files.app.wifiManager

class FtpServerWakeLock {
private val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, LOCK_TAG)
class WakeWifiLock(tag: String) {
private val wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, tag)
.apply { setReferenceCounted(false) }
private val wifiLock =
wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, LOCK_TAG)
wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, tag)
.apply { setReferenceCounted(false) }

fun acquire() {
wakeLock.acquire()
wifiLock.acquire()
}

fun release() {
wifiLock.release()
wakeLock.release()
}

companion object {
private val LOCK_TAG = FtpServerWakeLock::class.java.simpleName
}
var isAcquired: Boolean = false
set(value) {
if (field == value) {
return
}
if (value) {
wakeLock.acquire()
wifiLock.acquire()
} else {
wifiLock.release()
wakeLock.release()
}
field = value
}
}

0 comments on commit f7d5056

Please sign in to comment.