mirror of
https://github.com/YTVanced/VancedManager
synced 2024-11-23 11:45:11 +00:00
new services
This commit is contained in:
parent
f804344824
commit
8c2dc882cf
12 changed files with 171 additions and 70 deletions
|
@ -61,6 +61,7 @@
|
|||
<service android:name=".core.installer.StubInstaller" />
|
||||
<service android:name=".core.installer.RootAppUninstaller" />
|
||||
<service android:name=".core.installer.AppUninstallerService" />
|
||||
<service android:name=".core.installer.AppInstallerService" />
|
||||
<service android:name=".core.downloader.VancedDownloadService" />
|
||||
<service android:name=".core.downloader.MicrogDownloadService" />
|
||||
|
||||
|
|
|
@ -4,9 +4,4 @@ import androidx.fragment.app.Fragment
|
|||
|
||||
open class BaseFragment : Fragment() {
|
||||
|
||||
companion object {
|
||||
const val APP_UNINSTALL = 69
|
||||
const val MICROG_INSTALL = 420
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,33 @@
|
|||
package com.vanced.manager.core.base;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageInstaller;
|
||||
|
||||
import com.vanced.manager.core.installer.AppUninstallerService;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class DummyJava {
|
||||
|
||||
public static void installApp(Activity activity, InputStream in, String pkg) throws IOException {
|
||||
PackageInstaller packageInstaller = activity.getPackageManager().getPackageInstaller();
|
||||
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(PackageInstaller.SessionParams.MODE_FULL_INSTALL);
|
||||
params.setAppPackageName(pkg);
|
||||
int sessionId = packageInstaller.createSession(params);
|
||||
PackageInstaller.Session session = packageInstaller.openSession(sessionId);
|
||||
OutputStream outputStream = session.openWrite("install", 0, -1);
|
||||
byte[] buffer = new byte[65536];
|
||||
int c;
|
||||
while ((c = in.read(buffer)) != -1) {
|
||||
outputStream.write(buffer, 0, c);
|
||||
}
|
||||
session.fsync(outputStream);
|
||||
in.close();
|
||||
outputStream.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
package com.vanced.manager.core.installer
|
||||
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.Nullable
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.ui.MainActivity
|
||||
|
||||
class AppInstallerService: Service() {
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
when (intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_PENDING_USER_ACTION -> {
|
||||
Toast.makeText(this, "Installing...", Toast.LENGTH_SHORT).show()
|
||||
Log.d(TAG, "Requesting user confirmation for installation")
|
||||
val confirmationIntent = intent.getParcelableExtra<Intent>(Intent.EXTRA_INTENT)
|
||||
confirmationIntent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
try {
|
||||
startActivity(confirmationIntent)
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
Log.d(TAG, "Installation succeed")
|
||||
getSharedPreferences("installPrefs", Context.MODE_PRIVATE).edit().putBoolean("isInstalling", false).apply()
|
||||
val mIntent = Intent(MainActivity.INSTALL_COMPLETED)
|
||||
mIntent.action = MainActivity.INSTALL_COMPLETED
|
||||
mIntent.putExtra("package", "normal")
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(mIntent)
|
||||
}
|
||||
else -> sendFailure(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999))
|
||||
}
|
||||
stopSelf()
|
||||
return START_NOT_STICKY
|
||||
}
|
||||
|
||||
private fun sendFailure(status: Int) {
|
||||
val msg = when (status) {
|
||||
PackageInstaller.STATUS_FAILURE_ABORTED -> getString(R.string.installation_aborted)
|
||||
PackageInstaller.STATUS_FAILURE_BLOCKED -> getString(R.string.installation_blocked)
|
||||
PackageInstaller.STATUS_FAILURE_STORAGE -> getString(R.string.installation_storage)
|
||||
PackageInstaller.STATUS_FAILURE_INVALID -> getString(R.string.installation_invalid)
|
||||
PackageInstaller.STATUS_FAILURE_INCOMPATIBLE -> getString(R.string.installation_incompatible)
|
||||
PackageInstaller.STATUS_FAILURE_CONFLICT -> getString(R.string.installation_conflict)
|
||||
else -> getString(R.string.installation_failed)
|
||||
}
|
||||
|
||||
val mIntent = Intent(MainActivity.INSTALL_FAILED)
|
||||
mIntent.action = MainActivity.INSTALL_FAILED
|
||||
mIntent.putExtra("errorMsg", msg)
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(mIntent)
|
||||
}
|
||||
|
||||
@Nullable
|
||||
override fun onBind(intent: Intent?): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
companion object{
|
||||
const val TAG = "VMInstall"
|
||||
}
|
||||
|
||||
}
|
|
@ -4,19 +4,21 @@ import android.app.Service
|
|||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.vanced.manager.ui.fragments.HomeFragment
|
||||
import com.vanced.manager.ui.MainActivity
|
||||
|
||||
class AppUninstallerService: Service() {
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
when (intent?.getIntExtra(PackageInstaller.EXTRA_STATUS, -999)) {
|
||||
PackageInstaller.STATUS_SUCCESS -> {
|
||||
sendBroadCast(HomeFragment.APP_UNINSTALLED)
|
||||
|
||||
sendBroadCast(MainActivity.APP_UNINSTALLED)
|
||||
Log.d("VMpm", "Successfully uninstalled ${PackageInstaller.EXTRA_PACKAGE_NAME}")
|
||||
}
|
||||
PackageInstaller.STATUS_FAILURE -> {
|
||||
sendBroadCast(HomeFragment.APP_NOT_UNINSTALLED)
|
||||
sendBroadCast(MainActivity.APP_NOT_UNINSTALLED)
|
||||
Log.d("VMpm", "Failed to uninstall ${PackageInstaller.EXTRA_PACKAGE_NAME}")
|
||||
}
|
||||
}
|
||||
return START_NOT_STICKY
|
||||
|
|
|
@ -11,6 +11,7 @@ import androidx.annotation.Nullable
|
|||
import androidx.annotation.WorkerThread
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.topjohnwu.superuser.Shell
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.ui.MainActivity
|
||||
import com.vanced.manager.utils.FileInfo
|
||||
import java.io.File
|
||||
|
@ -75,10 +76,12 @@ class RootSplitInstallerService: Service() {
|
|||
if (installResult.isSuccess) {
|
||||
val mIntent = Intent(MainActivity.INSTALL_COMPLETED)
|
||||
mIntent.action = MainActivity.INSTALL_COMPLETED
|
||||
mIntent.putExtra("package", "split")
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(mIntent)
|
||||
} else {
|
||||
val mIntent = Intent(MainActivity.INSTALL_FAILED)
|
||||
mIntent.action = MainActivity.INSTALL_FAILED
|
||||
mIntent.putExtra("errorMsg", getString(R.string.installation_failed))
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(mIntent)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ class SplitInstallerService: Service() {
|
|||
getSharedPreferences("installPrefs", Context.MODE_PRIVATE).edit().putBoolean("isInstalling", false).apply()
|
||||
val mIntent = Intent(MainActivity.INSTALL_COMPLETED)
|
||||
mIntent.action = MainActivity.INSTALL_COMPLETED
|
||||
mIntent.putExtra("package", "split")
|
||||
LocalBroadcastManager.getInstance(this).sendBroadcast(mIntent)
|
||||
}
|
||||
else -> sendFailure(intent.getIntExtra(PackageInstaller.EXTRA_STATUS, -999))
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.vanced.manager.ui
|
|||
|
||||
import android.content.*
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.databinding.DataBindingUtil
|
||||
|
@ -16,6 +17,7 @@ import com.vanced.manager.core.Main
|
|||
import com.vanced.manager.databinding.ActivityMainBinding
|
||||
import com.vanced.manager.ui.dialogs.DialogContainer.installAlertBuilder
|
||||
import com.vanced.manager.ui.dialogs.DialogContainer.launchVanced
|
||||
import com.vanced.manager.ui.fragments.HomeFragment
|
||||
import com.vanced.manager.utils.ThemeHelper.setFinalTheme
|
||||
|
||||
class MainActivity : Main() {
|
||||
|
@ -54,10 +56,15 @@ class MainActivity : Main() {
|
|||
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
when (intent.action) {
|
||||
INSTALL_COMPLETED -> launchVanced(this@MainActivity)
|
||||
INSTALL_FAILED -> {
|
||||
installAlertBuilder(intent.getStringExtra("errorMsg") as String, this@MainActivity)
|
||||
INSTALL_COMPLETED -> {
|
||||
if (intent.getStringExtra("package") == "split")
|
||||
launchVanced(this@MainActivity)
|
||||
else
|
||||
installAlertBuilder(getString(R.string.microg_installed), this@MainActivity)
|
||||
}
|
||||
INSTALL_FAILED -> installAlertBuilder(intent.getStringExtra("errorMsg") as String, this@MainActivity)
|
||||
APP_UNINSTALLED -> restartActivity()
|
||||
APP_NOT_UNINSTALLED -> installAlertBuilder(getString(R.string.failed_uninstall) + intent.getStringExtra("pkgName"), this@MainActivity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,8 +136,15 @@ class MainActivity : Main() {
|
|||
|
||||
}
|
||||
|
||||
private fun restartActivity() {
|
||||
startActivity(Intent(this, MainActivity::class.java))
|
||||
finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val INSTALL_COMPLETED = "Installation completed"
|
||||
const val INSTALL_FAILED = "it just failed idk"
|
||||
const val APP_UNINSTALLED = "App uninstalled"
|
||||
const val APP_NOT_UNINSTALLED = "App not uninstalled"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,10 +35,13 @@ import com.vanced.manager.core.installer.RootAppUninstaller
|
|||
import com.vanced.manager.databinding.FragmentHomeBinding
|
||||
import com.vanced.manager.ui.MainActivity
|
||||
import com.vanced.manager.ui.viewmodels.HomeViewModel
|
||||
import com.vanced.manager.utils.PackageHelper.installApp
|
||||
import com.vanced.manager.utils.PackageHelper.isPackageInstalled
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
|
||||
class HomeFragment : Home() {
|
||||
|
||||
|
@ -227,21 +230,6 @@ class HomeFragment : Home() {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
val tag = "VMpm"
|
||||
when (requestCode) {
|
||||
MICROG_INSTALL -> {
|
||||
Log.d(tag, "Microg install status: $resultCode")
|
||||
restartActivity()
|
||||
}
|
||||
APP_UNINSTALL -> {
|
||||
Log.d(tag, "App uninstall status: $resultCode")
|
||||
restartActivity()
|
||||
}
|
||||
}
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
}
|
||||
|
||||
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
val viewModel: HomeViewModel by viewModels()
|
||||
|
@ -284,7 +272,7 @@ class HomeFragment : Home() {
|
|||
MICROG_DOWNLOADED -> {
|
||||
view?.findViewById<TextView>(R.id.microg_downloading)?.visibility = View.GONE
|
||||
view?.findViewById<ProgressBar>(R.id.microg_progress)?.visibility = View.GONE
|
||||
activity?.let { installMicrog(it) }
|
||||
activity?.let { installApp(it, it.filesDir.path + "/microg.apk", "com.mgoogle.android.gms") }
|
||||
}
|
||||
VANCED_DOWNLOADED -> {
|
||||
view?.findViewById<TextView>(R.id.vanced_downloading)?.visibility = View.GONE
|
||||
|
@ -296,15 +284,6 @@ class HomeFragment : Home() {
|
|||
Toast.makeText(activity, error, Toast.LENGTH_SHORT).show()
|
||||
Log.d("VMDwnld", error)
|
||||
}
|
||||
APP_UNINSTALLED -> {
|
||||
val pkgName = intent.getStringExtra("pkgName")
|
||||
restartActivity()
|
||||
Log.d(tag, "successfully uninstalled $pkgName")
|
||||
}
|
||||
APP_NOT_UNINSTALLED -> {
|
||||
val pkgName = intent.getStringExtra("pkgName")
|
||||
Log.d(tag, "Failed to uninstall $pkgName")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -351,18 +330,6 @@ class HomeFragment : Home() {
|
|||
)
|
||||
)
|
||||
}
|
||||
activity?.let {
|
||||
LocalBroadcastManager.getInstance(it).registerReceiver(broadcastReceiver, IntentFilter(
|
||||
APP_UNINSTALLED
|
||||
)
|
||||
)
|
||||
}
|
||||
activity?.let {
|
||||
LocalBroadcastManager.getInstance(it).registerReceiver(broadcastReceiver, IntentFilter(
|
||||
APP_NOT_UNINSTALLED
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -409,11 +376,6 @@ class HomeFragment : Home() {
|
|||
vancedinstallbtn?.icon = null
|
||||
}
|
||||
|
||||
private fun restartActivity() {
|
||||
startActivity(Intent(activity, MainActivity::class.java))
|
||||
activity?.finish()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SIGNATURE_DISABLED = "Signature verification disabled"
|
||||
const val SIGNATURE_ENABLED = "Signature verification enabled"
|
||||
|
@ -422,8 +384,6 @@ class HomeFragment : Home() {
|
|||
const val VANCED_DOWNLOADED = "Vanced downloaded"
|
||||
const val MICROG_DOWNLOADED = "MicroG downloaded"
|
||||
const val DOWNLOAD_ERROR = "Error occurred"
|
||||
const val APP_UNINSTALLED = "App uninstalled"
|
||||
const val APP_NOT_UNINSTALLED = "App not uninstalled"
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@ import com.downloader.PRDownloader
|
|||
import com.vanced.manager.BuildConfig
|
||||
|
||||
import com.vanced.manager.R
|
||||
import com.vanced.manager.utils.PackageHelper.installApp
|
||||
import io.reactivex.disposables.Disposable
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
|
||||
class UpdateCheckFragment : DialogFragment() {
|
||||
|
||||
|
@ -91,18 +93,12 @@ class UpdateCheckFragment : DialogFragment() {
|
|||
prefs.getBoolean("isUpgrading", false)
|
||||
prefs.edit().putBoolean("isUpgrading", true).apply()
|
||||
|
||||
val pn = activity?.packageName
|
||||
val apk = File(activity?.filesDir?.path, "manager.apk")
|
||||
val uri =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
FileProvider.getUriForFile(requireContext(), "$pn.provider", apk)
|
||||
} else
|
||||
Uri.fromFile(apk)
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.setDataAndType(uri, "application/vnd.android.package-archive")
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
startActivity(intent)
|
||||
activity?.let {
|
||||
installApp(
|
||||
it,
|
||||
it.filesDir.path + "/microg.apk",
|
||||
"com.vanced.manager")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(error: Error?) {
|
||||
|
|
|
@ -3,8 +3,12 @@ package com.vanced.manager.utils
|
|||
import android.app.Activity
|
||||
import android.app.PendingIntent
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageInstaller.SessionParams
|
||||
import android.content.pm.PackageManager
|
||||
import com.vanced.manager.core.installer.SplitInstallerService
|
||||
import com.vanced.manager.core.installer.AppUninstallerService
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
object PackageHelper {
|
||||
|
||||
|
@ -17,8 +21,35 @@ object PackageHelper {
|
|||
}
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
fun installApp(
|
||||
activity: Activity,
|
||||
path: String,
|
||||
pkg: String?
|
||||
) {
|
||||
val callbackIntent = Intent(activity.applicationContext, AppUninstallerService::class.java)
|
||||
val pendingIntent = PendingIntent.getService(activity.applicationContext, 0, callbackIntent, 0)
|
||||
val packageInstaller = activity.packageManager.packageInstaller
|
||||
val params = SessionParams(SessionParams.MODE_FULL_INSTALL)
|
||||
params.setAppPackageName(pkg)
|
||||
val sessionId = packageInstaller.createSession(params)
|
||||
val session = packageInstaller.openSession(sessionId)
|
||||
val inputStream = FileInputStream(path)
|
||||
val outputStream = session.openWrite("install", 0, -1)
|
||||
val buffer = ByteArray(65536)
|
||||
var c: Int
|
||||
while (inputStream.read(buffer).also { c = it } != -1) {
|
||||
outputStream.write(buffer, 0, c)
|
||||
}
|
||||
session.fsync(outputStream)
|
||||
inputStream.close()
|
||||
outputStream.close()
|
||||
session.commit(pendingIntent.intentSender)
|
||||
}
|
||||
|
||||
|
||||
fun uninstallApk(pkg: String, activity: Activity) {
|
||||
val callbackIntent = Intent(activity.applicationContext, SplitInstallerService::class.java)
|
||||
val callbackIntent = Intent(activity.applicationContext, AppUninstallerService::class.java)
|
||||
val pendingIntent = PendingIntent.getService(activity.applicationContext, 0, callbackIntent, 0)
|
||||
activity.packageManager.packageInstaller.uninstall(pkg, pendingIntent.intentSender)
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<!-- Home Page -->
|
||||
<string name="changelogs">Changelogs</string>
|
||||
<string name="check">Check</string>
|
||||
<string name="failed_uninstall">Failed to uninstall package: </string>
|
||||
<string name="install">Install</string>
|
||||
<string name="installation_aborted">Operation failed because user aborted installation</string>
|
||||
<string name="installation_blocked">Operation failed because user blocked installation</string>
|
||||
|
@ -27,6 +28,7 @@
|
|||
<string name="version_installed">Installed:</string>
|
||||
<string name="latest">Latest:</string>
|
||||
<string name="loading">Loading…</string>
|
||||
<string name="microg_installed">MicroG successfully installed</string>
|
||||
<string name="network_error">Network connection unavailable</string>
|
||||
<string name="no_microg">No Microg!</string>
|
||||
<string name="unavailable">Unavailable</string>
|
||||
|
|
Loading…
Reference in a new issue