Abort long-running benchmarks, report progress.
A typical storage device finishes the benchmark in under 10 seconds, but some extremely slow devices can take minutes, resulting in a confusing UX that looks like we've frozen. Even worse, we keep churning through all that I/O even though we know the device will blow past our user-warning threshold. So periodically check if we've timed out, and also use that to report progress up into the Settings UI. Test: manual Bug: 62201209, 65639764, 67055204 Exempt-From-Owner-Approval: I wrote the original code. Change-Id: Idd9d8c181651202d1434af879cff9355478a25c1
This commit is contained in:
@@ -16,15 +16,19 @@
|
|||||||
|
|
||||||
package com.android.settings.deviceinfo;
|
package com.android.settings.deviceinfo;
|
||||||
|
|
||||||
|
import static com.android.settings.deviceinfo.StorageSettings.TAG;
|
||||||
|
|
||||||
import android.annotation.LayoutRes;
|
import android.annotation.LayoutRes;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.SystemClock;
|
||||||
import android.os.storage.DiskInfo;
|
import android.os.storage.DiskInfo;
|
||||||
import android.os.storage.StorageEventListener;
|
import android.os.storage.StorageEventListener;
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.os.storage.VolumeInfo;
|
import android.os.storage.VolumeInfo;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
@@ -202,13 +206,27 @@ public abstract class StorageWizardBase extends Activity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected VolumeInfo findFirstVolume(int type) {
|
protected VolumeInfo findFirstVolume(int type) {
|
||||||
final List<VolumeInfo> vols = mStorage.getVolumes();
|
return findFirstVolume(type, 1);
|
||||||
for (VolumeInfo vol : vols) {
|
}
|
||||||
if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type)) {
|
|
||||||
return vol;
|
protected VolumeInfo findFirstVolume(int type, int attempts) {
|
||||||
|
while (true) {
|
||||||
|
final List<VolumeInfo> vols = mStorage.getVolumes();
|
||||||
|
for (VolumeInfo vol : vols) {
|
||||||
|
if (Objects.equals(mDisk.getId(), vol.getDiskId()) && (vol.getType() == type)
|
||||||
|
&& (vol.getState() == VolumeInfo.STATE_MOUNTED)) {
|
||||||
|
return vol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--attempts > 0) {
|
||||||
|
Log.w(TAG, "Missing mounted volume of type " + type + " hosted by disk "
|
||||||
|
+ mDisk.getId() + "; trying again");
|
||||||
|
SystemClock.sleep(250);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final StorageEventListener mStorageListener = new StorageEventListener() {
|
private final StorageEventListener mStorageListener = new StorageEventListener() {
|
||||||
|
@@ -16,15 +16,20 @@
|
|||||||
|
|
||||||
package com.android.settings.deviceinfo;
|
package com.android.settings.deviceinfo;
|
||||||
|
|
||||||
|
import static android.os.storage.VolumeInfo.TYPE_PRIVATE;
|
||||||
|
|
||||||
|
import static com.android.settings.deviceinfo.StorageSettings.TAG;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.DialogFragment;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.IPackageMoveObserver;
|
import android.content.pm.IPackageMoveObserver;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IVoldTaskListener;
|
||||||
|
import android.os.PersistableBundle;
|
||||||
import android.os.storage.DiskInfo;
|
import android.os.storage.DiskInfo;
|
||||||
import android.os.storage.StorageManager;
|
import android.os.storage.StorageManager;
|
||||||
import android.os.storage.VolumeInfo;
|
import android.os.storage.VolumeInfo;
|
||||||
@@ -38,8 +43,8 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
import static com.android.settings.deviceinfo.StorageSettings.TAG;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class StorageWizardFormatProgress extends StorageWizardBase {
|
public class StorageWizardFormatProgress extends StorageWizardBase {
|
||||||
private static final String TAG_SLOW_WARNING = "slow_warning";
|
private static final String TAG_SLOW_WARNING = "slow_warning";
|
||||||
@@ -99,9 +104,21 @@ public class StorageWizardFormatProgress extends StorageWizardBase {
|
|||||||
storage.partitionPrivate(activity.mDisk.getId());
|
storage.partitionPrivate(activity.mDisk.getId());
|
||||||
publishProgress(40);
|
publishProgress(40);
|
||||||
|
|
||||||
final VolumeInfo privateVol = activity.findFirstVolume(VolumeInfo.TYPE_PRIVATE);
|
final VolumeInfo privateVol = activity.findFirstVolume(TYPE_PRIVATE, 5);
|
||||||
mPrivateBench = storage.benchmark(privateVol.getId());
|
final CompletableFuture<PersistableBundle> result = new CompletableFuture<>();
|
||||||
mPrivateBench /= 1000000;
|
storage.benchmark(privateVol.getId(), new IVoldTaskListener.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onStatus(int status, PersistableBundle extras) {
|
||||||
|
// Map benchmark 0-100% progress onto 40-80%
|
||||||
|
publishProgress(40 + ((status * 40) / 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinished(int status, PersistableBundle extras) {
|
||||||
|
result.complete(extras);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mPrivateBench = result.get(60, TimeUnit.SECONDS).getLong("run", Long.MAX_VALUE);
|
||||||
|
|
||||||
// If we just adopted the device that had been providing
|
// If we just adopted the device that had been providing
|
||||||
// physical storage, then automatically move storage to the
|
// physical storage, then automatically move storage to the
|
||||||
|
Reference in New Issue
Block a user