Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1a523b4 authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Allows users to add details about a bugreport in progress."

parents 6eba3bb3 bc73ffc0
Loading
Loading
Loading
Loading
+43 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2015 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.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <EditText
        android:id="@+id/name"
        android:maxLength="30"
        android:singleLine="true"
        android:inputType="textNoSuggestions"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/bugreport_info_name"/>
    <EditText
        android:id="@+id/title"
        android:maxLength="80"
        android:singleLine="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/bugreport_info_title"/>
    <EditText
        android:id="@+id/description"
        android:singleLine="false"
        android:inputType="textMultiLine"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/bugreport_info_description"/>
</LinearLayout>
+15 −0
Original line number Diff line number Diff line
@@ -42,4 +42,19 @@
    <!-- Title for bug reports received from dumpstate without a name. [CHAR LIMIT=30]-->
    <string name="bugreport_unnamed">unnamed</string>

    <!-- Title of the notification action that opens the dialog for the user-defined bug report details. -->
    <string name="bugreport_info_action">Details</string>

    <!--  Title of the dialog asking for user-defined bug report details like name, title, and description. -->
    <string name="bugreport_info_dialog_title">Bug report details</string>

    <!-- Text of the hint asking for the bug report name, which when set will define a suffix in the
         bug report file names. [CHAR LIMIT=30] -->
    <string name="bugreport_info_name">Short name</string>
    <!-- Text of hint asking for the bug report title, which when set will define the
         Subject of the email message. [CHAR LIMIT=60] -->
    <string name="bugreport_info_title">1-line summary</string>
    <!-- Text of hint asking for the bug report description, which when set will describe
         what the bug report is about. [CHAR LIMIT=NONE] -->
    <string name="bugreport_info_description">Detailed description</string>
</resources>
+332 −21

File changed.

Preview size limit exceeded, changes collapsed.

+0 −2
Original line number Diff line number Diff line
@@ -8,9 +8,7 @@ LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_JAVA_LIBRARIES := android.test.runner

# TODO: update and/or remove
LOCAL_STATIC_JAVA_LIBRARIES := ub-uiautomator
#LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 mockito-target ub-uiautomator

LOCAL_PACKAGE_NAME := ShellTests
LOCAL_INSTRUMENTATION_FOR := Shell
+159 −6
Original line number Diff line number Diff line
@@ -94,7 +94,11 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
    private static final int PID = 42;
    private static final String PROGRESS_PROPERTY = "dumpstate.42.progress";
    private static final String MAX_PROPERTY = "dumpstate.42.max";
    private static final String NAME_PROPERTY = "dumpstate.42.name";
    private static final String NAME = "BUG, Y U NO REPORT?";
    private static final String NEW_NAME = "Bug_Forrest_Bug";
    private static final String TITLE = "Wimbugdom Champion 2015";
    private String mDescription;

    private String mPlainTextPath;
    private String mZipPath;
