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

Commit 9ca36723 authored by Rhed Jao's avatar Rhed Jao Committed by Gerrit Code Review
Browse files

Merge changes I5e1802c5,I4542568f,I99a052d7,Iae89206d,Ie955266a

* changes:
  Returns immediately if the bugreport file already exists
  Fixes an error handling in BugreportProgressService
  Fixes BugreportReceiverTest failed
  Fix BugreportReceiverTest
  Do not buzzing for each progress of bugreport notification
parents 8bdd40d2 7cb78fdf
Loading
Loading
Loading
Loading
+72 −20
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.BugreportManager;
import android.os.BugreportManager.BugreportCallback;
import android.os.BugreportManager.BugreportCallback.BugreportErrorCode;
@@ -186,7 +187,7 @@ public class BugreportProgressService extends Service {
    static final int SCREENSHOT_DELAY_SECONDS = 3;

    /** System property where dumpstate stores last triggered bugreport id */
    private static final String PROPERTY_LAST_ID = "dumpstate.last_id";
    static final String PROPERTY_LAST_ID = "dumpstate.last_id";

    private static final String BUGREPORT_SERVICE = "bugreport";

@@ -233,7 +234,7 @@ public class BugreportProgressService extends Service {

    private File mBugreportsDir;

    private BugreportManager mBugreportManager;
    @VisibleForTesting BugreportManager mBugreportManager;

    /**
     * id of the notification used to set service on foreground.
@@ -248,6 +249,11 @@ public class BugreportProgressService extends Service {
     */
    private boolean mTakingScreenshot;

    /**
     * The delay timeout before taking a screenshot.
     */
    @VisibleForTesting int mScreenshotDelaySec = SCREENSHOT_DELAY_SECONDS;

    @GuardedBy("sNotificationBundle")
    private static final Bundle sNotificationBundle = new Bundle();

@@ -282,6 +288,7 @@ public class BugreportProgressService extends Service {
                        mContext.getString(R.string.bugreport_notification_channel),
                        isTv(this) ? NotificationManager.IMPORTANCE_DEFAULT
                                : NotificationManager.IMPORTANCE_LOW));
        mBugreportManager = mContext.getSystemService(BugreportManager.class);
    }

    @Override
@@ -305,7 +312,7 @@ public class BugreportProgressService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
        return new LocalBinder();
    }

    @Override
