Merge "[RESTRICT AUTOMERGE] Add starting silent bugreporting" into qt-qpr1-dev
diff --git a/tests/BugReportApp/AndroidManifest.xml b/tests/BugReportApp/AndroidManifest.xml
index af9ee25..68bbc0c 100644
--- a/tests/BugReportApp/AndroidManifest.xml
+++ b/tests/BugReportApp/AndroidManifest.xml
@@ -16,8 +16,8 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.car.bugreport"
- android:versionCode="9"
- android:versionName="1.6.1">
+ android:versionCode="10"
+ android:versionName="1.6.2">
<uses-permission android:name="android.car.permission.CAR_DRIVING_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
@@ -41,6 +41,7 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.VIEW"/>
+ <action android:name="com.google.android.car.bugreport.action.START_SILENT"/>
</intent-filter>
</activity>
diff --git a/tests/BugReportApp/README.md b/tests/BugReportApp/README.md
index 2dac8e9..acd4347 100644
--- a/tests/BugReportApp/README.md
+++ b/tests/BugReportApp/README.md
@@ -48,6 +48,17 @@
BugReport app uses `res/raw/gcs_credentials.json` for authentication and
`res/values/configs.xml` for obtaining GCS bucket name.
+## Starting bugreporting
+
+The app supports following intents:
+
+1. `adb shell am start com.google.android.car.bugreport/com.google.android.car.bugreport.BugReportActivity`
+ - generates `MetaBugReport.Type.INTERACTIVE` bug report, with audio message, shows a
+ SUBMIT/CANCEL dialog.
+2. `adb shell am start -n com.google.android.car.bugreport/com.google.android.car.bugreport.BugReportActivity -a com.google.android.car.bugreport.action.START_SILENT`
+ - generates `MetaBugReport.Type.SILENT` bug report, without audio message. The app doesn't
+ auto-upload these bugreports.
+
## Testing
### Manually testing the app using the test script
diff --git a/tests/BugReportApp/res/layout/bug_info_view.xml b/tests/BugReportApp/res/layout/bug_info_view.xml
index d4c573f..089acb5 100644
--- a/tests/BugReportApp/res/layout/bug_info_view.xml
+++ b/tests/BugReportApp/res/layout/bug_info_view.xml
@@ -30,6 +30,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
+ android:textColor="@*android:color/car_yellow_500"
android:textSize="@dimen/bug_report_default_text_size" />
<LinearLayout
@@ -53,7 +54,6 @@
android:id="@+id/bug_info_row_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textColor="@*android:color/car_yellow_500"
android:visibility="gone"
android:textSize="@dimen/bug_report_default_text_size" />
diff --git a/tests/BugReportApp/res/values/strings.xml b/tests/BugReportApp/res/values/strings.xml
index 9aca56e..6244691 100644
--- a/tests/BugReportApp/res/values/strings.xml
+++ b/tests/BugReportApp/res/values/strings.xml
@@ -30,7 +30,7 @@
<string name="bugreport_dialog_in_progress_title" translatable="false">A bug report is already being collected</string>
<string name="bugreport_dialog_in_progress_title_finished" translatable="false">A bug report has been collected</string>
<string name="bugreport_move_button_text" translatable="false">Move to USB</string>
- <string name="bugreport_upload_button_text" translatable="false">Upload</string>
+ <string name="bugreport_upload_button_text" translatable="false">Upload to Google</string>
<string name="toast_permissions_denied" translatable="false">Please grant permissions</string>
<string name="toast_bug_report_in_progress" translatable="false">Bug report already being collected</string>
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugInfoAdapter.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugInfoAdapter.java
index 0e01027..07084fc 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugInfoAdapter.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugInfoAdapter.java
@@ -26,6 +26,12 @@
import java.util.ArrayList;
import java.util.List;
+/**
+ * Shows bugreport title, status, status message and user action buttons. "Upload to Google" button
+ * is enabled when the status is {@link Status#STATUS_PENDING_USER_ACTION}, "Move to USB" button is
+ * enabled only when status is {@link Status#STATUS_PENDING_USER_ACTION} and USB device is plugged
+ * in.
+ */
public class BugInfoAdapter extends RecyclerView.Adapter<BugInfoAdapter.BugInfoViewHolder> {
static final int BUTTON_TYPE_UPLOAD = 0;
static final int BUTTON_TYPE_MOVE = 1;
@@ -96,33 +102,30 @@
holder.mTitleView.setText(bugreport.getTitle());
holder.mStatusView.setText(Status.toString(bugreport.getStatus()));
holder.mMessageView.setText(bugreport.getStatusMessage());
- if (bugreport.getStatusMessage() == null || bugreport.getStatusMessage().isEmpty()) {
+ if (bugreport.getStatusMessage().isEmpty()) {
holder.mMessageView.setVisibility(View.GONE);
} else {
holder.mMessageView.setVisibility(View.VISIBLE);
}
- if (getUserActionButtonsVisible()) {
- holder.mMoveButton.setVisibility(View.VISIBLE);
- holder.mUploadButton.setVisibility(View.VISIBLE);
- } else {
- holder.mMoveButton.setVisibility(View.GONE);
- holder.mUploadButton.setVisibility(View.GONE);
- }
boolean enableUserActionButtons =
bugreport.getStatus() == Status.STATUS_PENDING_USER_ACTION.getValue()
|| bugreport.getStatus() == Status.STATUS_MOVE_FAILED.getValue()
|| bugreport.getStatus() == Status.STATUS_UPLOAD_FAILED.getValue();
if (enableUserActionButtons) {
holder.mMoveButton.setEnabled(true);
+ holder.mMoveButton.setVisibility(View.VISIBLE);
holder.mMoveButton.setOnClickListener(
view -> mItemClickedListener.onItemClicked(BUTTON_TYPE_MOVE, bugreport,
holder));
holder.mUploadButton.setEnabled(true);
+ holder.mUploadButton.setVisibility(View.VISIBLE);
holder.mUploadButton.setOnClickListener(
view -> mItemClickedListener.onItemClicked(BUTTON_TYPE_UPLOAD, bugreport,
holder));
} else {
+ holder.mMoveButton.setVisibility(View.GONE);
holder.mMoveButton.setEnabled(false);
+ holder.mUploadButton.setVisibility(View.GONE);
holder.mUploadButton.setEnabled(false);
}
}
@@ -141,12 +144,6 @@
}
}
- /** Returns true if the upload/move buttons should be visible. */
- private boolean getUserActionButtonsVisible() {
- // Do not show buttons if bugreports are uploaded by default.
- return !JobSchedulingUtils.uploadByDefault();
- }
-
@Override
public long getItemId(int position) {
return mDataset.get(position).getId();
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java
index 456192e..d8597d8 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportActivity.java
@@ -25,6 +25,7 @@
import android.car.drivingstate.CarDrivingStateEvent;
import android.car.drivingstate.CarDrivingStateManager;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
@@ -61,10 +62,18 @@
* submit button it initiates {@link BugReportService}.
*
* <p>If bug report is in-progress, it shows a progress bar.
+ *
+ * <p>If the activity is started with action {@link #ACTION_START_SILENT}, it will start
+ * bugreporting without showing dialog and recording audio message, see
+ * {@link MetaBugReport#TYPE_SILENT}.
*/
public class BugReportActivity extends Activity {
private static final String TAG = BugReportActivity.class.getSimpleName();
+ /** Starts headless (no audio message recording) bugreporting. */
+ private static final String ACTION_START_SILENT =
+ "com.google.android.car.bugreport.action.START_SILENT";
+
private static final int VOICE_MESSAGE_MAX_DURATION_MILLIS = 60 * 1000;
private static final int AUDIO_PERMISSIONS_REQUEST_ID = 1;
@@ -132,6 +141,14 @@
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ if (ACTION_START_SILENT.equals(getIntent().getAction())) {
+ Log.i(TAG, "Starting headless bugreport.");
+ MetaBugReport bugReport = createBugReport(this, MetaBugReport.TYPE_SILENT);
+ startBugReportingInService(this, bugReport);
+ finish();
+ return;
+ }
+
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.bug_report_activity);
@@ -261,11 +278,7 @@
mAudioRecordingStarted = true;
showSubmitBugReportUi(/* isRecording= */ true);
- Date initiatedAt = new Date();
- String timestamp = BUG_REPORT_TIMESTAMP_DATE_FORMAT.format(initiatedAt);
- String username = getCurrentUserName();
- String title = BugReportTitleGenerator.generateBugReportTitle(initiatedAt, username);
- mMetaBugReport = BugStorageUtils.createBugReport(this, title, timestamp, username);
+ mMetaBugReport = createBugReport(this, MetaBugReport.TYPE_INTERACTIVE);
if (!hasRecordPermissions()) {
requestRecordPermissions();
@@ -294,7 +307,9 @@
}
private void buttonSubmitClick(View view) {
- startBugReportingInService();
+ stopAudioRecording();
+ startBugReportingInService(this, mMetaBugReport);
+ mBugReportServiceStarted = true;
finish();
}
@@ -314,16 +329,6 @@
finish();
}
- private void startBugReportingInService() {
- stopAudioRecording();
- Bundle bundle = new Bundle();
- bundle.putParcelable(EXTRA_META_BUG_REPORT, mMetaBugReport);
- Intent intent = new Intent(this, BugReportService.class);
- intent.putExtras(bundle);
- startService(intent);
- mBugReportServiceStarted = true;
- }
-
private void requestRecordPermissions() {
requestPermissions(
new String[]{Manifest.permission.RECORD_AUDIO}, AUDIO_PERMISSIONS_REQUEST_ID);
@@ -430,11 +435,33 @@
mVoiceRecordingView.setRecorder(null);
}
- private String getCurrentUserName() {
- UserManager um = UserManager.get(this);
+ private static void startBugReportingInService(Context context, MetaBugReport bugReport) {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(EXTRA_META_BUG_REPORT, bugReport);
+ Intent intent = new Intent(context, BugReportService.class);
+ intent.putExtras(bundle);
+ context.startForegroundService(intent);
+ }
+
+ private static String getCurrentUserName(Context context) {
+ UserManager um = UserManager.get(context);
return um.getUserName();
}
+ /**
+ * Creates a {@link MetaBugReport} and saves it in a local sqlite database.
+ *
+ * @param context an Android context.
+ * @param type bug report type, {@link MetaBugReport.BugReportType}.
+ */
+ private static MetaBugReport createBugReport(Context context, int type) {
+ Date initiatedAt = new Date();
+ String timestamp = BUG_REPORT_TIMESTAMP_DATE_FORMAT.format(initiatedAt);
+ String username = getCurrentUserName(context);
+ String title = BugReportTitleGenerator.generateBugReportTitle(initiatedAt, username);
+ return BugStorageUtils.createBugReport(context, title, timestamp, username, type);
+ }
+
/** A helper class to generate bugreport title. */
private static final class BugReportTitleGenerator {
/** Contains easily readable characters. */
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
index f6fc651..cab945b 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugReportService.java
@@ -213,6 +213,9 @@
}
private Notification buildProgressNotification() {
+ Intent intent = new Intent(getApplicationContext(), BugReportInfoActivity.class);
+ PendingIntent startBugReportInfoActivity =
+ PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
return new Notification.Builder(this, PROGRESS_CHANNEL_ID)
.setContentTitle(getText(R.string.notification_bugreport_in_progress))
.setSubText(String.format("%.1f%%", mBugReportProgress.get()))
@@ -220,6 +223,7 @@
.setCategory(Notification.CATEGORY_STATUS)
.setOngoing(true)
.setProgress((int) MAX_PROGRESS_VALUE, (int) mBugReportProgress.get(), false)
+ .setContentIntent(startBugReportInfoActivity)
.build();
}
@@ -346,12 +350,16 @@
Intent intent = new Intent(getApplicationContext(), BugReportInfoActivity.class);
PendingIntent startBugReportInfoActivity =
PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
+ CharSequence contentText;
+ if (JobSchedulingUtils.autoUploadBugReport(mMetaBugReport)) {
+ contentText = getText(R.string.notification_bugreport_auto_upload_finished_text);
+ } else {
+ contentText = getText(R.string.notification_bugreport_manual_upload_finished_text);
+ }
Notification notification = new Notification
.Builder(getApplicationContext(), STATUS_CHANNEL_ID)
.setContentTitle(getText(R.string.notification_bugreport_finished_title))
- .setContentText(getText(JobSchedulingUtils.uploadByDefault()
- ? R.string.notification_bugreport_auto_upload_finished_text
- : R.string.notification_bugreport_manual_upload_finished_text))
+ .setContentText(contentText)
.setCategory(Notification.CATEGORY_STATUS)
.setSmallIcon(R.drawable.ic_upload)
.setContentIntent(startBugReportInfoActivity)
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageProvider.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageProvider.java
index 1ed4e81..b762cb3 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageProvider.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageProvider.java
@@ -35,7 +35,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.List;
+import java.util.Optional;
/**
@@ -54,6 +54,7 @@
static final Uri BUGREPORT_CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/" + BUG_REPORTS_TABLE);
+ /** See {@link MetaBugReport} for column descriptions. */
static final String COLUMN_ID = "_ID";
static final String COLUMN_USERNAME = "username";
static final String COLUMN_TITLE = "title";
@@ -62,6 +63,7 @@
static final String COLUMN_FILEPATH = "filepath";
static final String COLUMN_STATUS = "status";
static final String COLUMN_STATUS_MESSAGE = "message";
+ static final String COLUMN_TYPE = "type";
// URL Matcher IDs.
private static final int URL_MATCHED_BUG_REPORTS_URI = 1;
@@ -84,9 +86,11 @@
/**
* All changes in database versions should be recorded here.
* 1: Initial version.
+ * 2: Add integer column details_needed.
*/
private static final int INITIAL_VERSION = 1;
- private static final int DATABASE_VERSION = INITIAL_VERSION;
+ private static final int TYPE_VERSION = 2;
+ private static final int DATABASE_VERSION = TYPE_VERSION;
private static final String CREATE_TABLE = "CREATE TABLE " + BUG_REPORTS_TABLE + " ("
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
@@ -96,7 +100,8 @@
+ COLUMN_DESCRIPTION + " TEXT NULL,"
+ COLUMN_FILEPATH + " TEXT DEFAULT NULL,"
+ COLUMN_STATUS + " INTEGER DEFAULT " + Status.STATUS_WRITE_PENDING.getValue() + ","
- + COLUMN_STATUS_MESSAGE + " TEXT NULL"
+ + COLUMN_STATUS_MESSAGE + " TEXT NULL,"
+ + COLUMN_TYPE + " INTEGER DEFAULT " + MetaBugReport.TYPE_INTERACTIVE
+ ");";
DatabaseHelper(Context context) {
@@ -111,6 +116,10 @@
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading from " + oldVersion + " to " + newVersion);
+ if (oldVersion == INITIAL_VERSION && newVersion == TYPE_VERSION) {
+ db.execSQL("ALTER TABLE " + BUG_REPORTS_TABLE + " ADD COLUMN "
+ + COLUMN_TYPE + " INTEGER DEFAULT " + MetaBugReport.TYPE_INTERACTIVE);
+ }
}
}
@@ -301,27 +310,12 @@
throw new IllegalArgumentException("unknown uri:" + uri);
}
- Cursor c = query(uri, new String[]{COLUMN_FILEPATH}, null, null, null);
- int count = (c != null) ? c.getCount() : 0;
- if (count != 1) {
- // If there is not exactly one result, throw an appropriate
- // exception.
- if (c != null) {
- c.close();
- }
- if (count == 0) {
- throw new FileNotFoundException("No entry for " + uri);
- }
- throw new FileNotFoundException("Multiple items at " + uri);
- }
-
- c.moveToFirst();
- int i = c.getColumnIndex(COLUMN_FILEPATH);
- String path = (i >= 0 ? c.getString(i) : null);
- c.close();
- if (path == null) {
- throw new FileNotFoundException("Column for path not found.");
- }
+ // Because we expect URI to be URL_MATCHED_BUG_REPORT_ID_URI.
+ int bugreportId = Integer.parseInt(uri.getLastPathSegment());
+ MetaBugReport bugReport =
+ BugStorageUtils.findBugReport(getContext(), bugreportId)
+ .orElseThrow(() -> new FileNotFoundException("No record found for " + uri));
+ String path = bugReport.getFilePath();
int modeBits = ParcelFileDescriptor.parseMode(mode);
try {
@@ -337,8 +331,9 @@
Status status;
if (e == null) {
// success writing the file. Update the field to indicate bugreport
- // is ready for upload
- status = JobSchedulingUtils.uploadByDefault() ? Status.STATUS_UPLOAD_PENDING
+ // is ready for upload.
+ status = JobSchedulingUtils.autoUploadBugReport(bugReport)
+ ? Status.STATUS_UPLOAD_PENDING
: Status.STATUS_PENDING_USER_ACTION;
} else {
// We log it and ignore it
@@ -363,16 +358,21 @@
}
private boolean deleteZipFile(int bugreportId) {
- String selection = COLUMN_ID + " = ?";
- String[] selectionArgs = new String[]{Integer.toString(bugreportId)};
- List<MetaBugReport> bugs = BugStorageUtils.getBugreports(
- getContext(), selection, selectionArgs, null);
- if (bugs.isEmpty()) {
+ Optional<MetaBugReport> bugReport =
+ BugStorageUtils.findBugReport(getContext(), bugreportId);
+ if (!bugReport.isPresent()) {
Log.i(TAG,
"Failed to delete zip file for bug " + bugreportId + ": bugreport not found.");
return false;
}
- Path zipPath = new File(bugs.get(0).getFilePath()).toPath();
+ Path zipPath = new File(bugReport.get().getFilePath()).toPath();
+ // This statement is to prevent the app to print confusing full FileNotFound error stack
+ // when the user is navigating from BugReportActivity (audio message recording dialog) to
+ // BugReportInfoActivity by clicking "Show Bug Reports" button.
+ if (!Files.exists(zipPath)) {
+ Log.w(TAG, "Failed to delete " + zipPath + ". File not found.");
+ return false;
+ }
try {
Files.delete(zipPath);
return true;
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageUtils.java b/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageUtils.java
index 3dba420..4cdc7cd 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageUtils.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/BugStorageUtils.java
@@ -21,6 +21,7 @@
import static com.google.android.car.bugreport.BugStorageProvider.COLUMN_STATUS_MESSAGE;
import static com.google.android.car.bugreport.BugStorageProvider.COLUMN_TIMESTAMP;
import static com.google.android.car.bugreport.BugStorageProvider.COLUMN_TITLE;
+import static com.google.android.car.bugreport.BugStorageProvider.COLUMN_TYPE;
import static com.google.android.car.bugreport.BugStorageProvider.COLUMN_USERNAME;
import android.annotation.NonNull;
@@ -41,6 +42,7 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
+import java.util.Optional;
/**
* A class that hides details when communicating with the bug storage provider.
@@ -67,6 +69,7 @@
* @param title - title of the bug report.
* @param timestamp - timestamp when the bug report was initiated.
* @param username - current user name. Note, it's a user name, not an account name.
+ * @param type - bug report type, {@link MetaBugReport.BugReportType}.
* @return an instance of {@link MetaBugReport} that was created in a database.
*/
@NonNull
@@ -74,12 +77,14 @@
@NonNull Context context,
@NonNull String title,
@NonNull String timestamp,
- @NonNull String username) {
+ @NonNull String username,
+ @MetaBugReport.BugReportType int type) {
// insert bug report username and title
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE, title);
values.put(COLUMN_TIMESTAMP, timestamp);
values.put(COLUMN_USERNAME, username);
+ values.put(COLUMN_TYPE, type);
ContentResolver r = context.getContentResolver();
Uri uri = r.insert(BugStorageProvider.BUGREPORT_CONTENT_URI, values);
@@ -95,6 +100,7 @@
return new MetaBugReport.Builder(id, timestamp)
.setTitle(title)
.setUserName(username)
+ .setType(type)
.build();
}
@@ -157,7 +163,19 @@
return getBugreports(context, null, null, COLUMN_ID + " DESC");
}
- static List<MetaBugReport> getBugreports(
+ /** Returns {@link MetaBugReport} for given bugreport id. */
+ static Optional<MetaBugReport> findBugReport(Context context, int bugreportId) {
+ String selection = COLUMN_ID + " = ?";
+ String[] selectionArgs = new String[]{Integer.toString(bugreportId)};
+ List<MetaBugReport> bugs = BugStorageUtils.getBugreports(
+ context, selection, selectionArgs, null);
+ if (bugs.isEmpty()) {
+ return Optional.empty();
+ }
+ return Optional.of(bugs.get(0));
+ }
+
+ private static List<MetaBugReport> getBugreports(
Context context, String selection, String[] selectionArgs, String order) {
ArrayList<MetaBugReport> bugReports = new ArrayList<>();
String[] projection = {
@@ -167,7 +185,8 @@
COLUMN_TIMESTAMP,
COLUMN_FILEPATH,
COLUMN_STATUS,
- COLUMN_STATUS_MESSAGE};
+ COLUMN_STATUS_MESSAGE,
+ COLUMN_TYPE};
ContentResolver r = context.getContentResolver();
Cursor c = r.query(BugStorageProvider.BUGREPORT_CONTENT_URI, projection,
selection, selectionArgs, order);
@@ -183,6 +202,7 @@
.setFilepath(getString(c, COLUMN_FILEPATH))
.setStatus(getInt(c, COLUMN_STATUS))
.setStatusMessage(getString(c, COLUMN_STATUS_MESSAGE))
+ .setType(getInt(c, COLUMN_TYPE))
.build();
bugReports.add(meta);
c.moveToNext();
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/JobSchedulingUtils.java b/tests/BugReportApp/src/com/google/android/car/bugreport/JobSchedulingUtils.java
index 7a6de23..95c4685 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/JobSchedulingUtils.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/JobSchedulingUtils.java
@@ -80,7 +80,12 @@
* after bugreport is successfully written. A user then has an option to choose whether to
* upload the bugreport or copy it to an external drive.
*/
- static boolean uploadByDefault() {
+ private static boolean uploadByDefault() {
return !SystemProperties.getBoolean(PROP_DISABLE_AUTO_UPLOAD, false);
}
+
+ /** Returns {@code true} if bugreports has to be auto-uploaded. */
+ static boolean autoUploadBugReport(MetaBugReport bugReport) {
+ return uploadByDefault() && bugReport.getType() == MetaBugReport.TYPE_INTERACTIVE;
+ }
}
diff --git a/tests/BugReportApp/src/com/google/android/car/bugreport/MetaBugReport.java b/tests/BugReportApp/src/com/google/android/car/bugreport/MetaBugReport.java
index 85d3d9b..6d5e89b 100644
--- a/tests/BugReportApp/src/com/google/android/car/bugreport/MetaBugReport.java
+++ b/tests/BugReportApp/src/com/google/android/car/bugreport/MetaBugReport.java
@@ -15,11 +15,35 @@
*/
package com.google.android.car.bugreport;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
import android.os.Parcel;
import android.os.Parcelable;
+import com.google.common.base.Strings;
+
+import java.lang.annotation.Retention;
+
/** Represents the information that a bugreport can contain. */
public final class MetaBugReport implements Parcelable {
+
+ /** Contains {@link #TYPE_SILENT} and audio message. */
+ static final int TYPE_INTERACTIVE = 0;
+
+ /**
+ * Contains dumpstate and screenshots.
+ *
+ * <p>Silent bugreports are not uploaded automatically. The app asks user to add audio
+ * message either through notification or {@link BugReportInfoActivity}.
+ */
+ static final int TYPE_SILENT = 1;
+
+ /** Annotation for bug report types. */
+ @Retention(SOURCE)
+ @IntDef({TYPE_INTERACTIVE, TYPE_SILENT})
+ @interface BugReportType {};
+
private final int mId;
private final String mTimestamp;
private final String mTitle;
@@ -27,6 +51,8 @@
private final String mFilePath;
private final int mStatus;
private final String mStatusMessage;
+ /** One of {@link BugReportType}. */
+ private final int mType;
private MetaBugReport(Builder builder) {
mId = builder.mId;
@@ -36,6 +62,7 @@
mFilePath = builder.mFilePath;
mStatus = builder.mStatus;
mStatusMessage = builder.mStatusMessage;
+ mType = builder.mType;
}
/**
@@ -49,32 +76,32 @@
* @return Username (LDAP) that created this bugreport
*/
public String getUsername() {
- return mUsername == null ? "" : mUsername;
+ return Strings.nullToEmpty(mUsername);
}
/**
* @return Title of the bug.
*/
public String getTitle() {
- return mTitle == null ? "" : mTitle;
+ return Strings.nullToEmpty(mTitle);
}
/**
* @return Timestamp when the bug report is initialized.
*/
public String getTimestamp() {
- return mTimestamp == null ? "" : mTimestamp;
+ return Strings.nullToEmpty(mTimestamp);
}
/**
* @return path to the zip file
*/
public String getFilePath() {
- return mFilePath == null ? "" : mFilePath;
+ return Strings.nullToEmpty(mFilePath);
}
/**
- * @return Status of the bug upload.
+ * @return {@link Status} of the bug upload.
*/
public int getStatus() {
return mStatus;
@@ -84,7 +111,14 @@
* @return StatusMessage of the bug upload.
*/
public String getStatusMessage() {
- return mStatusMessage == null ? "" : mStatusMessage;
+ return Strings.nullToEmpty(mStatusMessage);
+ }
+
+ /**
+ * @return {@link BugReportType}.
+ */
+ public int getType() {
+ return mType;
}
@Override
@@ -99,7 +133,8 @@
.setStatus(mStatus)
.setStatusMessage(mStatusMessage)
.setTitle(mTitle)
- .setUserName(mUsername);
+ .setUserName(mUsername)
+ .setType(mType);
}
@Override
@@ -111,6 +146,7 @@
dest.writeString(mFilePath);
dest.writeInt(mStatus);
dest.writeString(mStatusMessage);
+ dest.writeInt(mType);
}
/** A creator that's used by Parcelable. */
@@ -124,12 +160,14 @@
String filePath = in.readString();
int status = in.readInt();
String statusMessage = in.readString();
+ int type = in.readInt();
return new Builder(id, timestamp)
.setTitle(title)
.setUserName(username)
.setFilepath(filePath)
.setStatus(status)
.setStatusMessage(statusMessage)
+ .setType(type)
.build();
}
@@ -147,6 +185,7 @@
private String mFilePath;
private int mStatus;
private String mStatusMessage;
+ private int mType;
/**
* Initializes MetaBugReport.Builder.
@@ -177,7 +216,7 @@
return this;
}
- /** Sets status. */
+ /** Sets {@link Status}. */
public Builder setStatus(int status) {
mStatus = status;
return this;
@@ -189,6 +228,12 @@
return this;
}
+ /** Sets the {@link BugReportType}. */
+ public Builder setType(@BugReportType int type) {
+ mType = type;
+ return this;
+ }
+
/** Returns a {@link MetaBugReport}. */
public MetaBugReport build() {
return new MetaBugReport(this);