Merge changes I8942a2db,Ibcef3f40,I6e765563 into rvc-dev

* changes:
  [incfs] Cleanup storage creation and don't use temp directory
  [incfs] Notify IncrementalService about system startup later
  [incfs] Fix bad path::join() path preparation
This commit is contained in:
Yurii Zubrytskyi
2020-04-22 18:25:49 +00:00
committed by Android (Google) Code Review
3 changed files with 59 additions and 91 deletions

View File

@@ -38,16 +38,10 @@ import android.content.pm.DataLoaderParams;
import android.content.pm.IDataLoaderStatusListener; import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.InstallationFileParcel; import android.content.pm.InstallationFileParcel;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Slog;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Random;
/** /**
* This class manages storage instances used during a package installation session. * This class manages storage instances used during a package installation session.
@@ -56,13 +50,9 @@ import java.util.Random;
public final class IncrementalFileStorages { public final class IncrementalFileStorages {
private static final String TAG = "IncrementalFileStorages"; private static final String TAG = "IncrementalFileStorages";
private static final String TMP_DIR_ROOT = "/data/incremental/tmp"; private @NonNull final IncrementalManager mIncrementalManager;
private static final Random TMP_DIR_RANDOM = new Random(); private @NonNull final File mStageDir;
private @Nullable IncrementalStorage mDefaultStorage; private @Nullable IncrementalStorage mDefaultStorage;
private @Nullable String mDefaultDir;
private @NonNull IncrementalManager mIncrementalManager;
private @NonNull File mStageDir;
/** /**
* Set up files and directories used in an installation session. Only used by Incremental. * Set up files and directories used in an installation session. Only used by Incremental.
@@ -85,15 +75,9 @@ public final class IncrementalFileStorages {
throw new IOException("Failed to obtain incrementalManager."); throw new IOException("Failed to obtain incrementalManager.");
} }
IncrementalFileStorages result = null; final IncrementalFileStorages result =
try { new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams,
result = new IncrementalFileStorages(stageDir, incrementalManager, dataLoaderParams,
dataLoaderStatusListener); dataLoaderStatusListener);
if (!addedFiles.isEmpty()) {
result.mDefaultStorage.bind(stageDir.getAbsolutePath());
}
for (InstallationFileParcel file : addedFiles) { for (InstallationFileParcel file : addedFiles) {
if (file.location == LOCATION_DATA_APP) { if (file.location == LOCATION_DATA_APP) {
try { try {
@@ -108,49 +92,46 @@ public final class IncrementalFileStorages {
} }
} }
// TODO(b/146080380): remove 5 secs wait in startLoading
if (!result.mDefaultStorage.startLoading()) { if (!result.mDefaultStorage.startLoading()) {
// TODO(b/146080380): add incremental-specific error code // TODO(b/146080380): add incremental-specific error code
throw new IOException("Failed to start loading data for Incremental installation."); throw new IOException("Failed to start loading data for Incremental installation.");
} }
return result; return result;
} catch (IOException e) {
Slog.e(TAG, "Failed to initialize Incremental file storages. Cleaning up...", e);
if (result != null) {
result.cleanUp();
}
throw e;
}
} }
private IncrementalFileStorages(@NonNull File stageDir, private IncrementalFileStorages(@NonNull File stageDir,
@NonNull IncrementalManager incrementalManager, @NonNull IncrementalManager incrementalManager,
@NonNull DataLoaderParams dataLoaderParams, @NonNull DataLoaderParams dataLoaderParams,
@Nullable IDataLoaderStatusListener dataLoaderStatusListener) throws IOException { @Nullable IDataLoaderStatusListener dataLoaderStatusListener) throws IOException {
try {
mStageDir = stageDir; mStageDir = stageDir;
mIncrementalManager = incrementalManager; mIncrementalManager = incrementalManager;
if (dataLoaderParams.getComponentName().getPackageName().equals("local")) { if (dataLoaderParams.getComponentName().getPackageName().equals("local")) {
final String incrementalPath = dataLoaderParams.getArguments(); final String incrementalPath = dataLoaderParams.getArguments();
mDefaultDir = incrementalPath; if (TextUtils.isEmpty(incrementalPath)) {
if (TextUtils.isEmpty(mDefaultDir)) {
throw new IOException("Failed to create storage: incrementalPath is empty"); throw new IOException("Failed to create storage: incrementalPath is empty");
} }
mDefaultStorage = mIncrementalManager.openStorage(incrementalPath); mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
} else { if (mDefaultStorage == null) {
mDefaultDir = getTempDir(); throw new IOException(
if (mDefaultDir == null) { "Couldn't open incremental storage at " + incrementalPath);
throw new IOException("Failed to create storage: tempDir is empty");
} }
mDefaultStorage = mIncrementalManager.createStorage(mDefaultDir, mDefaultStorage.bind(stageDir.getAbsolutePath());
} else {
mDefaultStorage = mIncrementalManager.createStorage(stageDir.getAbsolutePath(),
dataLoaderParams, dataLoaderParams,
dataLoaderStatusListener, dataLoaderStatusListener,
IncrementalManager.CREATE_MODE_CREATE IncrementalManager.CREATE_MODE_CREATE
| IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false); | IncrementalManager.CREATE_MODE_TEMPORARY_BIND, false);
}
if (mDefaultStorage == null) { if (mDefaultStorage == null) {
throw new IOException("Failed to create storage"); throw new IOException(
"Couldn't create incremental storage at " + stageDir);
}
}
} catch (IOException e) {
cleanUp();
throw e;
} }
} }
@@ -167,27 +148,14 @@ public final class IncrementalFileStorages {
* TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept * TODO(b/136132412): make sure unnecessary binds are removed but useful storages are kept
*/ */
public void cleanUp() { public void cleanUp() {
Objects.requireNonNull(mDefaultStorage); if (mDefaultStorage == null) {
return;
}
try { try {
mDefaultStorage.unBind(mDefaultDir);
mDefaultStorage.unBind(mStageDir.getAbsolutePath()); mDefaultStorage.unBind(mStageDir.getAbsolutePath());
} catch (IOException ignored) { } catch (IOException ignored) {
} }
mDefaultDir = null;
mDefaultStorage = null; mDefaultStorage = null;
} }
private static String getTempDir() {
final Path tmpDir = Paths.get(TMP_DIR_ROOT,
String.valueOf(TMP_DIR_RANDOM.nextInt(Integer.MAX_VALUE - 1)));
try {
Files.createDirectories(tmpDir);
} catch (Exception ex) {
Slog.e(TAG, "Failed to create dir", ex);
return null;
}
return tmpDir.toAbsolutePath().toString();
}
} }

