Commit 5a57507e authored by Ricki Hirner's avatar Ricki Hirner

Require READ_CALENDAR permission when adding subscription, too:

* update build tools, Kotlin, cert4android, ical4android
* minor refactoring
parent ac16c3d0
......@@ -12,7 +12,7 @@ apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 27
buildToolsVersion "27.0.3"
buildToolsVersion "28.0.1"
defaultConfig {
applicationId "at.bitfire.icsdroid"
......
......@@ -12,7 +12,6 @@ import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.content.ContextCompat
import android.support.v7.app.AppCompatActivity
import android.widget.Toast
import at.bitfire.icsdroid.R
......@@ -30,8 +29,10 @@ class AddCalendarActivity: AppCompatActivity() {
supportActionBar?.setDisplayHomeAsUpEnabled(true)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_CALENDAR), 0)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR), 0)
if (inState == null)
supportFragmentManager
......@@ -44,6 +45,7 @@ class AddCalendarActivity: AppCompatActivity() {
permissions.forEachIndexed { idx, perm ->
if (grantResults[idx] != PackageManager.PERMISSION_GRANTED)
when (perm) {
Manifest.permission.READ_CALENDAR,
Manifest.permission.WRITE_CALENDAR ->
finish()
Manifest.permission.READ_EXTERNAL_STORAGE ->
......
......@@ -101,7 +101,7 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
override fun onOptionsItemSelected(item: MenuItem) =
if (item.itemId == R.id.create_calendar) {
if (createCalendar())
activity!!.finish()
requireActivity().finish()
true
} else
false
......@@ -111,12 +111,12 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
this.title = title
this.color = color
activity!!.invalidateOptionsMenu()
requireActivity().invalidateOptionsMenu()
}
private fun createCalendar(): Boolean {
AppAccount.makeAvailable(activity!!)
AppAccount.makeAvailable(requireActivity())
val calInfo = ContentValues(9)
calInfo.put(Calendars.ACCOUNT_NAME, AppAccount.account.name)
......@@ -129,15 +129,15 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
calInfo.put(Calendars.VISIBLE, 1)
calInfo.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_READ)
val client: ContentProviderClient? = activity!!.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)
val client: ContentProviderClient? = requireActivity().contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)
return try {
client?.let {
val uri = AndroidCalendar.create(AppAccount.account, it, calInfo)
val calendar = LocalCalendar.findById(AppAccount.account, client, ContentUris.parseId(uri))
CalendarCredentials.putCredentials(activity!!, calendar, info.username, info.password)
CalendarCredentials.putCredentials(requireActivity(), calendar, info.username, info.password)
}
Toast.makeText(activity, getString(R.string.add_calendar_created), Toast.LENGTH_LONG).show()
activity!!.invalidateOptionsMenu()
requireActivity().invalidateOptionsMenu()
true
} catch(e: Exception) {
Log.e(Constants.TAG, "Couldn't create calendar", e)
......
......@@ -13,7 +13,6 @@ import android.content.pm.PackageManager
import android.os.Bundle
import android.support.v4.app.ActivityCompat
import android.support.v4.app.Fragment
import android.support.v4.content.ContextCompat
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
......@@ -89,7 +88,7 @@ class AddCalendarEnterUrlFragment: Fragment(), TextWatcher, CredentialsFragment.
val authOK = !credentials.requiresAuth || (credentials.username != null && credentials.password != null)
val permOK = if (uri?.scheme.equals("file", true))
ContextCompat.checkSelfPermission(activity!!, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
else
true
......@@ -140,8 +139,8 @@ class AddCalendarEnterUrlFragment: Fragment(), TextWatcher, CredentialsFragment.
.hide(credentials)
.commit()
// 2. permission required
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(activity!!, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 0)
if (ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(requireActivity(), arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 0)
}
(uri.scheme.equals("http", true) || uri.scheme.equals("https", true)) && !uri.authority.isNullOrBlank() -> {
childFragmentManager.beginTransaction()
......
......@@ -62,7 +62,7 @@ class AddCalendarValidationFragment: DialogFragment(), LoaderManager.LoaderCallb
// loader callbacks
override fun onCreateLoader(id: Int, args: Bundle?) =
ResourceInfoLoader(activity!!, args?.getSerializable(ARG_INFO) as ResourceInfo)
ResourceInfoLoader(requireActivity(), args?.getSerializable(ARG_INFO) as ResourceInfo)
override fun onLoadFinished(loader: Loader<ResourceInfo>, info: ResourceInfo) {
dialog.dismiss()
......@@ -79,7 +79,7 @@ class AddCalendarValidationFragment: DialogFragment(), LoaderManager.LoaderCallb
if (info.calendarName.isNullOrBlank())
info.calendarName = info.url?.file
fragmentManager!!
requireFragmentManager()
.beginTransaction()
.replace(R.id.fragment_container, AddCalendarDetailsFragment.newInstance(info))
.addToBackStack(null)
......
......@@ -24,7 +24,6 @@ import android.support.v4.app.ActivityCompat
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.LoaderManager
import android.support.v4.content.ContextCompat
import android.support.v4.content.Loader
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.app.AppCompatActivity
......@@ -74,8 +73,8 @@ class CalendarListActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
DonateDialogFragment().show(supportFragmentManager, "donate")
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED)
supportLoaderManager.initLoader(0, null, this)
else
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR), 0)
......@@ -114,9 +113,9 @@ class CalendarListActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
val syncActive = AppAccount.isSyncActive()
Log.d(Constants.TAG, "Is sync. active? ${if (syncActive) "yes" else "no"}")
// workaround: see https://code.google.com/p/android/issues/detail?id=77712
refresh.post({
refresh.post {
refresh.isRefreshing = syncActive
})
}
true
})
syncStatusHandle = ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE, this)
......@@ -149,9 +148,9 @@ class CalendarListActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
!ContentResolver.getMasterSyncAutomatically() -> {
snackBar = Snackbar.make(coordinator, R.string.calendar_list_master_sync_disabled, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.calendar_list_master_sync_enable, {
.setAction(R.string.calendar_list_master_sync_enable) {
ContentResolver.setMasterSyncAutomatically(true)
})
}
snackBar?.show()
}
......@@ -160,10 +159,10 @@ class CalendarListActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
!(getSystemService(Context.POWER_SERVICE) as PowerManager).isIgnoringBatteryOptimizations(BuildConfig.APPLICATION_ID) &&
AppAccount.getSyncInterval(this) < 86400 -> {
snackBar = Snackbar.make(coordinator, R.string.calendar_list_battery_whitelist, Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.calendar_list_battery_whitelist_settings, { _ ->
.setAction(R.string.calendar_list_battery_whitelist_settings) { _ ->
val intent = Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS)
startActivity(intent)
})
}
snackBar?.show()
}
}
......
......@@ -26,18 +26,18 @@ class DonateDialogFragment: DialogFragment() {
.setIcon(R.mipmap.ic_launcher)
.setTitle(R.string.donate_title)
.setMessage(R.string.donate_message)
.setPositiveButton(R.string.donate_now, { _, _ ->
.setPositiveButton(R.string.donate_now) { _, _ ->
activity!!.getPreferences(0).edit()
.putLong(PREF_NEXT_REMINDER, System.currentTimeMillis() + 60*86400000L)
.apply()
startActivity(Intent(Intent.ACTION_VIEW, Constants.donationUri))
})
.setNegativeButton(R.string.donate_later, { _, _ ->
}
.setNegativeButton(R.string.donate_later) { _, _ ->
activity!!.getPreferences(0).edit()
.putLong(PREF_NEXT_REMINDER, System.currentTimeMillis() + 14*86400000L)
.apply()
dismiss()
})
}
.setCancelable(false)
.create()!!
......
......@@ -19,10 +19,7 @@ import android.database.ContentObserver
import android.net.Uri
import android.os.Bundle
import android.provider.CalendarContract
import android.support.v4.app.DialogFragment
import android.support.v4.app.FragmentTransaction
import android.support.v4.app.LoaderManager
import android.support.v4.app.ShareCompat
import android.support.v4.app.*
import android.support.v4.content.ContextCompat
import android.support.v4.content.Loader
import android.support.v7.app.AlertDialog
......@@ -61,11 +58,11 @@ class EditCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
super.onCreate(inState)
setContentView(R.layout.edit_calendar)
sync_calendar.setOnClickListener({ _ ->
sync_calendar.setOnClickListener { _ ->
dirty = true
})
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED)
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALENDAR) == PackageManager.PERMISSION_GRANTED)
// load calendar from provider
supportLoaderManager.initLoader(0, null, this)
else
......@@ -298,14 +295,14 @@ class EditCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
override fun onCreateDialog(savedInstanceState: Bundle?) =
AlertDialog.Builder(requireActivity())
.setTitle(R.string.edit_calendar_unsaved_changes)
.setPositiveButton(R.string.edit_calendar_save, { dialog, _ ->
.setPositiveButton(R.string.edit_calendar_save) { dialog, _ ->
dialog.dismiss()
(activity as? EditCalendarActivity)?.onSave(null)
})
.setNegativeButton(R.string.edit_calendar_dismiss, { dialog, _ ->
}
.setNegativeButton(R.string.edit_calendar_dismiss) { dialog, _ ->
dialog.dismiss()
(activity as? EditCalendarActivity)?.onCancel(null)
})
}
.create()!!
}
......@@ -318,13 +315,13 @@ class EditCalendarActivity: AppCompatActivity(), LoaderManager.LoaderCallbacks<L
override fun onCreateDialog(savedInstanceState: Bundle?) =
AlertDialog.Builder(requireActivity())
.setMessage(R.string.edit_calendar_really_delete)
.setPositiveButton(R.string.edit_calendar_delete, { dialog, _ ->
.setPositiveButton(R.string.edit_calendar_delete) { dialog, _ ->
dialog.dismiss()
(activity as EditCalendarActivity?)?.onDelete()
})
.setNegativeButton(R.string.edit_calendar_cancel, { dialog, _ ->
}
.setNegativeButton(R.string.edit_calendar_cancel) { dialog, _ ->
dialog.dismiss()
})
}
.create()!!
}
......
......@@ -119,7 +119,7 @@ class InfoActivity: AppCompatActivity() {
}
override fun onCreateLoader(id: Int, args: Bundle?) =
LicenseLoader(activity!!, args!!.getString(KEY_LICENSE_FILE))
LicenseLoader(requireActivity(), args!!.getString(KEY_LICENSE_FILE))
override fun onLoadFinished(loader: Loader<Spanned?>, text: Spanned?) {
text?.let {
......
......@@ -24,19 +24,19 @@ class SyncIntervalDialogFragment: DialogFragment() {
val builder = AlertDialog.Builder(activity)
// read sync intervals from resources
val syncIntervalSeconds = activity!!.resources.getStringArray(R.array.set_sync_interval_seconds)
val syncIntervalSeconds = requireActivity().resources.getStringArray(R.array.set_sync_interval_seconds)
.map { it.toLong() }
val v = activity!!.layoutInflater.inflate(R.layout.set_sync_interval, null)
val v = requireActivity().layoutInflater.inflate(R.layout.set_sync_interval, null)
val currentSyncInterval = AppAccount.getSyncInterval(activity!!)
val currentSyncInterval = AppAccount.getSyncInterval(requireActivity())
if (syncIntervalSeconds.contains(currentSyncInterval))
v.sync_interval.setSelection(syncIntervalSeconds.indexOf(currentSyncInterval))
builder .setView(v)
.setPositiveButton(R.string.set_sync_interval_save, { _, _ ->
.setPositiveButton(R.string.set_sync_interval_save) { _, _ ->
AppAccount.setSyncInterval(syncIntervalSeconds[v.sync_interval.selectedItemPosition])
})
}
return builder.create()
}
......
......@@ -46,7 +46,7 @@ class TitleColorFragment: Fragment(), TextWatcher {
color = arguments!!.getInt(ARG_COLOR)
v.color.setColor(color)
v.color.setOnClickListener({ _ ->
v.color.setOnClickListener { _ ->
AmbilWarnaDialog(activity, color, object: AmbilWarnaDialog.OnAmbilWarnaListener {
override fun onCancel(ambilWarnaDialog: AmbilWarnaDialog) {
}
......@@ -57,7 +57,7 @@ class TitleColorFragment: Fragment(), TextWatcher {
notifyListener()
}
}).show()
})
}
return v
}
......
......@@ -7,7 +7,7 @@
*/
buildscript {
ext.kotlin_version = '1.2.50'
ext.kotlin_version = '1.2.51'
repositories {
jcenter()
......
Subproject commit c90823f6f6cf481f183b198a95e1e0ae85d81403
Subproject commit c8f189d1d62f2bc6e397e3c57e2d329af330823b
Subproject commit 626c36d90ffdcfa75d3d5989294fd275ddab45f4
Subproject commit 2ee64a8d09eb844f9a25983deb602058930a55bc
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment