Allow selecting root or services, only when access is available

This commit is contained in:
Rahul Kumar Patel
2021-02-25 11:39:40 +05:30
parent 45ecc96345
commit d255419977
6 changed files with 152 additions and 58 deletions

View File

@@ -35,6 +35,7 @@ import com.aurora.store.BuildConfig
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.event.SessionEvent import com.aurora.store.data.event.SessionEvent
import com.aurora.store.util.Log import com.aurora.store.util.Log
import com.aurora.store.util.PackageUtil
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import java.io.File import java.io.File
@@ -48,21 +49,34 @@ class ServiceInstaller(context: Context) : InstallerBase(context) {
@RequiresApi(Build.VERSION_CODES.LOLLIPOP) @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
override fun install(packageName: String, files: List<Any>) { override fun install(packageName: String, files: List<Any>) {
if (isAlreadyQueued(packageName)) {
Log.i("$packageName already queued") when {
} else { isAlreadyQueued(packageName) -> {
Log.i("Received service install request for $packageName") Log.i("$packageName already queued")
val uriList = files.map {
when (it) {
is File -> getUri(it)
is String -> getUri(File(it))
else -> {
throw Exception("Invalid data, expecting listOf() File or String")
}
}
} }
xInstall(packageName, uriList) PackageUtil.isInstalled(context, PRIVILEGED_EXTENSION_PACKAGE_NAME) -> {
Log.i("Received service install request for $packageName")
val uriList = files.map {
when (it) {
is File -> getUri(it)
is String -> getUri(File(it))
else -> {
throw Exception("Invalid data, expecting listOf() File or String")
}
}
}
xInstall(packageName, uriList)
}
else -> {
val event = SessionEvent.Failed(
packageName,
context.getString(R.string.installer_status_failure),
context.getString(R.string.installer_service_unavailable)
)
EventBus.getDefault().post(event)
}
} }
} }
@@ -103,16 +117,13 @@ class ServiceInstaller(context: Context) : InstallerBase(context) {
Log.e("Failed to connect Aurora Services") Log.e("Failed to connect Aurora Services")
} }
} else { } else {
Log.e(context.getString(R.string.installer_service_unavailable)) Log.e(context.getString(R.string.installer_service_misconfigured))
EventBus val event = SessionEvent.Failed(
.getDefault() packageName,
.post( context.getString(R.string.installer_status_failure),
SessionEvent.Failed( context.getString(R.string.installer_service_misconfigured)
packageName, )
context.getString(R.string.installer_status_failure), EventBus.getDefault().post(event)
context.getString(R.string.installer_service_unavailable)
)
)
} }
} }

View File

@@ -76,4 +76,9 @@ class InstallerView : RelativeLayout {
fun checked(onCheckedChangeListener: CompoundButton.OnCheckedChangeListener?) { fun checked(onCheckedChangeListener: CompoundButton.OnCheckedChangeListener?) {
B.checkbox.setOnCheckedChangeListener(onCheckedChangeListener) B.checkbox.setOnCheckedChangeListener(onCheckedChangeListener)
} }
@CallbackProp
fun click(onClickListener: OnClickListener?) {
B.root.setOnClickListener(onClickListener)
}
} }

View File

@@ -19,20 +19,26 @@
package com.aurora.store.view.ui.onboarding package com.aurora.store.view.ui.onboarding
import android.content.DialogInterface
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.annotation.StringRes
import com.aurora.extensions.getStyledAttributeColor
import com.aurora.extensions.runOnUiThread
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.installer.ServiceInstaller
import com.aurora.store.data.model.Installer import com.aurora.store.data.model.Installer
import com.aurora.store.databinding.FragmentOnboardingInstallerBinding import com.aurora.store.databinding.FragmentOnboardingInstallerBinding
import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences
import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID import com.aurora.store.util.Preferences.PREFERENCE_INSTALLER_ID
import com.aurora.extensions.runOnUiThread
import com.aurora.extensions.toast
import com.aurora.store.util.save import com.aurora.store.util.save
import com.aurora.store.view.epoxy.views.preference.InstallerViewModel_ import com.aurora.store.view.epoxy.views.preference.InstallerViewModel_
import com.aurora.store.view.ui.commons.BaseFragment import com.aurora.store.view.ui.commons.BaseFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
@@ -81,12 +87,9 @@ class InstallerFragment : BaseFragment() {
.id(it.id) .id(it.id)
.installer(it) .installer(it)
.markChecked(installerId == it.id) .markChecked(installerId == it.id)
.checked { _, checked -> .click { _ ->
if (checked) { save(it.id)
installerId = it.id requestModelBuild()
save(installerId)
requestModelBuild()
}
} }
) )
} }
@@ -94,21 +97,32 @@ class InstallerFragment : BaseFragment() {
} }
private fun save(installerId: Int) { private fun save(installerId: Int) {
if (installerId == 2) { when (installerId) {
checkRoot() 2 -> {
} if (checkRootAvailability()) {
save(PREFERENCE_INSTALLER_ID, installerId) this.installerId = installerId
} save(PREFERENCE_INSTALLER_ID, installerId)
} else {
private fun checkRoot() { showDialog(
Shell.getShell { R.string.action_installations,
runOnUiThread { R.string.installer_root_unavailable
requireContext().toast( )
if (it.isRoot) }
getString(R.string.installer_root_available) }
else 3 -> {
getString(R.string.installer_root_unavailable) if (checkServicesAvailability()) {
) this.installerId = installerId
save(PREFERENCE_INSTALLER_ID, installerId)
} else {
showDialog(
R.string.action_installations,
R.string.installer_service_unavailable
)
}
}
else -> {
this.installerId = installerId
save(PREFERENCE_INSTALLER_ID, installerId)
} }
} }
} }
@@ -125,4 +139,31 @@ class InstallerFragment : BaseFragment() {
object : TypeToken<MutableList<Installer?>?>() {}.type object : TypeToken<MutableList<Installer?>?>() {}.type
) )
} }
private fun checkRootAvailability(): Boolean {
return Shell.getShell().isRoot
}
private fun checkServicesAvailability(): Boolean {
return PackageUtil.isInstalled(
requireContext(),
ServiceInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME
)
}
private fun showDialog(@StringRes titleId: Int, @StringRes messageId: Int) {
runOnUiThread {
val backgroundColor: Int =
requireContext().getStyledAttributeColor(android.R.attr.colorBackground)
val builder = MaterialAlertDialogBuilder(requireContext()).apply {
setTitle(titleId)
setMessage(messageId)
setPositiveButton(android.R.string.ok) { dialog: DialogInterface, _ -> dialog.dismiss() }
background = ColorDrawable(backgroundColor)
}.create()
builder.show()
}
}
} }

