Add product flavors. Switch to evernote's job scheduler

This commit is contained in:
len 2016-11-06 18:44:14 +01:00
parent 71fac76e3d
commit 2856d9d6a3
11 changed files with 152 additions and 168 deletions

View file

@ -28,10 +28,6 @@ ext {
} }
} }
def includeUpdater() {
return hasProperty("include_updater")
}
android { android {
compileSdkVersion 25 compileSdkVersion 25
buildToolsVersion "25.0.0" buildToolsVersion "25.0.0"
@ -48,7 +44,6 @@ android {
buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\"" buildConfigField "String", "COMMIT_COUNT", "\"${getCommitCount()}\""
buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\"" buildConfigField "String", "COMMIT_SHA", "\"${getGitSha()}\""
buildConfigField "String", "BUILD_TIME", "\"${getBuildTime()}\"" buildConfigField "String", "BUILD_TIME", "\"${getBuildTime()}\""
buildConfigField "boolean", "INCLUDE_UPDATER", "${includeUpdater()}"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
@ -71,6 +66,16 @@ android {
} }
} }
productFlavors {
standard {
buildConfigField "boolean", "INCLUDE_UPDATER", "true"
}
fdroid {
buildConfigField "boolean", "INCLUDE_UPDATER", "false"
}
}
packagingOptions { packagingOptions {
exclude 'META-INF/DEPENDENCIES' exclude 'META-INF/DEPENDENCIES'
exclude 'LICENSE.txt' exclude 'LICENSE.txt'
@ -108,6 +113,8 @@ dependencies {
compile 'com.android.support:multidex:1.0.1' compile 'com.android.support:multidex:1.0.1'
// Job scheduling
compile 'com.evernote:android-job:1.1.2'
compile 'com.google.android.gms:play-services-gcm:9.8.0' compile 'com.google.android.gms:play-services-gcm:9.8.0'
// ReactiveX // ReactiveX
@ -117,6 +124,7 @@ dependencies {
// Network client // Network client
compile "com.squareup.okhttp3:okhttp:3.4.2" compile "com.squareup.okhttp3:okhttp:3.4.2"
compile 'com.squareup.okio:okio:1.11.0'
// REST // REST
final retrofit_version = '2.1.0' final retrofit_version = '2.1.0'
@ -124,9 +132,6 @@ dependencies {
compile "com.squareup.retrofit2:converter-gson:$retrofit_version" compile "com.squareup.retrofit2:converter-gson:$retrofit_version"
compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version" compile "com.squareup.retrofit2:adapter-rxjava:$retrofit_version"
// IO
compile 'com.squareup.okio:okio:1.11.0'
// JSON // JSON
compile 'com.google.code.gson:gson:2.8.0' compile 'com.google.code.gson:gson:2.8.0'
compile 'com.github.salomonbrys.kotson:kotson:2.4.0' compile 'com.github.salomonbrys.kotson:kotson:2.4.0'
@ -140,7 +145,7 @@ dependencies {
// Disk cache // Disk cache
compile 'com.jakewharton:disklrucache:2.0.2' compile 'com.jakewharton:disklrucache:2.0.2'
// Parse HTML // HTML parser
compile 'org.jsoup:jsoup:1.10.1' compile 'org.jsoup:jsoup:1.10.1'
// Changelog // Changelog

View file

@ -63,24 +63,6 @@
<service android:name=".data.mangasync.UpdateMangaSyncService" <service android:name=".data.mangasync.UpdateMangaSyncService"
android:exported="false"/> android:exported="false"/>
<service
android:name=".data.library.LibraryUpdateTrigger"
android:exported="true"
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
</intent-filter>
</service>
<service
android:name=".data.updater.UpdateCheckerService"
android:exported="true"
android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
</intent-filter>
</service>
<service android:name=".data.updater.UpdateDownloaderService" <service android:name=".data.updater.UpdateDownloaderService"
android:exported="false"/> android:exported="false"/>

View file

@ -3,6 +3,9 @@ package eu.kanade.tachiyomi
import android.app.Application import android.app.Application
import android.content.Context import android.content.Context
import android.support.multidex.MultiDex import android.support.multidex.MultiDex
import com.evernote.android.job.JobManager
import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.updater.UpdateCheckerJob
import org.acra.ACRA import org.acra.ACRA
import org.acra.annotation.ReportsCrashes import org.acra.annotation.ReportsCrashes
import timber.log.Timber import timber.log.Timber
@ -27,6 +30,7 @@ open class App : Application() {
if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree()) if (BuildConfig.DEBUG) Timber.plant(Timber.DebugTree())
setupAcra() setupAcra()
setupJobManager()
} }
override fun attachBaseContext(base: Context) { override fun attachBaseContext(base: Context) {
@ -40,4 +44,14 @@ open class App : Application() {
ACRA.init(this) ACRA.init(this)
} }
protected open fun setupJobManager() {
JobManager.create(this).addJobCreator { tag ->
when (tag) {
LibraryUpdateJob.TAG -> LibraryUpdateJob()
UpdateCheckerJob.TAG -> UpdateCheckerJob()
else -> null
}
}
}
} }

View file

@ -0,0 +1,47 @@
package eu.kanade.tachiyomi.data.library
import com.evernote.android.job.Job
import com.evernote.android.job.JobManager
import com.evernote.android.job.JobRequest
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class LibraryUpdateJob : Job() {
override fun onRunJob(params: Params): Result {
LibraryUpdateService.start(context)
return Job.Result.SUCCESS
}
companion object {
const val TAG = "LibraryUpdate"
fun setupTask(prefInterval: Int? = null) {
val preferences = Injekt.get<PreferencesHelper>()
val interval = prefInterval ?: preferences.libraryUpdateInterval().getOrDefault()
if (interval > 0) {
val restrictions = preferences.libraryUpdateRestriction()
val acRestriction = "ac" in restrictions
val wifiRestriction = if ("wifi" in restrictions)
JobRequest.NetworkType.UNMETERED
else
JobRequest.NetworkType.CONNECTED
JobRequest.Builder(TAG)
.setPeriodic(interval * 60 * 60 * 1000L)
.setRequiredNetworkType(wifiRestriction)
.setRequiresCharging(acRestriction)
.setPersisted(true)
.setUpdateCurrent(true)
.build()
.schedule()
}
}
fun cancelTask() {
JobManager.instance().cancelAllForTag(TAG)
}
}
}

View file

@ -267,7 +267,7 @@ class LibraryUpdateService : Service() {
} else { } else {
showResultNotification(newUpdates, failedUpdates) showResultNotification(newUpdates, failedUpdates)
} }
LibraryUpdateTrigger.setupTask(this) LibraryUpdateJob.setupTask()
} }
} }

