Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ android {
targetSdk = 35
versionCode = 24
versionName = "7.2.0"
setProperty("archivesBaseName", "Iconify v${defaultConfig.versionName}")
setProperty("archivesBaseName", "Iconify Vivo Safe v${defaultConfig.versionName}")
buildConfigField("int", "MIN_SDK_VERSION", "$minSdk")
buildConfigField("boolean", "VIVO_SAFE_MODE", "true")

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
Expand Down Expand Up @@ -51,7 +52,7 @@ android {
isCrunchPngs = false
proguardFiles("proguard-android-optimize.txt", "proguard.pro", "proguard-rules.pro")
applicationIdSuffix = ".debug"
resValue("string", "derived_app_name", "Iconify (Debug)")
resValue("string", "derived_app_name", "Iconify Vivo Safe")
signingConfig = releaseSigning
}

Expand All @@ -60,7 +61,7 @@ android {
isShrinkResources = true
isCrunchPngs = false
proguardFiles("proguard-android-optimize.txt", "proguard.pro", "proguard-rules.pro")
resValue("string", "derived_app_name", "Iconify")
resValue("string", "derived_app_name", "Iconify Vivo Safe")
signingConfig = releaseSigning
}
}
Expand All @@ -71,13 +72,13 @@ android {
create("standard") {
isDefault = true
dimension = "distribution"
resValue("string", "derived_app_name", "Iconify")
resValue("string", "derived_app_name", "Iconify Vivo Safe")
}

create("foss") {
dimension = "distribution"
applicationIdSuffix = ".foss"
resValue("string", "derived_app_name", "Iconify (FOSS)")
resValue("string", "derived_app_name", "Iconify Vivo Safe")
}
}

