StartupDialogFragment.kt 9.51 KB
Newer Older
Ricki Hirner's avatar
Ricki Hirner committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * Copyright © Ricki Hirner (bitfire web engineering).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v3.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/gpl.html
 */

package at.bitfire.davdroid.ui

import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.Dialog
14 15
import android.app.DialogFragment
import android.app.LoaderManager
Ricki Hirner's avatar
Ricki Hirner committed
16 17 18
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
19
import android.content.Loader
Ricki Hirner's avatar
Ricki Hirner committed
20 21 22 23 24 25 26 27 28
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.PowerManager
import android.support.v7.app.AlertDialog
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
29
import at.bitfire.davdroid.log.Logger
Ricki Hirner's avatar
Ricki Hirner committed
30
import at.bitfire.davdroid.resource.LocalTaskList
31
import at.bitfire.davdroid.settings.ISettings
Ricki Hirner's avatar
Ricki Hirner committed
32 33 34
import java.util.*
import java.util.logging.Level

35
class StartupDialogFragment: DialogFragment(), LoaderManager.LoaderCallbacks<ISettings?> {
Ricki Hirner's avatar
Ricki Hirner committed
36 37 38 39

    enum class Mode {
        BATTERY_OPTIMIZATIONS,
        GOOGLE_PLAY_ACCOUNTS_REMOVED,
40 41
        OPENTASKS_NOT_INSTALLED,
        OSE_DONATE
Ricki Hirner's avatar
Ricki Hirner committed
42 43 44 45
    }

    companion object {

Ricki Hirner's avatar
Ricki Hirner committed
46 47
        private val SETTING_NEXT_DONATION_POPUP = "time_nextDonationPopup"

Ricki Hirner's avatar
Ricki Hirner committed
48 49 50 51 52 53
        @JvmField val HINT_BATTERY_OPTIMIZATIONS = "hint_BatteryOptimizations"
        @JvmField val HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED = "hint_GooglePlayAccountsRemoved"
        @JvmField val HINT_OPENTASKS_NOT_INSTALLED = "hint_OpenTasksNotInstalled"

        val ARGS_MODE = "mode"

54
        fun getStartupDialogs(context: Context, settings: ISettings): List<StartupDialogFragment> {
Ricki Hirner's avatar
Ricki Hirner committed
55 56
            val dialogs = LinkedList<StartupDialogFragment>()

57
            /* if (System.currentTimeMillis() > settings.getLong(SETTING_NEXT_DONATION_POPUP, 0))
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
                dialogs += StartupDialogFragment.instantiate(Mode.OSE_DONATE) */

            // store-specific information
            /*if (BuildConfig.FLAVOR == App.FLAVOR_GOOGLE_PLAY) {
                // Play store
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP &&         // only on Android <5
                    settings.getBoolean(HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED, true))   // and only when "Don't show again" hasn't been clicked yet
                    dialogs += StartupDialogFragment.instantiate(Mode.GOOGLE_PLAY_ACCOUNTS_REMOVED)
            }*/

            // battery optimization white-listing
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && settings.getBoolean(HINT_BATTERY_OPTIMIZATIONS, true)) {
                val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
                if (!powerManager.isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID))
                    dialogs.add(StartupDialogFragment.instantiate(Mode.BATTERY_OPTIMIZATIONS))
Ricki Hirner's avatar
Ricki Hirner committed
73 74
            }

75 76 77 78
            // OpenTasks information
            if (!LocalTaskList.tasksProviderAvailable(context) && settings.getBoolean(HINT_OPENTASKS_NOT_INSTALLED, true))
                dialogs.add(StartupDialogFragment.instantiate(Mode.OPENTASKS_NOT_INSTALLED))

Ricki Hirner's avatar
Ricki Hirner committed
79 80 81 82 83 84 85 86 87 88 89 90 91
            return dialogs.reversed()
        }

        fun instantiate(mode: Mode): StartupDialogFragment {
            val frag = StartupDialogFragment()
            val args = Bundle(1)
            args.putString(ARGS_MODE, mode.name)
            frag.arguments = args
            return frag
        }

    }

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111

    var settings: ISettings? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        loaderManager.initLoader(0, null, this)
    }

    override fun onCreateLoader(code: Int, args: Bundle?): Loader<ISettings?> =
            SettingsLoader(activity)

    override fun onLoadFinished(loader: Loader<ISettings?>?, result: ISettings?) {
        settings = result
    }

    override fun onLoaderReset(loader: Loader<ISettings?>?) {
        settings = null
    }


