/* * Copyright (C) 2019 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.car; import android.annotation.FloatRange; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.os.Handler; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import com.android.internal.util.Preconditions; import libcore.io.IoUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; /** * Car specific bugreport manager. Only available for userdebug and eng builds. * * @hide */ public final class CarBugreportManager extends CarManagerBase { private final ICarBugreportService mService; /** * Callback from carbugreport manager. Callback methods are always called on the main thread. */ public abstract static class CarBugreportManagerCallback { @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"CAR_BUGREPORT_ERROR_"}, value = { CAR_BUGREPORT_DUMPSTATE_FAILED, CAR_BUGREPORT_IN_PROGRESS, CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED, CAR_BUGREPORT_SERVICE_NOT_AVAILABLE }) public @interface CarBugreportErrorCode { } /** Dumpstate failed to generate bugreport. */ public static final int CAR_BUGREPORT_DUMPSTATE_FAILED = 1; /** * Another bugreport is in progress. */ public static final int CAR_BUGREPORT_IN_PROGRESS = 2; /** Cannot connect to dumpstate */ public static final int CAR_BUGREPORT_DUMPSTATE_CONNECTION_FAILED = 3; /** Car bugreport service is not available (true for user builds) */ public static final int CAR_BUGREPORT_SERVICE_NOT_AVAILABLE = 4; /** * Called when bugreport progress changes. * *
It's never called after {@link #onError} or {@link #onFinished}.
*
* @param progress - a number in [0.0, 100.0].
*/
public void onProgress(@FloatRange(from = 0f, to = 100f) float progress) {
}
/**
* Called on an error condition with one of the error codes listed above.
*
* @param errorCode the error code that defines failure reason.
*/
public void onError(@CarBugreportErrorCode int errorCode) {
}
/**
* Called when taking bugreport finishes successfully.
*/
public void onFinished() {
}
}
/**
* Internal wrapper class to service.
*/
private static final class CarBugreportManagerCallbackWrapper extends
ICarBugreportCallback.Stub {
private final WeakReference The file descriptor is closed when bugreport is written or if an exception happens.
*
* This method is enabled only for one bug reporting app. It can be configured using
* {@code config_car_bugreport_application} string that is defined in
* {@code packages/services/Car/service/res/values/config.xml}. To learn more please
* see {@code packages/services/Car/tests/BugReportApp/README.md}.
*
* @param output the zipped bugreport file
* @param extraOutput a zip file that contains extra files generated for automotive.
* @param callback the callback for reporting dump status
*/
@RequiresPermission(android.Manifest.permission.DUMP)
public void requestBugreport(
@NonNull ParcelFileDescriptor output,
@NonNull ParcelFileDescriptor extraOutput,
@NonNull CarBugreportManagerCallback callback) {
Preconditions.checkNotNull(output);
Preconditions.checkNotNull(extraOutput);
Preconditions.checkNotNull(callback);
try {
CarBugreportManagerCallbackWrapper wrapper =
new CarBugreportManagerCallbackWrapper(callback, getEventHandler());
mService.requestBugreport(output, extraOutput, wrapper);
} catch (RemoteException e) {
handleRemoteExceptionFromCarService(e);
} finally {
IoUtils.closeQuietly(output);
IoUtils.closeQuietly(extraOutput);
}
}
@Override
public void onCarDisconnected() {
}
}