View File

@@ -19,17 +19,24 @@
package com.aurora.store.view.ui.preferences package com.aurora.store.view.ui.preferences
import android.content.DialogInterface
import android.graphics.drawable.ColorDrawable
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.annotation.StringRes
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import com.aurora.extensions.getStyledAttributeColor
import com.aurora.extensions.runOnUiThread import com.aurora.extensions.runOnUiThread
import com.aurora.extensions.toast import com.aurora.extensions.toast
import com.aurora.store.R import com.aurora.store.R
import com.aurora.store.data.installer.ServiceInstaller
import com.aurora.store.util.CommonUtil import com.aurora.store.util.CommonUtil
import com.aurora.store.util.PackageUtil
import com.aurora.store.util.Preferences import com.aurora.store.util.Preferences
import com.aurora.store.util.save import com.aurora.store.util.save
import com.aurora.store.view.custom.preference.AuroraListPreference import com.aurora.store.view.custom.preference.AuroraListPreference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@@ -63,10 +70,25 @@ class InstallationPreference : PreferenceFragmentCompat() {
Preference.OnPreferenceChangeListener { _, newValue -> Preference.OnPreferenceChangeListener { _, newValue ->
val selectedId = Integer.parseInt(newValue as String) val selectedId = Integer.parseInt(newValue as String)
if (selectedId == 2) { if (selectedId == 2) {
if (checkRoot()) { if (checkRootAvailability()) {
save(Preferences.PREFERENCE_INSTALLER_ID, selectedId) save(Preferences.PREFERENCE_INSTALLER_ID, selectedId)
true true
} else { } else {
showDialog(
R.string.action_installations,
R.string.installer_root_unavailable
)
false
}
} else if (selectedId == 3) {
if (checkServicesAvailability()) {
save(Preferences.PREFERENCE_INSTALLER_ID, selectedId)
true
} else {
showDialog(
R.string.action_installations,
R.string.installer_service_unavailable
)
false false
} }
} else { } else {
@@ -77,18 +99,30 @@ class InstallationPreference : PreferenceFragmentCompat() {
} }
} }
private fun checkRoot(): Boolean { private fun checkRootAvailability(): Boolean {
var isRootAvailable = false return Shell.getShell().isRoot
}
Shell.getShell { private fun checkServicesAvailability(): Boolean {
isRootAvailable = it.isRoot return PackageUtil.isInstalled(
requireContext(),
ServiceInstaller.PRIVILEGED_EXTENSION_PACKAGE_NAME
)
}
if (isRootAvailable) private fun showDialog(@StringRes titleId: Int, @StringRes messageId: Int) {
toast(R.string.installer_root_available) runOnUiThread {
else val backgroundColor: Int =
toast(R.string.installer_root_unavailable) requireContext().getStyledAttributeColor(android.R.attr.colorBackground)
val builder = MaterialAlertDialogBuilder(requireContext()).apply {
setTitle(titleId)
setMessage(messageId)
setPositiveButton(android.R.string.ok) { dialog: DialogInterface, _ -> dialog.dismiss() }
background = ColorDrawable(backgroundColor)
}.create()
builder.show()
} }
return isRootAvailable
} }
} }

View File

@@ -56,5 +56,7 @@
android:layout_height="@dimen/icon_size_category" android:layout_height="@dimen/icon_size_category"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_centerInParent="true" android:layout_centerInParent="true"
android:clickable="false"
android:focusable="false"
android:minWidth="0dp" /> android:minWidth="0dp" />
</RelativeLayout> </RelativeLayout>

View File

@@ -205,7 +205,8 @@
<string name="installer_root_available">"Root access available"</string> <string name="installer_root_available">"Root access available"</string>
<string name="installer_root_unavailable">"No Root, grant root access or change the installer."</string> <string name="installer_root_unavailable">"No Root, grant root access or change the installer."</string>
<string name="installer_service_available">"Aurora services is available and ready to install."</string> <string name="installer_service_available">"Aurora services is available and ready to install."</string>
<string name="installer_service_unavailable">"Aurora services not configured. Make sure service is enabled &amp; all permissions are granted"</string> <string name="installer_service_unavailable">"Aurora services not installed, kindly install it or change installer"</string>
<string name="installer_service_misconfigured">"Aurora services not configured. Make sure service is enabled &amp; all permissions are granted"</string>
<string name="installer_status_failure">"Installation failed"</string> <string name="installer_status_failure">"Installation failed"</string>
<string name="installer_status_failure_aborted">"Installation cancelled"</string> <string name="installer_status_failure_aborted">"Installation cancelled"</string>
<string name="installer_status_failure_blocked">"Installation was blocked"</string> <string name="installer_status_failure_blocked">"Installation was blocked"</string>