Commit 3ec52b9c authored by David Trainor's avatar David Trainor Committed by Commit Bot

Add helper adapter to AsyncFeedbackSource

Add a helper class to make extending AsyncFeedbackSource easy for the
common case.  This removes all of the work involving the AsyncTask,
status management, callback triggering, etc.

BUG=773403

Change-Id: Ic64a41dea7bf49cc005850418967a9f36da6df40
Reviewed-on: https://chromium-review.googlesource.com/811824
Commit-Queue: David Trainor <dtrainor@chromium.org>
Reviewed-by: default avatarTommy Nyquist <nyquist@chromium.org>
Cr-Commit-Position: refs/heads/master@{#522502}
parent 80a982a1
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.feedback;
import android.content.Context;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import org.chromium.base.ContextUtils;
import java.util.concurrent.ExecutionException;
/**
* A helper class to make implementing an AsyncFeedbackSource easier for the common case. The bulk
* of the background work is meant to be done in {@link #doInBackground(Context)} and the result can
* be queried from {@link #getResult()}. Subclasses are meant to override {@link #getFeedback()} or
* {@link #getLogs()} as necessary and use {@link #getResult()} if they need the result from the
* asynchronous work.
* @param <Result> The {@link Object} type that represents the result of doing the background work.
*/
public abstract class AsyncFeedbackSourceAdapter<Result> implements AsyncFeedbackSource {
private Worker mWorker;
private class Worker extends AsyncTask<Context, Void, Result> {
private final Runnable mCallback;
public Worker(Runnable callback) {
mCallback = callback;
}
// AsyncTask implementation.
@Override
protected Result doInBackground(Context... params) {
return AsyncFeedbackSourceAdapter.this.doInBackground(params[0]);
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
mCallback.run();
}
}
/**
* Meant to do the actual work in the background. This method will be called from a thread in
* the {@link AsyncTask} thread pool.
* @param context The application {@link Context}.
* @return The result of doing the work in the background or {@code null}.
*/
protected abstract Result doInBackground(Context context);
/**
* @return The result of the background work if it has been started and finished. This will be
* null if the underlying background task has not finished yet (see {@link #isReady()})
* or if {@link #doInBackground(Context)} returned {@code null}.
*/
protected final Result getResult() {
try {
return mWorker != null && mWorker.getStatus() == Status.FINISHED ? mWorker.get() : null;
} catch (ExecutionException | InterruptedException e) {
return null;
}
}
// AsyncFeedbackSource implementation.
@Override
public final boolean isReady() {
return mWorker != null && mWorker.getStatus() == Status.FINISHED;
}
@Override
public final void start(Runnable callback) {
if (mWorker != null) return;
mWorker = new Worker(callback);
mWorker.executeOnExecutor(
AsyncTask.THREAD_POOL_EXECUTOR, ContextUtils.getApplicationContext());
}
}
\ No newline at end of file
......@@ -4,8 +4,7 @@
package org.chromium.chrome.browser.feedback;
import android.os.AsyncTask;
import android.os.AsyncTask.Status;
import android.content.Context;
import android.os.Environment;
import android.os.StatFs;
import android.util.Pair;
......@@ -17,78 +16,19 @@ import org.chromium.base.annotations.JNINamespace;
import java.io.File;
import java.util.Map;
import java.util.concurrent.ExecutionException;
/** Grabs feedback about the current system. */
@JNINamespace("chrome::android")
public class SystemInfoFeedbackSource implements AsyncFeedbackSource {
private StorageTask mStorageTask;
private static class StorageTask extends AsyncTask<Void, Void, StatFs> {
private Runnable mCallback;
public StorageTask(Runnable callback) {
mCallback = callback;
}
Long getAvailableSpaceMB() {
if (getStatus() != Status.FINISHED) return null;
try {
StatFs statFs = get();
if (statFs == null) return null;
long blockSize = ApiCompatibilityUtils.getBlockSize(statFs);
return ApiCompatibilityUtils.getAvailableBlocks(statFs) * blockSize / 1024 / 1024;
} catch (ExecutionException | InterruptedException e) {
return null;
}
}
Long getTotalSpaceMB() {
if (getStatus() != Status.FINISHED) return null;
try {
StatFs statFs = get();
if (statFs == null) return null;
long blockSize = ApiCompatibilityUtils.getBlockSize(statFs);
return ApiCompatibilityUtils.getBlockCount(statFs) * blockSize / 1024 / 1024;
} catch (ExecutionException | InterruptedException e) {
return null;
}
}
// AsyncTask implementation.
public class SystemInfoFeedbackSource extends AsyncFeedbackSourceAdapter<StatFs> {
// AsyncFeedbackSourceAdapter implementation.
@Override
protected StatFs doInBackground(Void... params) {
protected StatFs doInBackground(Context context) {
File directory = Environment.getDataDirectory();
if (!directory.exists()) return null;
return new StatFs(directory.getPath());
}
@Override
protected void onPostExecute(StatFs result) {
super.onPostExecute(result);
mCallback.run();
}
}
SystemInfoFeedbackSource() {}
// AsyncFeedbackSource implementation.
@Override
public boolean isReady() {
return mStorageTask != null && mStorageTask.getStatus() == Status.FINISHED;
}
@Override
public void start(Runnable callback) {
if (mStorageTask != null) return;
mStorageTask = new StorageTask(callback);
mStorageTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
@Override
public Map<String, String> getFeedback() {
Map<String, String> feedback = CollectionUtil.newHashMap(
......@@ -100,12 +40,15 @@ public class SystemInfoFeedbackSource implements AsyncFeedbackSource {
Pair.create("GPU Model", nativeGetGpuModel()),
Pair.create("UI Locale", LocaleUtils.getDefaultLocaleString()));
if (isReady()) {
Long availSpace = mStorageTask.getAvailableSpaceMB();
Long totalSpace = mStorageTask.getTotalSpaceMB();
StatFs statFs = getResult();
if (statFs != null) {
long blockSize = ApiCompatibilityUtils.getBlockSize(statFs);
long availSpace =
ApiCompatibilityUtils.getAvailableBlocks(statFs) * blockSize / 1024 / 1024;
long totalSpace = ApiCompatibilityUtils.getBlockCount(statFs) * blockSize / 1024 / 1024;
if (availSpace != null) feedback.put("Available Storage (MB)", availSpace.toString());
if (totalSpace != null) feedback.put("Total Storage (MB)", totalSpace.toString());
feedback.put("Available Storage (MB)", Long.toString(availSpace));
feedback.put("Total Storage (MB)", Long.toString(totalSpace));
}
return feedback;
......
......@@ -409,6 +409,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitor.java",
"java/src/org/chromium/chrome/browser/feature_engagement/ScreenshotMonitorDelegate.java",
"java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/AsyncFeedbackSourceAdapter.java",
"java/src/org/chromium/chrome/browser/feedback/ChromeHomeFeedbackSource.java",
"java/src/org/chromium/chrome/browser/feedback/ConnectivityChecker.java",
"java/src/org/chromium/chrome/browser/feedback/ConnectivityFeedbackSource.java",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment