Added installing external modules from storage

This commit is contained in:
Viktor De Pasquale 2019-11-16 19:13:40 +01:00
parent 711799b194
commit 0f140b408c
7 changed files with 99 additions and 2 deletions

View File

@ -81,6 +81,13 @@ class RepoRvItem(val item: Repo) : ComparableRvItem<RepoRvItem>() {
override fun itemSameAs(other: RepoRvItem): Boolean = item.id == other.item.id override fun itemSameAs(other: RepoRvItem): Boolean = item.id == other.item.id
} }
object InstallModule : ComparableRvItem<InstallModule>() {
override val layoutRes = R.layout.item_module_download
override fun contentSameAs(other: InstallModule) = this == other
override fun itemSameAs(other: InstallModule) = this === other
}
class SectionTitle( class SectionTitle(
val title: Int, val title: Int,
val button: Int = 0, val button: Int = 0,

View File

@ -0,0 +1,38 @@
package com.topjohnwu.magisk.model.events
import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import com.topjohnwu.magisk.Const
import com.topjohnwu.magisk.base.BaseActivity
import com.topjohnwu.magisk.intent
import com.topjohnwu.magisk.ui.flash.FlashActivity
class InstallExternalModuleEvent : ViewEvent(), ActivityExecutor {
override fun invoke(activity: AppCompatActivity) {
activity as BaseActivity<*, *>
activity.withExternalRW {
onSuccess {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "application/zip"
activity.startActivityForResult(intent, Const.ID.FETCH_ZIP)
}
}
}
companion object {
fun onActivityResult(context: Context, requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == Const.ID.FETCH_ZIP && resultCode == Activity.RESULT_OK && data != null) {
// Get the URI of the selected file
val intent = context.intent(FlashActivity::class.java)
intent.setData(data.data).putExtra(Const.Key.FLASH_ACTION, Const.Value.FLASH_ZIP)
context.startActivity(intent)
}
}
}
}

View File

@ -1,5 +1,6 @@
package com.topjohnwu.magisk.redesign.module package com.topjohnwu.magisk.redesign.module
import android.content.Intent
import android.graphics.Insets import android.graphics.Insets
import android.os.Bundle import android.os.Bundle
import android.view.Menu import android.view.Menu
@ -9,6 +10,7 @@ import android.view.View
import androidx.recyclerview.widget.StaggeredGridLayoutManager import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.topjohnwu.magisk.R import com.topjohnwu.magisk.R
import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding import com.topjohnwu.magisk.databinding.FragmentModuleMd2Binding
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
import com.topjohnwu.magisk.redesign.MainActivity import com.topjohnwu.magisk.redesign.MainActivity
import com.topjohnwu.magisk.redesign.ReselectionTarget import com.topjohnwu.magisk.redesign.ReselectionTarget
import com.topjohnwu.magisk.redesign.compat.CompatFragment import com.topjohnwu.magisk.redesign.compat.CompatFragment
@ -27,6 +29,11 @@ class ModuleFragment : CompatFragment<ModuleViewModel, FragmentModuleMd2Binding>
override fun consumeSystemWindowInsets(insets: Insets) = insets override fun consumeSystemWindowInsets(insets: Insets) = insets
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
InstallExternalModuleEvent.onActivityResult(requireContext(), requestCode, resultCode, data)
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
setHasOptionsMenu(true) setHasOptionsMenu(true)

View File

@ -15,9 +15,11 @@ import com.topjohnwu.magisk.model.download.RemoteFileService
import com.topjohnwu.magisk.model.entity.internal.DownloadSubject import com.topjohnwu.magisk.model.entity.internal.DownloadSubject
import com.topjohnwu.magisk.model.entity.module.Module import com.topjohnwu.magisk.model.entity.module.Module
import com.topjohnwu.magisk.model.entity.module.Repo import com.topjohnwu.magisk.model.entity.module.Repo
import com.topjohnwu.magisk.model.entity.recycler.InstallModule
import com.topjohnwu.magisk.model.entity.recycler.ModuleItem import com.topjohnwu.magisk.model.entity.recycler.ModuleItem
import com.topjohnwu.magisk.model.entity.recycler.RepoItem import com.topjohnwu.magisk.model.entity.recycler.RepoItem
import com.topjohnwu.magisk.model.entity.recycler.SectionTitle import com.topjohnwu.magisk.model.entity.recycler.SectionTitle
import com.topjohnwu.magisk.model.events.InstallExternalModuleEvent
import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog import com.topjohnwu.magisk.model.events.dialog.ModuleInstallDialog
import com.topjohnwu.magisk.redesign.compat.CompatViewModel import com.topjohnwu.magisk.redesign.compat.CompatViewModel
import com.topjohnwu.magisk.redesign.compat.Queryable import com.topjohnwu.magisk.redesign.compat.Queryable
@ -219,10 +221,12 @@ class ModuleViewModel(
fun download(item: RepoItem) = ModuleInstallDialog(item.item).publish() fun download(item: RepoItem) = ModuleInstallDialog(item.item).publish()
fun sectionPressed(item: SectionTitle) = when (item) { fun sectionPressed(item: SectionTitle) = when (item) {
sectionActive -> reboot() sectionActive -> reboot() //TODO add reboot picker, regular reboot is not always preferred
else -> Unit else -> Unit
} }
fun installPressed() = InstallExternalModuleEvent().publish()
// --- // ---
/** Callable only from worker thread because of expensive list filtering */ /** Callable only from worker thread because of expensive list filtering */
@ -230,7 +234,7 @@ class ModuleViewModel(
private fun build( private fun build(
active: List<ModuleItem> = itemsInstalled, active: List<ModuleItem> = itemsInstalled,
remote: List<RepoItem> = itemsRemote remote: List<RepoItem> = itemsRemote
) = active.prependIfNotEmpty { sectionActive } + ) = (active + InstallModule).prependIfNotEmpty { sectionActive } +
remote.prependIfNotEmpty { sectionRemote } remote.prependIfNotEmpty { sectionRemote }
private fun <T> List<T>.prependIfNotEmpty(item: () -> T) = private fun <T> List<T>.prependIfNotEmpty(item: () -> T) =

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="?colorOnSurface"
android:pathData="M2,10.96C1.5,10.68 1.35,10.07 1.63,9.59L3.13,7C3.24,6.8 3.41,6.66 3.6,6.58L11.43,2.18C11.59,2.06 11.79,2 12,2C12.21,2 12.41,2.06 12.57,2.18L20.47,6.62C20.66,6.72 20.82,6.88 20.91,7.08L22.36,9.6C22.64,10.08 22.47,10.69 22,10.96L21,11.54V16.5C21,16.88 20.79,17.21 20.47,17.38L12.57,21.82C12.41,21.94 12.21,22 12,22C11.79,22 11.59,21.94 11.43,21.82L3.53,17.38C3.21,17.21 3,16.88 3,16.5V10.96C2.7,11.13 2.32,11.14 2,10.96M12,4.15V4.15L12,10.85V10.85L17.96,7.5L12,4.15M5,15.91L11,19.29V12.58L5,9.21V15.91M19,15.91V12.69L14,15.59C13.67,15.77 13.3,15.76 13,15.6V19.29L19,15.91M13.85,13.36L20.13,9.73L19.55,8.72L13.27,12.35L13.85,13.36Z" />
</vector>

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="item"
type="com.topjohnwu.magisk.model.entity.recycler.InstallModule" />
<variable
name="viewModel"
type="com.topjohnwu.magisk.redesign.module.ModuleViewModel" />
</data>
<com.google.android.material.button.MaterialButton
style="?styleButtonText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{() -> viewModel.installPressed()}"
android:text="@string/module_action_install_external"
android:textAllCaps="false"
android:textSize="12sp"
app:icon="@drawable/ic_module_storage_md2"
app:iconPadding="@dimen/l_50"
tools:layout_width="150dp" />
</layout>

View File

@ -80,6 +80,7 @@
<string name="module_section_remote">Remote</string> <string name="module_section_remote">Remote</string>
<string name="module_state_remove">Remove</string> <string name="module_state_remove">Remove</string>
<string name="module_state_restore">Restore</string> <string name="module_state_restore">Restore</string>
<string name="module_action_install_external">Install from storage</string>
<string name="superuser_toggle_log">Toggles logging</string> <string name="superuser_toggle_log">Toggles logging</string>
<string name="superuser_toggle_notification">Toggles “toast” notifications</string> <string name="superuser_toggle_notification">Toggles “toast” notifications</string>