Commit 5508cea4 authored by Ricki Hirner's avatar Ricki Hirner

Optimizations

* lib updates
* don't rely on a single SQL statement for retaining events
* minor fixes
parent f22ddb30
Pipeline #13570355 passed with stage
in 5 minutes and 28 seconds
......@@ -35,7 +35,8 @@ android {
}
lintOptions {
disable 'ExtraTranslation', 'MissingTranslation'
disable 'IconLauncherFormat' // build tools still too dump for Android 8 icons
disable 'InvalidPackage'
disable 'OnClick'
disable 'PrivateResource'
}
}
......
......@@ -15,6 +15,7 @@
# ical4j: ignore unused dynamic libraries
-dontwarn aQute.**
-dontwarn groovy.** # Groovy-based ContentBuilder not used
-dontwarn javax.cache.** # no JCache support in Android
-dontwarn net.fortuna.ical4j.model.**
-dontwarn org.codehaus.groovy.**
-dontwarn org.apache.log4j.** # ignore warnings from log4j dependency
......
......@@ -255,7 +255,7 @@ class SyncAdapter(
private fun processEvents(events: List<Event>) {
Log.i(Constants.TAG, "Processing ${events.size} events")
//String[] uids = new String[events.size()];
val uids = LinkedList<String>()
val uids = HashSet<String>(events.size)
for (event in events) {
val uid = event.uid!!
......
......@@ -10,11 +10,13 @@ package at.bitfire.icsdroid.db
import android.accounts.Account
import android.content.ContentProviderClient
import android.content.ContentUris
import android.content.ContentValues
import android.database.DatabaseUtils
import android.os.RemoteException
import android.provider.CalendarContract
import android.provider.CalendarContract.Calendars
import android.provider.CalendarContract.Events
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.AndroidCalendarFactory
import at.bitfire.ical4android.CalendarStorageException
......@@ -130,17 +132,26 @@ class LocalCalendar private constructor(
@Throws(CalendarStorageException::class)
fun queryByUID(uid: String) =
queryEvents("${CalendarContract.Events._SYNC_ID}=?", arrayOf(uid))
queryEvents("${Events._SYNC_ID}=?", arrayOf(uid))
@Throws(CalendarStorageException::class)
fun retainByUID(uids: List<String>): Int {
val sqlUIDs = uids.map { DatabaseUtils.sqlEscapeString(it) }.joinToString(",")
fun retainByUID(uids: Set<String>): Int {
var deleted = 0
try {
return provider.delete(syncAdapterURI(CalendarContract.Events.CONTENT_URI),
"${CalendarContract.Events.CALENDAR_ID}=? AND (" +
"${CalendarContract.Events._SYNC_ID} NOT IN ($sqlUIDs) OR " +
"${CalendarContract.Events.ORIGINAL_SYNC_ID} NOT IN ($sqlUIDs)" +
")", arrayOf(id.toString()))
provider.query(syncAdapterURI(Events.CONTENT_URI, account),
arrayOf(Events._ID, Events._SYNC_ID, Events.ORIGINAL_SYNC_ID),
"${Events.CALENDAR_ID}=?", arrayOf(id.toString()), null).use { row ->
while (row.moveToNext()) {
val eventId = row.getLong(0)
val syncId = row.getString(1)
val originalSyncId = row.getString(2)
if (!uids.contains(syncId) && !uids.contains(originalSyncId)) {
provider.delete(syncAdapterURI(ContentUris.withAppendedId(Events.CONTENT_URI, eventId), account), null, null)
deleted++
}
}
}
return deleted
} catch(e: RemoteException) {
throw CalendarStorageException("Couldn't delete local events")
}
......
......@@ -53,7 +53,7 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
info = arguments.getSerializable(ARG_INFO) as ResourceInfo
info = arguments!!.getSerializable(ARG_INFO) as ResourceInfo
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, inState: Bundle?): View {
......@@ -97,7 +97,7 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
override fun onOptionsItemSelected(item: MenuItem) =
if (item.itemId == R.id.create_calendar) {
if (createCalendar())
activity.finish()
activity!!.finish()
true
} else
false
......@@ -107,12 +107,12 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
this.title = title
this.color = color
activity.invalidateOptionsMenu()
activity!!.invalidateOptionsMenu()
}
private fun createCalendar(): Boolean {
AppAccount.makeAvailable(context)
AppAccount.makeAvailable(activity!!)
val calInfo = ContentValues(9)
calInfo.put(Calendars.ACCOUNT_NAME, AppAccount.account.name)
......@@ -125,15 +125,15 @@ class AddCalendarDetailsFragment: Fragment(), TitleColorFragment.OnChangeListene
calInfo.put(Calendars.VISIBLE, 1)
calInfo.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_READ)
val client: ContentProviderClient? = context.contentResolver.acquireContentProviderClient(CalendarContract.AUTHORITY)
val client: ContentProviderClient? = activity!!.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(activity!!, calendar, info.username, info.password)
}
Toast.makeText(activity, getString(R.string.add_calendar_created), Toast.LENGTH_LONG).show()
activity.invalidateOptionsMenu()
activity!!.invalidateOptionsMenu()
true
} catch(e: Exception) {
Log.e(Constants.TAG, "Couldn't create calendar", e)
......
......@@ -36,7 +36,7 @@ class AddCalendarEnterUrlFragment: Fragment(), TextWatcher, CredentialsFragment.
var username: String? = null
var password: String? = null
activity.intent.data?.let { uri ->
activity?.intent?.data?.let { uri ->
// This causes the onTextChanged listeners to be activated - credentials and insecureAuthWarning are already required!
uri.userInfo?.let {
val info = it.split(':', limit = 2).iterator()
......@@ -89,7 +89,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
ContextCompat.checkSelfPermission(activity!!, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
else
true
......@@ -140,8 +140,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 (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(activity!!, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 0)
}
(uri.scheme.equals("http", true) || uri.scheme.equals("https", true)) && !uri.authority.isNullOrBlank() -> {
childFragmentManager.beginTransaction()
......@@ -161,7 +161,7 @@ class AddCalendarEnterUrlFragment: Fragment(), TextWatcher, CredentialsFragment.
else
View.GONE
activity.invalidateOptionsMenu()
activity?.invalidateOptionsMenu()
}
......
......@@ -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(activity!!, 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
fragmentManager!!
.beginTransaction()
.replace(R.id.fragment_container, AddCalendarDetailsFragment.newInstance(info))
.addToBackStack(null)
......
......@@ -76,7 +76,7 @@ class CredentialsFragment: Fragment(), CompoundButton.OnCheckedChangeListener, T
return v
}
override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
updateViews()
}
......
......@@ -22,18 +22,18 @@ class DonateDialogFragment: DialogFragment() {
}
override fun onCreateDialog(savedInstanceState: Bundle?) =
AlertDialog.Builder(activity)
AlertDialog.Builder(activity!!)
.setIcon(R.mipmap.ic_launcher)
.setTitle(R.string.donate_title)
.setMessage(R.string.donate_message)
.setPositiveButton(R.string.donate_now, { _, _ ->
activity.getPreferences(0).edit()
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, { _, _ ->
activity.getPreferences(0).edit()
activity!!.getPreferences(0).edit()
.putLong(PREF_NEXT_REMINDER, System.currentTimeMillis() + 14*86400000L)
.apply()
dismiss()
......
......@@ -98,7 +98,7 @@ class InfoActivity: AppCompatActivity() {
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val info = components[arguments.getInt(KEY_POSITION)]
val info = components[arguments!!.getInt(KEY_POSITION)]
val v = inflater.inflate(R.layout.app_info_component, container, false)
......@@ -117,7 +117,7 @@ class InfoActivity: AppCompatActivity() {
}
override fun onCreateLoader(id: Int, args: Bundle) =
LicenseLoader(context, args.getString(KEY_LICENSE_FILE))
LicenseLoader(activity!!, args.getString(KEY_LICENSE_FILE))
override fun onLoadFinished(loader: Loader<Spanned?>, text: Spanned?) {
text?.let {
......
......@@ -24,12 +24,12 @@ 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 = activity!!.resources.getStringArray(R.array.set_sync_interval_seconds)
.map { it.toLong() }
val v = activity.layoutInflater.inflate(R.layout.set_sync_interval, null)
val v = activity!!.layoutInflater.inflate(R.layout.set_sync_interval, null)
val currentSyncInterval = AppAccount.getSyncInterval(activity)
val currentSyncInterval = AppAccount.getSyncInterval(activity!!)
if (syncIntervalSeconds.contains(currentSyncInterval))
v.sync_interval.setSelection(syncIntervalSeconds.indexOf(currentSyncInterval))
......
......@@ -37,14 +37,14 @@ class TitleColorFragment: Fragment(), TextWatcher {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, inState: Bundle?): View {
val v = inflater.inflate(R.layout.calendar_title_color, container, false)
url = arguments.getString(ARG_URL)
url = arguments!!.getString(ARG_URL)
v.url.text = url
title = arguments.getString(ARG_TITLE)
title = arguments!!.getString(ARG_TITLE)
v.title.setText(title)
v.title.addTextChangedListener(this)
color = arguments.getInt(ARG_COLOR)
color = arguments!!.getInt(ARG_COLOR)
v.color.setColor(color)
v.color.setOnClickListener({ _ ->
AmbilWarnaDialog(activity, color, object: AmbilWarnaDialog.OnAmbilWarnaListener {
......
......@@ -11,6 +11,9 @@ buildscript {
repositories {
jcenter()
maven {
url "https://maven.google.com"
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
......
Subproject commit fb3b55af4194b58bb4c0696c6bdf1262612d357f
Subproject commit 38a5c2a06d92bf347d5c7e3d588d726db66c23c3
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