Format data module

This commit is contained in:
moezbhatti
2019-04-10 22:04:44 -04:00
parent 69d2ae0544
commit b64672c472
19 changed files with 154 additions and 81 deletions
@@ -74,7 +74,8 @@ class ExternalBlockingManagerImpl @Inject constructor(
if (prefs.sia.get()) {
intent = tryOrNull(false) {
context.packageManager.getApplicationInfo("org.mistergroup.shouldianswerpersonal", 0).enabled
Intent("org.mistergroup.shouldianswerpersonal.PublicService").setPackage("org.mistergroup.shouldianswerpersonal")
Intent("org.mistergroup.shouldianswerpersonal.PublicService")
.setPackage("org.mistergroup.shouldianswerpersonal")
} ?: tryOrNull(false) {
context.packageManager.getApplicationInfo("org.mistergroup.muzutozvednout", 0).enabled
Intent("org.mistergroup.muzutozvednout.PublicService").setPackage("org.mistergroup.muzutozvednout")
@@ -31,16 +31,29 @@ class PermissionManagerImpl @Inject constructor(private val context: Context) :
return Telephony.Sms.getDefaultSmsPackage(context) == context.packageName
}
override fun hasReadSms(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) == PERMISSION_GRANTED
override fun hasReadSms(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) == PERMISSION_GRANTED
}
override fun hasSendSms(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) == PERMISSION_GRANTED
override fun hasSendSms(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.SEND_SMS) == PERMISSION_GRANTED
}
override fun hasContacts(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PERMISSION_GRANTED
override fun hasContacts(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS) == PERMISSION_GRANTED
}
override fun hasPhone(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PERMISSION_GRANTED
override fun hasPhone(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) == PERMISSION_GRANTED
}
override fun hasCalling(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) == PERMISSION_GRANTED
override fun hasCalling(): Boolean {
return ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) == PERMISSION_GRANTED
}
override fun hasStorage(): Boolean = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED
override fun hasStorage(): Boolean {
return ContextCompat.checkSelfPermission(context,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_GRANTED
}
}
@@ -40,7 +40,8 @@ class CursorToConversationImpl @Inject constructor(
Threads.RECIPIENT_IDS,
Threads.MESSAGE_COUNT,
Threads.READ,
Threads.SNIPPET)
Threads.SNIPPET
)
const val ID = 0
const val DATE = 1
@@ -67,10 +68,7 @@ class CursorToConversationImpl @Inject constructor(
override fun getConversationsCursor(lastSync: Long): Cursor? {
return when (permissionManager.hasReadSms()) {
true -> context.contentResolver.query(URI, PROJECTION,
"date > $lastSync", null,
"date desc")
true -> context.contentResolver.query(URI, PROJECTION, "date > $lastSync", null, "date desc")
false -> null
}
}
@@ -67,7 +67,8 @@ class CursorToMessageImpl @Inject constructor(
Mms.DELIVERY_REPORT,
Mms.READ_REPORT,
MmsSms.PendingMessages.ERROR_TYPE,
Mms.STATUS)
Mms.STATUS
)
override fun map(from: Pair<Cursor, CursorToMessage.MessageColumns>): Message {
val cursor = from.first
@@ -40,8 +40,8 @@ class RatingManagerImpl @Inject constructor(
override val shouldShowRating = Observables.combineLatest(
sessions.asObservable(),
rated.asObservable(),
dismissed.asObservable()) { sessions, rated, dismissed ->
dismissed.asObservable()
) { sessions, rated, dismissed ->
sessions > RATING_THRESHOLD && !rated && !dismissed
}
@@ -22,7 +22,6 @@ import io.realm.DynamicRealm
import io.realm.FieldAttribute
import io.realm.RealmMigration
class QkRealmMigration : RealmMigration {
companion object {
@@ -68,9 +68,11 @@ class MmsSentReceiver : BroadcastReceiver() {
// Need to figure out why the message isn't appearing in the PendingMessages Uri,
// so that we can properly assign the error type
val errorTypeValues = ContentValues(1)
errorTypeValues.put(Telephony.MmsSms.PendingMessages.ERROR_TYPE, Telephony.MmsSms.ERR_TYPE_GENERIC_PERMANENT)
errorTypeValues.put(Telephony.MmsSms.PendingMessages.ERROR_TYPE,
Telephony.MmsSms.ERR_TYPE_GENERIC_PERMANENT)
SqliteWrapper.update(context, context.contentResolver, Telephony.MmsSms.PendingMessages.CONTENT_URI,
errorTypeValues, "${Telephony.MmsSms.PendingMessages.MSG_ID} = ?", arrayOf(messageId.toString()))
errorTypeValues, "${Telephony.MmsSms.PendingMessages.MSG_ID} = ?",
arrayOf(messageId.toString()))
} catch (e: MmsException) {
e.printStackTrace()
@@ -42,7 +42,6 @@ import javax.inject.Inject
import javax.inject.Singleton
import kotlin.concurrent.schedule
@Singleton
class BackupRepositoryImpl @Inject constructor(
private val context: Context,
@@ -78,11 +77,14 @@ class BackupRepositoryImpl @Inject constructor(
val protocol: Int,
val serviceCenter: String?,
val locked: Boolean,
val subId: Int)
val subId: Int
)
// Subjects to emit our progress events to
private val backupProgress: Subject<BackupRepository.Progress> = BehaviorSubject.createDefault(BackupRepository.Progress.Idle())
private val restoreProgress: Subject<BackupRepository.Progress> = BehaviorSubject.createDefault(BackupRepository.Progress.Idle())
private val backupProgress: Subject<BackupRepository.Progress> =
BehaviorSubject.createDefault(BackupRepository.Progress.Idle())
private val restoreProgress: Subject<BackupRepository.Progress> =
BehaviorSubject.createDefault(BackupRepository.Progress.Idle())
@Volatile private var stopFlag: Boolean = false
@@ -116,7 +118,8 @@ class BackupRepositoryImpl @Inject constructor(
try {
// Create the directory and file
val dir = File(BACKUP_DIRECTORY).apply { mkdirs() }
val file = File(dir, "backup-${SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(System.currentTimeMillis())}.json")
val timestamp = SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()).format(System.currentTimeMillis())
val file = File(dir, "backup-$timestamp.json")
// Write the log to the file
FileOutputStream(file, true).use { fileOutputStream -> fileOutputStream.write(json) }
@@ -140,7 +143,8 @@ class BackupRepositoryImpl @Inject constructor(
protocol = 0,
serviceCenter = null,
locked = message.locked,
subId = message.subId)
subId = message.subId
)
override fun getBackupProgress(): Observable<BackupRepository.Progress> = backupProgress
@@ -190,18 +194,19 @@ class BackupRepositoryImpl @Inject constructor(
try {
context.contentResolver.insert(Telephony.Sms.CONTENT_URI, contentValuesOf(
Telephony.Sms.TYPE to message.type,
Telephony.Sms.ADDRESS to message.address,
Telephony.Sms.DATE to message.date,
Telephony.Sms.DATE_SENT to message.dateSent,
Telephony.Sms.READ to message.read,
Telephony.Sms.SEEN to 1,
Telephony.Sms.STATUS to message.status,
Telephony.Sms.BODY to message.body,
Telephony.Sms.PROTOCOL to message.protocol,
Telephony.Sms.SERVICE_CENTER to message.serviceCenter,
Telephony.Sms.LOCKED to message.locked,
Telephony.Sms.SUBSCRIPTION_ID to message.subId))
Telephony.Sms.TYPE to message.type,
Telephony.Sms.ADDRESS to message.address,
Telephony.Sms.DATE to message.date,
Telephony.Sms.DATE_SENT to message.dateSent,
Telephony.Sms.READ to message.read,
Telephony.Sms.SEEN to 1,
Telephony.Sms.STATUS to message.status,
Telephony.Sms.BODY to message.body,
Telephony.Sms.PROTOCOL to message.protocol,
Telephony.Sms.SERVICE_CENTER to message.serviceCenter,
Telephony.Sms.LOCKED to message.locked,
Telephony.Sms.SUBSCRIPTION_ID to message.subId)
)
} catch (e: Exception) {
Timber.w(e)
errorCount++
@@ -47,8 +47,13 @@ class ContactRepositoryImpl @Inject constructor(
return Flowable.just(address)
.map {
when {
address.contains('@') -> Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(address))
else -> Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address))
address.contains('@') -> {
Uri.withAppendedPath(Email.CONTENT_FILTER_URI, Uri.encode(address))
}
else -> {
Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(address))
}
}
}
.mapNotNull { uri -> context.contentResolver.query(uri, arrayOf(BaseColumns._ID), null, null, null) }
@@ -61,27 +61,31 @@ class ConversationRepositoryImpl @Inject constructor(
override fun getConversationsSnapshot(): List<Conversation> {
val realm = Realm.getDefaultInstance()
return realm.copyFromRealm(realm.where(Conversation::class.java)
.notEqualTo("id", 0L)
.greaterThan("count", 0)
.equalTo("archived", false)
.equalTo("blocked", false)
.isNotEmpty("recipients")
.sort("pinned", Sort.DESCENDING, "date", Sort.DESCENDING)
.findAll())
return realm.copyFromRealm(
realm.where(Conversation::class.java)
.notEqualTo("id", 0L)
.greaterThan("count", 0)
.equalTo("archived", false)
.equalTo("blocked", false)
.isNotEmpty("recipients")
.sort("pinned", Sort.DESCENDING, "date", Sort.DESCENDING)
.findAll()
)
}
override fun getTopConversations(): List<Conversation> {
val realm = Realm.getDefaultInstance()
return realm.copyFromRealm(realm.where(Conversation::class.java)
.notEqualTo("id", 0L)
.greaterThan("count", 0)
.greaterThan("date", System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
.equalTo("archived", false)
.equalTo("blocked", false)
.isNotEmpty("recipients")
.sort("pinned", Sort.DESCENDING, "count", Sort.DESCENDING)
.findAll())
return realm.copyFromRealm(
realm.where(Conversation::class.java)
.notEqualTo("id", 0L)
.greaterThan("count", 0)
.greaterThan("date", System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
.equalTo("archived", false)
.equalTo("blocked", false)
.isNotEmpty("recipients")
.sort("pinned", Sort.DESCENDING, "count", Sort.DESCENDING)
.findAll()
)
}
override fun setConversationName(id: Long, name: String) {
@@ -32,7 +32,6 @@ import java.io.FileOutputStream
import java.io.IOException
import javax.inject.Inject
class ImageRepostoryImpl @Inject constructor(private val context: Context) : ImageRepository {
override fun loadImage(uri: Uri): Bitmap? {
@@ -210,7 +210,14 @@ class MessageRepositoryImpl @Inject constructor(
}
}
override fun sendMessage(subId: Int, threadId: Long, addresses: List<String>, body: String, attachments: List<Attachment>, delay: Int) {
override fun sendMessage(
subId: Int,
threadId: Long,
addresses: List<String>,
body: String,
attachments: List<Attachment>,
delay: Int
) {
if (addresses.size == 1 && attachments.isEmpty()) { // SMS
if (delay > 0) { // With delay
val sendTime = System.currentTimeMillis() + delay
@@ -273,7 +280,8 @@ class MessageRepositoryImpl @Inject constructor(
?.let(SmsManagerFactory::createSmsManager)
?: SmsManager.getDefault()
val parts = smsManager.divideMessage(if (prefs.unicode.get()) StripAccents.stripAccents(message.body) else message.body)
val parts = smsManager
.divideMessage(if (prefs.unicode.get()) StripAccents.stripAccents(message.body) else message.body)
?: arrayListOf()
val sentIntents = parts.map {
@@ -285,11 +293,18 @@ class MessageRepositoryImpl @Inject constructor(
val deliveredIntents = parts.map {
context.registerReceiver(SmsDeliveredReceiver(), IntentFilter(SmsDeliveredReceiver.ACTION))
val intent = Intent(SmsDeliveredReceiver.ACTION).putExtra("id", message.id)
val pendingIntent = PendingIntent.getBroadcast(context, message.id.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT)
val pendingIntent = PendingIntent
.getBroadcast(context, message.id.toInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT)
if (prefs.delivery.get()) pendingIntent else null
}
smsManager.sendMultipartTextMessage(message.address, null, parts, ArrayList(sentIntents), ArrayList(deliveredIntents))
smsManager.sendMultipartTextMessage(
message.address,
null,
parts,
ArrayList(sentIntents),
ArrayList(deliveredIntents)
)
}
override fun cancelDelayedSms(id: Long) {
@@ -26,15 +26,21 @@ import javax.inject.Inject
class ScheduledMessageRepositoryImpl @Inject constructor() : ScheduledMessageRepository {
override fun saveScheduledMessage(date: Long, subId: Int, recipients: List<String>, sendAsGroup: Boolean,
body: String, attachments: List<String>) {
override fun saveScheduledMessage(
date: Long,
subId: Int,
recipients: List<String>,
sendAsGroup: Boolean,
body: String,
attachments: List<String>
) {
Realm.getDefaultInstance().use { realm ->
val id = (realm.where(ScheduledMessage::class.java).max("id")?.toLong() ?: -1) + 1
val recipientsRealmList = RealmList(*recipients.toTypedArray())
val attachmentsRealmList = RealmList(*attachments.toTypedArray())
val message = ScheduledMessage(id, date, subId, recipientsRealmList, sendAsGroup, body, attachmentsRealmList)
val message = ScheduledMessage(id, date, subId, recipientsRealmList, sendAsGroup, body,
attachmentsRealmList)
realm.executeTransaction { realm.insertOrUpdate(message) }
}
@@ -20,7 +20,6 @@ package com.moez.QKSMS.repository
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.provider.Telephony
import android.telephony.PhoneNumberUtils
@@ -48,7 +47,6 @@ import javax.inject.Singleton
@Singleton
class SyncRepositoryImpl @Inject constructor(
private val context: Context,
private val contentResolver: ContentResolver,
private val conversationRepo: ConversationRepository,
private val cursorToConversation: CursorToConversation,
@@ -67,9 +65,11 @@ class SyncRepositoryImpl @Inject constructor(
val archived: Boolean,
val blocked: Boolean,
val pinned: Boolean,
val name: String)
val name: String
)
override val syncProgress: Subject<SyncRepository.SyncProgress> = BehaviorSubject.createDefault(SyncRepository.SyncProgress.Idle())
override val syncProgress: Subject<SyncRepository.SyncProgress> =
BehaviorSubject.createDefault(SyncRepository.SyncProgress.Idle())
override fun syncMessages() {
@@ -111,7 +111,6 @@ class SyncRepositoryImpl @Inject constructor(
var progress = 0
// Sync messages
messageCursor?.use {
val messageColumns = CursorToMessage.MessageColumns(messageCursor)
@@ -152,7 +151,8 @@ class SyncRepositoryImpl @Inject constructor(
.distinct("threadId")
.findAll()
.forEach { message ->
val conversation = conversations.firstOrNull { conversation -> conversation.id == message.threadId }
val conversation = conversations
.firstOrNull { conversation -> conversation.id == message.threadId }
conversation?.date = message.date
conversation?.snippet = message.getSummary()
conversation?.me = message.isMe()
@@ -161,7 +161,6 @@ class SyncRepositoryImpl @Inject constructor(
realm.insertOrUpdate(conversations)
}
// Sync recipients
recipientCursor?.use {
val contacts = realm.copyToRealm(getContacts())
@@ -276,7 +275,11 @@ class SyncRepositoryImpl @Inject constructor(
// Update all the matching recipients with the new contact
val updatedRecipients = recipients
.filter { recipient -> contact.numbers.any { number -> PhoneNumberUtils.compare(recipient.address, number.address) } }
.filter { recipient ->
contact.numbers.any { number ->
PhoneNumberUtils.compare(recipient.address, number.address)
}
}
.map { recipient -> recipient.apply { this.contact = contact } }
realm.insertOrUpdate(updatedRecipients)
@@ -36,7 +36,6 @@ import io.reactivex.schedulers.Schedulers
import java.io.InputStream
import java.security.MessageDigest
class ContactImageLoader(
private val context: Context,
private val contactRepo: ContactRepository
@@ -46,12 +45,20 @@ class ContactImageLoader(
return PhoneNumberUtils.isGlobalPhoneNumber(model)
}
override fun buildLoadData(model: String, width: Int, height: Int, options: Options): ModelLoader.LoadData<InputStream>? {
override fun buildLoadData(
model: String,
width: Int,
height: Int,
options: Options
): ModelLoader.LoadData<InputStream>? {
return ModelLoader.LoadData(ContactImageKey(model), ContactImageFetcher(context, contactRepo, model))
}
class Factory(val context: Context, val prefs: Preferences) : ModelLoaderFactory<String, InputStream> {
override fun build(multiFactory: MultiModelLoaderFactory) = ContactImageLoader(context, ContactRepositoryImpl(context, prefs))
override fun build(multiFactory: MultiModelLoaderFactory): ContactImageLoader {
return ContactImageLoader(context, ContactRepositoryImpl(context, prefs))
}
override fun teardown() {} // nothing to do here
}
@@ -86,10 +86,15 @@ class GifEncoder internal constructor(
return decoder
}
private fun getTransformedFrame(currentFrame: Bitmap?, transformation: Transformation<Bitmap>, drawable: GifDrawable): Resource<Bitmap> {
private fun getTransformedFrame(
currentFrame: Bitmap?,
transformation: Transformation<Bitmap>,
drawable: GifDrawable
): Resource<Bitmap> {
// TODO: what if current frame is null?
val bitmapResource = factory.buildFrameResource(currentFrame!!, bitmapPool)
val transformedResource = transformation.transform(context, bitmapResource, drawable.intrinsicWidth, drawable.intrinsicHeight)
val transformedResource = transformation.transform(
context, bitmapResource, drawable.intrinsicWidth, drawable.intrinsicHeight)
if (bitmapResource != transformedResource) {
bitmapResource.recycle()
}
@@ -38,7 +38,8 @@ class GlideAppModule : AppGlideModule() {
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
// TODO use DI to create the ContactImageLoader.Factory
registry.append(String::class.java, InputStream::class.java, ContactImageLoader.Factory(context, Preferences(RxSharedPreferences.create(PreferenceManager.getDefaultSharedPreferences(context)))))
registry.append(String::class.java, InputStream::class.java, ContactImageLoader.Factory(context,
Preferences(RxSharedPreferences.create(PreferenceManager.getDefaultSharedPreferences(context)))))
}
}
@@ -24,7 +24,6 @@ import android.net.Uri
import com.bumptech.glide.load.resource.bitmap.CenterCrop
import java.io.ByteArrayOutputStream
object ImageUtils {
fun compressGif(context: Context, uri: Uri, maxBytes: Int): ByteArray {
@@ -87,8 +87,18 @@ class NightModeManager @Inject constructor(
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
if (prefs.nightMode.get() == Preferences.NIGHT_MODE_AUTO) {
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, dayCalendar.timeInMillis, AlarmManager.INTERVAL_DAY, dayIntent)
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, nightCalendar.timeInMillis, AlarmManager.INTERVAL_DAY, nightIntent)
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
dayCalendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
dayIntent
)
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
nightCalendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
nightIntent
)
} else {
alarmManager.cancel(dayIntent)
alarmManager.cancel(nightIntent)