@@ -373,8 +380,14 @@ public class BugreportProgressService extends Service {
        public void onFinished() {
            mInfo.renameBugreportFile();
            mInfo.renameScreenshots();
            if (mInfo.bugreportFile.length() == 0) {
                Log.e(TAG, "Bugreport file empty. File path = " + mInfo.bugreportFile);
                onError(BUGREPORT_ERROR_RUNTIME);
                return;
            }
            synchronized (mLock) {
                sendBugreportFinishedBroadcastLocked();
                mMainThreadHandler.post(() -> mInfoDialog.onBugreportFinished(mInfo));
            }
        }

@@ -400,10 +413,6 @@ public class BugreportProgressService extends Service {
        @GuardedBy("mLock")
        private void sendBugreportFinishedBroadcastLocked() {
            final String bugreportFilePath = mInfo.bugreportFile.getAbsolutePath();
            if (mInfo.bugreportFile.length() == 0) {
                Log.e(TAG, "Bugreport file empty. File path = " + bugreportFilePath);
                return;
            }
            if (mInfo.type == BugreportParams.BUGREPORT_MODE_REMOTE) {
                sendRemoteBugreportFinishedBroadcast(mContext, bugreportFilePath,
                        mInfo.bugreportFile);
@@ -609,12 +618,21 @@ public class BugreportProgressService extends Service {

        BugreportInfo info = new BugreportInfo(mContext, baseName, name,
                shareTitle, shareDescription, bugreportType, mBugreportsDir);
        synchronized (mLock) {
            if (info.bugreportFile.exists()) {
                Log.e(TAG, "Failed to start bugreport generation, the requested bugreport file "
                        + info.bugreportFile + " already exists");
                return;
            }
            info.createBugreportFile();
        }
        ParcelFileDescriptor bugreportFd = info.getBugreportFd();
        if (bugreportFd == null) {
            Log.e(TAG, "Failed to start bugreport generation as "
                    + " bugreport parcel file descriptor is null.");
            return;
        }
        info.createScreenshotFile(mBugreportsDir);
        ParcelFileDescriptor screenshotFd = null;
        if (isDefaultScreenshotRequired(bugreportType, /* hasScreenshotButton= */ !mIsTv)) {
            screenshotFd = info.getDefaultScreenshotFd();
@@ -627,8 +645,6 @@ public class BugreportProgressService extends Service {
            }
        }

        mBugreportManager = (BugreportManager) mContext.getSystemService(
                Context.BUGREPORT_SERVICE);
        final Executor executor = ActivityThread.currentActivityThread().getExecutor();

        Log.i(TAG, "bugreport type = " + bugreportType
@@ -888,12 +904,12 @@ public class BugreportProgressService extends Service {
        collapseNotificationBar();
        final String msg = mContext.getResources()
                .getQuantityString(com.android.internal.R.plurals.bugreport_countdown,
                        SCREENSHOT_DELAY_SECONDS, SCREENSHOT_DELAY_SECONDS);
                        mScreenshotDelaySec, mScreenshotDelaySec);
        Log.i(TAG, msg);
        // Show a toast just once, otherwise it might be captured in the screenshot.
        Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();

        takeScreenshot(id, SCREENSHOT_DELAY_SECONDS);
        takeScreenshot(id, mScreenshotDelaySec);
    }

    /**
@@ -1248,6 +1264,7 @@ public class BugreportProgressService extends Service {
                .setContentText(content)
                .setContentIntent(PendingIntent.getService(mContext, info.id, shareIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT))
                .setOnlyAlertOnce(false)
                .setDeleteIntent(newCancelIntent(mContext, info));

        if (!TextUtils.isEmpty(info.getName())) {
@@ -1287,6 +1304,7 @@ public class BugreportProgressService extends Service {
                .setLocalOnly(true)
                .setColor(context.getColor(
                        com.android.internal.R.color.system_notification_accent_color))
                .setOnlyAlertOnce(true)
                .extend(new Notification.TvExtender());
    }

@@ -1620,6 +1638,16 @@ public class BugreportProgressService extends Service {
                || c == '_' || c == '-';
    }

    /**
     * A local binder with interface to return an instance of BugreportProgressService for the
     * purpose of testing.
     */
    final class LocalBinder extends Binder {
        @VisibleForTesting BugreportProgressService getService() {
            return BugreportProgressService.this;
        }
    }

    /**
     * Helper class encapsulating the UI elements and logic used to display a dialog where user
     * can change the details of a bugreport.
@@ -1749,6 +1777,22 @@ public class BugreportProgressService extends Service {
            }
        }

        /**
         * Notifies the dialog that the bugreport has finished so it disables the {@code name}
         * field.
         * <p>Once the bugreport is finished dumpstate has already generated the final files, so
         * changing the name would have no effect.
         */
        void onBugreportFinished(BugreportInfo info) {
            if (mId == info.id && mInfoName != null) {
                mInfoName.setEnabled(false);
                mInfoName.setText(null);
                if (!TextUtils.isEmpty(info.getName())) {
                    mInfoName.setText(info.getName());
                }
            }
        }

        void cancel() {
            if (mDialog != null) {
                mDialog.cancel();
@@ -1883,12 +1927,10 @@ public class BugreportProgressService extends Service {
            this.shareDescription = shareDescription == null ? "" : shareDescription;
            this.type = type;
            this.baseName = baseName;
            createBugreportFile(bugreportsDir);
            createScreenshotFile(bugreportsDir);
            this.bugreportFile = new File(bugreportsDir, getFileName(this, ".zip"));
        }

        void createBugreportFile(File bugreportsDir) {
            bugreportFile = new File(bugreportsDir, getFileName(this, ".zip"));
        void createBugreportFile() {
            createReadWriteFile(bugreportFile);
        }

@@ -1993,12 +2035,21 @@ public class BugreportProgressService extends Service {
                Log.i(TAG, "Deleting empty bugreport file: " + bugreportFile);
                bugreportFile.delete();
            }
            for (File file : screenshotFiles) {
                if (file.length() == 0) {
            deleteEmptyScreenshots();
        }

        /**
         * Deletes empty screenshot files.
         */
        private void deleteEmptyScreenshots() {
            screenshotFiles.removeIf(file -> {
                final long length = file.length();
                if (length == 0) {
                    Log.i(TAG, "Deleting empty screenshot file: " + file);
                    file.delete();
                }
            }
                return length == 0;
            });
        }

        /**
@@ -2006,7 +2057,8 @@ public class BugreportProgressService extends Service {
         * {@code initialName} if user has changed it.
         */
        void renameScreenshots() {
            if (TextUtils.isEmpty(name)) {
            deleteEmptyScreenshots();
            if (TextUtils.isEmpty(name) || screenshotFiles.isEmpty()) {
                return;
            }
            final List<File> renamedFiles = new ArrayList<>(screenshotFiles.size());
+268 −387

File changed.

Preview size limit exceeded, changes collapsed.

+59 −2
Original line number Diff line number Diff line
@@ -18,17 +18,23 @@ package com.android.shell;

import android.app.Instrumentation;
import android.app.StatusBarManager;
import android.os.SystemClock;
import android.support.test.uiautomator.By;
import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
import android.support.test.uiautomator.UiObject2;
import android.support.test.uiautomator.UiObjectNotFoundException;
import android.support.test.uiautomator.UiSelector;
import android.support.test.uiautomator.Until;
import android.text.format.DateUtils;
import android.util.Log;

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;

import java.util.List;

/**
 * A helper class for UI-related testing tasks.
 */
@@ -36,6 +42,9 @@ final class UiBot {

    private static final String TAG = "UiBot";
    private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
    private static final String ANDROID_PACKAGE = "android";

    private static final long SHORT_UI_TIMEOUT_MS = (3 * DateUtils.SECOND_IN_MILLIS);

    private final Instrumentation mInstrumentation;
    private final UiDevice mDevice;
@@ -48,9 +57,9 @@ final class UiBot {
    }

    /**
     * Opens the system notification and gets a given notification.
     * Opens the system notification and gets a UiObject with the text.
     *
     * @param text Notificaton's text as displayed by the UI.
     * @param text Notification's text as displayed by the UI.
     * @return notification object.
     */
    public UiObject getNotification(String text) {
@@ -62,6 +71,43 @@ final class UiBot {
        return getObject(text);
    }

    /**
     * Opens the system notification and gets a notification containing the text.
     *
     * @param text Notification's text as displayed by the UI.
     * @return notification object.
     */
    public UiObject2 getNotification2(String text) {
        boolean opened = mDevice.openNotification();
        Log.v(TAG, "openNotification(): " + opened);
        final UiObject2 notificationScroller = mDevice.wait(Until.findObject(
                By.res(SYSTEMUI_PACKAGE, "notification_stack_scroller")), mTimeout);
        assertNotNull("could not get notification stack scroller", notificationScroller);
        final List<UiObject2> notificationList = notificationScroller.getChildren();
        for (UiObject2 notification: notificationList) {
            final UiObject2 notificationText = notification.findObject(By.textContains(text));
            if (notificationText != null) {
                return notification;
            }
        }
        return null;
    }

    /**
     * Expands the notification.
     *
     * @param notification The notification object returned by {@link #getNotification2(String)}.
     */
    public void expandNotification(UiObject2 notification) {
        final UiObject2 expandBtn =  notification.findObject(
                By.res(ANDROID_PACKAGE, "expand_button"));
        if (expandBtn.getContentDescription().equals("Collapse")) {
            return;
        }
        expandBtn.click();
        mDevice.waitForIdle();
    }

    public void collapseStatusBar() throws Exception {
        // TODO: mDevice should provide such method..
        StatusBarManager sbm =
@@ -162,6 +208,12 @@ final class UiBot {
     */
    public void chooseActivity(String name) {
        // It uses an intent chooser now, so just getting the activity by text is enough...
        final String share = mInstrumentation.getContext().getString(
                com.android.internal.R.string.share);
        boolean gotIt = mDevice.wait(Until.hasObject(By.text(share)), mTimeout);
        assertTrue("could not get share activity (" + share + ")", gotIt);
        swipeUp();
        SystemClock.sleep(SHORT_UI_TIMEOUT_MS);
        UiObject activity = getObject(name);
        click(activity, name);
    }
@@ -173,6 +225,11 @@ final class UiBot {
    public void turnScreenOn() throws Exception {
        mDevice.executeShellCommand("input keyevent KEYCODE_WAKEUP");
        mDevice.executeShellCommand("wm dismiss-keyguard");
        mDevice.waitForIdle();
    }

    public void swipeUp() {
        mDevice.swipe(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() * 3 / 4,
                mDevice.getDisplayWidth() / 2, 0, 30);
    }
}