Loading Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ java_defaults { "core/java/android/os/ICancellationSignal.aidl", "core/java/android/os/IDeviceIdentifiersPolicyService.aidl", "core/java/android/os/IDeviceIdleController.aidl", "core/java/android/os/IDynamicAndroidService.aidl", "core/java/android/os/IHardwarePropertiesManager.aidl", ":libincident_aidl", "core/java/android/os/IMaintenanceActivityListener.aidl", Loading Loading @@ -601,6 +602,7 @@ java_defaults { ":storaged_aidl", ":vold_aidl", ":gsiservice_aidl", ":installd_aidl", ":dumpstate_aidl", Loading Loading @@ -657,6 +659,7 @@ java_defaults { "frameworks/native/aidl/gui", "system/core/storaged/binder", "system/vold/binder", "system/gsid/aidl", "system/bt/binder", "system/security/keystore/binder", ], Loading api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -838,6 +838,7 @@ package android.content { method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle); field public static final String BACKUP_SERVICE = "backup"; field public static final String CONTEXTHUB_SERVICE = "contexthub"; field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; field public static final String EUICC_CARD_SERVICE = "euicc_card"; field public static final String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final String NETD_SERVICE = "netd"; Loading core/java/android/app/SystemServiceRegistry.java +12 −0 Original line number Diff line number Diff line Loading @@ -114,11 +114,13 @@ import android.os.BugreportManager; import android.os.Build; import android.os.DeviceIdleManager; import android.os.DropBoxManager; import android.os.DynamicAndroidManager; import android.os.HardwarePropertiesManager; import android.os.IBatteryPropertiesRegistrar; import android.os.IBinder; import android.os.IDeviceIdleController; import android.os.IDumpstate; import android.os.IDynamicAndroidService; import android.os.IHardwarePropertiesManager; import android.os.IPowerManager; import android.os.IRecoverySystem; Loading Loading @@ -1065,6 +1067,16 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new TimeZoneDetector(); }}); registerService(Context.DYNAMIC_ANDROID_SERVICE, DynamicAndroidManager.class, new CachedServiceFetcher<DynamicAndroidManager>() { @Override public DynamicAndroidManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow( Context.DYNAMIC_ANDROID_SERVICE); return new DynamicAndroidManager( IDynamicAndroidService.Stub.asInterface(b)); }}); } /** Loading core/java/android/content/Context.java +8 −0 Original line number Diff line number Diff line Loading @@ -4304,6 +4304,14 @@ public abstract class Context { */ public static final String TELEPHONY_RCS_SERVICE = "ircs"; /** * Use with {@link #getSystemService(String)} to retrieve an * {@link android.os.DynamicAndroidManager}. * @hide */ @SystemApi public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. Loading core/java/android/os/DynamicAndroidManager.java 0 → 100644 +188 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; import android.gsi.GsiProgress; /** * The DynamicAndroidManager offers a mechanism to use a new Android image temporarily. After the * installation, the device can reboot into this image with a new created /data. This image will * last until the next reboot and then the device will go back to the original image. However the * installed image and the new created /data are not deleted but disabled. Thus the application can * either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to * delete it completely. In other words, there are three device states: no installation, installed * and running. The procedure to install a DynamicAndroid starts with a {@link #startInstallation}, * followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is * complete, the device state changes from no installation to the installed state and a followed * reboot will change its state to running. Note one instance of dynamic android can exist on a * given device thus the {@link #startInstallation} will fail if the device is currently running a * DynamicAndroid. * * @hide */ @SystemService(Context.DYNAMIC_ANDROID_SERVICE) public class DynamicAndroidManager { private static final String TAG = "DynamicAndroidManager"; private final IDynamicAndroidService mService; /** {@hide} */ public DynamicAndroidManager(IDynamicAndroidService service) { mService = service; } /** The DynamicAndroidManager.Session represents a started session for the installation. */ public class Session { private Session() {} /** * Write a chunk of the DynamicAndroid system image * * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean write(byte[] buf) { try { return mService.write(buf); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Finish write and make device to boot into the it after reboot. * * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean commit() { try { return mService.commit(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } } /** * Start DynamicAndroid installation. This call may take an unbounded amount of time. The caller * may use another thread to call the getStartProgress() to get the progress. * * @param systemSize system size in bytes * @param userdataSize userdata size in bytes * @return {@code true} if the call succeeds. {@code false} either the device does not contain * enough space or a DynamicAndroid is currently in use where the {@link #isInUse} would be * true. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public Session startInstallation(long systemSize, long userdataSize) { try { if (mService.startInstallation(systemSize, userdataSize)) { return new Session(); } else { return null; } } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Query the progress of the current installation operation. This can be called while the * installation is in progress. * * @return GsiProgress GsiProgress { int status; long bytes_processed; long total_bytes; } The * status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or * IGsiService.STATUS_COMPLETE. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public GsiProgress getInstallationProgress() { try { return mService.getInstallationProgress(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Abort the installation process. Note this method must be called in a thread other than the * one calling the startInstallation method as the startInstallation method will not return * until it is finished. * * @return {@code true} if the call succeeds. {@code false} if there is no installation * currently. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean abort() { try { return mService.abort(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** @return {@code true} if the device is running a dynamic android */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean isInUse() { try { return mService.isInUse(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** @return {@code true} if the device has a dynamic android installed */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean isInstalled() { try { return mService.isInstalled(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Remove DynamicAndroid installation if present * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean remove() { try { return mService.remove(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Enable DynamicAndroid when it's not enabled, otherwise, disable it. * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean toggle() { try { return mService.toggle(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } } Loading
Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -221,6 +221,7 @@ java_defaults { "core/java/android/os/ICancellationSignal.aidl", "core/java/android/os/IDeviceIdentifiersPolicyService.aidl", "core/java/android/os/IDeviceIdleController.aidl", "core/java/android/os/IDynamicAndroidService.aidl", "core/java/android/os/IHardwarePropertiesManager.aidl", ":libincident_aidl", "core/java/android/os/IMaintenanceActivityListener.aidl", Loading Loading @@ -601,6 +602,7 @@ java_defaults { ":storaged_aidl", ":vold_aidl", ":gsiservice_aidl", ":installd_aidl", ":dumpstate_aidl", Loading Loading @@ -657,6 +659,7 @@ java_defaults { "frameworks/native/aidl/gui", "system/core/storaged/binder", "system/vold/binder", "system/gsid/aidl", "system/bt/binder", "system/security/keystore/binder", ], Loading
api/system-current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -838,6 +838,7 @@ package android.content { method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void startActivityAsUser(@RequiresPermission android.content.Intent, android.os.UserHandle); field public static final String BACKUP_SERVICE = "backup"; field public static final String CONTEXTHUB_SERVICE = "contexthub"; field public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; field public static final String EUICC_CARD_SERVICE = "euicc_card"; field public static final String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final String NETD_SERVICE = "netd"; Loading
core/java/android/app/SystemServiceRegistry.java +12 −0 Original line number Diff line number Diff line Loading @@ -114,11 +114,13 @@ import android.os.BugreportManager; import android.os.Build; import android.os.DeviceIdleManager; import android.os.DropBoxManager; import android.os.DynamicAndroidManager; import android.os.HardwarePropertiesManager; import android.os.IBatteryPropertiesRegistrar; import android.os.IBinder; import android.os.IDeviceIdleController; import android.os.IDumpstate; import android.os.IDynamicAndroidService; import android.os.IHardwarePropertiesManager; import android.os.IPowerManager; import android.os.IRecoverySystem; Loading Loading @@ -1065,6 +1067,16 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new TimeZoneDetector(); }}); registerService(Context.DYNAMIC_ANDROID_SERVICE, DynamicAndroidManager.class, new CachedServiceFetcher<DynamicAndroidManager>() { @Override public DynamicAndroidManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow( Context.DYNAMIC_ANDROID_SERVICE); return new DynamicAndroidManager( IDynamicAndroidService.Stub.asInterface(b)); }}); } /** Loading
core/java/android/content/Context.java +8 −0 Original line number Diff line number Diff line Loading @@ -4304,6 +4304,14 @@ public abstract class Context { */ public static final String TELEPHONY_RCS_SERVICE = "ircs"; /** * Use with {@link #getSystemService(String)} to retrieve an * {@link android.os.DynamicAndroidManager}. * @hide */ @SystemApi public static final String DYNAMIC_ANDROID_SERVICE = "dynamic_android"; /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. Loading
core/java/android/os/DynamicAndroidManager.java 0 → 100644 +188 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.os; import android.annotation.RequiresPermission; import android.annotation.SystemService; import android.content.Context; import android.gsi.GsiProgress; /** * The DynamicAndroidManager offers a mechanism to use a new Android image temporarily. After the * installation, the device can reboot into this image with a new created /data. This image will * last until the next reboot and then the device will go back to the original image. However the * installed image and the new created /data are not deleted but disabled. Thus the application can * either re-enable the installed image by calling {@link #toggle} or use the {@link #remove} to * delete it completely. In other words, there are three device states: no installation, installed * and running. The procedure to install a DynamicAndroid starts with a {@link #startInstallation}, * followed by a series of {@link #write} and ends with a {@link commit}. Once the installation is * complete, the device state changes from no installation to the installed state and a followed * reboot will change its state to running. Note one instance of dynamic android can exist on a * given device thus the {@link #startInstallation} will fail if the device is currently running a * DynamicAndroid. * * @hide */ @SystemService(Context.DYNAMIC_ANDROID_SERVICE) public class DynamicAndroidManager { private static final String TAG = "DynamicAndroidManager"; private final IDynamicAndroidService mService; /** {@hide} */ public DynamicAndroidManager(IDynamicAndroidService service) { mService = service; } /** The DynamicAndroidManager.Session represents a started session for the installation. */ public class Session { private Session() {} /** * Write a chunk of the DynamicAndroid system image * * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean write(byte[] buf) { try { return mService.write(buf); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Finish write and make device to boot into the it after reboot. * * @return {@code true} if the call succeeds. {@code false} if there is any native runtime * error. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean commit() { try { return mService.commit(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } } /** * Start DynamicAndroid installation. This call may take an unbounded amount of time. The caller * may use another thread to call the getStartProgress() to get the progress. * * @param systemSize system size in bytes * @param userdataSize userdata size in bytes * @return {@code true} if the call succeeds. {@code false} either the device does not contain * enough space or a DynamicAndroid is currently in use where the {@link #isInUse} would be * true. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public Session startInstallation(long systemSize, long userdataSize) { try { if (mService.startInstallation(systemSize, userdataSize)) { return new Session(); } else { return null; } } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Query the progress of the current installation operation. This can be called while the * installation is in progress. * * @return GsiProgress GsiProgress { int status; long bytes_processed; long total_bytes; } The * status field can be IGsiService.STATUS_NO_OPERATION, IGsiService.STATUS_WORKING or * IGsiService.STATUS_COMPLETE. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public GsiProgress getInstallationProgress() { try { return mService.getInstallationProgress(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Abort the installation process. Note this method must be called in a thread other than the * one calling the startInstallation method as the startInstallation method will not return * until it is finished. * * @return {@code true} if the call succeeds. {@code false} if there is no installation * currently. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean abort() { try { return mService.abort(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** @return {@code true} if the device is running a dynamic android */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean isInUse() { try { return mService.isInUse(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** @return {@code true} if the device has a dynamic android installed */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean isInstalled() { try { return mService.isInstalled(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Remove DynamicAndroid installation if present * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean remove() { try { return mService.remove(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } /** * Enable DynamicAndroid when it's not enabled, otherwise, disable it. * * @return {@code true} if the call succeeds. {@code false} if there is no installed image. */ @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_ANDROID) public boolean toggle() { try { return mService.toggle(); } catch (RemoteException e) { throw new RuntimeException(e.toString()); } } }