View file

@ -1,52 +0,0 @@
package eu.kanade.tachiyomi.data.library
import android.content.Context
import com.google.android.gms.gcm.*
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class LibraryUpdateTrigger : GcmTaskService() {
override fun onInitializeTasks() {
setupTask(this)
}
override fun onRunTask(params: TaskParams): Int {
LibraryUpdateService.start(this)
return GcmNetworkManager.RESULT_SUCCESS
}
companion object {
fun setupTask(context: Context, prefInterval: Int? = null) {
val preferences = Injekt.get<PreferencesHelper>()
val interval = prefInterval ?: preferences.libraryUpdateInterval().getOrDefault()
if (interval > 0) {
val restrictions = preferences.libraryUpdateRestriction()
val acRestriction = "ac" in restrictions
val wifiRestriction = if ("wifi" in restrictions)
Task.NETWORK_STATE_UNMETERED
else
Task.NETWORK_STATE_ANY
val task = PeriodicTask.Builder()
.setService(LibraryUpdateTrigger::class.java)
.setTag("Library periodic update")
.setPeriod(interval * 60 * 60L)
.setFlex(5 * 60)
.setRequiredNetwork(wifiRestriction)
.setRequiresCharging(acRestriction)
.setUpdateCurrent(true)
.setPersisted(true)
.build()
GcmNetworkManager.getInstance(context).schedule(task)
}
}
fun cancelTask(context: Context) {
GcmNetworkManager.getInstance(context).cancelAllTasks(LibraryUpdateTrigger::class.java)
}
}
}

