Core provisioner logic for PawletOS Android 16: - BootReceiver: trigger provisioning on BOOT_COMPLETED and USER_PRESENT - ProvisioningService: run base tasks (APN, secure settings) and OTA tasks (deferred APK installs) as separate passes - VendorConfig: read vendor.cfg from partition; parse APNs, packages, settings - Android.bp: wire up AIDL, disable resource generation (no UI)
67 lines
2.4 KiB
Java
67 lines
2.4 KiB
Java
package dev.oxmc.configprovisioner;
|
|
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.util.Log;
|
|
|
|
public class BootReceiver extends BroadcastReceiver {
|
|
private static final String TAG = "ConfigProvisioner";
|
|
private static final String PREF_NAME = "config_provisioner_prefs";
|
|
static final String KEY_BASE_PROVISIONED = "has_base_provisioned";
|
|
static final String KEY_LAST_OTA_CHECK = "last_ota_check_ms";
|
|
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
if (intent == null || intent.getAction() == null) return;
|
|
String action = intent.getAction();
|
|
Log.d(TAG, "Received: " + action);
|
|
|
|
switch (action) {
|
|
case Intent.ACTION_BOOT_COMPLETED:
|
|
case "android.intent.action.LOCKED_BOOT_COMPLETED":
|
|
if (!isBaseProvisioned(context)) {
|
|
startService(context, ProvisioningService.ACTION_BASE_PROVISION);
|
|
}
|
|
break;
|
|
|
|
case Intent.ACTION_USER_PRESENT:
|
|
String url = VendorConfig.getConfigApkUrl();
|
|
if (isBaseProvisioned(context) && VendorConfig.isConfigApkServiceEnabled()
|
|
&& url != null && !url.isEmpty()) {
|
|
startService(context, ProvisioningService.ACTION_OTA_UPDATE);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
private static void startService(Context context, String action) {
|
|
Intent si = new Intent(context, ProvisioningService.class);
|
|
si.setAction(action);
|
|
context.startService(si);
|
|
}
|
|
|
|
// ---- SharedPrefs helpers (package-private so ProvisioningService can use them) ----
|
|
|
|
static boolean isBaseProvisioned(Context context) {
|
|
return prefs(context).getBoolean(KEY_BASE_PROVISIONED, false);
|
|
}
|
|
|
|
static void setBaseProvisioned(Context context, boolean value) {
|
|
prefs(context).edit().putBoolean(KEY_BASE_PROVISIONED, value).apply();
|
|
}
|
|
|
|
static long getLastOtaCheck(Context context) {
|
|
return prefs(context).getLong(KEY_LAST_OTA_CHECK, 0L);
|
|
}
|
|
|
|
static void setLastOtaCheck(Context context, long timeMs) {
|
|
prefs(context).edit().putLong(KEY_LAST_OTA_CHECK, timeMs).apply();
|
|
}
|
|
|
|
private static SharedPreferences prefs(Context context) {
|
|
return context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
|
}
|
|
}
|