forked from upstream-mirrors/quik
Move backup/restore status strings to resources, show completed state
This commit is contained in:
@@ -32,13 +32,14 @@ import io.reactivex.subjects.BehaviorSubject
|
||||
import io.reactivex.subjects.Subject
|
||||
import io.realm.Realm
|
||||
import okio.Okio
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.concurrent.schedule
|
||||
|
||||
|
||||
@Singleton
|
||||
@@ -95,23 +96,15 @@ class BackupRepositoryImpl @Inject constructor(
|
||||
messageCount = messages.size
|
||||
|
||||
// Map the messages to the new format
|
||||
val startTime = System.currentTimeMillis()
|
||||
messages.mapIndexed { index, message ->
|
||||
val progress = index.toDouble() / messageCount * 100
|
||||
val elapsed = System.currentTimeMillis() - startTime
|
||||
val remaining = when {
|
||||
index > 100 -> TimeUnit.MILLISECONDS.toSeconds((elapsed.toDouble() / index * (messageCount - index)).toLong())
|
||||
else -> 0
|
||||
}
|
||||
|
||||
// Update the progress
|
||||
backupProgress.onNext(BackupRepository.Progress.Running(progress.toInt(), "$remaining seconds remaining"))
|
||||
backupProgress.onNext(BackupRepository.Progress.Running(messageCount, index))
|
||||
messageToBackupMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
// Update the status, and set the progress to be indeterminate since we can no longer calculate progress
|
||||
backupProgress.onNext(BackupRepository.Progress.Running(0, "Saving..."))
|
||||
backupProgress.onNext(BackupRepository.Progress.Saving())
|
||||
|
||||
// Convert the data to json
|
||||
val adapter = moshi.adapter(Backup::class.java).indent("\t")
|
||||
@@ -125,9 +118,12 @@ class BackupRepositoryImpl @Inject constructor(
|
||||
// Write the log to the file
|
||||
FileOutputStream(file, true).use { fileOutputStream -> fileOutputStream.write(json) }
|
||||
} catch (e: Exception) {
|
||||
Timber.w(e)
|
||||
}
|
||||
|
||||
backupProgress.onNext(BackupRepository.Progress.Idle())
|
||||
// Mark the task finished, and set it as Idle a second later
|
||||
backupProgress.onNext(BackupRepository.Progress.Finished())
|
||||
Timer().schedule(1000) { backupProgress.onNext(BackupRepository.Progress.Idle()) }
|
||||
}
|
||||
|
||||
private fun messageToBackupMessage(message: Message): BackupMessage = BackupMessage(
|
||||
@@ -169,7 +165,7 @@ class BackupRepositoryImpl @Inject constructor(
|
||||
// If a backupFile or restore is already running, don't do anything
|
||||
if (isBackupOrRestoreRunning()) return
|
||||
|
||||
restoreProgress.onNext(BackupRepository.Progress.Running(0, "Parsing backup"))
|
||||
restoreProgress.onNext(BackupRepository.Progress.Parsing())
|
||||
|
||||
val file = File(filePath)
|
||||
val backup = Okio.buffer(Okio.source(file)).use { source ->
|
||||
@@ -180,8 +176,7 @@ class BackupRepositoryImpl @Inject constructor(
|
||||
|
||||
backup?.messages?.forEachIndexed { index, message ->
|
||||
// Update the progress
|
||||
val progress = Math.ceil(index.toDouble() / messageCount * 100).toInt()
|
||||
restoreProgress.onNext(BackupRepository.Progress.Running(progress, "$index/$messageCount messages"))
|
||||
restoreProgress.onNext(BackupRepository.Progress.Running(messageCount, index))
|
||||
|
||||
context.contentResolver.insert(Telephony.Sms.CONTENT_URI, contentValuesOf(
|
||||
Telephony.Sms.TYPE to message.type,
|
||||
@@ -198,18 +193,19 @@ class BackupRepositoryImpl @Inject constructor(
|
||||
Telephony.Sms.SUBSCRIPTION_ID to message.subId))
|
||||
}
|
||||
|
||||
restoreProgress.onNext(BackupRepository.Progress.Running(0, "Syncing messages"))
|
||||
|
||||
// Sync the messages
|
||||
restoreProgress.onNext(BackupRepository.Progress.Syncing())
|
||||
syncRepo.syncMessages()
|
||||
|
||||
restoreProgress.onNext(BackupRepository.Progress.Idle())
|
||||
// Mark the task finished, and set it as Idle a second later
|
||||
restoreProgress.onNext(BackupRepository.Progress.Finished())
|
||||
Timer().schedule(1000) { restoreProgress.onNext(BackupRepository.Progress.Idle()) }
|
||||
}
|
||||
|
||||
override fun getRestoreProgress(): Observable<BackupRepository.Progress> = restoreProgress
|
||||
|
||||
private fun isBackupOrRestoreRunning(): Boolean {
|
||||
return backupProgress.blockingFirst() is BackupRepository.Progress.Running
|
||||
|| restoreProgress.blockingFirst() is BackupRepository.Progress.Running
|
||||
return backupProgress.blockingFirst().running || restoreProgress.blockingFirst().running
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Moez Bhatti <moez.bhatti@gmail.com>
|
||||
*
|
||||
* This file is part of QKSMS.
|
||||
*
|
||||
* QKSMS is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* QKSMS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with QKSMS. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.moez.QKSMS.service
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.IBinder
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.moez.QKSMS.manager.NotificationManager
|
||||
import com.moez.QKSMS.repository.BackupRepository
|
||||
import dagger.android.AndroidInjection
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
class RestoreBackupService : Service() {
|
||||
|
||||
companion object {
|
||||
private const val NOTIFICATION_ID = -1
|
||||
|
||||
private const val ACTION_START = "com.moez.QKSMS.ACTION_START"
|
||||
private const val ACTION_STOP = "com.moez.QKSMS.ACTION_STOP"
|
||||
private const val EXTRA_FILE_PATH = "com.moez.QKSMS.EXTRA_FILE_PATH"
|
||||
|
||||
fun start(context: Context, filePath: String) {
|
||||
val intent = Intent(context, RestoreBackupService::class.java)
|
||||
.setAction(ACTION_START)
|
||||
.putExtra(EXTRA_FILE_PATH, filePath)
|
||||
|
||||
ContextCompat.startForegroundService(context, intent)
|
||||
}
|
||||
}
|
||||
|
||||
@Inject lateinit var backupRepo: BackupRepository
|
||||
@Inject lateinit var notificationManager: NotificationManager
|
||||
|
||||
private val notification by lazy { notificationManager.getNotificationForBackup() }
|
||||
|
||||
override fun onCreate() = AndroidInjection.inject(this)
|
||||
|
||||
override fun onBind(intent: Intent?): IBinder? = null
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
super.onStartCommand(intent, flags, startId)
|
||||
when (intent.action) {
|
||||
ACTION_START -> start(intent)
|
||||
ACTION_STOP -> stop()
|
||||
}
|
||||
|
||||
return Service.START_STICKY
|
||||
}
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private fun start(intent: Intent) {
|
||||
val notificationManager = NotificationManagerCompat.from(this)
|
||||
|
||||
startForeground(NOTIFICATION_ID, notification.build())
|
||||
|
||||
backupRepo.getRestoreProgress()
|
||||
.sample(200, TimeUnit.MILLISECONDS, true)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe { progress ->
|
||||
when (progress) {
|
||||
is BackupRepository.Progress.Running -> {
|
||||
notification
|
||||
.setProgress(100, progress.progress, false)
|
||||
.setContentText("${progress.progress}%")
|
||||
notificationManager.notify(NOTIFICATION_ID, notification.build())
|
||||
}
|
||||
|
||||
is BackupRepository.Progress.Idle -> stop()
|
||||
}
|
||||
}
|
||||
|
||||
// Start the restore
|
||||
Observable.just(intent)
|
||||
.map { it.getStringExtra(EXTRA_FILE_PATH) }
|
||||
.map(backupRepo::performRestore)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe({}, Timber::w)
|
||||
}
|
||||
|
||||
private fun stop() {
|
||||
stopForeground(true)
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user