Ricki Hirner's avatar
Ricki Hirner committed
112 113 114 115 116 117 118 119 120 121 122
    @SuppressLint("BatteryLife")
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        isCancelable = false

        val mode = Mode.valueOf(arguments.getString(ARGS_MODE))
        return when (mode) {
            Mode.BATTERY_OPTIMIZATIONS ->
                AlertDialog.Builder(activity)
                        .setIcon(R.drawable.ic_info_dark)
                        .setTitle(R.string.startup_battery_optimization)
                        .setMessage(R.string.startup_battery_optimization_message)
123
                        .setPositiveButton(android.R.string.ok, { _, _ -> })
124 125
                        .setNeutralButton(R.string.startup_battery_optimization_disable, @TargetApi(Build.VERSION_CODES.M) { _, _ ->
                            val intent = Intent(android.provider.Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,
Ricki Hirner's avatar
Ricki Hirner committed
126
                                        Uri.parse("package:" + BuildConfig.APPLICATION_ID))
127 128
                                if (intent.resolveActivity(activity.packageManager) != null)
                                    activity.startActivity(intent)
Ricki Hirner's avatar
Ricki Hirner committed
129 130
                            })
                        .setNegativeButton(R.string.startup_dont_show_again, { _: DialogInterface, _: Int ->
131
                            settings?.putBoolean(HINT_BATTERY_OPTIMIZATIONS, false)
Ricki Hirner's avatar
Ricki Hirner committed
132 133 134 135 136 137
                        })
                        .create()

            Mode.GOOGLE_PLAY_ACCOUNTS_REMOVED -> {
                var icon: Drawable? = null
                try {
138
                    icon = activity.packageManager.getApplicationIcon("com.android.vending").current
Ricki Hirner's avatar
Ricki Hirner committed
139 140 141 142 143 144 145
                } catch(e: PackageManager.NameNotFoundException) {
                    Logger.log.log(Level.WARNING, "Can't load Play Store icon", e)
                }
                return AlertDialog.Builder(activity)
                        .setIcon(icon)
                        .setTitle(R.string.startup_google_play_accounts_removed)
                        .setMessage(R.string.startup_google_play_accounts_removed_message)
146 147
                        .setPositiveButton(android.R.string.ok, { _, _ -> })
                        .setNeutralButton(R.string.startup_google_play_accounts_removed_more_info, { _, _ ->
Ricki Hirner's avatar
Ricki Hirner committed
148
                            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(getString(R.string.navigation_drawer_faq_url)))
149
                            activity.startActivity(intent)
Ricki Hirner's avatar
Ricki Hirner committed
150
                        })
151
                        .setNegativeButton(R.string.startup_dont_show_again, { _, _ ->
152
                            settings?.putBoolean(HINT_GOOGLE_PLAY_ACCOUNTS_REMOVED, false)
Ricki Hirner's avatar
Ricki Hirner committed
153 154 155 156 157 158 159 160 161
                        })
                        .create()
            }

            Mode.OPENTASKS_NOT_INSTALLED -> {
                val builder = StringBuilder(getString(R.string.startup_opentasks_not_installed_message))
                if (Build.VERSION.SDK_INT < 23)
                    builder.append("\n\n").append(getString(R.string.startup_opentasks_reinstall_davdroid))
                return AlertDialog.Builder(activity)
162
                        .setIcon(R.drawable.ic_playlist_add_check_dark)
Ricki Hirner's avatar
Ricki Hirner committed
163 164
                        .setTitle(R.string.startup_opentasks_not_installed)
                        .setMessage(builder.toString())
165 166
                        .setPositiveButton(android.R.string.ok, { _, _ -> })
                        .setNeutralButton(R.string.startup_opentasks_not_installed_install, { _, _ ->
Ricki Hirner's avatar
Ricki Hirner committed
167
                            val intent = Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=org.dmfs.tasks"))
168 169
                            if (intent.resolveActivity(activity.packageManager) != null)
                                activity.startActivity(intent)
Ricki Hirner's avatar
Ricki Hirner committed
170 171 172 173
                            else
                                Logger.log.warning("No market app available, can't install OpenTasks")
                        })
                        .setNegativeButton(R.string.startup_dont_show_again, { _: DialogInterface, _: Int ->
174
                            settings?.putBoolean(HINT_OPENTASKS_NOT_INSTALLED, false)
Ricki Hirner's avatar
Ricki Hirner committed
175 176 177
                        })
                        .create()
            }
178

Ricki Hirner's avatar
Ricki Hirner committed
179 180 181 182 183 184 185 186 187 188 189
            Mode.OSE_DONATE ->
                    return AlertDialog.Builder(activity)
                            .setIcon(R.mipmap.ic_launcher)
                            .setTitle(R.string.startup_donate)
                            .setMessage(R.string.startup_donate_message)
                            .setPositiveButton(R.string.startup_donate_now, { _, _ ->
                                val uri = Uri.parse(getString(R.string.homepage_url))
                                        .buildUpon()
                                        .appendEncodedPath("donate/")
                                        .build()
                                startActivity(Intent(Intent.ACTION_VIEW, uri))
190
                                settings?.putLong(SETTING_NEXT_DONATION_POPUP, System.currentTimeMillis() + 30 * 86400000L) // 30 days
Ricki Hirner's avatar
Ricki Hirner committed
191 192
                            })
                            .setNegativeButton(R.string.startup_donate_later, { _, _ ->
193
                                settings?.putLong(SETTING_NEXT_DONATION_POPUP, System.currentTimeMillis() + 14 * 86400000L) // 14 days
Ricki Hirner's avatar
Ricki Hirner committed
194 195
                            })
                            .create()
196

Ricki Hirner's avatar
Ricki Hirner committed
197 198 199
        }
    }

200 201 202 203 204 205 206 207 208 209 210 211

    class SettingsLoader(
            context: Context
    ): at.bitfire.davdroid.ui.SettingsLoader<ISettings?>(context) {

        override fun loadInBackground(): ISettings? {
            settings?.let { return it }
            return null
        }

    }

Ricki Hirner's avatar
Ricki Hirner committed
212
}