diff options
8 files changed, 103 insertions, 39 deletions
diff --git a/core/java/android/os/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java index fa2c480aaf41..8f68723e1b7d 100644 --- a/core/java/android/os/image/DynamicSystemClient.java +++ b/core/java/android/os/image/DynamicSystemClient.java @@ -35,6 +35,8 @@ import android.os.Message; import android.os.Messenger; import android.os.ParcelableException; import android.os.RemoteException; +import android.os.SystemProperties; +import android.util.FeatureFlagUtils; import android.util.Slog; import java.lang.annotation.Retention; @@ -315,6 +317,11 @@ public class DynamicSystemClient { */ @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void bind() { + if (!featureFlagEnabled()) { + Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; bind() aborted."); + return; + } + Intent intent = new Intent(); intent.setClassName("com.android.dynsystem", "com.android.dynsystem.DynamicSystemInstallationService"); @@ -381,6 +388,11 @@ public class DynamicSystemClient { @RequiresPermission(android.Manifest.permission.INSTALL_DYNAMIC_SYSTEM) public void start(@NonNull Uri systemUrl, @BytesLong long systemSize, @BytesLong long userdataSize) { + if (!featureFlagEnabled()) { + Slog.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; start() aborted."); + return; + } + Intent intent = new Intent(); intent.setClassName("com.android.dynsystem", @@ -395,6 +407,11 @@ public class DynamicSystemClient { mContext.startActivity(intent); } + private boolean featureFlagEnabled() { + return SystemProperties.getBoolean( + FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false); + } + private void handleMessage(Message msg) { switch (msg.what) { case MSG_POST_STATUS: diff --git a/core/java/android/os/image/DynamicSystemManager.java b/core/java/android/os/image/DynamicSystemManager.java index 0458c2a8b735..cec19457dd07 100644 --- a/core/java/android/os/image/DynamicSystemManager.java +++ b/core/java/android/os/image/DynamicSystemManager.java @@ -159,6 +159,16 @@ public class DynamicSystemManager { } } + /** @return {@code true} if the device has a dynamic system enabled */ + @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) + public boolean isEnabled() { + try { + return mService.isEnabled(); + } catch (RemoteException e) { + throw new RuntimeException(e.toString()); + } + } + /** * Remove DynamicSystem installation if present * @@ -174,14 +184,13 @@ public class DynamicSystemManager { } /** - * Enable DynamicSystem when it's not enabled, otherwise, disable it. - * + * Enable or disable DynamicSystem. * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) - public boolean toggle() { + public boolean setEnable(boolean enable) { try { - return mService.toggle(); + return mService.setEnable(enable); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } diff --git a/core/java/android/os/image/IDynamicSystemService.aidl b/core/java/android/os/image/IDynamicSystemService.aidl index 15f5b68e354b..a34daca86ce5 100644 --- a/core/java/android/os/image/IDynamicSystemService.aidl +++ b/core/java/android/os/image/IDynamicSystemService.aidl @@ -58,6 +58,11 @@ interface IDynamicSystemService boolean isInstalled(); /** + * @return true if the device has an DynamicSystem image enabled + */ + boolean isEnabled(); + + /** * Remove DynamicSystem installation if present * * @return true if the call succeeds @@ -65,11 +70,11 @@ interface IDynamicSystemService boolean remove(); /** - * Enable DynamicSystem when it's not enabled, otherwise, disable it. + * Enable or disable DynamicSystem. * * @return true if the call succeeds */ - boolean toggle(); + boolean setEnable(boolean enable); /** * Write a chunk of the DynamicSystem system image diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java index 7f6423a74ced..5d33b49e181b 100644 --- a/core/java/android/util/FeatureFlagUtils.java +++ b/core/java/android/util/FeatureFlagUtils.java @@ -41,6 +41,7 @@ public class FeatureFlagUtils { public static final String GLOBAL_ACTIONS_GRID_ENABLED = "settings_global_actions_grid_enabled"; public static final String GLOBAL_ACTIONS_PANEL_ENABLED = "settings_global_actions_panel_enabled"; + public static final String DYNAMIC_SYSTEM = "settings_dynamic_system"; private static final Map<String, String> DEFAULT_FLAGS; @@ -52,7 +53,7 @@ public class FeatureFlagUtils { DEFAULT_FLAGS.put("settings_slice_injection", "true"); DEFAULT_FLAGS.put("settings_systemui_theme", "true"); DEFAULT_FLAGS.put("settings_mainline_module", "true"); - DEFAULT_FLAGS.put("settings_dynamic_system", "false"); + DEFAULT_FLAGS.put(DYNAMIC_SYSTEM, "false"); DEFAULT_FLAGS.put(SEAMLESS_TRANSFER, "false"); DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false"); DEFAULT_FLAGS.put(SAFETY_HUB, "true"); diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java index 38576ee47283..ea7b378eb607 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/BootCompletedReceiver.java @@ -19,8 +19,10 @@ package com.android.dynsystem; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.SystemProperties; import android.os.UserHandle; import android.os.image.DynamicSystemClient; +import android.util.FeatureFlagUtils; import android.util.Log; @@ -35,6 +37,10 @@ public class BootCompletedReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { + if (!featureFlagEnabled()) { + return; + } + String action = intent.getAction(); Log.d(TAG, "Broadcast received: " + action); @@ -47,4 +53,9 @@ public class BootCompletedReceiver extends BroadcastReceiver { context.startServiceAsUser(startServiceIntent, UserHandle.SYSTEM); } } + + private boolean featureFlagEnabled() { + return SystemProperties.getBoolean( + FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false); + } } diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java index 2ad72eb725a9..5c6885a801e8 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java @@ -257,7 +257,7 @@ public class DynamicSystemInstallationService extends Service return; } - if (getStatus() != STATUS_READY) { + if (!isDynamicSystemInstalled() && (getStatus() != STATUS_READY)) { Log.e(TAG, "Trying to discard AOT while there is no complete installation"); return; } @@ -273,13 +273,25 @@ public class DynamicSystemInstallationService extends Service } private void executeRebootToDynSystemCommand() { - if (mInstallTask == null || mInstallTask.getStatus() != FINISHED) { + boolean enabled = false; + + if (mInstallTask != null && mInstallTask.getStatus() == FINISHED) { + enabled = mInstallTask.commit(); + } else if (isDynamicSystemInstalled()) { + enabled = mDynSystem.setEnable(true); + } else { Log.e(TAG, "Trying to reboot to AOT while there is no complete installation"); return; } - if (!mInstallTask.commit()) { - Log.e(TAG, "Failed to commit installation because of native runtime error."); + if (enabled) { + PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); + + if (powerManager != null) { + powerManager.reboot("dynsystem"); + } + } else { + Log.e(TAG, "Failed to enable DynamicSystem because of native runtime error."); mNM.cancel(NOTIFICATION_ID); Toast.makeText(this, @@ -287,14 +299,6 @@ public class DynamicSystemInstallationService extends Service Toast.LENGTH_LONG).show(); mDynSystem.remove(); - - return; - } - - PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE); - - if (powerManager != null) { - powerManager.reboot("dynsystem"); } } diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java index 269645d8016b..b1c09381823b 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/VerificationActivity.java @@ -25,8 +25,10 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; +import android.os.SystemProperties; import android.os.UserHandle; import android.os.image.DynamicSystemClient; +import android.util.FeatureFlagUtils; import android.util.Log; @@ -49,6 +51,12 @@ public class VerificationActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!featureFlagEnabled()) { + Log.w(TAG, FeatureFlagUtils.DYNAMIC_SYSTEM + " not enabled; activity aborted."); + finish(); + return; + } + KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE); if (km != null) { @@ -98,6 +106,11 @@ public class VerificationActivity extends Activity { startServiceAsUser(intent, UserHandle.SYSTEM); } + private boolean featureFlagEnabled() { + return SystemProperties.getBoolean( + FeatureFlagUtils.PERSIST_PREFIX + FeatureFlagUtils.DYNAMIC_SYSTEM, false); + } + static boolean isVerified(String url) { return sVerifiedUrl != null && sVerifiedUrl.equals(url); } diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java index f5bd11cea779..99bbcf890a0a 100644 --- a/services/core/java/com/android/server/DynamicSystemService.java +++ b/services/core/java/com/android/server/DynamicSystemService.java @@ -70,25 +70,24 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements checkPermission(); if (!"running".equals(SystemProperties.get("init.svc.gsid"))) { SystemProperties.set("ctl.start", "gsid"); - } - for (int sleepMs = 64; sleepMs <= (GSID_ROUGH_TIMEOUT_MS << 1); sleepMs <<= 1) { - try { - Thread.sleep(sleepMs); - } catch (InterruptedException e) { - Slog.e(TAG, "Interrupted when waiting for GSID"); - break; - } - if ("running".equals(SystemProperties.get("init.svc.gsid"))) { - synchronized (this) { - if (mGsiService == null) { - mGsiService = connect(this); - } - return mGsiService; + for (int sleepMs = 64; sleepMs <= (GSID_ROUGH_TIMEOUT_MS << 1); sleepMs <<= 1) { + try { + Thread.sleep(sleepMs); + } catch (InterruptedException e) { + Slog.e(TAG, "Interrupted when waiting for GSID"); + break; + } + if ("running".equals(SystemProperties.get("init.svc.gsid"))) { + break; } } } - Slog.e(TAG, "Unable to start gsid"); - return null; + synchronized (this) { + if (mGsiService == null) { + mGsiService = connect(this); + } + return mGsiService; + } } private void checkPermission() { @@ -125,19 +124,24 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements } @Override + public boolean isEnabled() throws RemoteException { + return getGsiService().isGsiEnabled(); + } + + @Override public boolean remove() throws RemoteException { return getGsiService().removeGsiInstall(); } @Override - public boolean toggle() throws RemoteException { + public boolean setEnable(boolean enable) throws RemoteException { IGsiService gsiService = getGsiService(); - if (gsiService.isGsiRunning()) { - return gsiService.disableGsiInstall(); - } else { + if (enable) { final int status = gsiService.getGsiBootStatus(); final boolean singleBoot = (status == IGsiService.BOOT_STATUS_SINGLE_BOOT); return gsiService.setGsiBootable(singleBoot) == 0; + } else { + return gsiService.disableGsiInstall(); } } |