View file

@ -0,0 +1,61 @@
package eu.kanade.tachiyomi.data.updater
import android.support.v4.app.NotificationCompat
import com.evernote.android.job.Job
import com.evernote.android.job.JobManager
import com.evernote.android.job.JobRequest
import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.util.notificationManager
class UpdateCheckerJob : Job() {
override fun onRunJob(params: Params): Result {
return GithubUpdateChecker()
.checkForUpdate()
.map { result ->
if (result is GithubUpdateResult.NewUpdate) {
val url = result.release.downloadLink
NotificationCompat.Builder(context).update {
setContentTitle(context.getString(R.string.app_name))
setContentText(context.getString(R.string.update_check_notification_update_available))
setSmallIcon(android.R.drawable.stat_sys_download_done)
// Download action
addAction(android.R.drawable.stat_sys_download_done,
context.getString(R.string.action_download),
UpdateNotificationReceiver.downloadApkIntent(context, url))
}
}
Job.Result.SUCCESS
}
.onErrorReturn { Job.Result.FAILURE }
// Sadly, the task needs to be synchronous.
.toBlocking()
.single()
}
fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) {
block()
context.notificationManager.notify(NOTIFICATION_UPDATER_ID, build())
}
companion object {
const val TAG = "UpdateChecker"
fun setupTask() {
JobRequest.Builder(TAG)
.setPeriodic(24 * 60 * 60 * 1000)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
.setPersisted(true)
.setUpdateCurrent(true)
.build()
.schedule()
}
fun cancelTask() {
JobManager.instance().cancelAllForTag(TAG)
}
}
}

View file

@ -1,80 +0,0 @@
package eu.kanade.tachiyomi.data.updater
import android.content.Context
import android.support.v4.app.NotificationCompat
import com.google.android.gms.gcm.*
import eu.kanade.tachiyomi.Constants.NOTIFICATION_UPDATER_ID
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.notificationManager
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class UpdateCheckerService : GcmTaskService() {
override fun onInitializeTasks() {
val preferences: PreferencesHelper = Injekt.get()
if (preferences.automaticUpdates()) {
setupTask(this)
}
}
override fun onRunTask(params: TaskParams): Int {
return checkVersion()
}
fun checkVersion(): Int {
return GithubUpdateChecker()
.checkForUpdate()
.map { result ->
if (result is GithubUpdateResult.NewUpdate) {
val url = result.release.downloadLink
NotificationCompat.Builder(this).update {
setContentTitle(getString(R.string.app_name))
setContentText(getString(R.string.update_check_notification_update_available))
setSmallIcon(android.R.drawable.stat_sys_download_done)
// Download action
addAction(android.R.drawable.stat_sys_download_done,
getString(R.string.action_download),
UpdateNotificationReceiver.downloadApkIntent(
this@UpdateCheckerService, url))
}
}
GcmNetworkManager.RESULT_SUCCESS
}
.onErrorReturn { GcmNetworkManager.RESULT_FAILURE }
// Sadly, the task needs to be synchronous.
.toBlocking()
.single()
}
fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) {
block()
notificationManager.notify(NOTIFICATION_UPDATER_ID, build())
}
companion object {
fun setupTask(context: Context) {
val task = PeriodicTask.Builder()
.setService(UpdateCheckerService::class.java)
.setTag("Updater")
// 24 hours
.setPeriod(24 * 60 * 60)
// Run between the last two hours
.setFlex(2 * 60 * 60)
.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
.setPersisted(true)
.setUpdateCurrent(true)
.build()
GcmNetworkManager.getInstance(context).schedule(task)
}
fun cancelTask(context: Context) {
GcmNetworkManager.getInstance(context).cancelAllTasks(UpdateCheckerService::class.java)
}
}
}

View file