Expand Down Expand Up @@ -279,4 +280,4 @@ dependencies {

tasks.register("printVersionName") {
println(android.defaultConfig.versionName?.replace("-(Stable|Beta)".toRegex(), ""))
}
}
5 changes: 4 additions & 1 deletion app/src/foss/java/com/drdisagree/iconify/SplashActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ class SplashActivity : AppCompatActivity() {
(isOverlayInstalled || isXposedOnlyMode)

val intent: Intent =
if (SKIP_TO_HOMEPAGE_FOR_TESTING ||
if (BuildConfig.VIVO_SAFE_MODE && !isRooted) {
keepShowing = false
Intent(this@SplashActivity, MainActivity::class.java)
} else if (SKIP_TO_HOMEPAGE_FOR_TESTING ||
(isRooted &&
isModuleProperlyInstalled &&
isVersionCodeCorrect)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import com.airbnb.lottie.LottieCompositionFactory
import com.drdisagree.iconify.BuildConfig
import com.drdisagree.iconify.R
import com.drdisagree.iconify.data.common.Dynamic
import com.drdisagree.iconify.data.common.Preferences
Expand All @@ -37,9 +38,11 @@ import com.drdisagree.iconify.ui.preferences.preferencesearch.SearchPreferenceRe
import com.drdisagree.iconify.ui.utils.FragmentGroup
import com.drdisagree.iconify.ui.utils.isInGroup
import com.drdisagree.iconify.utils.HapticUtils.weakVibrate
import com.drdisagree.iconify.utils.RootUtils
import com.drdisagree.iconify.utils.SystemUtils
import com.drdisagree.iconify.utils.overlay.FabricatedUtils
import com.drdisagree.iconify.utils.overlay.OverlayUtils
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.jaredrummler.android.colorpicker.ColorPickerDialog
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -79,11 +82,14 @@ class MainActivity : BaseActivity(),
}

initData()
showVivoSafeNoticeIfNeeded()

setupFloatingActionButtons()
}

private fun initData() {
if (BuildConfig.VIVO_SAFE_MODE && !RootUtils.deviceProperlyRooted()) return

CoroutineScope(Dispatchers.IO).launch {
// Clear lottie cache
LottieCompositionFactory.clearCache(this@MainActivity)
Expand Down Expand Up @@ -136,6 +142,8 @@ class MainActivity : BaseActivity(),
binding.restartSystemui.setOnClickListener {
binding.restartSystemui.weakVibrate()

if (showVivoSafeBlockedIfNeeded()) return@setOnClickListener

Dynamic.requiresSystemUiRestart = false

showOrHidePendingActionButton(
Expand All @@ -152,6 +160,8 @@ class MainActivity : BaseActivity(),
binding.restartDevice.setOnClickListener {
binding.restartDevice.weakVibrate()

if (showVivoSafeBlockedIfNeeded()) return@setOnClickListener

Dynamic.requiresDeviceRestart = false

showOrHidePendingActionButton(
Expand All @@ -166,6 +176,28 @@ class MainActivity : BaseActivity(),
}
}

private fun showVivoSafeNoticeIfNeeded() {
if (!BuildConfig.VIVO_SAFE_MODE) return

MaterialAlertDialogBuilder(this)
.setTitle(R.string.vivo_safe_notice_title)
.setMessage(R.string.vivo_safe_notice_desc)
.setPositiveButton(android.R.string.ok, null)
.show()
}

private fun showVivoSafeBlockedIfNeeded(): Boolean {
if (!BuildConfig.VIVO_SAFE_MODE || RootUtils.deviceProperlyRooted()) return false

MaterialAlertDialogBuilder(this)
.setTitle(R.string.vivo_safe_blocked_title)
.setMessage(R.string.vivo_safe_blocked_desc)
.setPositiveButton(android.R.string.ok, null)
.show()

return true
}

private fun setupNavigation() {
if (Preferences.isXposedOnlyMode) {
binding.bottomNavigationView.menu.clear()
Expand Down Expand Up @@ -550,4 +582,4 @@ class MainActivity : BaseActivity(),
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ class OnboardingView : FrameLayout {
hasErroredOut = false

Shell.getShell {
if (BuildConfig.VIVO_SAFE_MODE && !deviceProperlyRooted()) {
openVivoSafePreview()
return@getShell
}

if (!isDeviceRooted) {
ErrorDialog(context).show(
R.string.root_not_found_title,
Expand Down Expand Up @@ -255,6 +260,11 @@ class OnboardingView : FrameLayout {
hasErroredOut = false

Shell.getShell {
if (BuildConfig.VIVO_SAFE_MODE && !deviceProperlyRooted()) {
openVivoSafePreview()
return@getShell
}

if (!isDeviceRooted) {
ErrorDialog(context).show(
R.string.root_not_found_title,
Expand Down Expand Up @@ -319,6 +329,21 @@ class OnboardingView : FrameLayout {
return true
}

private fun openVivoSafePreview() {
putBoolean(XPOSED_ONLY_MODE, false)

val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
animateSlideLeft(context)

Toast.makeText(
context,
R.string.vivo_safe_preview_toast,
Toast.LENGTH_LONG
).show()
}

private fun handleInstallation() {
LottieCompositionFactory.fromRawRes(context, R.raw.loading_anim)
.addListener {
Expand Down Expand Up @@ -729,4 +754,4 @@ class OnboardingView : FrameLayout {
binding.slider.setCurrentItem(numberOfPages - 1, true)
}
}
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/com/drdisagree/iconify/utils/ModuleUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ object ModuleUtils {
private val TAG = ModuleUtils::class.java.getSimpleName()

fun handleModule() {
if (BuildConfig.VIVO_SAFE_MODE && !RootUtils.deviceProperlyRooted()) {
Log.w(TAG, "Vivo Safe Mode blocked module handling without compatible root")
return
}

if (moduleExists()) {
// Clean temporary directory
Shell.cmd("rm -rf $TEMP_DIR").exec()
Expand Down Expand Up @@ -223,6 +228,10 @@ object ModuleUtils {
fun flashModule(modulePath: String): Boolean {
var result: Shell.Result? = null

if (BuildConfig.VIVO_SAFE_MODE && !RootUtils.deviceProperlyRooted()) {
throw Exception("Vivo Safe Mode blocked module flashing without compatible root")
}

if (RootUtils.isMagiskInstalled) {
result = Shell.cmd("magisk --install-module $modulePath").exec()
} else if (RootUtils.isKSUInstalled) {
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/com/drdisagree/iconify/utils/SystemUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ object SystemUtils {
get() = appContext.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_YES == Configuration.UI_MODE_NIGHT_YES

fun restartSystemUI() {
if (blockVivoSafeRootAction()) return

val loadTimeKey = String.format("%s%s", LOAD_TIME_KEY_KEY, SYSTEMUI_PACKAGE)
val strikeKey = String.format("%s%s", PACKAGE_STRIKE_KEY_KEY, SYSTEMUI_PACKAGE)
val currentTime = Calendar.getInstance().time.time
Expand All @@ -63,6 +65,8 @@ object SystemUtils {
}

private fun forceReloadUI() {
if (blockVivoSafeRootAction()) return

val state = RPrefs.getBoolean(FORCE_RELOAD_OVERLAY_STATE, false)
val pkgName: String = FORCE_RELOAD_PACKAGE_NAME

Expand Down Expand Up @@ -94,9 +98,23 @@ object SystemUtils {
}

fun restartDevice() {
if (blockVivoSafeRootAction()) return

Shell.cmd("am start -a android.intent.action.REBOOT").exec()
}

private fun blockVivoSafeRootAction(): Boolean {
if (!BuildConfig.VIVO_SAFE_MODE || RootUtils.deviceProperlyRooted()) return false

Toast.makeText(
appContext,
appContext.resources.getString(R.string.vivo_safe_blocked_desc),
Toast.LENGTH_LONG
).show()

return true
}

fun disableBlur(force: Boolean) {
Shell.cmd(
if (!force) "mv " + MODULE_DIR +
Expand Down
13 changes: 9 additions & 4 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_name" translatable="false">Iconify</string>
<string name="app_moto">Customize Boring Android UI</string>
<string name="app_name" translatable="false">Iconify Vivo Safe</string>
<string name="app_moto">Safe preview build for Vivo</string>
<string name="vivo_safe_notice_title">Vivo Safe Mode</string>
<string name="vivo_safe_notice_desc">This custom build is installed for Vivo V2111 stock Android 12 testing. Without Magisk, KernelSU, or APatch root, system overlays and module actions are blocked. You can browse the app, but do not expect system UI changes to apply.</string>
<string name="vivo_safe_blocked_title">Root action blocked</string>
<string name="vivo_safe_blocked_desc">Vivo Safe Mode blocked this action because this device does not have compatible root. No module, overlay, reboot, or SystemUI command was run.</string>
<string name="vivo_safe_preview_toast">Opened in Vivo Safe preview mode.</string>

<!-- Onboarding -->
<string name="init_module_installation">Initializing setup</string>
Expand All @@ -16,8 +21,8 @@
<string name="onboarding_subtitle_1">Let\'s customize everything to our likings.</string>
<string name="onboarding_desc_1">Ditch the stock UI monotony – personalize every tech detail to match your style and preferences.</string>
<string name="onboarding_title_2">Is My Device Supported ?</string>
<string name="onboarding_subtitle_2">Iconify supports all Pixel and AOSP ROMs.</string>
<string name="onboarding_desc_2">Compatible with all Pixel and AOSP-based ROMs, ensuring broad support for Android devices.</string>
<string name="onboarding_subtitle_2">This safe build is only for preview on Vivo stock ROM.</string>
<string name="onboarding_desc_2">Root-only module installation is blocked unless compatible Magisk, KernelSU, or APatch root is available.</string>
<string name="onboarding_title_3">Shall We Begin Now ?</string>
<string name="onboarding_subtitle_3">It is time for iconify to do some internal work.</string>
<string name="onboarding_desc_3">Starting internal tasks, marking the initiation of essential work. Ready to begin?</string>
Expand Down