From d1d99f5283942c391fa814827ce0413d0bca6fa6 Mon Sep 17 00:00:00 2001 From: moezbhatti Date: Mon, 28 Oct 2019 00:26:32 -0400 Subject: [PATCH] Support for Q Roles Closes #1409 --- .../moez/QKSMS/manager/PermissionManagerImpl.kt | 8 +++++++- .../java/com/moez/QKSMS/common/Navigator.kt | 17 +++++++++++++---- .../QKSMS/feature/compose/ComposeActivity.kt | 6 ++++++ .../moez/QKSMS/feature/compose/ComposeView.kt | 1 + .../QKSMS/feature/compose/ComposeViewModel.kt | 4 ++-- .../ConversationInfoController.kt | 4 ++++ .../ConversationInfoPresenter.kt | 2 +- .../conversationinfo/ConversationInfoView.kt | 3 ++- .../com/moez/QKSMS/feature/main/MainActivity.kt | 4 ++++ .../com/moez/QKSMS/feature/main/MainView.kt | 1 + .../moez/QKSMS/feature/main/MainViewModel.kt | 10 +++++----- .../moez/QKSMS/injection/scope/ActivityScope.kt | 2 +- 12 files changed, 47 insertions(+), 15 deletions(-) diff --git a/data/src/main/java/com/moez/QKSMS/manager/PermissionManagerImpl.kt b/data/src/main/java/com/moez/QKSMS/manager/PermissionManagerImpl.kt index 5ee266c4..f910428c 100644 --- a/data/src/main/java/com/moez/QKSMS/manager/PermissionManagerImpl.kt +++ b/data/src/main/java/com/moez/QKSMS/manager/PermissionManagerImpl.kt @@ -19,8 +19,10 @@ package com.moez.QKSMS.manager import android.Manifest +import android.app.role.RoleManager import android.content.Context import android.content.pm.PackageManager.PERMISSION_GRANTED +import android.os.Build import android.provider.Telephony import androidx.core.content.ContextCompat import javax.inject.Inject @@ -28,7 +30,11 @@ import javax.inject.Inject class PermissionManagerImpl @Inject constructor(private val context: Context) : PermissionManager { override fun isDefaultSms(): Boolean { - return Telephony.Sms.getDefaultSmsPackage(context) == context.packageName + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + context.getSystemService(RoleManager::class.java)?.isRoleHeld(RoleManager.ROLE_SMS) == true + } else { + Telephony.Sms.getDefaultSmsPackage(context) == context.packageName + } } override fun hasReadSms(): Boolean { diff --git a/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt b/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt index 6858739e..2b637271 100644 --- a/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt +++ b/presentation/src/main/java/com/moez/QKSMS/common/Navigator.kt @@ -18,6 +18,8 @@ */ package com.moez.QKSMS.common +import android.app.Activity +import android.app.role.RoleManager import android.content.ActivityNotFoundException import android.content.Context import android.content.Intent @@ -78,12 +80,19 @@ class Navigator @Inject constructor( startActivity(intent) } - fun showDefaultSmsDialog() { - val intent = Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT) - if (Telephony.Sms.getDefaultSmsPackage(context) != context.packageName) { + /** + * This won't work unless we use startActivityForResult + */ + fun showDefaultSmsDialog(context: Activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val roleManager = context.getSystemService(RoleManager::class.java) as RoleManager + val intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_SMS) + context.startActivityForResult(intent, 42389) + } else { + val intent = Intent(Telephony.Sms.Intents.ACTION_CHANGE_DEFAULT) intent.putExtra(Telephony.Sms.Intents.EXTRA_PACKAGE_NAME, context.packageName) + context.startActivity(intent) } - startActivity(intent) } fun showCompose(body: String? = null, images: List? = null) { diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt index 92b6e2b6..a0c38ad0 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeActivity.kt @@ -43,6 +43,7 @@ import com.google.android.material.snackbar.Snackbar import com.jakewharton.rxbinding2.view.clicks import com.jakewharton.rxbinding2.widget.textChanges import com.moez.QKSMS.R +import com.moez.QKSMS.common.Navigator import com.moez.QKSMS.common.base.QkThemedActivity import com.moez.QKSMS.common.util.DateFormatter import com.moez.QKSMS.common.util.extensions.autoScrollToStart @@ -78,6 +79,7 @@ class ComposeActivity : QkThemedActivity(), ComposeView { @Inject lateinit var contactsAdapter: ContactAdapter @Inject lateinit var dateFormatter: DateFormatter @Inject lateinit var messageAdapter: MessagesAdapter + @Inject lateinit var navigator: Navigator @Inject lateinit var viewModelFactory: ViewModelProvider.Factory override val activityVisibleIntent: Subject = PublishSubject.create() @@ -250,6 +252,10 @@ class ComposeActivity : QkThemedActivity(), ComposeView { .show() } + override fun requestDefaultSms() { + navigator.showDefaultSmsDialog(this) + } + override fun requestStoragePermission() { ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 0) } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt index 849eb510..137a2aae 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeView.kt @@ -61,6 +61,7 @@ interface ComposeView : QkView { fun clearSelection() fun showDetails(details: String) + fun requestDefaultSms() fun requestStoragePermission() fun requestSmsPermission() fun requestCamera() diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt index 803ed68d..4d42eb27 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/compose/ComposeViewModel.kt @@ -357,7 +357,7 @@ class ComposeViewModel @Inject constructor( // Delete the messages view.optionsItemIntent .filter { it == R.id.delete } - .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } } .withLatestFrom(view.messagesSelectedIntent, conversation) { _, messages, conversation -> deleteMessages.execute(DeleteMessages.Params(messages, conversation.id)) } @@ -631,7 +631,7 @@ class ComposeViewModel @Inject constructor( // Send a message when the send button is clicked, and disable editing mode if it's enabled view.sendIntent - .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } } .filter { permissionManager.hasSendSms().also { if (!it) view.requestSmsPermission() } } .withLatestFrom(view.textChangedIntent) { _, body -> body } .map { body -> body.toString() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt index 26c74217..45a010e3 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoController.kt @@ -152,6 +152,10 @@ class ConversationInfoController( blockingDialog.show(activity!!, conversations, block) } + override fun requestDefaultSms() { + navigator.showDefaultSmsDialog(activity!!) + } + override fun showDeleteDialog() { AlertDialog.Builder(activity!!) .setTitle(R.string.dialog_delete_title) diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt index 5e23e5b1..4f602902 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoPresenter.kt @@ -165,7 +165,7 @@ class ConversationInfoPresenter @Inject constructor( // Show the delete confirmation dialog view.deleteClicks() - .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } } .autoDisposable(view.scope()) .subscribe { view.showDeleteDialog() } diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt index d973f367..e2c1d971 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/conversationinfo/ConversationInfoView.kt @@ -36,6 +36,7 @@ interface ConversationInfoView : QkViewContract { fun showNameDialog(name: String) fun showThemePicker(threadId: Long) fun showBlockingDialog(conversations: List, block: Boolean) + fun requestDefaultSms() fun showDeleteDialog() -} \ No newline at end of file +} diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt index fc55c40c..35ab52d1 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainActivity.kt @@ -337,6 +337,10 @@ class MainActivity : QkThemedActivity(), MainView { } } + override fun requestDefaultSms() { + navigator.showDefaultSmsDialog(this) + } + override fun requestPermissions() { ActivityCompat.requestPermissions(this, arrayOf( Manifest.permission.READ_SMS, diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt index 873aa69c..f774a28c 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainView.kt @@ -43,6 +43,7 @@ interface MainView : QkView { val undoArchiveIntent: Observable val snackbarButtonIntent: Observable + fun requestDefaultSms() fun requestPermissions() fun clearSearch() fun clearSelection() diff --git a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt index 6fa78825..24a6cd21 100644 --- a/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt +++ b/presentation/src/main/java/com/moez/QKSMS/feature/main/MainViewModel.kt @@ -117,7 +117,7 @@ class MainViewModel @Inject constructor( super.bindView(view) when { - !permissionManager.isDefaultSms() -> navigator.showDefaultSmsDialog() + !permissionManager.isDefaultSms() -> view.requestDefaultSms() !permissionManager.hasReadSms() || !permissionManager.hasContacts() -> view.requestPermissions() } @@ -270,7 +270,7 @@ class MainViewModel @Inject constructor( view.optionsItemIntent .filter { itemId -> itemId == R.id.delete } - .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } } .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> view.showDeleteDialog(conversations) } @@ -311,7 +311,7 @@ class MainViewModel @Inject constructor( view.optionsItemIntent .filter { itemId -> itemId == R.id.read } - .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } } .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> markRead.execute(conversations) view.clearSelection() @@ -321,7 +321,7 @@ class MainViewModel @Inject constructor( view.optionsItemIntent .filter { itemId -> itemId == R.id.unread } - .filter { permissionManager.isDefaultSms().also { if (!it) navigator.showDefaultSmsDialog() } } + .filter { permissionManager.isDefaultSms().also { if (!it) view.requestDefaultSms() } } .withLatestFrom(view.conversationsSelectedIntent) { _, conversations -> markUnread.execute(conversations) view.clearSelection() @@ -412,7 +412,7 @@ class MainViewModel @Inject constructor( view.snackbarButtonIntent .withLatestFrom(state) { _, state -> when { - !state.defaultSms -> navigator.showDefaultSmsDialog() + !state.defaultSms -> view.requestDefaultSms() !state.smsPermission -> view.requestPermissions() !state.contactPermission -> view.requestPermissions() } diff --git a/presentation/src/main/java/com/moez/QKSMS/injection/scope/ActivityScope.kt b/presentation/src/main/java/com/moez/QKSMS/injection/scope/ActivityScope.kt index 762f16f7..007e63f4 100644 --- a/presentation/src/main/java/com/moez/QKSMS/injection/scope/ActivityScope.kt +++ b/presentation/src/main/java/com/moez/QKSMS/injection/scope/ActivityScope.kt @@ -21,4 +21,4 @@ package com.moez.QKSMS.injection.scope import javax.inject.Scope @Scope -annotation class ActivityScope \ No newline at end of file +annotation class ActivityScope