View File

@@ -44,7 +44,7 @@ bool PathLess::operator()(std::string_view l, std::string_view r) const {
PathCharsLess()); PathCharsLess());
} }
static void preparePathComponent(std::string_view path, bool trimFront) { static void preparePathComponent(std::string_view& path, bool trimFront) {
if (trimFront) { if (trimFront) {
while (!path.empty() && path.front() == '/') { while (!path.empty() && path.front() == '/') {
path.remove_prefix(1); path.remove_prefix(1);

View File

@@ -2174,12 +2174,6 @@ public final class SystemServer {
mPackageManagerService.systemReady(); mPackageManagerService.systemReady();
t.traceEnd(); t.traceEnd();
if (mIncrementalServiceHandle != 0) {
t.traceBegin("MakeIncrementalServiceReady");
setIncrementalServiceSystemReady(mIncrementalServiceHandle);
t.traceEnd();
}
t.traceBegin("MakeDisplayManagerServiceReady"); t.traceBegin("MakeDisplayManagerServiceReady");
try { try {
// TODO: use boot phase and communicate these flags some other way // TODO: use boot phase and communicate these flags some other way
@@ -2449,6 +2443,12 @@ public final class SystemServer {
reportWtf("Notifying incident daemon running", e); reportWtf("Notifying incident daemon running", e);
} }
t.traceEnd(); t.traceEnd();
if (mIncrementalServiceHandle != 0) {
t.traceBegin("MakeIncrementalServiceReady");
setIncrementalServiceSystemReady(mIncrementalServiceHandle);
t.traceEnd();
}
}, t); }, t);
t.traceEnd(); // startOtherServices t.traceEnd(); // startOtherServices