diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 0000000000..e9c71277e0 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,45 @@ +name: Signed APK Builder + +on: + push: + branches: + - master + - dev + pull_request: + branches: + - master + - dev + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Grant rights + run: chmod +x ./gradlew + + - name: Build project with Gradle + run: ./gradlew build + + - name: Build Release APK with Gradle + run: ./gradlew assembleRelease + + - name: Sign APK + uses: r0adkll/sign-android-release@v1 + id: sign-app + with: + releaseDirectory: app/build/outputs/apk/release + signingKeyBase64: ${{ secrets.TOKEN }} + alias: ${{ secrets.ALIAS }} + keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }} + + - name: Upload to GitHub + uses: actions/upload-artifact@v2 + with: + name: 'Vanced-Manager' + path: ${{ steps.sign-app.outputs.signedReleaseFile }} diff --git a/.github/workflows/debug.yml b/.github/workflows/debug.yml new file mode 100644 index 0000000000..1cb6367c54 --- /dev/null +++ b/.github/workflows/debug.yml @@ -0,0 +1,36 @@ +name: Debug APK Builder + +on: + push: + branches: + - master + - dev + pull_request: + branches: + - master + - dev + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + + - name: Grant rights + run: chmod +x ./gradlew + + - name: Build project with Gradle + run: ./gradlew build + + - name: Build Release APK with Gradle + run: ./gradlew assembleDebug + + - name: Upload to GitHub + uses: actions/upload-artifact@v2 + with: + name: 'Vanced-Manager' + path: app/build/outputs/apk/debug/app-debug.apk diff --git a/.gitignore b/.gitignore index 603b140773..6acf51c6a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,7 @@ -*.iml -.gradle -/local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -/build -/captures -.externalNativeBuild -.cxx +.gradle/ +.idea/ +.github/ +build/ +out/ +app/src/main/java/com/vanced/manager/core/base/DummyJava.java +local.properties diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 88ea3aa1e5..0000000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
- - -
-
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123c2b..0000000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 5cd135a064..0000000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 7bfef59df1..0000000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml deleted file mode 100644 index 7f68460d8b..0000000000 --- a/.idea/runConfigurations.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1ddfbb..0000000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index 353c3b3687..201e0d0225 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,21 @@ -# VancedInstaller -Vanced Installer +# Vanced Manager +Hi, when we released Vanced 15.05.54, people were upset because it used .apks format, which was way harder to install than a traditional .apk file. even tho we wrote clear instructions on how to install new Vanced, people still couldn't figure it out. +Then we thought, why don't we make a manager for vanced, which will download, update and uninstall Vanced and MicroG, have an easy and understandable UI and be less than 5mb. that's how Vanced Manager was born. + +After 3 months of making, we are finally ready to introduce Vanced Manager to you. Vanced manager can easily install and uninstall vanced and microg, has various settings for customisation and better experience. Manager comes with easy-to-use interface, support for background download and installation* +##### *Due to changes in Android Oreo and up, also because of aggressive battery optimisations in some ROMs, feature may not be available for all devices. + +## Vanced Developers +- xfileFIN +- KevinX8 +- Zanezam +- Laura Almeida + +## Vanced Manager Developer +- Xinto (X1nto) + +## Credits +- topjohnwu for his wonderful [LibSU](https://github.com/topjohnwu/libsu) +- Mindorks for their amazing [PRDownloader](https://github.com/MindorksOpenOource/PRDownloader) +- aefyr for [SAI](https://github.com/aefyr/SAI), which was inspiration for our Manager +- 100rabhkr for [GetJson](https://github.com/100rabhkr/getjson) library \ No newline at end of file diff --git a/READMEME.md b/READMEME.md new file mode 100644 index 0000000000..b6afbd3a2c --- /dev/null +++ b/READMEME.md @@ -0,0 +1,42 @@ +![Signed APK Builder](https://github.com/X1nto/VancedInstaller/workflows/Signed%20APK%20Builder/badge.svg?branch=master) + +# Prelude +Hi, my name is Steve Cock, I'm the main developer for the upcoming Vanced Manager. When xfileFIN first published Vanced 15.05.54, people were upset because new Vanced used split apk files. The reason for that was pretty simple: +1) YouTube itself does that +2) Split apk files reduce the size of the downloaded file itself + +No one really thought there would be problems with this format, because installation was pretty simple, at least that's what xfile thought... +## Problems with .apks format +Main problems with new format were either with device CPU architecture or MemeUI shit with MiUI optimisations. We wrote instructions for VancedHelper but no one used it for troubleshooting. Then some users complained about new format and refused to upgrade to newest version (We don't give a fuck about that) because "I dOn'T WaNT To HaVe OnE MoRE apP To insTalL VanCeD" so we decided to make an installer for Vanced +# Vanced Manager +Ladies and gentlemen, I'm very proud to introduce the new **Vancad Manger 1.0.0™** (typo is intentional) +Vanced Manager is an universal utility for installing/updating Vanced and MicroG. It will push notifications once the update is ready (Now that's what I call pwetty epic). +Vanced manager comes with a slick UI ~~that was stolen from the new Magisk Manager (I'm very sorry John but I looked at your code for about 100 times).~~ Actually, while UI may look very similar to new Magisk Manager's UI, It's still very different (that's a blatant lie, I know). + +Main Menu screenshot taken from tablet +![screenshot](https://i.imgur.com/r2jiq7J.png) +Isn't this lovely and beautiful? + +## Manager (clap) Reviews (clap) + +- 1337Potato: shit +- Response: Yes + +- Noobbot: The app is not useful because I have YT Premium. Thank you bye +- Response: I hope you get sucked by a di- + +- Vortextriangle: The app is so useful that I uninstalled it after installing Vanced +- Response: yo that's finna woke + +## Credits +### Vanced Manager developers +- X1nto (UI, UX, Downloader, Installer, Signature Checker, PussiSlayer69, Collector of 400 BAT, Professional Liar) +### The Vanced Team +- xfileFIN +![xfileFIN](https://i.imgur.com/hLdzTVq.png) +- KevinX8 +![KevinX8](https://i.imgur.com/cS9C7P8.png) +- Zanezam +![Zanezam](https://i.imgur.com/QVcXA6q.png) +- Laura Almeida +![Laura Almeida](https://i.imgur.com/ovVD939.png) diff --git a/Vanced Manager.iml b/Vanced Manager.iml new file mode 100644 index 0000000000..30b06914f8 --- /dev/null +++ b/Vanced Manager.iml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/app.iml b/app/app.iml new file mode 100644 index 0000000000..874c5236e8 --- /dev/null +++ b/app/app.iml @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 827fa744ec..ba62862188 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' android { compileSdkVersion 29 @@ -10,25 +11,38 @@ android { applicationId "com.vanced.manager" minSdkVersion 21 targetSdkVersion 29 - versionCode 1 - versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + versionCode 8 + versionName "1.0.0" vectorDrawables.useSupportLibrary = true } + lintOptions { + disable 'MissingTranslation', 'ExtraTranslation' + } + + aaptOptions { + noCompress 'apk', '.apk' + } + + applicationVariants.all { variant -> + variant.resValue "string", "versionName", variant.versionName + } + buildTypes { release { - minifyEnabled false + minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + dataBinding { + enabled = true + } + // To inline the bytecode built with JVM target 1.8 into // bytecode that is being built with JVM target 1.6. (e.g. navArgs) - compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -42,16 +56,18 @@ android { dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'androidx.appcompat:appcompat:1.0.2' - implementation 'androidx.core:core-ktx:1.0.2' - implementation 'com.google.android.material:material:1.0.0' + implementation 'androidx.appcompat:appcompat:1.1.0' + implementation 'androidx.core:core-ktx:1.3.0' + implementation 'androidx.fragment:fragment-ktx:1.2.5' + implementation 'androidx.preference:preference-ktx:1.1.1' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' - implementation 'androidx.navigation:navigation-fragment:2.0.0' - implementation 'androidx.navigation:navigation-ui:2.0.0' - implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0' - implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0' - implementation 'androidx.navigation:navigation-ui-ktx:2.0.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'androidx.browser:browser:1.2.0' + implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' + implementation 'androidx.navigation:navigation-fragment-ktx:2.2.2' + implementation 'androidx.navigation:navigation-ui-ktx:2.2.2' + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'com.google.android.material:material:1.1.0' + implementation 'com.github.100rabhkr:GetJSON:1.0' + implementation 'com.github.topjohnwu.libsu:core:2.5.1' + implementation 'com.mindorks.android:prdownloader:0.6.0' } diff --git a/app/src/androidTest/java/com/vanced/manager/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/vanced/manager/ExampleInstrumentedTest.kt deleted file mode 100644 index 0be9c2b2e3..0000000000 --- a/app/src/androidTest/java/com/vanced/manager/ExampleInstrumentedTest.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.vanced.manager - -import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.ext.junit.runners.AndroidJUnit4 - -import org.junit.Test -import org.junit.runner.RunWith - -import org.junit.Assert.* - -/** - * Instrumented test, which will execute on an Android device. - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -@RunWith(AndroidJUnit4::class) -class ExampleInstrumentedTest { - @Test - fun useAppContext() { - // Context of the app under test. - val appContext = InstrumentationRegistry.getInstrumentation().targetContext - assertEquals("com.vanced.manager", appContext.packageName) - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1887bd3ae8..55350fe611 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,26 +1,70 @@ - + + + + + + + tools:ignore="UnusedAttribute" + tools:replace="android:allowBackup"> + + android:name=".ui.core.SplashScreenActivity" + android:label="@string/app_name" + android:theme="@style/SplashTheme"> + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000..c78215cd29 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/vanced/manager/MainActivity.kt b/app/src/main/java/com/vanced/manager/MainActivity.kt deleted file mode 100644 index 3d57882b66..0000000000 --- a/app/src/main/java/com/vanced/manager/MainActivity.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.vanced.manager - -import android.os.Bundle -import com.google.android.material.bottomnavigation.BottomNavigationView -import androidx.appcompat.app.AppCompatActivity -import androidx.navigation.findNavController -import androidx.navigation.ui.AppBarConfiguration -import androidx.navigation.ui.setupActionBarWithNavController -import androidx.navigation.ui.setupWithNavController - -class MainActivity : AppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_main) - val navView: BottomNavigationView = findViewById(R.id.navigation_home) - - val navController = findNavController(R.id.mobile_navigation) - // Passing each menu ID as a set of Ids because each - // menu should be considered as top level destinations. - val appBarConfiguration = AppBarConfiguration(setOf( - R.id.navigation_home)) - setupActionBarWithNavController(navController, appBarConfiguration) - navView.setupWithNavController(navController) - } -} diff --git a/app/src/main/java/com/vanced/manager/adapter/SectionPageAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/SectionPageAdapter.kt new file mode 100644 index 0000000000..134c86cb42 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/SectionPageAdapter.kt @@ -0,0 +1,26 @@ +package com.vanced.manager.adapter + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.vanced.manager.ui.fragments.ManagerChangelogFragment +import com.vanced.manager.ui.fragments.MicrogChangelogFragment +import com.vanced.manager.ui.fragments.VancedChangelogFragment + +class SectionPageAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { + + private val fragmentItems = 3 + override fun getItemCount(): Int { + return fragmentItems + } + + override fun createFragment(position: Int): Fragment { + var fragment: Fragment? = null + when (position) { + 0 -> fragment = VancedChangelogFragment() + 1 -> fragment = MicrogChangelogFragment() + 2 -> fragment = ManagerChangelogFragment() + } + return fragment!! + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/adapter/SectionPageRootAdapter.kt b/app/src/main/java/com/vanced/manager/adapter/SectionPageRootAdapter.kt new file mode 100644 index 0000000000..ec7b1e4e49 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/adapter/SectionPageRootAdapter.kt @@ -0,0 +1,24 @@ +package com.vanced.manager.adapter + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter +import com.vanced.manager.ui.fragments.ManagerChangelogFragment +import com.vanced.manager.ui.fragments.VancedChangelogFragment + +class SectionPageRootAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { + + private val fragmentItems = 2 + override fun getItemCount(): Int { + return fragmentItems + } + + override fun createFragment(position: Int): Fragment { + var fragment: Fragment? = null + when (position) { + 0 -> fragment = VancedChangelogFragment() + 1 -> fragment = ManagerChangelogFragment() + } + return fragment!! + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/App.kt b/app/src/main/java/com/vanced/manager/core/App.kt new file mode 100644 index 0000000000..e0dcf9a7b9 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/App.kt @@ -0,0 +1,15 @@ +package com.vanced.manager.core + +import android.app.Application +import com.downloader.PRDownloader +import com.vanced.manager.utils.NotificationHelper.createNotifChannel + +class App: Application() { + + override fun onCreate() { + super.onCreate() + PRDownloader.initialize(applicationContext) + createNotifChannel(this) + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/Main.kt b/app/src/main/java/com/vanced/manager/core/Main.kt new file mode 100644 index 0000000000..0b9a854c14 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/Main.kt @@ -0,0 +1,64 @@ +package com.vanced.manager.core + +import android.annotation.SuppressLint +import android.content.Context +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.preference.PreferenceManager +import com.dezlum.codelabs.getjson.GetJson +import com.vanced.manager.ui.dialogs.DialogContainer.showSecurityDialog +import com.vanced.manager.ui.dialogs.DialogContainer.statementFalse +import com.vanced.manager.ui.fragments.UpdateCheckFragment +import com.vanced.manager.utils.InternetTools +import com.vanced.manager.R +import com.vanced.manager.ui.dialogs.DialogContainer.secondMiuiDialog +import com.vanced.manager.ui.dialogs.DialogContainer.showRootDialog +import com.vanced.manager.utils.MiuiHelper.isMiui +import com.vanced.manager.utils.MiuiHelper.isMiuiOptimisationsDisabled + +// This activity will NOT be used in manifest +// since MainActivity will extend it +@SuppressLint("Registered") +open class Main: AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + checkUpdates() + + val prefs = PreferenceManager.getDefaultSharedPreferences(this) + val firstStart = prefs.getBoolean("firstStart", true) + val isUpgrading = prefs.getBoolean("isUpgrading", false) + val variant = prefs.getString("vanced_variant", "nonroot") + val shouldShowRootDialog = prefs.getBoolean("show_root_dialog", true) + + val falseStatement = prefs.getBoolean("statement", true) + + when { + firstStart -> showSecurityDialog(this) + !falseStatement -> statementFalse(this) + isUpgrading -> prefs.edit().putBoolean("isUpgrading", false).apply() + variant == "root" && shouldShowRootDialog -> showRootDialog(this) + !firstStart && !isMiuiOptimisationsDisabled() -> secondMiuiDialog(this) + } + + } + + override fun onPause() { + getSharedPreferences("installPrefs", Context.MODE_PRIVATE).edit().putBoolean("isInstalling", false).apply() + getSharedPreferences("installPrefs", Context.MODE_PRIVATE).edit().putBoolean("isVancedDownloading", false).apply() + getSharedPreferences("installPrefs", Context.MODE_PRIVATE).edit().putBoolean("isMicrogDownloading", false).apply() + super.onPause() + } + + private fun checkUpdates() { + val checkPrefs = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("auto_check_update", false) + if (checkPrefs) { + if (GetJson().isConnected(this) && InternetTools.isUpdateAvailable()) { + UpdateCheckFragment().show(supportFragmentManager, "Update") + } else Toast.makeText(this, getString(R.string.update_notfound), Toast.LENGTH_SHORT).show() + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/base/BaseFragment.kt b/app/src/main/java/com/vanced/manager/core/base/BaseFragment.kt new file mode 100644 index 0000000000..1bcd46fbd0 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/base/BaseFragment.kt @@ -0,0 +1,7 @@ +package com.vanced.manager.core.base + +import androidx.fragment.app.Fragment + +open class BaseFragment : Fragment() { + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloadService.kt b/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloadService.kt new file mode 100644 index 0000000000..b2f49440c2 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/downloader/MicrogDownloadService.kt @@ -0,0 +1,84 @@ +package com.vanced.manager.core.downloader + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.IBinder +import android.widget.Toast +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.dezlum.codelabs.getjson.GetJson +import com.downloader.Error +import com.downloader.OnDownloadListener +import com.downloader.OnStartOrResumeListener +import com.downloader.PRDownloader +import com.vanced.manager.R +import com.vanced.manager.core.installer.AppInstaller +import com.vanced.manager.ui.fragments.HomeFragment +import com.vanced.manager.utils.InternetTools.getFileNameFromUrl +import com.vanced.manager.utils.NotificationHelper +import com.vanced.manager.utils.NotificationHelper.cancelNotif +import com.vanced.manager.utils.NotificationHelper.createBasicNotif +import java.util.concurrent.ExecutionException + +class MicrogDownloadService: Service() { + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + try { + downloadMicrog() + } catch (e: Exception) { + when (e) { + is ExecutionException, is InterruptedException -> Toast.makeText(this, "Unable to download Vanced", Toast.LENGTH_SHORT).show() + else -> throw e + } + } + stopSelf() + return START_NOT_STICKY + } + + private fun downloadMicrog() { + val prefs = getSharedPreferences("installPrefs", Context.MODE_PRIVATE) + + val apkUrl = GetJson().AsJSONObject("https://x1nto.github.io/VancedFiles/microg.json") + val dwnldUrl = apkUrl.get("url").asString + val channel = 420 + PRDownloader.download(dwnldUrl, filesDir.path, "microg.apk") + .build() + .setOnStartOrResumeListener { OnStartOrResumeListener { prefs?.edit()?.putBoolean("isMicrogDownloading", true)?.apply() } } + .setOnProgressListener { progress -> + val mProgress = progress.currentBytes * 100 / progress.totalBytes + NotificationHelper.displayDownloadNotif( + channel, + mProgress.toInt(), + getFileNameFromUrl(dwnldUrl), + this + ) + } + .start(object : OnDownloadListener { + override fun onDownloadComplete() { + prefs?.edit()?.putBoolean("isMicrogDownloading", false)?.apply() + cancelNotif(channel, this@MicrogDownloadService) + val intent = Intent(this@MicrogDownloadService, AppInstaller::class.java) + intent.putExtra("path", "${filesDir.path}/microg.apk") + intent.putExtra("pkg", "com.mgoogle.android.gms") + val mIntent = Intent(HomeFragment.MICROG_DOWNLOADED) + mIntent.action = HomeFragment.MICROG_DOWNLOADED + LocalBroadcastManager.getInstance(this@MicrogDownloadService).sendBroadcast(mIntent) + startService(intent) + } + override fun onError(error: Error) { + prefs?.edit()?.putBoolean("isMicrogDownloading", false)?.apply() + createBasicNotif(getString(R.string.error_downloading, "Microg"), channel, this@MicrogDownloadService) + } + }) + } + + override fun onDestroy() { + super.onDestroy() + cancelNotif(420, this) + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt new file mode 100644 index 0000000000..d03becc4e4 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/downloader/VancedDownloadService.kt @@ -0,0 +1,121 @@ +package com.vanced.manager.core.downloader + +import android.app.Service +import android.content.Context +import android.content.Intent +import android.os.Build +import android.os.IBinder +import android.widget.Toast +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import androidx.preference.PreferenceManager +import com.dezlum.codelabs.getjson.GetJson +import com.downloader.Error +import com.downloader.OnDownloadListener +import com.downloader.OnStartOrResumeListener +import com.downloader.PRDownloader +import com.vanced.manager.R +import com.vanced.manager.core.installer.RootSplitInstallerService +import com.vanced.manager.core.installer.SplitInstaller +import com.vanced.manager.ui.fragments.HomeFragment +import com.vanced.manager.utils.InternetTools.baseUrl +import com.vanced.manager.utils.InternetTools.getFileNameFromUrl +import com.vanced.manager.utils.NotificationHelper.cancelNotif +import com.vanced.manager.utils.NotificationHelper.createBasicNotif +import com.vanced.manager.utils.NotificationHelper.displayDownloadNotif +import java.util.concurrent.ExecutionException + +class VancedDownloadService: Service() { + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + try { + downloadSplits() + } catch (e: Exception) { + when (e) { + is ExecutionException, is InterruptedException -> Toast.makeText(this, "Unable to download Vanced", Toast.LENGTH_SHORT).show() + else -> throw e + } + + } + stopSelf() + return START_NOT_STICKY + } + + private fun downloadSplits( + type: String = "arch" + ) { + val baseUrl = PreferenceManager.getDefaultSharedPreferences(this).getString("install_url", baseUrl) + val vancedVer = GetJson().AsJSONObject("https://x1nto.github.io/VancedFiles/vanced.json").get("version").asString + val prefs = getSharedPreferences("installPrefs", Context.MODE_PRIVATE) + val variant = PreferenceManager.getDefaultSharedPreferences(this).getString("vanced_variant", "nonroot") + val lang = prefs?.getString("lang", "en") + val theme = prefs?.getString("theme", "dark") + val arch = + when { + Build.SUPPORTED_ABIS.contains("x86") -> "x86" + Build.SUPPORTED_ABIS.contains("arm64-v8a") -> "arm64_v8a" + else -> "armeabi_v7a" + } + val url = + when (type) { + "arch" -> "$baseUrl/apks/v$vancedVer/$variant/Config/config.$arch.apk" + "theme" -> "$baseUrl/apks/v$vancedVer/$variant/Theme/$theme.apk" + "lang" -> "$baseUrl/apks/v$vancedVer/$variant/Language/split_config.$lang.apk" + "enlang" -> "$baseUrl/apks/v$vancedVer/$variant/Language/split_config.en.apk" + else -> throw NotImplementedError("This type of APK is NOT valid. What the hell did you even do?") + } + + val channel = 69 + PRDownloader + .download(url, cacheDir.path, getFileNameFromUrl(url)) + .build() + .setOnStartOrResumeListener { OnStartOrResumeListener { prefs?.edit()?.putBoolean("isVancedDownloading", true)?.apply() } } + .setOnProgressListener { progress -> + val mProgress = progress.currentBytes * 100 / progress.totalBytes + displayDownloadNotif(channel, mProgress.toInt(), getFileNameFromUrl(url), this) + } + .start(object : OnDownloadListener { + override fun onDownloadComplete() { + when (type) { + "arch" -> downloadSplits("theme") + "theme" -> downloadSplits("lang") + "lang" -> { + if (lang == "en") { + prepareInstall(variant!!) + cancelNotif(channel, this@VancedDownloadService) + } else { + downloadSplits("enlang") + } + } + "enlang" -> { + prepareInstall(variant!!) + cancelNotif(channel, this@VancedDownloadService) + } + } + } + + override fun onError(error: Error) { + createBasicNotif(getString(R.string.error_downloading, "Vanced"), channel, this@VancedDownloadService) + } + }) + } + + private fun prepareInstall(variant: String) { + val intent = Intent(HomeFragment.VANCED_DOWNLOADED) + intent.action = HomeFragment.VANCED_DOWNLOADED + LocalBroadcastManager.getInstance(this).sendBroadcast(intent) + if (variant == "root") + startService(Intent(this, RootSplitInstallerService::class.java)) + else + startService(Intent(this, SplitInstaller::class.java)) + } + + override fun onDestroy() { + super.onDestroy() + cancelNotif(69, this) + } + + override fun onBind(intent: Intent?): IBinder? { + return null + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/fragments/About.kt b/app/src/main/java/com/vanced/manager/core/fragments/About.kt new file mode 100644 index 0000000000..9d470173dd --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/fragments/About.kt @@ -0,0 +1,48 @@ +package com.vanced.manager.core.fragments + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.MotionEvent +import android.view.View +import android.widget.Toast +import androidx.preference.PreferenceManager +import com.vanced.manager.core.base.BaseFragment + +open class About : BaseFragment() { + + private var count = 0 + private var startMillSec: Long = 0 + + @SuppressLint("ClickableViewAccessibility") + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + view.setOnTouchListener { _, event: MotionEvent -> + + val eventAction = event.action + if (eventAction == MotionEvent.ACTION_UP) { + val time = System.currentTimeMillis() + if (startMillSec == 0L || time - startMillSec > 3000) { + startMillSec = time + count = 1 + } else { + count++ + } + + if (count == 5) { + val prefs = PreferenceManager.getDefaultSharedPreferences(requireContext()) + val devSettings = prefs.getBoolean("devSettings", false) + if (!devSettings) { + Toast.makeText(requireContext(), "Dev options unlocked!", Toast.LENGTH_SHORT).show() + prefs.edit().putBoolean("devSettings", true).apply() + } else + Toast.makeText(requireContext(), "Dev options already unlocked", Toast.LENGTH_SHORT).show() + + } + return@setOnTouchListener true + } + false + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/fragments/Home.kt b/app/src/main/java/com/vanced/manager/core/fragments/Home.kt new file mode 100644 index 0000000000..c4be33fa40 --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/fragments/Home.kt @@ -0,0 +1,127 @@ +package com.vanced.manager.core.fragments + +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.View +import android.widget.* +import androidx.navigation.findNavController +import androidx.preference.PreferenceManager +import androidx.preference.PreferenceManager.getDefaultSharedPreferences +import com.google.android.material.button.MaterialButton +import com.topjohnwu.superuser.Shell +import com.vanced.manager.R +import com.vanced.manager.core.base.BaseFragment +import com.vanced.manager.core.downloader.MicrogDownloadService +import com.vanced.manager.core.downloader.VancedDownloadService +import com.vanced.manager.ui.MainActivity +import com.vanced.manager.ui.dialogs.DialogContainer.secondMiuiDialog +import com.vanced.manager.utils.MiuiHelper +import com.vanced.manager.utils.PackageHelper.uninstallApk + +open class Home : BaseFragment(), View.OnClickListener { + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val microginstallbtn = view.findViewById(R.id.microg_installbtn) + val vancedinstallbtn = view.findViewById(R.id.vanced_installbtn) + val microguninstallbtn = view.findViewById(R.id.microg_uninstallbtn) + val vanceduninstallbtn = view.findViewById(R.id.vanced_uninstallbtn) + val rootswitch = view.findViewById(R.id.root_switch) + val nonrootswitch = view.findViewById(R.id.nonroot_switch) + + vancedinstallbtn.setOnClickListener(this) + microginstallbtn.setOnClickListener(this) + microguninstallbtn.setOnClickListener(this) + vanceduninstallbtn.setOnClickListener(this) + rootswitch.setOnClickListener(this) + nonrootswitch.setOnClickListener(this) + + } + + override fun onResume() { + super.onResume() + val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE) + val isInstalling = prefs?.getBoolean("isInstalling", false) + if (isInstalling!!) { + activity?.startService(Intent(activity, VancedDownloadService::class.java)) + prefs.edit().putBoolean("isInstalling", false).apply() + } + } + + override fun onClick(v: View?) { + val prefs = activity?.getSharedPreferences("installPrefs", Context.MODE_PRIVATE) + val defPrefs = getDefaultSharedPreferences(activity) + val isVancedDownloading: Boolean? = prefs?.getBoolean("isVancedDownloading", false) + val isMicrogDownloading: Boolean? = prefs?.getBoolean("isMicrogDownloading", false) + val variant = getDefaultSharedPreferences(activity).getString("vanced_variant", "nonroot") + val vancedPkgName = + if (variant == "root") { + "com.google.android.youtube" + } else { + "com.vanced.android.youtube" + } + + when (v?.id) { + R.id.vanced_installbtn -> { + if (!isVancedDownloading!!) { + try { + activity?.cacheDir?.deleteRecursively() + } catch (e: Exception) { + Log.d("VMCache", "Unable to delete cacheDir") + } + if (prefs.getBoolean("valuesModified", false)) { + activity?.startService( + Intent( + activity, + VancedDownloadService::class.java + ) + ) + } else { + view?.findNavController()?.navigate(R.id.toInstallThemeFragment) + } + } else { + Toast.makeText( + activity, + "Please wait until installation finishes", + Toast.LENGTH_SHORT + ).show() + } + } + R.id.microg_installbtn -> { + if (!isMicrogDownloading!!) { + try { + activity?.startService(Intent(activity, MicrogDownloadService::class.java)) + } catch (e: Exception) { + Toast.makeText(activity, "Unable to start installation", Toast.LENGTH_SHORT).show() + } + } else { + Toast.makeText(activity, "Please wait until installation finishes", Toast.LENGTH_SHORT).show() + } + } + R.id.microg_uninstallbtn -> activity?.let { uninstallApk("com.mgoogle.android.gms", it) } + R.id.vanced_uninstallbtn -> activity?.let { uninstallApk(vancedPkgName, it) } + R.id.nonroot_switch -> writeToVariantPref("nonroot", R.anim.slide_in_left, R.anim.slide_out_right) + R.id.root_switch -> + if (Shell.rootAccess()) + writeToVariantPref("root", R.anim.slide_in_right, R.anim.slide_out_left) + else { + writeToVariantPref("nonroot", R.anim.slide_in_left, R.anim.slide_out_right) + Toast.makeText(activity, "Root access not granted", Toast.LENGTH_SHORT).show() + } + } + } + + private fun writeToVariantPref(variant: String, animIn: Int, animOut: Int) { + val prefs = getDefaultSharedPreferences(activity) + if (prefs.getString("vanced_variant", "nonroot") != variant) { + prefs.edit().putString("vanced_variant", variant).apply() + startActivity(Intent(activity, MainActivity::class.java)) + activity?.overridePendingTransition(animIn, animOut) + activity?.finish() + } else Log.d("VMvariant", "$variant is already selected") + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/vanced/manager/core/fragments/LanguageInstall.kt b/app/src/main/java/com/vanced/manager/core/fragments/LanguageInstall.kt new file mode 100644 index 0000000000..db7616b64f --- /dev/null +++ b/app/src/main/java/com/vanced/manager/core/fragments/LanguageInstall.kt @@ -0,0 +1,37 @@ +package com.vanced.manager.core.fragments + +import android.content.Context +import android.os.Bundle +import android.view.View +import android.widget.Button +import android.widget.RadioButton +import android.widget.RadioGroup +import androidx.navigation.findNavController +import com.vanced.manager.R +import com.vanced.manager.core.base.BaseFragment + +open class LanguageInstall : BaseFragment() { + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val finishButton = view.findViewById