Skip to content

Commit

Permalink
Remove SetupActivity, perform setup in MainActivity
Browse files Browse the repository at this point in the history
Squashed commit of the following:

commit ff6ece7
Author: Moez Bhatti <moez.bhatti@gmail.com>
Date:   Wed May 9 01:50:33 2018 -0400

    Remove default SMS UI from settings

commit 1ce79ea
Author: Moez Bhatti <moez.bhatti@gmail.com>
Date:   Wed May 9 01:45:33 2018 -0400

    Remove SetupActivity, perform setup in MainActivity

commit ccad342
Author: Moez Bhatti <moez.bhatti@gmail.com>
Date:   Mon May 7 18:02:26 2018 -0400

    Don't query ContentProvider without appropriate permission

commit 527be2e
Author: Moez Bhatti <moez.bhatti@gmail.com>
Date:   Mon May 7 17:12:00 2018 -0400

    Show non-blocking UI in MainActivity while syncing
  • Loading branch information
moezbhatti committed May 9, 2018
1 parent 4e4a72c commit 11167af
Show file tree
Hide file tree
Showing 63 changed files with 408 additions and 618 deletions.
13 changes: 11 additions & 2 deletions data/src/main/java/manager/PermissionManagerImpl.kt
Expand Up @@ -21,14 +21,23 @@ package manager
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.provider.Telephony
import android.support.v4.content.ContextCompat
import javax.inject.Inject

