WebView Tracing API: address comments from the API council.
Address comments from the API council regarding the WebView Tracing API.
android.webkit.TracingController:
* start() throws IllegalStateException if the system is already tracing
(this is instead of returning false)
* stop uses Executor instead of Handler
* removed stop() (the method w/o arguments)
* renamed stopAndFlush to stop
* use OutputStream instead of a custom callback interface TracingOutputStream
* dropped requirement for UI threading
* updated documentation
android.webkit.TracingFileOutputStream:
* removed the TracingFileOutputStream file completely (functionality
replaced by the existing FileOutputStream)
android.webkit.TracingConfig:
* removed example with CATEGORIES_NONE and “-input,-gpu”.
* customCategories are List<String> instead of String
* updated documentation
* added two more predefined categories: CATEGORIES_ALL,
CATEGORIES_ANDROID_WEBVIEW
* some refactoring, added a Builder class
* ensure that only include category patterns can be specified
* uniform addCategories interface for construction
* predefined category sets are a bitmask now
BUG: 71584598,71584599,63750258
Test: CTS
Change-Id: I615ef5f43d26968329182b09e7c26178f1f85ecc
diff --git a/api/current.txt b/api/current.txt
index 1fb64ed..fcc3ea7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -49685,41 +49685,37 @@
}
public class TracingConfig {
- ctor public TracingConfig(int);
- ctor public TracingConfig(int, java.lang.String, int);
- method public java.lang.String getCustomCategoryPattern();
- method public int getPresetCategories();
+ method public java.util.List<java.lang.String> getCustomIncludedCategories();
+ method public int getPredefinedCategories();
method public int getTracingMode();
- field public static final int CATEGORIES_FRAME_VIEWER = 4; // 0x4
- field public static final int CATEGORIES_INPUT_LATENCY = 1; // 0x1
- field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 3; // 0x3
- field public static final int CATEGORIES_NONE = -1; // 0xffffffff
- field public static final int CATEGORIES_RENDERING = 2; // 0x2
- field public static final int CATEGORIES_WEB_DEVELOPER = 0; // 0x0
+ field public static final int CATEGORIES_ALL = 1; // 0x1
+ field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+ field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+ field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+ field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+ field public static final int CATEGORIES_NONE = 0; // 0x0
+ field public static final int CATEGORIES_RENDERING = 16; // 0x10
+ field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
- field public static final int RECORD_TO_CONSOLE = 3; // 0x3
field public static final int RECORD_UNTIL_FULL = 0; // 0x0
field public static final int RECORD_UNTIL_FULL_LARGE_BUFFER = 2; // 0x2
}
+ public static class TracingConfig.Builder {
+ ctor public TracingConfig.Builder();
+ method public android.webkit.TracingConfig.Builder addCategories(int...);
+ method public android.webkit.TracingConfig.Builder addCategories(java.lang.String...);
+ method public android.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String>);
+ method public android.webkit.TracingConfig build();
+ method public android.webkit.TracingConfig.Builder setTracingMode(int);
+ }
+
public abstract class TracingController {
ctor public TracingController();
method public static android.webkit.TracingController getInstance();
method public abstract boolean isTracing();
- method public abstract boolean start(android.webkit.TracingConfig);
- method public abstract boolean stop();
- method public abstract boolean stopAndFlush(android.webkit.TracingController.TracingOutputStream, android.os.Handler);
- }
-
- public static abstract interface TracingController.TracingOutputStream {
- method public abstract void complete();
- method public abstract void write(byte[]);
- }
-
- public class TracingFileOutputStream implements android.webkit.TracingController.TracingOutputStream {
- ctor public TracingFileOutputStream(java.lang.String) throws java.io.FileNotFoundException;
- method public void complete();
- method public void write(byte[]);
+ method public abstract void start(android.webkit.TracingConfig);
+ method public abstract boolean stop(java.io.OutputStream, java.util.concurrent.Executor);
}
public final class URLUtil {
diff --git a/core/java/android/webkit/TracingConfig.java b/core/java/android/webkit/TracingConfig.java
index 75e2bf7..68badec 100644
--- a/core/java/android/webkit/TracingConfig.java
+++ b/core/java/android/webkit/TracingConfig.java
@@ -21,61 +21,76 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
/**
* Holds tracing configuration information and predefined settings.
*/
public class TracingConfig {
- private final String mCustomCategoryPattern;
- private final @PresetCategories int mPresetCategories;
+ private @PredefinedCategories int mPredefinedCategories;
+ private final List<String> mCustomIncludedCategories = new ArrayList<String>();
private @TracingMode int mTracingMode;
/** @hide */
- @IntDef({CATEGORIES_NONE, CATEGORIES_WEB_DEVELOPER, CATEGORIES_INPUT_LATENCY,
- CATEGORIES_RENDERING, CATEGORIES_JAVASCRIPT_AND_RENDERING, CATEGORIES_FRAME_VIEWER})
+ @IntDef(flag = true, value = {CATEGORIES_NONE, CATEGORIES_WEB_DEVELOPER,
+ CATEGORIES_INPUT_LATENCY, CATEGORIES_RENDERING, CATEGORIES_JAVASCRIPT_AND_RENDERING,
+ CATEGORIES_FRAME_VIEWER})
@Retention(RetentionPolicy.SOURCE)
- public @interface PresetCategories {}
+ public @interface PredefinedCategories {}
/**
- * Indicates that there are no preset categories.
+ * Indicates that there are no predefined categories.
*/
- public static final int CATEGORIES_NONE = -1;
+ public static final int CATEGORIES_NONE = 0;
/**
- * Predefined categories typically useful for web developers.
+ * Predefined set of categories, includes all categories enabled by default in chromium.
+ * Use with caution: this setting may produce large trace output.
+ */
+ public static final int CATEGORIES_ALL = 1 << 0;
+
+ /**
+ * Predefined set of categories typically useful for analyzing WebViews.
+ * Typically includes android_webview and Java.
+ */
+ public static final int CATEGORIES_ANDROID_WEBVIEW = 1 << 1;
+
+ /**
+ * Predefined set of categories typically useful for web developers.
* Typically includes blink, compositor, renderer.scheduler and v8 categories.
*/
- public static final int CATEGORIES_WEB_DEVELOPER = 0;
+ public static final int CATEGORIES_WEB_DEVELOPER = 1 << 2;
/**
- * Predefined categories for analyzing input latency issues.
+ * Predefined set of categories for analyzing input latency issues.
* Typically includes input, renderer.scheduler categories.
*/
- public static final int CATEGORIES_INPUT_LATENCY = 1;
+ public static final int CATEGORIES_INPUT_LATENCY = 1 << 3;
/**
- * Predefined categories for analyzing rendering issues.
+ * Predefined set of categories for analyzing rendering issues.
* Typically includes blink, compositor and gpu categories.
*/
- public static final int CATEGORIES_RENDERING = 2;
+ public static final int CATEGORIES_RENDERING = 1 << 4;
/**
- * Predefined categories for analyzing javascript and rendering issues.
- * Typically includes blink, compositor, gpu, renderer.schduler and v8 categories.
+ * Predefined set of categories for analyzing javascript and rendering issues.
+ * Typically includes blink, compositor, gpu, renderer.scheduler and v8 categories.
*/
- public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 3;
+ public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 1 << 5;
/**
- * Predefined categories for studying difficult rendering performance problems.
+ * Predefined set of categories for studying difficult rendering performance problems.
* Typically includes blink, compositor, gpu, renderer.scheduler, v8 and
* some other compositor categories which are disabled by default.
*/
- public static final int CATEGORIES_FRAME_VIEWER = 4;
+ public static final int CATEGORIES_FRAME_VIEWER = 1 << 6;
/** @hide */
- @IntDef({RECORD_UNTIL_FULL, RECORD_CONTINUOUSLY, RECORD_UNTIL_FULL_LARGE_BUFFER,
- RECORD_TO_CONSOLE})
+ @IntDef({RECORD_UNTIL_FULL, RECORD_CONTINUOUSLY, RECORD_UNTIL_FULL_LARGE_BUFFER})
@Retention(RetentionPolicy.SOURCE)
public @interface TracingMode {}
@@ -97,99 +112,38 @@
/**
* Record trace events using a larger internal tracing buffer until it is full.
- * Uses more memory than the other modes and may not be suitable on devices
- * with smaller RAM. Depending on the implementation typically allows up to
- * 512 million events to be stored.
+ * Uses significantly more memory than {@link #RECORD_UNTIL_FULL} and may not be
+ * suitable on devices with smaller RAM.
*/
public static final int RECORD_UNTIL_FULL_LARGE_BUFFER = 2;
/**
- * Record trace events to console (logcat). The events are discarded and nothing
- * is sent back to the caller. Uses the least memory as compared to the other modes.
+ * @hide
*/
- public static final int RECORD_TO_CONSOLE = 3;
-
- /**
- * Create config with the preset categories.
- * <p>
- * Example:
- * TracingConfig(CATEGORIES_WEB_DEVELOPER) -- records trace events from the "web developer"
- * preset categories.
- *
- * @param presetCategories preset categories to use, one of {@link #CATEGORIES_WEB_DEVELOPER},
- * {@link #CATEGORIES_INPUT_LATENCY}, {@link #CATEGORIES_RENDERING},
- * {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or
- * {@link #CATEGORIES_FRAME_VIEWER}.
- *
- * Note: for specifying custom categories without presets use
- * {@link #TracingConfig(int, String, int)}.
- *
- */
- public TracingConfig(@PresetCategories int presetCategories) {
- this(presetCategories, "", RECORD_UNTIL_FULL);
+ public TracingConfig(@PredefinedCategories int predefinedCategories,
+ @NonNull List<String> customIncludedCategories,
+ @TracingMode int tracingMode) {
+ mPredefinedCategories = predefinedCategories;
+ mCustomIncludedCategories.addAll(customIncludedCategories);
+ mTracingMode = tracingMode;
}
/**
- * Create a configuration with both preset categories and custom categories.
- * Also allows to specify the tracing mode.
- *
- * Note that the categories are defined by the currently-in-use version of WebView. They live
- * in chromium code and are not part of the Android API. See
- * See <a href="https://www.chromium.org/developers/how-tos/trace-event-profiling-tool">
- * chromium documentation on tracing</a> for more details.
- *
- * <p>
- * Examples:
- *
- * Preset category with a specified trace mode:
- * TracingConfig(CATEGORIES_WEB_DEVELOPER, "", RECORD_UNTIL_FULL_LARGE_BUFFER);
- * Custom categories:
- * TracingConfig(CATEGORIES_NONE, "browser", RECORD_UNTIL_FULL)
- * -- records only the trace events from the "browser" category.
- * TraceConfig(CATEGORIES_NONE, "-input,-gpu", RECORD_UNTIL_FULL)
- * -- records all trace events excluding the events from the "input" and 'gpu' categories.
- * TracingConfig(CATEGORIES_NONE, "blink*,devtools*", RECORD_UNTIL_FULL)
- * -- records only the trace events matching the "blink*" and "devtools*" patterns
- * (e.g. "blink_gc" and "devtools.timeline" categories).
- *
- * Combination of preset and additional custom categories:
- * TracingConfig(CATEGORIES_WEB_DEVELOPER, "memory-infra", RECORD_CONTINUOUSLY)
- * -- records events from the "web developer" categories and events from the "memory-infra"
- * category to understand where memory is being used.
- *
- * @param presetCategories preset categories to use, one of {@link #CATEGORIES_WEB_DEVELOPER},
- * {@link #CATEGORIES_INPUT_LATENCY}, {@link #CATEGORIES_RENDERING},
- * {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or
- * {@link #CATEGORIES_FRAME_VIEWER}.
- * @param customCategories a comma-delimited list of category wildcards. A category can
- * have an optional '-' prefix to make it an excluded category.
- * @param tracingMode tracing mode to use, one of {@link #RECORD_UNTIL_FULL},
- * {@link #RECORD_CONTINUOUSLY}, {@link #RECORD_UNTIL_FULL_LARGE_BUFFER}
- * or {@link #RECORD_TO_CONSOLE}.
+ * Returns a bitmask of the predefined categories values of this configuration.
*/
- public TracingConfig(@PresetCategories int presetCategories,
- @NonNull String customCategories, @TracingMode int tracingMode) {
- mPresetCategories = presetCategories;
- mCustomCategoryPattern = customCategories;
- mTracingMode = RECORD_UNTIL_FULL;
+ @PredefinedCategories
+ public int getPredefinedCategories() {
+ return mPredefinedCategories;
}
/**
- * Returns the custom category pattern for this configuration.
+ * Returns the list of included custom category patterns for this configuration.
*
- * @return empty string if no custom category pattern is specified.
+ * @return empty list if no custom category patterns are specified.
*/
@NonNull
- public String getCustomCategoryPattern() {
- return mCustomCategoryPattern;
- }
-
- /**
- * Returns the preset categories value of this configuration.
- */
- @PresetCategories
- public int getPresetCategories() {
- return mPresetCategories;
+ public List<String> getCustomIncludedCategories() {
+ return mCustomIncludedCategories;
}
/**
@@ -200,4 +154,111 @@
return mTracingMode;
}
+ /**
+ * Builder used to create {@link TracingConfig} objects.
+ *
+ * Examples:
+ * new TracingConfig.Builder().build()
+ * -- creates a configuration with default options: {@link #CATEGORIES_NONE},
+ * {@link #RECORD_UNTIL_FULL}.
+ * new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER).build()
+ * -- records trace events from the "web developer" predefined category sets.
+ * new TracingConfig.Builder().addCategories(CATEGORIES_RENDERING,
+ * CATEGORIES_INPUT_LATENCY).build()
+ * -- records trace events from the "rendering" and "input latency" predefined
+ * category sets.
+ * new TracingConfig.Builder().addCategories("browser").build()
+ * -- records only the trace events from the "browser" category.
+ * new TracingConfig.Builder().addCategories("blink*","renderer*").build()
+ * -- records only the trace events matching the "blink*" and "renderer*" patterns
+ * (e.g. "blink.animations", "renderer_host" and "renderer.scheduler" categories).
+ * new TracingConfig.Builder().addCategories(CATEGORIES_WEB_DEVELOPER)
+ * .addCategories("disabled-by-default-v8.gc")
+ * .setTracingMode(RECORD_CONTINUOUSLY).build()
+ * -- records events from the "web developer" predefined category set and events from
+ * the "disabled-by-default-v8.gc" category to understand where garbage collection
+ * is being triggered. Uses a ring buffer for internal storage during tracing.
+ */
+ public static class Builder {
+ private @PredefinedCategories int mPredefinedCategories = CATEGORIES_NONE;
+ private final List<String> mCustomIncludedCategories = new ArrayList<String>();
+ private @TracingMode int mTracingMode = RECORD_UNTIL_FULL;
+
+ /**
+ * Default constructor for Builder.
+ */
+ public Builder() {}
+
+ /**
+ * Build {@link TracingConfig} using the current settings.
+ */
+ public TracingConfig build() {
+ return new TracingConfig(mPredefinedCategories, mCustomIncludedCategories,
+ mTracingMode);
+ }
+
+ /**
+ * Adds categories from a predefined set of categories to be included in the trace output.
+ *
+ * @param predefinedCategories list or bitmask of predefined category sets to use:
+ * {@link #CATEGORIES_NONE}, {@link #CATEGORIES_ALL},
+ * {@link #CATEGORIES_WEB_DEVELOPER}, {@link #CATEGORIES_INPUT_LATENCY},
+ * {@link #CATEGORIES_RENDERING},
+ * {@link #CATEGORIES_JAVASCRIPT_AND_RENDERING} or
+ * {@link #CATEGORIES_FRAME_VIEWER}.
+ * @return The builder to facilitate chaining.
+ */
+ public Builder addCategories(@PredefinedCategories int... predefinedCategories) {
+ for (int categorySet : predefinedCategories) {
+ mPredefinedCategories |= categorySet;
+ }
+ return this;
+ }
+
+ /**
+ * Adds custom categories to be included in trace output.
+ *
+ * Note that the categories are defined by the currently-in-use version of WebView. They
+ * live in chromium code and are not part of the Android API. See
+ * See <a href="https://www.chromium.org/developers/how-tos/trace-event-profiling-tool">
+ * chromium documentation on tracing</a> for more details.
+ *
+ * @param categories a list of category patterns. A category pattern can contain wilcards,
+ * e.g. "blink*" or full category name e.g. "renderer.scheduler".
+ * @return The builder to facilitate chaining.
+ */
+ public Builder addCategories(String... categories) {
+ for (String category: categories) {
+ mCustomIncludedCategories.add(category);
+ }
+ return this;
+ }
+
+ /**
+ * Adds custom categories to be included in trace output.
+ *
+ * Same as {@link #addCategories(String...)} but allows to pass a Collection as a parameter.
+ *
+ * @param categories a list of category patters.
+ * @return The builder to facilitate chaining.
+ */
+ public Builder addCategories(Collection<String> categories) {
+ mCustomIncludedCategories.addAll(categories);
+ return this;
+ }
+
+ /**
+ * Sets the tracing mode for this configuration.
+ *
+ * @param tracingMode tracing mode to use, one of {@link #RECORD_UNTIL_FULL},
+ * {@link #RECORD_CONTINUOUSLY} or
+ * {@link #RECORD_UNTIL_FULL_LARGE_BUFFER}.
+ * @return The builder to facilitate chaining.
+ */
+ public Builder setTracingMode(@TracingMode int tracingMode) {
+ mTracingMode = tracingMode;
+ return this;
+ }
+ }
+
}
diff --git a/core/java/android/webkit/TracingController.java b/core/java/android/webkit/TracingController.java
index cadb8a1..7871021 100644
--- a/core/java/android/webkit/TracingController.java
+++ b/core/java/android/webkit/TracingController.java
@@ -16,9 +16,12 @@
package android.webkit;
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.os.Handler;
+
+import java.io.OutputStream;
+import java.util.concurrent.Executor;
/**
* Manages tracing of WebViews. In particular provides functionality for the app
@@ -29,40 +32,22 @@
* The resulting trace data is sent back as a byte sequence in json format. This
* file can be loaded in "chrome://tracing" for further analysis.
* <p>
- * Note: All methods in this class must be called on the UI thread. All callbacks
- * are also called on the UI thread.
- * <p>
* Example usage:
* <pre class="prettyprint">
* TracingController tracingController = TracingController.getInstance();
- * tracingController.start(new TraceConfig(CATEGORIES_WEB_DEVELOPER));
+ * tracingController.start(new TraceConfig.Builder()
+ * .addCategories(CATEGORIES_WEB_DEVELOPER).build());
* [..]
- * tracingController.stopAndFlush(new TraceFileOutput("trace.json"), null);
+ * tracingController.stop(new FileOutputStream("trace.json"),
+ * Executors.newSingleThreadExecutor());
* </pre></p>
*/
public abstract class TracingController {
/**
- * Interface for capturing tracing data.
- */
- public interface TracingOutputStream {
- /**
- * Will be called to return tracing data in chunks.
- * Tracing data is returned in json format an array of bytes.
- */
- void write(byte[] chunk);
-
- /**
- * Called when tracing is finished and the data collection is over.
- * There will be no calls to #write after #complete is called.
- */
- void complete();
- }
-
- /**
* Returns the default TracingController instance. At present there is
* only one TracingController instance for all WebView instances,
- * however this restriction may be relaxed in the future.
+ * however this restriction may be relaxed in a future Android release.
*
* @return the default TracingController instance
*/
@@ -72,55 +57,38 @@
}
/**
- * Starts tracing all webviews. Depeding on the trace mode in traceConfig
+ * Starts tracing all webviews. Depending on the trace mode in traceConfig
* specifies how the trace events are recorded.
*
* For tracing modes {@link TracingConfig#RECORD_UNTIL_FULL},
* {@link TracingConfig#RECORD_CONTINUOUSLY} and
* {@link TracingConfig#RECORD_UNTIL_FULL_LARGE_BUFFER} the events are recorded
* using an internal buffer and flushed to the outputStream when
- * {@link #stopAndFlush(TracingOutputStream, Handler)} is called.
+ * {@link #stop(OutputStream, Executor)} is called.
*
* @param tracingConfig configuration options to use for tracing
- * @return false if the system is already tracing, true otherwise.
+ * @throws IllegalStateException if the system is already tracing.
*/
- public abstract boolean start(TracingConfig tracingConfig);
+ public abstract void start(@NonNull TracingConfig tracingConfig);
/**
- * Stops tracing and discards all tracing data.
+ * Stops tracing and flushes tracing data to the specified outputStream.
*
- * This method is particularly useful in conjunction with the
- * {@link TracingConfig#RECORD_TO_CONSOLE} tracing mode because tracing data is logged to
- * console and not sent to an outputStream as with
- * {@link #stopAndFlush(TracingOutputStream, Handler)}.
+ * The data is sent to the specified output stream in json format typically
+ * in chunks by invoking {@link java.io.OutputStream#write(byte[])}. On completion
+ * the {@link java.io.OutputStream#close()} method is called.
*
+ * @param outputStream the output steam the tracing data will be sent to. If null
+ * the tracing data will be discarded.
+ * @param executor the {@link java.util.concurrent.Executor} on which the
+ * outputStream #write and #close methods will be invoked.
* @return false if the system was not tracing at the time of the call, true
* otherwise.
*/
- public abstract boolean stop();
-
- /**
- * Stops tracing and flushes tracing data to the specifid outputStream.
- *
- * Note that if the {@link TracingConfig#RECORD_TO_CONSOLE} tracing mode is used
- * nothing will be sent to the outputStream and no TracingOuputStream methods will be
- * called. In that case it is more convenient to just use {@link #stop()} instead.
- *
- * @param outputStream the output steam the tracing data will be sent to.
- * @param handler the {@link android.os.Handler} on which the outputStream callbacks
- * will be invoked. If the handler is null the current thread's Looper
- * will be used.
- * @return false if the system was not tracing at the time of the call, true
- * otherwise.
- */
- public abstract boolean stopAndFlush(TracingOutputStream outputStream,
- @Nullable Handler handler);
+ public abstract boolean stop(@Nullable OutputStream outputStream,
+ @NonNull @CallbackExecutor Executor executor);
/** True if the system is tracing */
public abstract boolean isTracing();
- // TODO: consider adding getTraceBufferUsage, percentage and approx event count.
- // TODO: consider adding String getCategories(), for obtaining the actual list
- // of categories used (given that presets are ints).
-
}
diff --git a/core/java/android/webkit/TracingFileOutputStream.java b/core/java/android/webkit/TracingFileOutputStream.java
deleted file mode 100644
index 8a5fa36..0000000
--- a/core/java/android/webkit/TracingFileOutputStream.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2017 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.webkit;
-
-import android.annotation.NonNull;
-
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-/**
- * Simple TracingOutputStream implementation which writes the trace data from
- * {@link TracingController} to a new file.
- *
- */
-public class TracingFileOutputStream implements TracingController.TracingOutputStream {
-
- private FileOutputStream mFileOutput;
-
- public TracingFileOutputStream(@NonNull String filename) throws FileNotFoundException {
- mFileOutput = new FileOutputStream(filename);
- }
-
- /**
- * Writes bytes chunk to the file.
- */
- public void write(byte[] chunk) {
- try {
- mFileOutput.write(chunk);
- } catch (IOException e) {
- onIOException(e);
- }
- }
-
- /**
- * Closes the file.
- */
- public void complete() {
- try {
- mFileOutput.close();
- } catch (IOException e) {
- onIOException(e);
- }
- }
-
- private void onIOException(IOException e) {
- throw new RuntimeException(e);
- }
-}