Merge changes from topics "dsu_ashmem", "dsu_clean_up"

am: 417aed2c61

Change-Id: I3382c8a7aca1fadb9e7ef37d050b52e1fff69155
This commit is contained in:
Howard Chen
2019-09-28 04:56:30 -07:00
committed by android-build-merger
5 changed files with 70 additions and 42 deletions

View File

@@ -20,6 +20,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemService; import android.annotation.SystemService;
import android.content.Context; import android.content.Context;
import android.gsi.GsiProgress; import android.gsi.GsiProgress;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
/** /**
@@ -52,21 +53,38 @@ public class DynamicSystemManager {
/** The DynamicSystemManager.Session represents a started session for the installation. */ /** The DynamicSystemManager.Session represents a started session for the installation. */
public class Session { public class Session {
private Session() {} private Session() {}
/** /**
* Write a chunk of the DynamicSystem system image * Set the file descriptor that points to a ashmem which will be used
* to fetch data during the submitFromAshmem.
* *
* @return {@code true} if the call succeeds. {@code false} if there is any native runtime * @param ashmem fd that points to a ashmem
* error. * @param size size of the ashmem file
*/ */
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean write(byte[] buf) { public boolean setAshmem(ParcelFileDescriptor ashmem, long size) {
try { try {
return mService.write(buf); return mService.setAshmem(ashmem, size);
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException(e.toString()); throw new RuntimeException(e.toString());
} }
} }
/**
* Submit bytes to the DSU partition from the ashmem previously set with
* setAshmem.
*
* @param size Number of bytes
* @return true on success, false otherwise.
*/
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean submitFromAshmem(int size) {
try {
return mService.submitFromAshmem(size);
} catch (RemoteException e) {
throw new RuntimeException(e.toString());
}
}
/** /**
* Finish write and make device to boot into the it after reboot. * Finish write and make device to boot into the it after reboot.
* *
@@ -76,7 +94,7 @@ public class DynamicSystemManager {
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean commit() { public boolean commit() {
try { try {
return mService.commit(); return mService.setEnable(true, true);
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException(e.toString()); throw new RuntimeException(e.toString());
} }
@@ -188,9 +206,9 @@ public class DynamicSystemManager {
* @return {@code true} if the call succeeds. {@code false} if there is no installed image. * @return {@code true} if the call succeeds. {@code false} if there is no installed image.
*/ */
@RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM) @RequiresPermission(android.Manifest.permission.MANAGE_DYNAMIC_SYSTEM)
public boolean setEnable(boolean enable) { public boolean setEnable(boolean enable, boolean oneShot) {
try { try {
return mService.setEnable(enable); return mService.setEnable(enable, oneShot);
} catch (RemoteException e) { } catch (RemoteException e) {
throw new RuntimeException(e.toString()); throw new RuntimeException(e.toString());
} }

View File

@@ -72,21 +72,27 @@ interface IDynamicSystemService
/** /**
* Enable or disable DynamicSystem. * Enable or disable DynamicSystem.
* *
* @return true if the call succeeds * @param oneShot If true, the GSI will boot once and then disable itself.
*/
boolean setEnable(boolean enable);
/**
* Write a chunk of the DynamicSystem system image
* *
* @return true if the call succeeds * @return true if the call succeeds
*/ */
boolean write(in byte[] buf); boolean setEnable(boolean enable, boolean oneShot);
/** /**
* Finish write and make device to boot into the it after reboot. * Set the file descriptor that points to a ashmem which will be used
* to fetch data during the submitFromAshmem.
* *
* @return true if the call succeeds * @param fd fd that points to a ashmem
* @param size size of the ashmem file
*/ */
boolean commit(); boolean setAshmem(in ParcelFileDescriptor fd, long size);
/**
* Submit bytes to the DSU partition from the ashmem previously set with
* setAshmem.
*
* @param bytes number of bytes that can be read from stream.
* @return true on success, false otherwise.
*/
boolean submitFromAshmem(long bytes);
} }

View File

@@ -291,7 +291,7 @@ public class DynamicSystemInstallationService extends Service
if (mInstallTask != null && mInstallTask.getResult() == RESULT_OK) { if (mInstallTask != null && mInstallTask.getResult() == RESULT_OK) {
enabled = mInstallTask.commit(); enabled = mInstallTask.commit();
} else if (isDynamicSystemInstalled()) { } else if (isDynamicSystemInstalled()) {
enabled = mDynSystem.setEnable(true); enabled = mDynSystem.setEnable(true, true);
} else { } else {
Log.e(TAG, "Trying to reboot to AOT while there is no complete installation"); Log.e(TAG, "Trying to reboot to AOT while there is no complete installation");
return; return;

View File

@@ -20,6 +20,8 @@ import android.content.Context;
import android.gsi.GsiProgress; import android.gsi.GsiProgress;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.MemoryFile;
import android.os.ParcelFileDescriptor;
import android.os.image.DynamicSystemManager; import android.os.image.DynamicSystemManager;
import android.util.Log; import android.util.Log;
import android.webkit.URLUtil; import android.webkit.URLUtil;
@@ -28,11 +30,9 @@ import java.io.BufferedInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> { class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
private static final String TAG = "InstallationAsyncTask"; private static final String TAG = "InstallationAsyncTask";
@@ -125,28 +125,26 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
Thread.sleep(10); Thread.sleep(10);
} }
if (mInstallationSession == null) { if (mInstallationSession == null) {
throw new IOException("Failed to start installation with requested size: " throw new IOException(
+ (mSystemSize + mUserdataSize)); "Failed to start installation with requested size: "
+ (mSystemSize + mUserdataSize));
} }
installedSize = mUserdataSize; installedSize = mUserdataSize;
MemoryFile memoryFile = new MemoryFile("dsu", READ_BUFFER_SIZE);
byte[] bytes = new byte[READ_BUFFER_SIZE]; byte[] bytes = new byte[READ_BUFFER_SIZE];
mInstallationSession.setAshmem(
new ParcelFileDescriptor(memoryFile.getFileDescriptor()), READ_BUFFER_SIZE);
int numBytesRead; int numBytesRead;
Log.d(TAG, "Start installation loop"); Log.d(TAG, "Start installation loop");
while ((numBytesRead = mStream.read(bytes, 0, READ_BUFFER_SIZE)) != -1) { while ((numBytesRead = mStream.read(bytes, 0, READ_BUFFER_SIZE)) != -1) {
memoryFile.writeBytes(bytes, 0, 0, numBytesRead);
if (isCancelled()) { if (isCancelled()) {
break; break;
} }
if (!mInstallationSession.submitFromAshmem(numBytesRead)) {
byte[] writeBuffer = numBytesRead == READ_BUFFER_SIZE
? bytes : Arrays.copyOf(bytes, numBytesRead);
if (!mInstallationSession.write(writeBuffer)) {
throw new IOException("Failed write() to DynamicSystem"); throw new IOException("Failed write() to DynamicSystem");
} }
@@ -157,7 +155,6 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
reportedInstalledSize = installedSize; reportedInstalledSize = installedSize;
} }
} }
return null; return null;
} catch (Exception e) { } catch (Exception e) {

View File

@@ -25,6 +25,7 @@ import android.gsi.IGsid;
import android.os.Environment; import android.os.Environment;
import android.os.IBinder; import android.os.IBinder;
import android.os.IBinder.DeathRecipient; import android.os.IBinder.DeathRecipient;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.os.SystemProperties; import android.os.SystemProperties;
@@ -181,28 +182,34 @@ public class DynamicSystemService extends IDynamicSystemService.Stub implements
@Override @Override
public boolean remove() throws RemoteException { public boolean remove() throws RemoteException {
return getGsiService().removeGsiInstall(); return getGsiService().removeGsi();
} }
@Override @Override
public boolean setEnable(boolean enable) throws RemoteException { public boolean setEnable(boolean enable, boolean oneShot) throws RemoteException {
IGsiService gsiService = getGsiService(); IGsiService gsiService = getGsiService();
if (enable) { if (enable) {
final int status = gsiService.getGsiBootStatus(); return gsiService.enableGsi(oneShot) == 0;
final boolean singleBoot = (status == IGsiService.BOOT_STATUS_SINGLE_BOOT);
return gsiService.setGsiBootable(singleBoot) == 0;
} else { } else {
return gsiService.disableGsiInstall(); return gsiService.disableGsi();
} }
} }
@Override @Override
public boolean write(byte[] buf) throws RemoteException { public boolean setAshmem(ParcelFileDescriptor ashmem, long size) {
return getGsiService().commitGsiChunkFromMemory(buf); try {
return getGsiService().setGsiAshmem(ashmem, size);
} catch (RemoteException e) {
throw new RuntimeException(e.toString());
}
} }
@Override @Override
public boolean commit() throws RemoteException { public boolean submitFromAshmem(long size) {
return getGsiService().setGsiBootable(true) == 0; try {
return getGsiService().commitGsiChunkFromAshmem(size);
} catch (RemoteException e) {
throw new RuntimeException(e.toString());
}
} }
} }