Skip to content

Commit e92ab08

Browse files
ADFA-4900: bank wizard maps selection, apply post-install (no live runrole pre-install)
In the initial-setup wizard there is no rootfs yet, so running runrole maps fails (can't sanitize binding installed-rootfs). Mirror the Books/ZIM pattern: in the wizard Maps banks the per-layer selection (MapsWishlist) and returns to the Get More hub with an 'Add to your setup' action instead of installing live; MapsProvisioner applies it post-install by handing the selection to the module-queue engine (runrole maps). Drain maps at the same post-install points as Books/ZIM (SetupProgressActivity, LibraryHome). Post-install Get More keeps installing directly (mapsWizard=false).
1 parent bfcfc66 commit e92ab08

7 files changed

Lines changed: 135 additions & 6 deletions

File tree

‎controller/app/src/main/java/org/iiab/controller/redesign/LibraryHomeFragment.java‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,8 @@ private void refreshStatuses() {
255255
// fail with no content installed. So gate the drain on the REST API actually answering;
256256
// the wishlist is untouched until then, and this poll (~3s) retries until it's ready.
257257
if (alive && !provisionProbing
258-
&& (BooksProvisioner.hasPending(requireContext()) || ZimProvisioner.hasPending(requireContext()))) {
258+
&& (BooksProvisioner.hasPending(requireContext()) || ZimProvisioner.hasPending(requireContext())
259+
|| MapsProvisioner.hasPending(requireContext()))) { // ADFA-4900
259260
provisionProbing = true;
260261
AppExecutors.get().io().execute(() -> {
261262
final boolean ready = RestReadiness.apiReady();
@@ -269,6 +270,7 @@ private void refreshStatuses() {
269270
android.util.Log.i("K2Go-Provision", "REST API ready -> draining wishlists (home fallback)");
270271
if (BooksProvisioner.hasPending(requireContext())) BooksProvisioner.drain(requireContext());
271272
if (ZimProvisioner.hasPending(requireContext())) ZimProvisioner.drain(requireContext());
273+
if (MapsProvisioner.hasPending(requireContext())) MapsProvisioner.drain(requireContext()); // ADFA-4900
272274
});
273275
});
274276
}

‎controller/app/src/main/java/org/iiab/controller/redesign/MapsConfirmFragment.java‎

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,17 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c
7575

7676
final String[] levels = a != null ? a.getStringArray(ARG_LEVELS) : null;
7777

78+
// ADFA-4900: in the wizard (pre-install) Maps banks the selection; post-install it installs.
79+
final boolean wizard = getActivity() instanceof SetupLibraryActivity
80+
&& ((SetupLibraryActivity) getActivity()).isMapsWizard();
81+
7882
Button start = root.findViewById(R.id.k2go_start_btn);
79-
start.setText(getString(R.string.k2go_maps_start_building, fmt(total)));
83+
start.setText(getString(wizard ? R.string.k2go_maps_add_setup_fmt : R.string.k2go_maps_start_building, fmt(total)));
8084
start.setOnClickListener(v -> {
8185
if (getActivity() instanceof SetupLibraryActivity) {
82-
((SetupLibraryActivity) getActivity()).openMapsPreparing(levels);
86+
SetupLibraryActivity act = (SetupLibraryActivity) getActivity();
87+
if (act.isMapsWizard()) act.mapsWizardConfirm(levels);
88+
else act.openMapsPreparing(levels);
8389
}
8490
});
8591

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* ============================================================================
3+
* Name : MapsProvisioner.java
4+
* Author : AppDevForAll
5+
* Copyright : Copyright (c) 2026 AppDevForAll
6+
* Description : ADFA-4900. Post-install drain of the maps wishlist. Mirrors Books/ZimProvisioner:
7+
* once the system is installed, it hands the banked per-layer selection to the
8+
* module-queue engine (InstallService ACTION_START_MODULES {"maps"} + the selection),
9+
* which writes the maps_* local_vars and runs runrole maps with the shared verdict /
10+
* revert / progress. Unlike ZIM this does not need the server up, only the rootfs, so
11+
* it can run at the same post-install drain point. Idempotent: cleared once handed off.
12+
* ============================================================================
13+
*/
14+
package org.iiab.controller.redesign;
15+
16+
import android.content.Context;
17+
import android.content.Intent;
18+
import android.os.Build;
19+
import android.util.Log;
20+
21+
import org.iiab.controller.install.presentation.InstallService;
22+
import org.iiab.controller.install.presentation.ModuleQueueRepository;
23+
24+
public final class MapsProvisioner {
25+
private MapsProvisioner() {}
26+
27+
private static final String TAG = "K2Go-Provision";
28+
29+
/** True when there is a banked maps selection waiting to be applied. */
30+
public static boolean hasPending(Context ctx) {
31+
return MapsWishlist.has(ctx);
32+
}
33+
34+
/** Hand the banked maps selection to the module-queue engine. No-op if empty or a queue is
35+
* already running. Requires the rootfs (runs runrole maps in the proot). */
36+
public static void drain(Context ctx) {
37+
if (!MapsWishlist.has(ctx)) return;
38+
if (ModuleQueueRepository.get().isRunning()) return;
39+
final Context app = ctx.getApplicationContext();
40+
Intent i = new Intent(app, InstallService.class);
41+
i.setAction(InstallService.ACTION_START_MODULES);
42+
i.putExtra(InstallService.EXTRA_MODULES, new String[]{"maps"});
43+
i.putExtra(InstallService.EXTRA_MAPS_VECTOR, MapsWishlist.base(app));
44+
i.putExtra(InstallService.EXTRA_MAPS_SAT, MapsWishlist.sat(app));
45+
i.putExtra(InstallService.EXTRA_MAPS_TERRAIN, MapsWishlist.terrain(app));
46+
i.putExtra(InstallService.EXTRA_MAPS_SEARCH, MapsWishlist.search(app));
47+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) app.startForegroundService(i);
48+
else app.startService(i);
49+
Log.i(TAG, "maps drain: handed the banked selection to InstallService (runrole maps)");
50+
// Handed off; the module-queue owns the run from here.
51+
MapsWishlist.clear(app);
52+
}
53+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* ============================================================================
3+
* Name : MapsWishlist.java
4+
* Author : AppDevForAll
5+
* Copyright : Copyright (c) 2026 AppDevForAll
6+
* Description : ADFA-4900. The persisted maps per-layer selection chosen in the wizard, before the
7+
* system exists. Mirrors ZimWishlist/BooksWishlist: the wizard cannot run runrole
8+
* (no rootfs yet), so it banks the selection here and MapsProvisioner applies it
9+
* after the system is installed. Unlike ZIM/Books (a list of items), maps is a single
10+
* selection (base / satellite / terrain / search), so this stores one record.
11+
* ============================================================================
12+
*/
13+
package org.iiab.controller.redesign;
14+
15+
import android.content.Context;
16+
import android.content.SharedPreferences;
17+
18+
public final class MapsWishlist {
19+
private MapsWishlist() {}
20+
21+
private static final String PREFS = "k2go_maps_wishlist";
22+
23+
private static SharedPreferences prefs(Context ctx) {
24+
return ctx.getApplicationContext().getSharedPreferences(PREFS, Context.MODE_PRIVATE);
25+
}
26+
27+
/** Bank the wizard selection. Layer keys use the maps role's values; satellite/terrain "none"
28+
* = off, and {@code search} = the static pop-1k-cities engine on/off. */
29+
public static void save(Context ctx, String base, String sat, String terrain, boolean search) {
30+
prefs(ctx).edit()
31+
.putBoolean("has", true)
32+
.putString("base", base == null ? "osm-z11" : base)
33+
.putString("sat", sat == null ? "none" : sat)
34+
.putString("terrain", terrain == null ? "none" : terrain)
35+
.putBoolean("search", search)
36+
.apply();
37+
}
38+
39+
public static boolean has(Context ctx) { return prefs(ctx).getBoolean("has", false); }
40+
public static String base(Context ctx) { return prefs(ctx).getString("base", "osm-z11"); }
41+
public static String sat(Context ctx) { return prefs(ctx).getString("sat", "none"); }
42+
public static String terrain(Context ctx) { return prefs(ctx).getString("terrain", "none"); }
43+
public static boolean search(Context ctx) { return prefs(ctx).getBoolean("search", false); }
44+
45+
public static void clear(Context ctx) { prefs(ctx).edit().clear().apply(); }
46+
}

‎controller/app/src/main/java/org/iiab/controller/redesign/SetupLibraryActivity.java‎

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ public class SetupLibraryActivity extends AppCompatActivity {
4040
// then persists the cart to ZimWishlist instead of starting a live download.
4141
private boolean zimWizard = false;
4242

43+
// ADFA-4900: true while the Maps flow runs inside the wizard (pre-install). The Confirm step then
44+
// banks the per-layer selection to MapsWishlist instead of starting a live runrole.
45+
private boolean mapsWizard = false;
46+
4347
@Override
4448
protected void onCreate(Bundle savedInstanceState) {
4549
super.onCreate(savedInstanceState);
@@ -118,6 +122,7 @@ private InstallationPlanner.Tier readInstalledTier() {
118122
* the rest are navigable placeholders for now so the hub is reviewable. */
119123
public void openContentType(String key, String title) {
120124
zimWizard = false; // live (post-install) path; the ZIM terminal downloads, not wishlists
125+
mapsWizard = false; // ADFA-4900: live (post-install) path; Maps installs, not wishlists
121126
androidx.fragment.app.Fragment f;
122127
if ("maps".equals(key)) f = new MapsLandingFragment();
123128
else if ("wikipedia".equals(key)) f = new ZimLandingFragment(); // Wikipedia & ZIM content
@@ -190,9 +195,9 @@ public void goToWizardContent() {
190195
public void openWizardContent(String key, String title) {
191196
if ("books".equals(key)) { openBooksWizard(); return; }
192197
if ("wikipedia".equals(key)) { openZimWizard(); return; }
193-
// Maps is identical pre/post-install (it stops everything and runs the proot), so it reuses
194-
// the existing Maps flow rather than a wizard-specific mode.
195-
if ("maps".equals(key)) { openContentType(key, title); return; }
198+
// ADFA-4900: in the wizard there is no rootfs yet, so Maps cannot run runrole. It banks the
199+
// per-layer selection (MapsWishlist) like Books/ZIM and MapsProvisioner applies it post-install.
200+
if ("maps".equals(key)) { openContentType(key, title); mapsWizard = true; return; }
196201
getSupportFragmentManager().beginTransaction()
197202
.replace(R.id.k2go_setup_host, PlaceholderFragment.newInstance(title))
198203
.addToBackStack("wizard_" + key)
@@ -261,6 +266,21 @@ public void openMapsPreparing(String[] levels) {
261266
.commit();
262267
}
263268

269+
/** ADFA-4900: true while Maps runs inside the wizard (pre-install) — Confirm banks the selection. */
270+
public boolean isMapsWizard() { return mapsWizard; }
271+
272+
/** ADFA-4900: Maps Confirm terminal in wizard mode — bank the per-layer selection to MapsWishlist
273+
* (MapsProvisioner applies it post-install) and return to the Get More hub. No live runrole. */
274+
public void mapsWizardConfirm(String[] levels) {
275+
String base = levels != null && levels.length > 0 && levels[0] != null ? levels[0] : "osm-z11";
276+
String sat = levels != null && levels.length > 1 && levels[1] != null ? levels[1] : "none";
277+
String ter = levels != null && levels.length > 2 && levels[2] != null ? levels[2] : "none";
278+
boolean search = levels != null && levels.length > 3 && levels[3] != null;
279+
MapsWishlist.save(this, base, sat, ter, search);
280+
getSupportFragmentManager().popBackStack("getmore_maps",
281+
androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE);
282+
}
283+
264284
/** ADFA-4900: start the maps install through the module-queue engine (a queue of {"maps"} plus
265285
* the per-layer selection). InstallService writes the full maps_* local_vars and runs runrole
266286
* with the shared success/failure verdict, revert-on-fail and observable progress. {@code levels}

‎controller/app/src/main/java/org/iiab/controller/redesign/SetupProgressActivity.java‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ public void onBackPressed() {
130130
if (!drained) {
131131
if (BooksProvisioner.hasPending(SetupProgressActivity.this)) BooksProvisioner.drain(SetupProgressActivity.this);
132132
if (ZimProvisioner.hasPending(SetupProgressActivity.this)) ZimProvisioner.drain(SetupProgressActivity.this);
133+
if (MapsProvisioner.hasPending(SetupProgressActivity.this)) MapsProvisioner.drain(SetupProgressActivity.this); // ADFA-4900
133134
drained = true;
134135
}
135136
render();

‎controller/app/src/main/res/values/strings_k2go.xml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,7 @@
384384
<string name="k2go_maps_use_wifi" translatable="false">Use Wi-Fi</string>
385385
<string name="k2go_maps_keep_charged" translatable="false">Keep charged</string>
386386
<string name="k2go_maps_start_building" translatable="false">Start building \u00b7 %1$s</string>
387+
<string name="k2go_maps_add_setup_fmt" translatable="false">Add to your setup \u00b7 %1$s</string>
387388
<string name="k2go_maps_keep_using" translatable="false">You can keep using the app meanwhile.</string>
388389
<string name="k2go_maps_preparing_title" translatable="false">Preparing your maps\u2026</string>
389390
<string name="k2go_maps_preparing_sub" translatable="false">This can take a while. You can leave it running.</string>

0 commit comments

Comments
 (0)