implement deep links support

This commit is contained in:
Chloe committed 2025-12-26 17:37:22 -07:00
1 parent b69c915e51
commit 92d876560a
5 files changed
+131 -24

No files matched your search

+68 -8
View File
@@ -57,19 +57,43 @@
android:theme="@style/Theme.GeodeLauncher" />
<activity
android:name=".preferences.DeveloperSettingsActivity"
android:exported="false"
android:exported="true"
android:label="@string/title_activity_developer_settings"
android:theme="@style/Theme.GeodeLauncher" />
android:theme="@style/Theme.GeodeLauncher">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="developer-settings" />
</intent-filter>
</activity>
<activity
android:name=".preferences.ApplicationLogsActivity"
android:exported="false"
android:exported="true"
android:label="@string/title_activity_application_logs"
android:theme="@style/Theme.GeodeLauncher" />
android:theme="@style/Theme.GeodeLauncher">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="logs" />
</intent-filter>
</activity>
<activity
android:name=".preferences.CrashLogsActivity"
android:exported="false"
android:exported="true"
android:label="@string/title_activity_crash_logs"
android:theme="@style/Theme.GeodeLauncher" />
android:theme="@style/Theme.GeodeLauncher">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="crashes" />
</intent-filter>
</activity>
<activity
android:name=".preferences.ApplicationIconActivity"
android:exported="false"
@@ -77,9 +101,17 @@
android:theme="@style/Theme.GeodeLauncher" />
<activity
android:name=".preferences.SettingsActivity"
android:exported="false"
android:exported="true"
android:label="@string/title_activity_settings"
android:theme="@style/Theme.GeodeLauncher" />
android:theme="@style/Theme.GeodeLauncher">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="settings" />
</intent-filter>
</activity>
<activity
android:name=".GeometryDashActivity"
android:configChanges="orientation|screenSize|smallestScreenSize"
@@ -101,6 +133,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="main" />
</intent-filter>
</activity>
<activity-alias
@@ -115,6 +154,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="main" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".MainActivityPride"
@@ -128,6 +174,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="main" />
</intent-filter>
</activity-alias>
<activity-alias
android:name=".MainActivityGeode"
@@ -141,6 +194,13 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="geode-launcher" android:host="main" />
</intent-filter>
</activity-alias>
<provider
@@ -96,12 +96,16 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
clearDownloadedApks(this)
val gdInstalled = GamePackageUtils.isGameInstalled(packageManager)
val geodeInstalled = LaunchUtils.isGeodeInstalled(this)
if (gdInstalled && geodeInstalled && intent.getBooleanExtra("restarted", false)) {
onLaunch(this)
}
enableEdgeToEdge()
clearDownloadedApks(this)
val returnMessage = intent.extras?.getString(LaunchUtils.LAUNCHER_KEY_RETURN_MESSAGE)
val returnExtendedMessage = intent.extras?.getString(LaunchUtils.LAUNCHER_KEY_RETURN_EXTENDED_MESSAGE)
@@ -115,8 +119,23 @@ class MainActivity : ComponentActivity() {
LoadFailureInfo(LaunchUtils.LauncherError.CRASHED)
} else { null }
var launchArguments: LaunchArguments? = null
val intentData = intent.data
if (intent.action == Intent.ACTION_VIEW && intentData != null) {
val isLaunch = intentData.path == "/launch"
val safeMode = if (isLaunch) {
intentData.getBooleanQueryParameter("safe-mode", false)
} else false
launchArguments = LaunchArguments(
autoSafeMode = safeMode,
forcePause = !isLaunch,
forceLaunch = isLaunch,
)
}
val redirectToAlt = PreferenceUtils.get(this).getBoolean(PreferenceUtils.Key.DISABLE_REDESIGN)
if (redirectToAlt) {
if (redirectToAlt && launchArguments == null) {
val launchIntent = Intent(this, LegacyMainActivity::class.java)
launchIntent.putExtras(intent)
startActivity(launchIntent)
@@ -137,6 +156,10 @@ class MainActivity : ComponentActivity() {
launchViewModel.loadFailure = loadFailureInfo
}
if (launchArguments != null) {
launchViewModel.launchArguments = launchArguments
}
CompositionLocalProvider(LocalTheme provides theme) {
GeodeLauncherTheme(theme = theme, blackBackground = backgroundOption, dynamicColor = !dynamicColorOption) {
Surface(
@@ -147,14 +170,6 @@ class MainActivity : ComponentActivity() {
}
}
}
if (gdInstalled && geodeInstalled) {
intent.getBooleanExtra("restarted", false).let {
if (it) {
onLaunch(this)
}
}
}
}
}
@@ -605,7 +620,7 @@ fun GeodeUpdateIndicator(snackbarHostState: SnackbarHostState, onRetry: () -> Un
val context = LocalContext.current
val resources = LocalResources.current
val releaseState = ReleaseManager.get(context).uiState.value
val releaseState = ReleaseManager.get(context).uiState.collectAsState().value
if (releaseState !is ReleaseManager.ReleaseManagerState.Failure) {
return
@@ -659,7 +674,9 @@ fun AltMainScreen(
val launchUIState by launchViewModel.uiState.collectAsState()
val coroutineScope = rememberCoroutineScope()
var launchInSafeMode by remember { mutableStateOf(false) }
var launchInSafeMode by remember {
mutableStateOf(launchViewModel.launchArguments?.autoSafeMode == true)
}
var showErrorInfo by remember { mutableStateOf(false) }
@@ -18,6 +18,12 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.takeWhile
import kotlinx.coroutines.launch
data class LaunchArguments(
val autoSafeMode: Boolean,
val forcePause: Boolean,
val forceLaunch: Boolean
)
class LaunchViewModel(private val application: Application): ViewModel() {
companion object {
val Factory: ViewModelProvider.Factory = viewModelFactory {
@@ -113,6 +119,8 @@ class LaunchViewModel(private val application: Application): ViewModel() {
val nextLauncherUpdate = ReleaseManager.get(application).availableLauncherUpdate
var loadFailure: LoadFailureInfo? = null
var launchArguments: LaunchArguments? = null
private var hasCheckedForUpdates = false
private var isCancelling = false
private var hasManuallyStarted = false
@@ -191,8 +199,15 @@ class LaunchViewModel(private val application: Application): ViewModel() {
return _uiState.emit(LaunchUIState.Cancelled(LaunchCancelReason.GEODE_NOT_FOUND))
}
// if forcing immediate launch, then act as if it's manually started (skips timers)
val forceImmediate = launchArguments?.forceLaunch == true
if (forceImmediate) {
hasManuallyStarted = true
}
val loadAutomatically = PreferenceUtils.get(application).getBoolean(PreferenceUtils.Key.LOAD_AUTOMATICALLY)
if (!loadAutomatically && !hasManuallyStarted) {
val forcePause = launchArguments?.forcePause == true
if (!hasManuallyStarted && (forcePause || !loadAutomatically)) {
return cancelLaunch(true)
}
@@ -107,7 +107,7 @@ fun onOpenFileManager(context: Context) {
try {
context.startActivity(intent)
} catch (e: ActivityNotFoundException) {
} catch (_: ActivityNotFoundException) {
Toast.makeText(
context,
context.getText(R.string.no_activity_found), Toast.LENGTH_SHORT