class PermissionManagerImpl @Inject constructor(private val context: Context) : PermissionManager {

override fun isDefaultSms(): Boolean {
return Telephony.Sms.getDefaultSmsPackage(context) == context.packageName
}

override fun hasSmsAndContacts(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
return hasSms() && hasContacts()
}

override fun hasSms(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) == PackageManager.PERMISSION_GRANTED

override fun hasContacts(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED


}
11 changes: 9 additions & 2 deletions data/src/main/java/mapper/CursorToContactImpl.kt
Expand Up @@ -21,11 +21,15 @@ package mapper
import android.content.Context
import android.database.Cursor
import android.provider.ContactsContract.CommonDataKinds.Phone.*
import manager.PermissionManager
import model.Contact
import model.PhoneNumber
import javax.inject.Inject

class CursorToContactImpl @Inject constructor(private val context: Context) : CursorToContact {
class CursorToContactImpl @Inject constructor(
private val context: Context,
private val permissionManager: PermissionManager
) : CursorToContact {

companion object {
val URI = CONTENT_URI
Expand All @@ -48,7 +52,10 @@ class CursorToContactImpl @Inject constructor(private val context: Context) : Cu
}

override fun getContactsCursor(): Cursor? {
return context.contentResolver.query(URI, PROJECTION, null, null, null)
return when (permissionManager.hasContacts()) {
true -> context.contentResolver.query(URI, PROJECTION, null, null, null)
false -> null
}
}

}
16 changes: 12 additions & 4 deletions data/src/main/java/mapper/CursorToConversationImpl.kt
Expand Up @@ -22,11 +22,15 @@ import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.Telephony.Threads
import manager.PermissionManager
import model.Conversation
import model.Recipient
import javax.inject.Inject

class CursorToConversationImpl @Inject constructor(private val context: Context) : CursorToConversation {
class CursorToConversationImpl @Inject constructor(
private val context: Context,
private val permissionManager: PermissionManager
) : CursorToConversation {

companion object {
val URI: Uri = Uri.parse("content://mms-sms/conversations?simple=true")
Expand Down Expand Up @@ -62,9 +66,13 @@ class CursorToConversationImpl @Inject constructor(private val context: Context)
}

override fun getConversationsCursor(lastSync: Long): Cursor? {
return context.contentResolver.query(URI, PROJECTION,
"date > $lastSync", null,
"date desc")
return when (permissionManager.hasSms()) {
true -> context.contentResolver.query(URI, PROJECTION,
"date > $lastSync", null,
"date desc")

false -> null
}
}

override fun getConversationCursor(threadId: Long): Cursor? {
Expand Down
9 changes: 7 additions & 2 deletions data/src/main/java/mapper/CursorToMessageImpl.kt
Expand Up @@ -24,14 +24,16 @@ import android.net.Uri
import android.provider.Telephony.*
import com.google.android.mms.pdu_alt.PduHeaders
import manager.KeyManager
import manager.PermissionManager
import model.Message
import util.extensions.map
import javax.inject.Inject

class CursorToMessageImpl @Inject constructor(
private val context: Context,
private val cursorToPart: CursorToPart,
private val keys: KeyManager,
private val cursorToPart: CursorToPart
private val permissionManager: PermissionManager
) : CursorToMessage {

companion object {
Expand Down Expand Up @@ -120,7 +122,10 @@ class CursorToMessageImpl @Inject constructor(
}

override fun getMessagesCursor(): Cursor? {
return context.contentResolver.query(URI, PROJECTION, null, null, "normalized_date desc")
return when (permissionManager.hasSms()) {
true -> context.contentResolver.query(URI, PROJECTION, null, null, "normalized_date desc")
false -> null
}
}

override fun getMessageCursor(id: Long): Cursor? {
Expand Down
11 changes: 9 additions & 2 deletions data/src/main/java/mapper/CursorToRecipientImpl.kt
Expand Up @@ -21,10 +21,14 @@ package mapper
import android.content.Context
import android.database.Cursor
import android.net.Uri
import manager.PermissionManager
import model.Recipient
import javax.inject.Inject

class CursorToRecipientImpl @Inject constructor(private val context: Context) : CursorToRecipient {
class CursorToRecipientImpl @Inject constructor(
private val context: Context,
private val permissionManager: PermissionManager
) : CursorToRecipient {

companion object {
val URI = Uri.parse("content://mms-sms/canonical-addresses")
Expand All @@ -40,7 +44,10 @@ class CursorToRecipientImpl @Inject constructor(private val context: Context) :
}

override fun getRecipientCursor(): Cursor? {
return context.contentResolver.query(URI, null, null, null, null)
return when (permissionManager.hasSms()) {
true -> context.contentResolver.query(URI, null, null, null, null)
false -> null
}
}

override fun getRecipientCursor(id: Long): Cursor? {
Expand Down
82 changes: 33 additions & 49 deletions data/src/main/java/repository/SyncRepositoryImpl.kt
Expand Up @@ -24,6 +24,8 @@ import android.net.Uri
import android.provider.Telephony
import android.telephony.PhoneNumberUtils
import com.f2prateek.rx.preferences2.RxSharedPreferences
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
import io.realm.Realm
import mapper.CursorToContact
import mapper.CursorToConversation
Expand All @@ -34,10 +36,8 @@ import model.Conversation
import model.Message
import model.MmsPart
import model.Recipient
import model.SyncLog
import util.extensions.insertOrUpdate
import util.extensions.map
import util.extensions.mapWhile
import util.tryOrNull
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -53,58 +53,41 @@ class SyncRepositoryImpl @Inject constructor(
private val rxPrefs: RxSharedPreferences
) : SyncRepository {

sealed class Status {
class Idle : Status()
class Running : Status()
}

/**
* Holds data that should be persisted across full syncs
*/
private data class PersistedData(val id: Long, val archived: Boolean, val blocked: Boolean)

private var status: Status = Status.Idle()
override val syncProgress: Subject<SyncRepository.SyncProgress> = BehaviorSubject.createDefault(SyncRepository.SyncProgress.Idle())

override fun syncMessages(fullSync: Boolean) {
override fun syncMessages() {

// If the sync is already running, don't try to do another one
if (status is Status.Running) return
status = Status.Running()
if (syncProgress.blockingFirst() is SyncRepository.SyncProgress.Running) return
syncProgress.onNext(SyncRepository.SyncProgress.Running(0f))

val realm = Realm.getDefaultInstance()
realm.beginTransaction()

var persistedData: List<PersistedData> = listOf()

if (fullSync) {
persistedData += realm.where(Conversation::class.java)
.beginGroup()
.equalTo("archived", true)
.or()
.equalTo("blocked", true)
.endGroup()
.findAll()
.map { conversation ->
PersistedData(conversation.id, conversation.archived, conversation.blocked)
}

realm.delete(Conversation::class.java)
realm.delete(Message::class.java)
realm.delete(MmsPart::class.java)
realm.delete(Recipient::class.java)
realm.delete(SyncLog::class.java)
}
var persistedData = realm.where(Conversation::class.java)
.beginGroup()
.equalTo("archived", true)
.or()
.equalTo("blocked", true)
.endGroup()
.findAll()
.map { PersistedData(it.id, it.archived, it.blocked) }

val lastSync = realm.where(SyncLog::class.java)?.max("date")?.toLong() ?: 0
realm.insert(SyncLog())
realm.delete(Conversation::class.java)
realm.delete(Message::class.java)
realm.delete(MmsPart::class.java)
realm.delete(Recipient::class.java)


// Sync messages
cursorToMessage.getMessagesCursor()?.use { messageCursor ->
val messageColumns = CursorToMessage.MessageColumns(messageCursor)
val messages = messageCursor.mapWhile(
{ cursor -> cursorToMessage.map(Pair(cursor, messageColumns)) },
{ message -> message.date > lastSync })
val messages = messageCursor.map { cursor -> cursorToMessage.map(Pair(cursor, messageColumns)) }
realm.insertOrUpdate(messages)
}

Expand Down Expand Up @@ -144,7 +127,7 @@ class SyncRepositoryImpl @Inject constructor(

syncContacts()

status = Status.Idle()
syncProgress.onNext(SyncRepository.SyncProgress.Idle())
}

override fun syncMessage(uri: Uri): Message? {
Expand Down Expand Up @@ -204,26 +187,27 @@ class SyncRepositoryImpl @Inject constructor(
}
} ?: listOf()

val realm = Realm.getDefaultInstance()
val recipients = realm.where(Recipient::class.java).findAll()
Realm.getDefaultInstance()?.use { realm ->
val recipients = realm.where(Recipient::class.java).findAll()

realm.executeTransaction {
realm.delete(Contact::class.java)
realm.executeTransaction {
realm.delete(Contact::class.java)

contacts = realm.copyToRealm(contacts)
contacts = realm.copyToRealm(contacts)

// Update all the recipients with the new contacts
val updatedRecipients = recipients.map { recipient ->
recipient.apply {
contact = contacts.firstOrNull {
it.numbers.any { PhoneNumberUtils.compare(recipient.address, it.address) }
// Update all the recipients with the new contacts
val updatedRecipients = recipients.map { recipient ->
recipient.apply {
contact = contacts.firstOrNull {
it.numbers.any { PhoneNumberUtils.compare(recipient.address, it.address) }
}
}
}

realm.insertOrUpdate(updatedRecipients)
}

realm.insertOrUpdate(updatedRecipients)
}
realm.close()
}

}
1 change: 0 additions & 1 deletion data/src/main/java/util/Preferences.kt
Expand Up @@ -48,7 +48,6 @@ class Preferences @Inject constructor(private val rxPrefs: RxSharedPreferences)
const val SEND_DELAY_LONG = 3
}

val defaultSms = rxPrefs.getBoolean("defaultSms", false)
val night = rxPrefs.getBoolean("night", false)
val nightMode = rxPrefs.getInteger("nightModeSummary", NIGHT_MODE_OFF)
val nightStart = rxPrefs.getString("nightStart", "6:00 PM")
Expand Down
42 changes: 0 additions & 42 deletions domain/src/main/java/interactor/PartialSync.kt

This file was deleted.

Expand Up @@ -25,15 +25,15 @@ import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject

class FullSync @Inject constructor(
class SyncMessages @Inject constructor(
private val syncManager: SyncRepository,
private val keys: KeyManager
) : Interactor<Unit>() {

override fun buildObservable(params: Unit): Flowable<Long> {
return Flowable.just(System.currentTimeMillis())
.doOnNext { keys.reset() }
.doOnNext { syncManager.syncMessages(true) }
.doOnNext { syncManager.syncMessages() }
.map { startTime -> System.currentTimeMillis() - startTime }
.map { elapsed -> TimeUnit.MILLISECONDS.toSeconds(elapsed) }
.doOnNext { seconds -> Timber.v("Completed sync in $seconds seconds") }
Expand Down
6 changes: 6 additions & 0 deletions domain/src/main/java/manager/PermissionManager.kt
Expand Up @@ -20,6 +20,12 @@ package manager

interface PermissionManager {

fun isDefaultSms(): Boolean

fun hasSmsAndContacts(): Boolean

fun hasSms(): Boolean

fun hasContacts(): Boolean

}
10 changes: 9 additions & 1 deletion domain/src/main/java/repository/SyncRepository.kt
Expand Up @@ -19,11 +19,19 @@
package repository

import android.net.Uri
import io.reactivex.Observable
import model.Message

interface SyncRepository {

fun syncMessages(fullSync: Boolean = false)
sealed class SyncProgress {
class Idle : SyncProgress()
class Running(progress: Float) : SyncProgress()
}

val syncProgress: Observable<SyncProgress>

fun syncMessages()

fun syncMessage(uri: Uri): Message?

Expand Down

0 comments on commit 11167af

Please sign in to comment.