@@ -120,10 +124,17 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
        createTextFile(mScreenshotPath, SCREENSHOT_CONTENT);
        createZipFile(mZipPath, BUGREPORT_FILE, BUGREPORT_CONTENT);

        // Creates a multi-line description.
        StringBuilder sb = new StringBuilder();
        for (int i = 1; i <= 20; i++) {
            sb.append("All work and no play makes Shell a dull app!\n");
        }
        mDescription = sb.toString();

        BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_HIDE);
    }

    public void testFullWorkflow() throws Exception {
    public void testProgress() throws Exception {
        resetProperties();
        sendBugreportStarted(1000);

@@ -145,6 +156,81 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
        assertServiceNotRunning();
    }

    public void testProgress_changeDetails() throws Exception {
        resetProperties();
        sendBugreportStarted(1000);

        DetailsUi detailsUi = new DetailsUi(mUiBot);

        // Check initial name.
        String actualName = detailsUi.nameField.getText().toString();
        assertEquals("Wrong value on field 'name'", NAME, actualName);

        // Change name - it should have changed system property once focus is changed.
        detailsUi.nameField.setText(NEW_NAME);
        detailsUi.focusAwayFromName();
        assertPropertyValue(NAME_PROPERTY, NEW_NAME);

        // Cancel the dialog to make sure property was restored.
        detailsUi.clickCancel();
        assertPropertyValue(NAME_PROPERTY, NAME);

        // Now try to set an invalid name.
        detailsUi.reOpen();
        detailsUi.nameField.setText("/etc/passwd");
        detailsUi.clickOk();
        assertPropertyValue(NAME_PROPERTY, "_etc_passwd");

        // Finally, make the real changes.
        detailsUi.reOpen();
        detailsUi.nameField.setText(NEW_NAME);
        detailsUi.titleField.setText(TITLE);
        detailsUi.descField.setText(mDescription);

        detailsUi.clickOk();

        assertPropertyValue(NAME_PROPERTY, NEW_NAME);
        assertProgressNotification(NEW_NAME, "0.00%");

        Bundle extras = sendBugreportFinishedAndGetSharedIntent(PID, mPlainTextPath,
                mScreenshotPath);
        assertActionSendMultiple(extras, TITLE, mDescription, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);

        assertServiceNotRunning();
    }

    public void testProgress_bugreportFinishedWhileChangingDetails() throws Exception {
        resetProperties();
        sendBugreportStarted(1000);

        DetailsUi detailsUi = new DetailsUi(mUiBot);

        // Finish the bugreport while user's still typing the name.
        detailsUi.nameField.setText(NEW_NAME);
        sendBugreportFinished(PID, mPlainTextPath, mScreenshotPath);

        // Wait until the share notifcation is received...
        mUiBot.getNotification(mContext.getString(R.string.bugreport_finished_title));
        // ...then close notification bar.
        mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));

        // Make sure UI was updated properly.
        assertFalse("didn't disable name on UI", detailsUi.nameField.isEnabled());
        assertEquals("didn't revert name on UI", NAME, detailsUi.nameField.getText().toString());

        // Finish changing other fields.
        detailsUi.titleField.setText(TITLE);
        detailsUi.descField.setText(mDescription);
        detailsUi.clickOk();

        // Finally, share bugreport.
        Bundle extras = acceptBugreportAndGetSharedIntent();
        assertActionSendMultiple(extras, TITLE, mDescription, BUGREPORT_CONTENT,
                SCREENSHOT_CONTENT);

        assertServiceNotRunning();
    }

    public void testBugreportFinished_withWarning() throws Exception {
        // Explicitly shows the warning.
        BugreportPrefs.setWarningState(mContext, BugreportPrefs.STATE_SHOW);
@@ -204,14 +290,18 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
    private void assertProgressNotification(String name, String percent) {
        // TODO: it current looks for 3 distinct objects, without taking advantage of their
        // relationship.
        String title = mContext.getString(R.string.bugreport_in_progress_title);
        Log.v(TAG, "Looking for progress notification title: '" + title+ "'");
        mUiBot.getNotification(title);
        openProgressNotification();
        Log.v(TAG, "Looking for progress notification details: '" + name + "-" + percent + "'");
        mUiBot.getObject(name);
        mUiBot.getObject(percent);
    }

    private void openProgressNotification() {
        String title = mContext.getString(R.string.bugreport_in_progress_title);
        Log.v(TAG, "Looking for progress notification title: '" + title + "'");
        mUiBot.getNotification(title);
    }

    void resetProperties() {
        // TODO: call method to remove property instead
        SystemProperties.set(PROGRESS_PROPERTY, "0");
@@ -270,7 +360,6 @@ public class BugreportReceiverTest extends InstrumentationTestCase {

    /**
     * Sends a "bugreport finished" intent.
     *
     */
    private void sendBugreportFinished(Integer pid, String bugreportPath, String screenshotPath) {
        Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
@@ -292,13 +381,21 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
     */
    private void assertActionSendMultiple(Bundle extras, String bugreportContent,
            String screenshotContent) throws IOException {
        assertActionSendMultiple(extras, ZIP_FILE, null, bugreportContent, screenshotContent);
    }

    private void assertActionSendMultiple(Bundle extras, String subject, String description,
            String bugreportContent, String screenshotContent) throws IOException {
        String body = extras.getString(Intent.EXTRA_TEXT);
        assertContainsRegex("missing build info",
                SystemProperties.get("ro.build.description"), body);
        assertContainsRegex("missing serial number",
                SystemProperties.get("ro.serialno"), body);
        if (description != null) {
            assertContainsRegex("missing description", description, body);
        }

        assertEquals("wrong subject", ZIP_FILE, extras.getString(Intent.EXTRA_SUBJECT));
        assertEquals("wrong subject", subject, extras.getString(Intent.EXTRA_SUBJECT));

        List<Uri> attachments = extras.getParcelableArrayList(Intent.EXTRA_STREAM);
        int expectedSize = screenshotContent != null ? 2 : 1;
@@ -355,6 +452,11 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
        fail("Did not find entry '" + entryName + "' on file '" + uri + "'");
    }

    private void assertPropertyValue(String key, String expectedValue) {
        String actualValue = SystemProperties.get(key);
        assertEquals("Wrong value for property '" + key + "'", expectedValue, actualValue);
    }

    private void assertServiceNotRunning() {
        String service = BugreportProgressService.class.getName();
        assertFalse("Service '" + service + "' is still running", isServiceRunning(service));
@@ -402,4 +504,55 @@ public class BugreportReceiverTest extends InstrumentationTestCase {
        Log.v(TAG, "Path for '" + file + "': " + path);
        return path;
    }

    /**
     * Helper class containing the UiObjects present in the bugreport info dialog.
     */
    private final class DetailsUi {

        final UiObject detailsButton;
        final UiObject nameField;
        final UiObject titleField;
        final UiObject descField;
        final UiObject okButton;
        final UiObject cancelButton;

        /**
         * Gets the UI objects by opening the progress notification and clicking DETAILS.
         */
        DetailsUi(UiBot uiBot) {
            openProgressNotification();
            detailsButton = mUiBot.getVisibleObject(
                    mContext.getString(R.string.bugreport_info_action).toUpperCase());
            mUiBot.click(detailsButton, "details_button");
            // TODO: unhardcode resource ids
            nameField = mUiBot.getVisibleObjectById("com.android.shell:id/name");
            titleField = mUiBot.getVisibleObjectById("com.android.shell:id/title");
            descField = mUiBot.getVisibleObjectById("com.android.shell:id/description");
            okButton = mUiBot.getObjectById("android:id/button1");
            cancelButton = mUiBot.getObjectById("android:id/button2");
        }

        /**
         * Takes focus away from the name field so it can be validated.
         */
        void focusAwayFromName() {
            mUiBot.click(titleField, "title_field"); // Change focus.
            mUiBot.pressBack(); // Dismiss keyboard.
        }

        void reOpen() {
            openProgressNotification();
            mUiBot.click(detailsButton, "details_button");

        }

        void clickOk() {
            mUiBot.click(okButton, "details_ok_button");
        }

        void clickCancel() {
            mUiBot.click(cancelButton, "details_cancel_button");
        }
    }
}
Loading