App 2.19.2: Full screen for CarPlay (experiment)

Adds com.allgo.carplay.service to immersive.full in Android 9's
policy_control setting when switched on, removes only that entry when
off. Car build (system user) only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LhzAVaUyqcw5PkGjz4mWW6
This commit is contained in:
2026-10-23 20:50:35 +02:00
co-authored by Claude Opus 5.5
parent 209a231511
commit 50217aef74
10 changed files with 219 additions and 14 deletions
@@ -1066,6 +1066,56 @@ public class MainActivity extends AppCompatActivity {
// ---------- Upload page ----------
/** The car's CarPlay app, as the Logs tab's foreground list showed it on SWI68. */
private static final String CARPLAY_PACKAGE = "com.allgo.carplay.service";
/**
* Experiment: forces CarPlay into immersive mode through Android 9's policy_control setting.
* The switch shows what the setting holds, not a preference, and switching off removes only
* our entry. Writing it needs WRITE_SECURE_SETTINGS, which only the car build (system user)
* has; elsewhere the switch is disabled.
*/
private void bindCarPlayFullScreen() {
com.google.android.material.switchmaterial.SwitchMaterial sw =
settingsPane.findViewById(R.id.carplay_full_screen_switch);
boolean mayWrite = checkSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
== android.content.pm.PackageManager.PERMISSION_GRANTED;
String current = android.provider.Settings.Global.getString(getContentResolver(), PolicyControl.KEY);
sw.setOnCheckedChangeListener(null);
sw.setChecked(PolicyControl.hasFull(current, CARPLAY_PACKAGE));
sw.setEnabled(mayWrite);
if (!mayWrite) {
((TextView) settingsPane.findViewById(R.id.carplay_full_screen_hint))
.setText(R.string.hint_carplay_full_screen_unavailable);
return;
}
sw.setOnCheckedChangeListener((btn, checked) -> diagReader.execute(() -> {
boolean ok;
try {
android.content.ContentResolver cr = getContentResolver();
String before = android.provider.Settings.Global.getString(cr, PolicyControl.KEY);
String after = checked ? PolicyControl.withFull(before, CARPLAY_PACKAGE)
: PolicyControl.withoutFull(before, CARPLAY_PACKAGE);
android.provider.Settings.Global.putString(cr, PolicyControl.KEY, after);
String now = android.provider.Settings.Global.getString(cr, PolicyControl.KEY);
ok = PolicyControl.hasFull(now, CARPLAY_PACKAGE) == checked;
android.util.Log.i("EVABRP.Settings", "policy_control " + (checked ? "on" : "off") + ": " + now);
} catch (RuntimeException e) {
android.util.Log.w("EVABRP.Settings", "policy_control not written", e);
ok = false;
}
final boolean written = ok;
runOnUiThread(() -> {
if (isDestroyed()) return;
if (!written) {
Toast.makeText(this, R.string.carplay_full_screen_failed, Toast.LENGTH_LONG).show();
bindCarPlayFullScreen();
}
refreshForeground();
});
}));
}
private void bindServicePane() {
voiceKeySwitch = settingsPane.findViewById(R.id.voice_key_switch);
voiceKeySwitch.setChecked(UploadSettings.voiceKeyOpensApp(prefs));
@@ -1079,6 +1129,7 @@ public class MainActivity extends AppCompatActivity {
prefs.edit().putBoolean(UploadSettings.KEY_FULL_SCREEN, checked).apply();
applyFullScreen();
});
bindCarPlayFullScreen();
liveTelemetrySwitch = servicePane.findViewById(R.id.abrp_upload_switch);
intervalChoices = servicePane.findViewById(R.id.interval_choices);
boostSwitch = servicePane.findViewById(R.id.boost_switch);