BugreportReceiverTest.java revision fcca68dfb137c061952d23e1873e995e6bcf172d
1e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme/*
2e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Copyright (C) 2015 The Android Open Source Project
3e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme *
4e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
5e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * you may not use this file except in compliance with the License.
6e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * You may obtain a copy of the License at
7e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme *
8e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
9e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme *
10e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Unless required by applicable law or agreed to in writing, software
11e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
12e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * See the License for the specific language governing permissions and
14e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * limitations under the License.
15e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */
16e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
17e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemepackage com.android.shell;
18e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
19e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport static android.test.MoreAsserts.assertContainsRegex;
20fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme
21e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport static com.android.shell.ActionSendMultipleConsumerActivity.UI_NAME;
22fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Lemeimport static com.android.shell.BugreportPrefs.PREFS_BUGREPORT;
23fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Lemeimport static com.android.shell.BugreportPrefs.STATE_HIDE;
24fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Lemeimport static com.android.shell.BugreportPrefs.STATE_SHOW;
25fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Lemeimport static com.android.shell.BugreportPrefs.STATE_UNKNOWN;
26fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Lemeimport static com.android.shell.BugreportPrefs.getWarningState;
27fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Lemeimport static com.android.shell.BugreportPrefs.setWarningState;
28b9238b37838d653c38ce4e712421adb61978fc22Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_BUGREPORT;
2985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_ID;
3069c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_MAX;
3169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_NAME;
3269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_PID;
33b9238b37838d653c38ce4e712421adb61978fc22Felipe Lemeimport static com.android.shell.BugreportProgressService.EXTRA_SCREENSHOT;
3469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_FINISHED;
3569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Lemeimport static com.android.shell.BugreportProgressService.INTENT_BUGREPORT_STARTED;
363fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Lemeimport static com.android.shell.BugreportProgressService.POLLING_FREQUENCY;
37d1e0f12979441733753b538611f6d73e5527c43cFelipe Lemeimport static com.android.shell.BugreportProgressService.SCREENSHOT_DELAY_SECONDS;
38e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
39e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.BufferedOutputStream;
40e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.BufferedWriter;
41e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.ByteArrayOutputStream;
42a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Lemeimport java.io.File;
43e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.FileOutputStream;
44e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.IOException;
45e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.InputStream;
46e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.OutputStreamWriter;
47e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.io.Writer;
48e86b63bd17da3d347b9392f897e361919655edd6Felipe Lemeimport java.text.NumberFormat;
49d1e0f12979441733753b538611f6d73e5527c43cFelipe Lemeimport java.util.ArrayList;
50e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.List;
51d1e0f12979441733753b538611f6d73e5527c43cFelipe Lemeimport java.util.SortedSet;
52d1e0f12979441733753b538611f6d73e5527c43cFelipe Lemeimport java.util.TreeSet;
53e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.zip.ZipEntry;
54e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.zip.ZipInputStream;
55e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport java.util.zip.ZipOutputStream;
56e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
57e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport libcore.io.Streams;
58fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme
59ba477939f0ae38926b4b0a6501a2371acc612433Felipe Lemeimport android.app.ActivityManager;
60ba477939f0ae38926b4b0a6501a2371acc612433Felipe Lemeimport android.app.ActivityManager.RunningServiceInfo;
61e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.app.Instrumentation;
62e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.app.NotificationManager;
63e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.content.Context;
64e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.content.Intent;
65e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.net.Uri;
66e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.os.Bundle;
67e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.os.SystemProperties;
68e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.service.notification.StatusBarNotification;
69e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.support.test.uiautomator.UiDevice;
706bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Lemeimport android.support.test.uiautomator.UiObject;
71e86b63bd17da3d347b9392f897e361919655edd6Felipe Lemeimport android.support.test.uiautomator.UiObjectNotFoundException;
72e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.test.InstrumentationTestCase;
732bfa0858a8cb67e19a1c9df8aad0a4da423a52b8Felipe Lemeimport android.test.suitebuilder.annotation.LargeTest;
744967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Lemeimport android.text.TextUtils;
75d1e0f12979441733753b538611f6d73e5527c43cFelipe Lemeimport android.text.format.DateUtils;
76e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport android.util.Log;
77e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
78e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemeimport com.android.shell.ActionSendMultipleConsumerActivity.CustomActionSendMultipleListener;
79e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
80e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme/**
81e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * Integration tests for {@link BugreportReceiver}.
82e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p>
83e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * These tests don't mock any component and rely on external UI components (like the notification
84e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * bar and activity chooser), which can make them unreliable and slow.
85e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p>
86e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * The general workflow is:
87e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <ul>
88e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>creates the bug report files
89e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>generates the BUGREPORT_FINISHED intent
90e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>emulate user actions to share the intent with a custom activity
91e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <li>asserts the extras received by the custom activity
92e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * </ul>
93e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme * <p>
946bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme * <strong>NOTE</strong>: these tests only work if the device is unlocked.
95e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme */
962bfa0858a8cb67e19a1c9df8aad0a4da423a52b8Felipe Leme@LargeTest
97e53e85f6051d20cbd477bc25d446a41996411fabFelipe Lemepublic class BugreportReceiverTest extends InstrumentationTestCase {
98e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private static final String TAG = "BugreportReceiverTest";
99e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
100e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    // Timeout for UI operations, in milliseconds.
1013fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme    private static final int TIMEOUT = (int) POLLING_FREQUENCY * 4;
102e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
103c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    // Timeout for when waiting for a screenshot to finish.
104c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    private static final int SAFE_SCREENSHOT_DELAY = SCREENSHOT_DELAY_SECONDS + 10;
105c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
106a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    private static final String BUGREPORTS_DIR = "bugreports";
107e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private static final String BUGREPORT_FILE = "test_bugreport.txt";
108e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private static final String ZIP_FILE = "test_bugreport.zip";
109262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final String ZIP_FILE2 = "test_bugreport2.zip";
110a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    private static final String SCREENSHOT_FILE = "test_screenshot.png";
111e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
112e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private static final String BUGREPORT_CONTENT = "Dump, might as well dump!\n";
113e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private static final String SCREENSHOT_CONTENT = "A picture is worth a thousand words!\n";
114e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
11593702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    private static final int PID = 42;
116262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final int PID2 = 24;
11785ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private static final int ID = 108;
118262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final int ID2 = 801;
11985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private static final String PROGRESS_PROPERTY = "dumpstate." + PID + ".progress";
12085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private static final String MAX_PROPERTY = "dumpstate." + PID + ".max";
12185ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private static final String NAME_PROPERTY = "dumpstate." + PID + ".name";
12293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    private static final String NAME = "BUG, Y U NO REPORT?";
123262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final String NAME2 = "A bugreport's life";
124bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    private static final String NEW_NAME = "Bug_Forrest_Bug";
125262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final String NEW_NAME2 = "BugsyReportsy";
126bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    private static final String TITLE = "Wimbugdom Champion 2015";
127262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final String TITLE2 = "Master of the Universe";
128262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final String DESCRIPTION = "One's description...";
129262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private static final String DESCRIPTION2 = "...is another's treasure.";
1304967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
1314967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    private static final String NO_DESCRIPTION = null;
1324967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    private static final String NO_NAME = null;
1334967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    private static final String NO_SCREENSHOT = null;
1344967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    private static final String NO_TITLE = null;
13585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private static final int NO_ID = 0;
136c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme    private static final boolean RENAMED_SCREENSHOTS = true;
137c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme    private static final boolean DIDNT_RENAME_SCREENSHOTS = false;
1384967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
1395ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme    private static final boolean PENDING_SCREENSHOT = true;
1405ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme    private static final boolean NOT_PENDING_SCREENSHOT = false;
1415ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme
142bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    private String mDescription;
14393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
144a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    private String mPlainTextPath;
145a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    private String mZipPath;
146262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private String mZipPath2;
147a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    private String mScreenshotPath;
148a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme
149e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private Context mContext;
150e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private UiBot mUiBot;
151e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private CustomActionSendMultipleListener mListener;
152e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
153e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    @Override
154e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    protected void setUp() throws Exception {
155c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        Log.i(TAG, "#### setup() on " + getName());
156e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        Instrumentation instrumentation = getInstrumentation();
157e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        mContext = instrumentation.getTargetContext();
158e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        mUiBot = new UiBot(UiDevice.getInstance(instrumentation), TIMEOUT);
159e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        mListener = ActionSendMultipleConsumerActivity.getListener(mContext);
16093702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
16193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        cancelExistingNotifications();
16293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
163a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme        mPlainTextPath = getPath(BUGREPORT_FILE);
164a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme        mZipPath = getPath(ZIP_FILE);
165262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        mZipPath2 = getPath(ZIP_FILE2);
166a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme        mScreenshotPath = getPath(SCREENSHOT_FILE);
16793702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        createTextFile(mPlainTextPath, BUGREPORT_CONTENT);
16893702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        createTextFile(mScreenshotPath, SCREENSHOT_CONTENT);
16993702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        createZipFile(mZipPath, BUGREPORT_FILE, BUGREPORT_CONTENT);
170262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        createZipFile(mZipPath2, BUGREPORT_FILE, BUGREPORT_CONTENT);
17193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
172bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Creates a multi-line description.
173bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        StringBuilder sb = new StringBuilder();
174bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        for (int i = 1; i <= 20; i++) {
175bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            sb.append("All work and no play makes Shell a dull app!\n");
176bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
177bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        mDescription = sb.toString();
178bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
179fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        setWarningState(mContext, STATE_HIDE);
180e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
181e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
182bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    public void testProgress() throws Exception {
18393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        resetProperties();
18493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        sendBugreportStarted(1000);
1852288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        waitForScreenshotButtonEnabled(true);
18669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
1879ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 0f);
18869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
18993702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "108");
1909ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 10.80f);
19169c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
1929ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 50.00f);
19369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
1943fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "950");
1959ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 95.00f);
1963fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme
1973fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        // Make sure progress never goes back...
19893702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        SystemProperties.set(MAX_PROPERTY, "2000");
1993fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        Thread.sleep(POLLING_FREQUENCY + DateUtils.SECOND_IN_MILLIS);
2009ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 95.00f);
2013fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme
2023fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "1000");
2039ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 95.00f);
2043fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme
2053fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        // ...only forward...
2063fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "1902");
2079ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 95.10f);
2083fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme
2093fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "1960");
2109ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 98.00f);
2113fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme
2123fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        // ...but never more than the capped value.
2133fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "2000");
2149ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 99.00f);
2153fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme
2163fc44b9a6274254e8d3a53b6b1e245c5f9177229Felipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "3000");
2179ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 99.00f);
218719aaae3c167c2b15525dbe5c7db514a2c0c8269Felipe Leme
21993702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        Bundle extras =
22085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme                sendBugreportFinishedAndGetSharedIntent(ID, mPlainTextPath, mScreenshotPath);
22185ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, ZIP_FILE,
222c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NAME, NO_TITLE, NO_DESCRIPTION, 1, RENAMED_SCREENSHOTS);
223d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
224d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        assertServiceNotRunning();
225d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    }
226d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
227db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    public void testProgress_cancel() throws Exception {
228db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        resetProperties();
229db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        sendBugreportStarted(1000);
230db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        waitForScreenshotButtonEnabled(true);
231db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
232db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        final NumberFormat nf = NumberFormat.getPercentInstance();
233db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        nf.setMinimumFractionDigits(2);
234db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        nf.setMaximumFractionDigits(2);
235db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
2369ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NAME, 00.00f);
237db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
238db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        openProgressNotification(ID);
239db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        UiObject cancelButton = mUiBot.getVisibleObject(mContext.getString(
240db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme                com.android.internal.R.string.cancel).toUpperCase());
241db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        mUiBot.click(cancelButton, "cancel_button");
242db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
243db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        waitForService(false);
244db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    }
245db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
246d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    public void testProgress_takeExtraScreenshot() throws Exception {
247c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        takeExtraScreenshotTest(false);
248c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
249c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
250c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    public void testProgress_takeExtraScreenshotServiceDiesAfterScreenshotTaken() throws Exception {
251c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        takeExtraScreenshotTest(true);
252c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
253c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
254c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    private void takeExtraScreenshotTest(boolean serviceDies) throws Exception {
255d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        resetProperties();
256d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        sendBugreportStarted(1000);
257d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
258d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        waitForScreenshotButtonEnabled(true);
259d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        takeScreenshot();
260d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        assertScreenshotButtonEnabled(false);
261d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        waitForScreenshotButtonEnabled(true);
262d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
26385ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        sendBugreportFinished(ID, mPlainTextPath, mScreenshotPath);
264c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
265c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        if (serviceDies) {
26685ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme            waitShareNotification(ID);
267c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            killService();
268c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        }
269c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
27085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = acceptBugreportAndGetSharedIntent(ID);
27185ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, ZIP_FILE,
272c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NAME, NO_TITLE, NO_DESCRIPTION, 2, RENAMED_SCREENSHOTS);
27369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
27493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        assertServiceNotRunning();
27569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme    }
27669c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
277c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    public void testScreenshotFinishesAfterBugreport() throws Exception {
278c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        screenshotFinishesAfterBugreportTest(false);
279c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
280c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
281c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    public void testScreenshotFinishesAfterBugreportAndServiceDiesBeforeSharing() throws Exception {
282c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        screenshotFinishesAfterBugreportTest(true);
283c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
284c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
285c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    private void screenshotFinishesAfterBugreportTest(boolean serviceDies) throws Exception {
286c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        resetProperties();
287c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
288c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        sendBugreportStarted(1000);
28985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        sendBugreportFinished(ID, mPlainTextPath, NO_SCREENSHOT);
29085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        waitShareNotification(ID);
291c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
292c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        // There's no indication in the UI about the screenshot finish, so just sleep like a baby...
293c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        Thread.sleep(SAFE_SCREENSHOT_DELAY * DateUtils.SECOND_IN_MILLIS);
294c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
295c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        if (serviceDies) {
296c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            killService();
297c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        }
298c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
29985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = acceptBugreportAndGetSharedIntent(ID);
30085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT, ID, PID, ZIP_FILE,
301c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NAME, NO_TITLE, NO_DESCRIPTION, 1, RENAMED_SCREENSHOTS);
302c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
303c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        assertServiceNotRunning();
304c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
305c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
3064967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    public void testProgress_changeDetailsInvalidInput() throws Exception {
307bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        resetProperties();
308bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        sendBugreportStarted(1000);
3092288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        waitForScreenshotButtonEnabled(true);
310bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
31185ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        DetailsUi detailsUi = new DetailsUi(mUiBot, ID);
312bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
313bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Check initial name.
314262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.assertName(NAME);
315bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
316bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Change name - it should have changed system property once focus is changed.
317208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        detailsUi.focusOnName();
318bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.nameField.setText(NEW_NAME);
319bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.focusAwayFromName();
320bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertPropertyValue(NAME_PROPERTY, NEW_NAME);
321bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
322bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Cancel the dialog to make sure property was restored.
323bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.clickCancel();
324bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertPropertyValue(NAME_PROPERTY, NAME);
325bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
326bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Now try to set an invalid name.
327bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.reOpen();
328bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.nameField.setText("/etc/passwd");
329bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.clickOk();
330bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertPropertyValue(NAME_PROPERTY, "_etc_passwd");
331bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
332bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Finally, make the real changes.
333bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.reOpen();
334bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.nameField.setText(NEW_NAME);
335bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.titleField.setText(TITLE);
336bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.descField.setText(mDescription);
337bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
338bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.clickOk();
339bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
340bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertPropertyValue(NAME_PROPERTY, NEW_NAME);
3419ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NEW_NAME, 00.00f);
342bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
34385ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID, mPlainTextPath,
344bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme                mScreenshotPath);
34585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE,
346c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NEW_NAME, TITLE, mDescription, 1, RENAMED_SCREENSHOTS);
3474967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3484967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        assertServiceNotRunning();
3494967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    }
3504967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3514967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    public void testProgress_changeDetailsPlainBugreport() throws Exception {
3524967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        changeDetailsTest(true);
3534967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    }
3544967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3554967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    public void testProgress_changeDetailsZippedBugreport() throws Exception {
3564967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        changeDetailsTest(false);
3574967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    }
3584967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3594967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme    public void changeDetailsTest(boolean plainText) throws Exception {
3604967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        resetProperties();
3614967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        sendBugreportStarted(1000);
3624967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        waitForScreenshotButtonEnabled(true);
3634967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
36485ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        DetailsUi detailsUi = new DetailsUi(mUiBot, ID);
3654967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3664967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        // Check initial name.
367262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.assertName(NAME);
3684967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3694967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        // Change fields.
3704967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        detailsUi.reOpen();
3714967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        detailsUi.nameField.setText(NEW_NAME);
3724967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        detailsUi.titleField.setText(TITLE);
3734967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        detailsUi.descField.setText(mDescription);
3744967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3754967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        detailsUi.clickOk();
3764967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
3774967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        assertPropertyValue(NAME_PROPERTY, NEW_NAME);
3789ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        assertProgressNotification(NEW_NAME, 00.00f);
3794967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme
38085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID,
3814967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme                plainText? mPlainTextPath : mZipPath, mScreenshotPath);
38285ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE,
383c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NEW_NAME, TITLE, mDescription, 1, RENAMED_SCREENSHOTS);
384c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme
385c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        assertServiceNotRunning();
386c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme    }
387c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme
388db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    public void testProgress_changeJustDetailsTouchingDetails() throws Exception {
389db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        changeJustDetailsTest(true);
390db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    }
391db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
392db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    public void testProgress_changeJustDetailsTouchingNotification() throws Exception {
393db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        changeJustDetailsTest(false);
394db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    }
395db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
396db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    private void changeJustDetailsTest(boolean touchDetails) throws Exception {
397c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        resetProperties();
398c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        sendBugreportStarted(1000);
399c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        waitForScreenshotButtonEnabled(true);
400c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme
401db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        DetailsUi detailsUi = new DetailsUi(mUiBot, ID, touchDetails);
402c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme
403c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        detailsUi.nameField.setText("");
404c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        detailsUi.titleField.setText("");
405c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        detailsUi.descField.setText(mDescription);
406c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme        detailsUi.clickOk();
407c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme
40885ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID, mZipPath, mScreenshotPath);
40985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, ZIP_FILE,
410c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NO_NAME, NO_TITLE, mDescription, 1, DIDNT_RENAME_SCREENSHOTS);
411bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
412bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertServiceNotRunning();
413bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    }
414bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
415262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    /*
416262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     * TODO: this test can be flanky because it relies in the order the notifications are displayed,
417262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     * since mUiBot gets the first notification.
418262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     * Ideally, openProgressNotification() should return the whole notification, so DetailsUi
419262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     * could use it and find children instead, but unfortunately the notification object hierarchy
420262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     * is too complex and getting it from the notification text object would be to fragile
421262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     * (for instance, it could require navigating many parents up in the hierarchy).
422262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme     */
423262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    public void testProgress_changeJustDetailsIsClearedOnSecondBugreport() throws Exception {
424262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        resetProperties();
425262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        sendBugreportStarted(ID, PID, NAME, 1000);
426262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        waitForScreenshotButtonEnabled(true);
427262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
428262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        DetailsUi detailsUi = new DetailsUi(mUiBot, ID);
429262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.assertName(NAME);
430bbd91e58444f092e1080f5a0a746fcd4b21ce113Felipe Leme        detailsUi.assertTitle("");
431bbd91e58444f092e1080f5a0a746fcd4b21ce113Felipe Leme        detailsUi.assertDescription("");
432262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.nameField.setText(NEW_NAME);
433262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.titleField.setText(TITLE);
434262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.descField.setText(DESCRIPTION);
435262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.clickOk();
436262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
437262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        sendBugreportStarted(ID2, PID2, NAME2, 1000);
438262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
4395ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        sendBugreportFinished(ID, mZipPath, mScreenshotPath);
4405ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        Bundle extras = acceptBugreportAndGetSharedIntent(ID, PENDING_SCREENSHOT);
441262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
442262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi = new DetailsUi(mUiBot, ID2);
443262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.assertName(NAME2);
444bbd91e58444f092e1080f5a0a746fcd4b21ce113Felipe Leme        detailsUi.assertTitle("");
445bbd91e58444f092e1080f5a0a746fcd4b21ce113Felipe Leme        detailsUi.assertDescription("");
446262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.nameField.setText(NEW_NAME2);
447262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.titleField.setText(TITLE2);
448262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.descField.setText(DESCRIPTION2);
449262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        detailsUi.clickOk();
450262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
451262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        // Must use a different zip file otherwise it will fail because zip already contains
452262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        // title.txt and description.txt entries.
453262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        extras = sendBugreportFinishedAndGetSharedIntent(ID2, mZipPath2, NO_SCREENSHOT);
454262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT, ID2, PID2, TITLE2,
455262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme                NEW_NAME2, TITLE2, DESCRIPTION2, 1, RENAMED_SCREENSHOTS);
456262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
457262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        assertServiceNotRunning();
458262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    }
459262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
4602288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme    /**
4612288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     * Tests the scenario where the initial screenshot and dumpstate are finished while the user
4622288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     * is changing the info in the details screen.
4632288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     */
4642288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme    public void testProgress_bugreportAndScreenshotFinishedWhileChangingDetails() throws Exception {
4652288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        bugreportFinishedWhileChangingDetailsTest(false);
4662288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme    }
4672288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme
4682288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme    /**
4692288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     * Tests the scenario where dumpstate is finished while the user is changing the info in the
4702288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     * details screen, but the initial screenshot finishes afterwards.
4712288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     */
472bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    public void testProgress_bugreportFinishedWhileChangingDetails() throws Exception {
4732288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        bugreportFinishedWhileChangingDetailsTest(true);
4742288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme    }
4752288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme
4762288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme    private void bugreportFinishedWhileChangingDetailsTest(boolean waitScreenshot) throws Exception {
477bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        resetProperties();
478bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        sendBugreportStarted(1000);
4792288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        if (waitScreenshot) {
4802288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme            waitForScreenshotButtonEnabled(true);
4812288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        }
482bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
48385ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        DetailsUi detailsUi = new DetailsUi(mUiBot, ID);
484bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
485bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Finish the bugreport while user's still typing the name.
486bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.nameField.setText(NEW_NAME);
48785ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        sendBugreportFinished(ID, mPlainTextPath, mScreenshotPath);
488bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
4892288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme        // Wait until the share notification is received...
49085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        waitShareNotification(ID);
491bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // ...then close notification bar.
492bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        mContext.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
493bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
494bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Make sure UI was updated properly.
495bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertFalse("didn't disable name on UI", detailsUi.nameField.isEnabled());
496bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertEquals("didn't revert name on UI", NAME, detailsUi.nameField.getText().toString());
497bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
498bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Finish changing other fields.
499bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.titleField.setText(TITLE);
500bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.descField.setText(mDescription);
501bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        detailsUi.clickOk();
502bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
503bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        // Finally, share bugreport.
50485ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = acceptBugreportAndGetSharedIntent(ID);
50585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE,
506c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NAME, TITLE, mDescription, 1, RENAMED_SCREENSHOTS);
507bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
508bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertServiceNotRunning();
509bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    }
510bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
511fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    public void testBugreportFinished_withWarningFirstTime() throws Exception {
512fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        bugreportFinishedWithWarningTest(null);
513fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    }
514fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme
515fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    public void testBugreportFinished_withWarningUnknownState() throws Exception {
516fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        bugreportFinishedWithWarningTest(STATE_UNKNOWN);
517fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    }
518fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme
519fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    public void testBugreportFinished_withWarningShowAgain() throws Exception {
520fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        bugreportFinishedWithWarningTest(STATE_SHOW);
521fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    }
522fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme
523fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme    private void bugreportFinishedWithWarningTest(Integer propertyState) throws Exception {
524fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        if (propertyState == null) {
525fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            // Clear properties
526fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            mContext.getSharedPreferences(PREFS_BUGREPORT, Context.MODE_PRIVATE)
527fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme                    .edit().clear().commit();
528fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            // Sanity check...
529fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            assertEquals("Did not reset properties", STATE_UNKNOWN,
530fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme                    getWarningState(mContext, STATE_UNKNOWN));
531fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        } else {
532fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            setWarningState(mContext, propertyState);
533fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        }
5346bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme
5356bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        // Send notification and click on share.
53685ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        sendBugreportFinished(NO_ID, mPlainTextPath, null);
53785ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        acceptBugreport(NO_ID);
5386bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme
5396bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        // Handle the warning
5406bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm));
541fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        // TODO: get ok and dontShowAgain from the dialog reference above
542fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        UiObject dontShowAgain =
543fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme                mUiBot.getVisibleObject(mContext.getString(R.string.bugreport_confirm_dont_repeat));
544fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        final boolean firstTime = propertyState == null || propertyState == STATE_UNKNOWN;
545fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        if (firstTime) {
546fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            assertTrue("Checkbox should be checked by default", dontShowAgain.isChecked());
547fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        } else {
548fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            assertFalse("Checkbox should not be checked", dontShowAgain.isChecked());
549fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme            mUiBot.click(dontShowAgain, "dont-show-again");
550fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        }
5516bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        UiObject ok = mUiBot.getVisibleObject(mContext.getString(com.android.internal.R.string.ok));
5526bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        mUiBot.click(ok, "ok");
5536bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme
5546bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        // Share the bugreport.
5556bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        mUiBot.chooseActivity(UI_NAME);
5566bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        Bundle extras = mListener.getExtras();
5574967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
5586bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme
5596bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme        // Make sure it's hidden now.
560fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        int newState = getWarningState(mContext, STATE_UNKNOWN);
561fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        assertEquals("Didn't change state", STATE_HIDE, newState);
5626bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme    }
5636bbb6b9caf0e91afa11421e6d64a95a9ee4ca26eFelipe Leme
564c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    public void testShareBugreportAfterServiceDies() throws Exception {
56585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        sendBugreportFinished(NO_ID, mPlainTextPath, NO_SCREENSHOT);
566c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        killService();
56785ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        Bundle extras = acceptBugreportAndGetSharedIntent(NO_ID);
568c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
569c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
570c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
571e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    public void testBugreportFinished_plainBugreportAndScreenshot() throws Exception {
57293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, mScreenshotPath);
573e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
574e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
575e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
576e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    public void testBugreportFinished_zippedBugreportAndScreenshot() throws Exception {
57793702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(mZipPath, mScreenshotPath);
578e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT);
579e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
580e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
581e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    public void testBugreportFinished_plainBugreportAndNoScreenshot() throws Exception {
5824967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(mPlainTextPath, NO_SCREENSHOT);
5834967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
584e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
585e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
586e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    public void testBugreportFinished_zippedBugreportAndNoScreenshot() throws Exception {
5874967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        Bundle extras = sendBugreportFinishedAndGetSharedIntent(mZipPath, NO_SCREENSHOT);
5884967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        assertActionSendMultiple(extras, BUGREPORT_CONTENT, NO_SCREENSHOT);
589e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
590e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
591e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private void cancelExistingNotifications() {
592e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        NotificationManager nm = NotificationManager.from(mContext);
593e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        for (StatusBarNotification notification : nm.getActiveNotifications()) {
594e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            int id = notification.getId();
595e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            Log.i(TAG, "Canceling existing notification (id=" + id + ")");
596e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            nm.cancel(id);
597e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
598e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
599e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
6009ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme    private void assertProgressNotification(String name, float percent) {
601d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        // TODO: it currently looks for 3 distinct objects, without taking advantage of their
60269c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme        // relationship.
60385ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        openProgressNotification(ID);
60469c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme        Log.v(TAG, "Looking for progress notification details: '" + name + "-" + percent + "'");
60569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme        mUiBot.getObject(name);
6069ca5e5639048375100acd98a40ad82d8b699c575Felipe Leme        // TODO: need a way to get the ProgresBar from the "android:id/progress" UIObject...
60769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme    }
60869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
609db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme    private UiObject openProgressNotification(int id) {
61085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        String title = mContext.getString(R.string.bugreport_in_progress_title, id);
611bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        Log.v(TAG, "Looking for progress notification title: '" + title + "'");
612db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        return mUiBot.getNotification(title);
613bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    }
614bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
61593702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    void resetProperties() {
61693702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        // TODO: call method to remove property instead
61785ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        SystemProperties.set(PROGRESS_PROPERTY, "Reset");
61885ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        SystemProperties.set(MAX_PROPERTY, "Reset");
61985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        SystemProperties.set(NAME_PROPERTY, "Reset");
62093702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    }
62193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
62293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    /**
62393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * Sends a "bugreport started" intent with the default values.
62493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     */
625d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    private void sendBugreportStarted(int max) throws Exception {
626262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        sendBugreportStarted(ID, PID, NAME, max);
627262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    }
628262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
629262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private void sendBugreportStarted(int id, int pid, String name, int max) throws Exception {
63093702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        Intent intent = new Intent(INTENT_BUGREPORT_STARTED);
631ec17538d46a49530ed6efdc2842ee16eaf18b9f6Felipe Leme        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
632262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        intent.putExtra(EXTRA_ID, id);
633262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        intent.putExtra(EXTRA_PID, pid);
634262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        intent.putExtra(EXTRA_NAME, name);
63593702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        intent.putExtra(EXTRA_MAX, max);
63693702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        mContext.sendBroadcast(intent);
63793702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    }
63893702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
639e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    /**
640e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme     * Sends a "bugreport finished" intent and waits for the result.
641e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme     *
64293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * @return extras sent in the shared intent.
643e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme     */
64493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    private Bundle sendBugreportFinishedAndGetSharedIntent(String bugreportPath,
64593702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme            String screenshotPath) {
64685ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        return sendBugreportFinishedAndGetSharedIntent(NO_ID, bugreportPath, screenshotPath);
64769c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme    }
64869c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme
64993702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    /**
65093702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * Sends a "bugreport finished" intent and waits for the result.
65193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     *
65293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * @return extras sent in the shared intent.
65393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     */
65485ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private Bundle sendBugreportFinishedAndGetSharedIntent(int id, String bugreportPath,
65569c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme            String screenshotPath) {
65685ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        sendBugreportFinished(id, bugreportPath, screenshotPath);
6575ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        return acceptBugreportAndGetSharedIntent(id, NOT_PENDING_SCREENSHOT);
65893702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    }
65993702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
66093702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    /**
66193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * Accepts the notification to share the finished bugreport and waits for the result.
66293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     *
66393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * @return extras sent in the shared intent.
66493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     */
66585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private Bundle acceptBugreportAndGetSharedIntent(int id) {
6665ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        return acceptBugreportAndGetSharedIntent(id, NOT_PENDING_SCREENSHOT);
6675ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme    }
6685ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme
6695ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme    private Bundle acceptBugreportAndGetSharedIntent(int id, boolean pendingScreenshot) {
6705ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        acceptBugreport(id, pendingScreenshot);
67193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        mUiBot.chooseActivity(UI_NAME);
67293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        return mListener.getExtras();
67393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    }
67493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
67593702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    /**
676c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme     * Waits for the notification to share the finished bugreport.
677c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme     */
67885ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private void waitShareNotification(int id) {
67985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        mUiBot.getNotification(mContext.getString(R.string.bugreport_finished_title, id));
680c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
681c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
682c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    /**
68393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * Accepts the notification to share the finished bugreport.
68493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     */
68585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private void acceptBugreport(int id) {
6865ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        acceptBugreport(id, NOT_PENDING_SCREENSHOT);
6875ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme    }
6885ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme
6895ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme    private void acceptBugreport(int id, boolean pendingScreenshot) {
6905ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        final int res = pendingScreenshot ? R.string.bugreport_finished_pending_screenshot_title
6915ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme                : R.string.bugreport_finished_title;
6925ee846dd18022307341c9808c9aacded2b2f60fdFelipe Leme        mUiBot.clickOnNotification(mContext.getString(res, id));
69393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    }
69493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
69593702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    /**
69693702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     * Sends a "bugreport finished" intent.
69793702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme     */
69885ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme    private void sendBugreportFinished(int id, String bugreportPath, String screenshotPath) {
69969c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme        Intent intent = new Intent(INTENT_BUGREPORT_FINISHED);
700ec17538d46a49530ed6efdc2842ee16eaf18b9f6Felipe Leme        intent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
70185ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        if (id != NO_ID) {
70285ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme            intent.putExtra(EXTRA_ID, id);
70369c0292affe8be51e10afb2dbf58f0133918a2c3Felipe Leme        }
704e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        if (bugreportPath != null) {
705e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            intent.putExtra(EXTRA_BUGREPORT, bugreportPath);
706e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
707e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        if (screenshotPath != null) {
708e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            intent.putExtra(EXTRA_SCREENSHOT, screenshotPath);
709e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
710e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
711e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        mContext.sendBroadcast(intent);
712e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
713e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
714e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    /**
715d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * Asserts the proper {@link Intent#ACTION_SEND_MULTIPLE} intent was sent.
716e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme     */
717e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private void assertActionSendMultiple(Bundle extras, String bugreportContent,
718e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            String screenshotContent) throws IOException {
71985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        assertActionSendMultiple(extras, bugreportContent, screenshotContent, ID, PID, ZIP_FILE,
720c8e2b6092c0fbf87e71f81fd2cffbb29ff8d9039Felipe Leme                NO_NAME, NO_TITLE, NO_DESCRIPTION, 0, DIDNT_RENAME_SCREENSHOTS);
721bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    }
722bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
723d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    /**
724d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * Asserts the proper {@link Intent#ACTION_SEND_MULTIPLE} intent was sent.
725d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     *
726d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * @param extras extras received in the intent
727d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * @param bugreportContent expected content in the bugreport file
728d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * @param screenshotContent expected content in the screenshot file (sent by dumpstate), if any
72985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme     * @param id emulated dumpstate id
730d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * @param pid emulated dumpstate pid
7314967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme     * @param name expected subject
7324967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme     * @param name bugreport name as provided by the user (or received by dumpstate)
7334967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme     * @param title bugreport name as provided by the user
734d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * @param description bugreport description as provided by the user
735d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * @param numberScreenshots expected number of screenshots taken by Shell.
7362288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme     * @param renamedScreenshots whether the screenshots are expected to be renamed
737d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     */
738d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    private void assertActionSendMultiple(Bundle extras, String bugreportContent,
73985ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme            String screenshotContent, int id, int pid, String subject,
7404967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme            String name, String title, String description,
7412288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme            int numberScreenshots, boolean renamedScreenshots) throws IOException {
742e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        String body = extras.getString(Intent.EXTRA_TEXT);
743e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        assertContainsRegex("missing build info",
744e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                SystemProperties.get("ro.build.description"), body);
745e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        assertContainsRegex("missing serial number",
746e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                SystemProperties.get("ro.serialno"), body);
747bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        if (description != null) {
748bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            assertContainsRegex("missing description", description, body);
749bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
750e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
7514967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        assertEquals("wrong subject", subject, extras.getString(Intent.EXTRA_SUBJECT));
752e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
753e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        List<Uri> attachments = extras.getParcelableArrayList(Intent.EXTRA_STREAM);
754d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        int expectedNumberScreenshots = numberScreenshots;
755d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        if (screenshotContent != null) {
756d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            expectedNumberScreenshots ++; // Add screenshot received by dumpstate
757d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        }
758d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        int expectedSize = expectedNumberScreenshots + 1; // All screenshots plus the bugreport file
759c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        assertEquals("wrong number of attachments (" + attachments + ")",
760c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme                expectedSize, attachments.size());
761e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
762e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        // Need to interact through all attachments, since order is not guaranteed.
763d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        Uri zipUri = null;
764d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        List<Uri> screenshotUris = new ArrayList<>(expectedNumberScreenshots);
765e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        for (Uri attachment : attachments) {
766e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            if (attachment.getPath().endsWith(".zip")) {
767e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                zipUri = attachment;
768e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            }
769e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            if (attachment.getPath().endsWith(".png")) {
770d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                screenshotUris.add(attachment);
771e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            }
772e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
773e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        assertNotNull("did not get .zip attachment", zipUri);
774e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        assertZipContent(zipUri, BUGREPORT_FILE, BUGREPORT_CONTENT);
7754967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        if (!TextUtils.isEmpty(title)) {
7764967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme            assertZipContent(zipUri, "title.txt", title);
7774967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        }
7784967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        if (!TextUtils.isEmpty(description)) {
7794967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme            assertZipContent(zipUri, "description.txt", description);
7804967f737d9906e3d5c9bf3a0584a7b7cf83b5a8cFelipe Leme        }
781e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
782d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        // URI of the screenshot taken by dumpstate.
783d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        Uri externalScreenshotUri = null;
784d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        SortedSet<String> internalScreenshotNames = new TreeSet<>();
785d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        for (Uri screenshotUri : screenshotUris) {
786d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            String screenshotName = screenshotUri.getLastPathSegment();
787d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            if (screenshotName.endsWith(SCREENSHOT_FILE)) {
788d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                externalScreenshotUri = screenshotUri;
789d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            } else {
790d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                internalScreenshotNames.add(screenshotName);
791d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            }
792d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        }
793d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        // Check external screenshot
794e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        if (screenshotContent != null) {
795d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            assertNotNull("did not get .png attachment for external screenshot",
796d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                    externalScreenshotUri);
797d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            assertContent(externalScreenshotUri, SCREENSHOT_CONTENT);
798e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        } else {
799d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            assertNull("should not have .png attachment for external screenshot",
800d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                    externalScreenshotUri);
801d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        }
802d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        // Check internal screenshots.
803d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        SortedSet<String> expectedNames = new TreeSet<>();
804d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        for (int i = 1 ; i <= numberScreenshots; i++) {
8052288129d5208cd26ab41191db69a418d15ead9eeFelipe Leme            String prefix = renamedScreenshots  ? name : Integer.toString(pid);
806d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            String expectedName = "screenshot-" + prefix + "-" + i + ".png";
807d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            expectedNames.add(expectedName);
808e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
809d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        // Ideally we should use MoreAsserts, but the error message in case of failure is not
810d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        // really useful.
811d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        assertEquals("wrong names for internal screenshots",
812d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                expectedNames, internalScreenshotNames);
813e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
814e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
815e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private void assertContent(Uri uri, String expectedContent) throws IOException {
816e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        Log.v(TAG, "assertContents(uri=" + uri);
817e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        try (InputStream is = mContext.getContentResolver().openInputStream(uri)) {
818e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            String actualContent = new String(Streams.readFully(is));
819e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            assertEquals("wrong content for '" + uri + "'", expectedContent, actualContent);
820e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
821e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
822e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
823e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private void assertZipContent(Uri uri, String entryName, String expectedContent)
824e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            throws IOException, IOException {
825e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        Log.v(TAG, "assertZipEntry(uri=" + uri + ", entryName=" + entryName);
826e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        try (ZipInputStream zis = new ZipInputStream(mContext.getContentResolver().openInputStream(
827e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                uri))) {
828e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            ZipEntry entry;
829e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            while ((entry = zis.getNextEntry()) != null) {
830e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                Log.v(TAG, "Zip entry: " + entry.getName());
831e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                if (entry.getName().equals(entryName)) {
832e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                    ByteArrayOutputStream bos = new ByteArrayOutputStream();
833e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                    Streams.copy(zis, bos);
834e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                    String actualContent = new String(bos.toByteArray(), "UTF-8");
835e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                    bos.close();
836e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                    assertEquals("wrong content for zip entry'" + entryName + "' on '" + uri + "'",
837e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                            expectedContent, actualContent);
838e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                    return;
839e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                }
840e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            }
841e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
842e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        fail("Did not find entry '" + entryName + "' on file '" + uri + "'");
843e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
844e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
845bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    private void assertPropertyValue(String key, String expectedValue) {
846bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        String actualValue = SystemProperties.get(key);
847bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        assertEquals("Wrong value for property '" + key + "'", expectedValue, actualValue);
848bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    }
849bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
85093702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    private void assertServiceNotRunning() {
85193702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        String service = BugreportProgressService.class.getName();
85293702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme        assertFalse("Service '" + service + "' is still running", isServiceRunning(service));
85393702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme    }
85493702abf6e9a87079e81c46c82d8c3954a426759Felipe Leme
855c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    private void killService() {
856c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        waitForService(true);
857c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        Log.v(TAG, "Stopping service");
858c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        boolean stopped = mContext.stopService(new Intent(mContext, BugreportProgressService.class));
859c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        Log.d(TAG, "stopService returned " + stopped);
860c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        waitForService(false);
861c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        assertServiceNotRunning();  // Sanity check.
862c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
863c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
864ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme    private boolean isServiceRunning(String name) {
865ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme        ActivityManager manager = (ActivityManager) mContext
866ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme                .getSystemService(Context.ACTIVITY_SERVICE);
867ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme        for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
868ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme            if (service.service.getClassName().equals(name)) {
869ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme                return true;
870ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme            }
871ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme        }
872ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme        return false;
873ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme    }
874ba477939f0ae38926b4b0a6501a2371acc612433Felipe Leme
875c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    private void waitForService(boolean expectRunning) {
876c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        String service = BugreportProgressService.class.getName();
877c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        boolean actualRunning;
878c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        for (int i = 1; i <= 5; i++) {
879c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            actualRunning = isServiceRunning(service);
880c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            Log.d(TAG, "Attempt " + i + " to check status of service '"
881c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme                    + service + "': expected=" + expectRunning + ", actual= " + actualRunning);
882c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            if (actualRunning == expectRunning) {
883c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme                return;
884c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            }
885c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            try {
886c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme                Thread.sleep(DateUtils.SECOND_IN_MILLIS);
887c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            } catch (InterruptedException e) {
888c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme                Log.w(TAG, "thread interrupted");
889c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme                Thread.currentThread().interrupt();
890c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            }
891c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        }
892c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        if (!expectRunning) {
893c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            // Typically happens when service is waiting for a screenshot to finish.
894c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            Log.w(TAG, "Service didn't stop; try to kill it again");
895c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            killService();
896c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme            return;
897c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        }
898c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
899c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        fail("Service status didn't change to " + expectRunning);
900c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme    }
901c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme
902262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme    private void createTextFile(String path, String content) throws IOException {
903e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        Log.v(TAG, "createFile(" + path + ")");
904e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        try (Writer writer = new BufferedWriter(new OutputStreamWriter(
905e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                new FileOutputStream(path)))) {
906e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            writer.write(content);
907e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
908e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
909e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme
910e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    private void createZipFile(String path, String entryName, String content) throws IOException {
911e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        Log.v(TAG, "createZipFile(" + path + ", " + entryName + ")");
912e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        try (ZipOutputStream zos = new ZipOutputStream(
913e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme                new BufferedOutputStream(new FileOutputStream(path)))) {
914e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            ZipEntry entry = new ZipEntry(entryName);
915e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            zos.putNextEntry(entry);
916e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            byte[] data = content.getBytes();
917e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            zos.write(data, 0, data.length);
918e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme            zos.closeEntry();
919e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme        }
920e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme    }
921a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme
922a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    private String getPath(String file) {
923fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        final File rootDir = mContext.getFilesDir();
924fcca68dfb137c061952d23e1873e995e6bcf172dFelipe Leme        final File dir = new File(rootDir, BUGREPORTS_DIR);
925e2b4f49795b4f23fa563a0ffb9986b49aee7f9beFelipe Leme        if (!dir.exists()) {
926e2b4f49795b4f23fa563a0ffb9986b49aee7f9beFelipe Leme            Log.i(TAG, "Creating directory " + dir);
927e2b4f49795b4f23fa563a0ffb9986b49aee7f9beFelipe Leme            assertTrue("Could not create directory " + dir, dir.mkdir());
928e2b4f49795b4f23fa563a0ffb9986b49aee7f9beFelipe Leme        }
929a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme        String path = new File(dir, file).getAbsolutePath();
930a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme        Log.v(TAG, "Path for '" + file + "': " + path);
931a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme        return path;
932a0bf0336f0b6ff39cd90aabe0eb48b022d008ed6Felipe Leme    }
933bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
934bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    /**
935d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * Gets the notification button used to take a screenshot.
936d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     */
937d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    private UiObject getScreenshotButton() {
93885ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        openProgressNotification(ID);
939d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        return mUiBot.getVisibleObject(
940d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                mContext.getString(R.string.bugreport_screenshot_action).toUpperCase());
941d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    }
942d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
943d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    /**
944d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     * Takes a screenshot using the system notification.
945d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme     */
946d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    private void takeScreenshot() throws Exception {
947d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        UiObject screenshotButton = getScreenshotButton();
948d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        mUiBot.click(screenshotButton, "screenshot_button");
949d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    }
950d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
951d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    private UiObject waitForScreenshotButtonEnabled(boolean expectedEnabled) throws Exception {
952d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        UiObject screenshotButton = getScreenshotButton();
953c4f6467702e308844ef0769ba17dcb7b7b32a9e6Felipe Leme        int maxAttempts = SAFE_SCREENSHOT_DELAY;
954d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        int i = 0;
955d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        do {
956d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            boolean enabled = screenshotButton.isEnabled();
957d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            if (enabled == expectedEnabled) {
958d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                return screenshotButton;
959d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            }
960d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            i++;
961d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            Log.v(TAG, "Sleeping for 1 second while waiting for screenshot.enable to be "
962d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                    + expectedEnabled + " (attempt " + i + ")");
963d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme            Thread.sleep(DateUtils.SECOND_IN_MILLIS);
964d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        } while (i <= maxAttempts);
965d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        fail("screenshot.enable didn't change to " + expectedEnabled + " in " + maxAttempts + "s");
966d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        return screenshotButton;
967d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    }
968d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
969d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    private void assertScreenshotButtonEnabled(boolean expectedEnabled) throws Exception {
970d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        UiObject screenshotButton = getScreenshotButton();
971d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme        assertEquals("wrong state for screenshot button ", expectedEnabled,
972d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme                screenshotButton.isEnabled());
973d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    }
974d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme
975d1e0f12979441733753b538611f6d73e5527c43cFelipe Leme    /**
976bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme     * Helper class containing the UiObjects present in the bugreport info dialog.
977bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme     */
978bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    private final class DetailsUi {
979bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
980bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        final UiObject detailsButton;
981bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        final UiObject nameField;
982bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        final UiObject titleField;
983bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        final UiObject descField;
984bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        final UiObject okButton;
985bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        final UiObject cancelButton;
986bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
987bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        /**
988bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme         * Gets the UI objects by opening the progress notification and clicking DETAILS.
989bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme         */
99085ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme        DetailsUi(UiBot uiBot, int id) throws UiObjectNotFoundException {
991db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme            this(uiBot, id, true);
992db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        }
993db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme
994db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        /**
995db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme         * Gets the UI objects by opening the progress notification and clicking on DETAILS or in
996db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme         * the notification itself.
997db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme         */
998db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme        DetailsUi(UiBot uiBot, int id, boolean clickDetails) throws UiObjectNotFoundException {
999db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme            UiObject notification = openProgressNotification(id);
1000262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme            detailsButton = mUiBot.getVisibleObject(mContext.getString(
1001262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme                    R.string.bugreport_info_action).toUpperCase());
1002262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
1003db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme            if (clickDetails) {
1004db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme                mUiBot.click(detailsButton, "details_button");
1005db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme            } else {
1006db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme                mUiBot.click(notification, "notification");
1007db31363aa9670dbbc5837af7a04bdd8012493fd7Felipe Leme            }
1008bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            // TODO: unhardcode resource ids
1009e86b63bd17da3d347b9392f897e361919655edd6Felipe Leme            UiObject dialogTitle = mUiBot.getVisibleObjectById("android:id/alertTitle");
1010e86b63bd17da3d347b9392f897e361919655edd6Felipe Leme            assertEquals("Wrong title", mContext.getString(R.string.bugreport_info_dialog_title,
101185ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme                    id), dialogTitle.getText().toString());
1012bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            nameField = mUiBot.getVisibleObjectById("com.android.shell:id/name");
1013bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            titleField = mUiBot.getVisibleObjectById("com.android.shell:id/title");
1014bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            descField = mUiBot.getVisibleObjectById("com.android.shell:id/description");
1015bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            okButton = mUiBot.getObjectById("android:id/button1");
1016bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            cancelButton = mUiBot.getObjectById("android:id/button2");
1017bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
1018bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
1019208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        private void assertField(String name, UiObject field, String expected)
1020208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme                throws UiObjectNotFoundException {
1021208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme            String actual = field.getText().toString();
1022208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme            assertEquals("Wrong value on field '" + name + "'", expected, actual);
1023262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        }
1024262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
1025208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        void assertName(String expected) throws UiObjectNotFoundException {
1026262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme            assertField("name", nameField, expected);
1027262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        }
1028262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
1029208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        void assertTitle(String expected) throws UiObjectNotFoundException {
1030262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme            assertField("title", titleField, expected);
1031262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        }
1032262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
1033208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        void assertDescription(String expected) throws UiObjectNotFoundException {
1034262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme            assertField("description", descField, expected);
1035262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme        }
1036262887834c7938b7a7bbbd7ef026b5965d6412fcFelipe Leme
1037bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        /**
1038208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme         * Set focus on the name field so it can be validated once focus is lost.
1039208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme         */
1040208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        void focusOnName() throws UiObjectNotFoundException {
1041208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme            mUiBot.click(nameField, "name_field");
1042208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme            assertTrue("name_field not focused", nameField.isFocused());
1043208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        }
1044208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme
1045208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        /**
1046bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme         * Takes focus away from the name field so it can be validated.
1047bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme         */
1048208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme        void focusAwayFromName() throws UiObjectNotFoundException {
1049bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            mUiBot.click(titleField, "title_field"); // Change focus.
1050bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            mUiBot.pressBack(); // Dismiss keyboard.
1051208b1881ae924cd0c2bed326555e4aa18424d927Felipe Leme            assertFalse("name_field is focused", nameField.isFocused());
1052bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
1053bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
1054bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        void reOpen() {
105585ae3cf46ad66d71e5a29a93e89a0f569d74288bFelipe Leme            openProgressNotification(ID);
1056bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            mUiBot.click(detailsButton, "details_button");
1057bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
1058bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
1059bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        void clickOk() {
1060bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            mUiBot.click(okButton, "details_ok_button");
1061bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
1062bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme
1063bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        void clickCancel() {
1064bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme            mUiBot.click(cancelButton, "details_cancel_button");
1065bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme        }
1066bc73ffc06fd2b5b30802cc7e8874a986626b897dFelipe Leme    }
1067e53e85f6051d20cbd477bc25d446a41996411fabFelipe Leme}
1068