@ -11,15 +11,22 @@ import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
import eu.kanade.tachiyomi.data.updater.UpdateCheckerJob
import it.gmariotti.changelibs.library.view.ChangeLogRecyclerView import it.gmariotti.changelibs.library.view.ChangeLogRecyclerView
class ChangelogDialogFragment : DialogFragment() { class ChangelogDialogFragment : DialogFragment() {
companion object { companion object {
fun show(preferences: PreferencesHelper, fragmentManager: FragmentManager) { fun show(preferences: PreferencesHelper, fragmentManager: FragmentManager) {
if (preferences.lastVersionCode().getOrDefault() < BuildConfig.VERSION_CODE) { val oldVersion = preferences.lastVersionCode().getOrDefault()
if (oldVersion < BuildConfig.VERSION_CODE) {
preferences.lastVersionCode().set(BuildConfig.VERSION_CODE) preferences.lastVersionCode().set(BuildConfig.VERSION_CODE)
ChangelogDialogFragment().show(fragmentManager, "changelog") ChangelogDialogFragment().show(fragmentManager, "changelog")
// FIXME Ugly check to restore auto updates setting. Remove me in a few months :D
if (oldVersion < 14 && BuildConfig.INCLUDE_UPDATER && preferences.automaticUpdates()) {
UpdateCheckerJob.setupTask()
}
} }
} }
} }

View file

@ -8,7 +8,7 @@ import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.updater.GithubUpdateChecker import eu.kanade.tachiyomi.data.updater.GithubUpdateChecker
import eu.kanade.tachiyomi.data.updater.GithubUpdateResult import eu.kanade.tachiyomi.data.updater.GithubUpdateResult
import eu.kanade.tachiyomi.data.updater.UpdateCheckerService import eu.kanade.tachiyomi.data.updater.UpdateCheckerJob
import eu.kanade.tachiyomi.data.updater.UpdateDownloaderService import eu.kanade.tachiyomi.data.updater.UpdateDownloaderService
import eu.kanade.tachiyomi.util.toast import eu.kanade.tachiyomi.util.toast
import net.xpece.android.support.preference.SwitchPreference import net.xpece.android.support.preference.SwitchPreference
@ -64,9 +64,9 @@ class SettingsAboutFragment : SettingsFragment() {
automaticUpdates.setOnPreferenceChangeListener { preference, any -> automaticUpdates.setOnPreferenceChangeListener { preference, any ->
val checked = any as Boolean val checked = any as Boolean
if (checked) { if (checked) {
UpdateCheckerService.setupTask(context) UpdateCheckerJob.setupTask()
} else { } else {
UpdateCheckerService.cancelTask(context) UpdateCheckerJob.cancelTask()
} }
true true
} }

View file

@ -7,7 +7,7 @@ import android.support.v7.preference.XpPreferenceFragment
import android.view.View import android.view.View
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.library.LibraryUpdateTrigger import eu.kanade.tachiyomi.data.library.LibraryUpdateJob
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.plusAssign import eu.kanade.tachiyomi.util.plusAssign
import eu.kanade.tachiyomi.widget.preference.IntListPreference import eu.kanade.tachiyomi.widget.preference.IntListPreference
@ -59,9 +59,9 @@ class SettingsGeneralFragment : SettingsFragment(),
updateInterval.setOnPreferenceChangeListener { preference, newValue -> updateInterval.setOnPreferenceChangeListener { preference, newValue ->
val interval = (newValue as String).toInt() val interval = (newValue as String).toInt()
if (interval > 0) if (interval > 0)
LibraryUpdateTrigger.setupTask(context, interval) LibraryUpdateJob.setupTask(interval)
else else
LibraryUpdateTrigger.cancelTask(context) LibraryUpdateJob.cancelTask()
true true
} }
@ -69,7 +69,7 @@ class SettingsGeneralFragment : SettingsFragment(),
updateRestriction.setOnPreferenceChangeListener { preference, newValue -> updateRestriction.setOnPreferenceChangeListener { preference, newValue ->
// Post to event looper to allow the preference to be updated. // Post to event looper to allow the preference to be updated.
subscriptions += Observable.fromCallable { subscriptions += Observable.fromCallable {
LibraryUpdateTrigger.setupTask(context) LibraryUpdateJob.setupTask()
}.subscribeOn(AndroidSchedulers.mainThread()).subscribe() }.subscribeOn(AndroidSchedulers.mainThread()).subscribe()
true true