diff options
Diffstat (limited to 'service/java/com/android/server/deviceconfig/DeviceConfigInit.java')
-rw-r--r-- | service/java/com/android/server/deviceconfig/DeviceConfigInit.java | 105 |
1 files changed, 98 insertions, 7 deletions
diff --git a/service/java/com/android/server/deviceconfig/DeviceConfigInit.java b/service/java/com/android/server/deviceconfig/DeviceConfigInit.java index 0921d81..b1ed0d6 100644 --- a/service/java/com/android/server/deviceconfig/DeviceConfigInit.java +++ b/service/java/com/android/server/deviceconfig/DeviceConfigInit.java @@ -1,18 +1,45 @@ package com.android.server.deviceconfig; +import static com.android.server.deviceconfig.Flags.enableRebootNotification; +import static com.android.server.deviceconfig.Flags.enableUnattendedReboot; + +import java.io.IOException; import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import android.aconfig.Aconfig.parsed_flags; +import android.aconfig.Aconfig.parsed_flag; +import android.content.Intent; import android.annotation.NonNull; import android.annotation.SystemApi; +import android.content.BroadcastReceiver; import android.content.Context; +import android.os.AsyncTask; import android.os.Binder; +import android.content.IntentFilter; +import android.provider.DeviceConfig; import android.provider.UpdatableDeviceConfigServiceReadiness; - +import android.content.ServiceConnection; +import android.os.IBinder; +import android.content.ComponentName; +import android.util.Slog; +import com.android.modules.utils.build.SdkLevel; import com.android.server.SystemService; /** @hide */ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public class DeviceConfigInit { + private static final String TAG = "DEVICE_CONFIG_INIT"; + private static final String STAGED_NAMESPACE = "staged"; + + private static final String SYSTEM_FLAGS_PATH = "/system/etc/aconfig_flags.pb"; + private static final String SYSTEM_EXT_FLAGS_PATH = "/system_ext/etc/aconfig_flags.pb"; + private static final String VENDOR_FLAGS_PATH = "/vendor/etc/aconfig_flags.pb"; private DeviceConfigInit() { // do not instantiate @@ -21,24 +48,88 @@ public class DeviceConfigInit { /** @hide */ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public static class Lifecycle extends SystemService { - private DeviceConfigShellService mShellService; + private DeviceConfigServiceImpl mService; + private UnattendedRebootManager mUnattendedRebootManager; /** @hide */ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public Lifecycle(@NonNull Context context) { super(context); - // this service is always instantiated but should only launch subsequent services + // this service is always instantiated but should only launch subsequent service(s) // if the module is ready if (UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService()) { - mShellService = new DeviceConfigShellService(); + mService = new DeviceConfigServiceImpl(getContext()); + publishBinderService(DeviceConfig.SERVICE_NAME, mService); } + applyBootstrapValues(); } - /** @hide */ + /** + * @hide + */ @Override public void onStart() { - if (UpdatableDeviceConfigServiceReadiness.shouldStartUpdatableService()) { - publishBinderService("device_config_updatable", mShellService); + if (enableRebootNotification()) { + Map<String, Set<String>> aconfigFlags = new HashMap<>(); + try { + addAconfigFlagsFromFile(aconfigFlags, SYSTEM_FLAGS_PATH); + addAconfigFlagsFromFile(aconfigFlags, SYSTEM_EXT_FLAGS_PATH); + addAconfigFlagsFromFile(aconfigFlags, VENDOR_FLAGS_PATH); + } catch (IOException e) { + Slog.e(TAG, "error loading aconfig flags", e); + } + + BootNotificationCreator notifCreator = new BootNotificationCreator( + getContext().getApplicationContext(), + aconfigFlags); + + DeviceConfig.addOnPropertiesChangedListener( + STAGED_NAMESPACE, + AsyncTask.THREAD_POOL_EXECUTOR, + notifCreator); + } + + if (enableUnattendedReboot()) { + mUnattendedRebootManager = + new UnattendedRebootManager(getContext().getApplicationContext()); + getContext() + .registerReceiver( + new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mUnattendedRebootManager.prepareUnattendedReboot(); + mUnattendedRebootManager.scheduleReboot(); + } + }, + new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); + } + } + + private void addAconfigFlagsFromFile(Map<String, Set<String>> aconfigFlags, + String fileName) throws IOException { + byte[] contents = (new FileInputStream(fileName)).readAllBytes(); + parsed_flags parsedFlags = parsed_flags.parseFrom(contents); + for (parsed_flag flag : parsedFlags.getParsedFlagList()) { + if (aconfigFlags.get(flag.getNamespace()) == null) { + aconfigFlags.put(flag.getNamespace(), new HashSet<>()); + aconfigFlags.get(flag.getNamespace()).add(flag.getName()); + } else { + aconfigFlags.get(flag.getNamespace()).add(flag.getName()); + } + } + } + + private void applyBootstrapValues() { + if (SdkLevel.isAtLeastV()) { + try { + new DeviceConfigBootstrapValues().applyValuesIfNeeded(); + } catch (RuntimeException e) { + Slog.e(TAG, "Failed to load boot overrides", e); + throw e; + } catch (IOException e) { + Slog.e(TAG, "Failed to load boot overrides", e); + throw new RuntimeException(e); + } } } } |