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

Commit dabdc65a authored by Mark Renouf's avatar Mark Renouf
Browse files

Screenshots logging update

Unify logging tags and flags across screenshots
Log to single tag by default, with option for class name
Individual flags for categories of logs and a master on/off

Test: set LogConfig.DEBUG_ALL = true
      adb shell input keyevent SYSRQ
      adb logcat -s Screenshot:*

Change-Id: I728de8e8b77269d74d40f382fcd947e4e40520ae
parent e5e1ff02
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.screenshot;

@SuppressWarnings("PointlessBooleanExpression")
class LogConfig {

    /** Log ALL the things... */
    private static final boolean DEBUG_ALL = false;

    /** Default log logTag for screenshot code */
    private static final String TAG_SS = "Screenshot";

    /** Use class name as Log tag instead of the default */
    private static final boolean TAG_WITH_CLASS_NAME = false;

    /** Action creation and user selection: Share, Save, Edit, Delete, Smart action, etc */
    static final boolean DEBUG_ACTIONS = DEBUG_ALL || false;

    /** Debug info about animations such as start, complete and cancel */
    static final boolean DEBUG_ANIM = DEBUG_ALL || false;

    /** Whenever Uri is supplied to consumer, or onComplete runnable is run() */
    static final boolean DEBUG_CALLBACK = DEBUG_ALL || false;

    /** Logs information about dismissing the screenshot tool */
    static final boolean DEBUG_DISMISS = DEBUG_ALL || false;

    /** Touch or key event driven action or side effects */
    static final boolean DEBUG_INPUT = DEBUG_ALL || false;

    /** Scroll capture usage */
    static final boolean DEBUG_SCROLL = DEBUG_ALL || false;

    /** Service lifecycle events and callbacks */
    static final boolean DEBUG_SERVICE = DEBUG_ALL || false;

    /** Storage related actions, Bitmap.compress, ContentManager, etc */
    static final boolean DEBUG_STORAGE = DEBUG_ALL || false;

    /** High level logical UI actions: timeout, onConfigChanged, insets, show actions, reset  */
    static final boolean DEBUG_UI = DEBUG_ALL || false;

    /** Interactions with Window and WindowManager */
    static final boolean DEBUG_WINDOW = DEBUG_ALL || false;

    static String logTag(Class<?> cls) {
        return TAG_WITH_CLASS_NAME ? cls.getSimpleName() : TAG_SS;
    }
}
+43 −8
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@

package com.android.systemui.screenshot;

import static com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_STORAGE;
import static com.android.systemui.screenshot.LogConfig.logTag;

import android.app.ActivityTaskManager;
import android.app.Notification;
import android.app.PendingIntent;
@@ -45,7 +50,7 @@ import android.provider.MediaStore;
import android.provider.MediaStore.MediaColumns;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.Slog;
import android.util.Log;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
@@ -74,7 +79,7 @@ import java.util.concurrent.CompletableFuture;
 * An AsyncTask that saves an image to the media store in the background.
 */
class  SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
    private static final String TAG = "SaveImageInBackgroundTask";
    private static final String TAG = logTag(SaveImageInBackgroundTask.class);

    private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png";
    private static final String SCREENSHOT_ID_TEMPLATE = "Screenshot_%s";
@@ -121,6 +126,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
    @Override
    protected Void doInBackground(Void... paramsUnused) {
        if (isCancelled()) {
            if (DEBUG_STORAGE) {
                Log.d(TAG, "cancelled! returning null");
            }
            return null;
        }
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
@@ -151,9 +159,19 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
            try {
                // First, write the actual data for our screenshot
                try (OutputStream out = resolver.openOutputStream(uri)) {
                    if (DEBUG_STORAGE) {
                        Log.d(TAG, "Compressing PNG:"
                                + " w=" + image.getWidth() + " h=" + image.getHeight());
                    }
                    if (!image.compress(Bitmap.CompressFormat.PNG, 100, out)) {
                        if (DEBUG_STORAGE) {
                            Log.d(TAG, "Bitmap.compress returned false");
                        }
                        throw new IOException("Failed to compress");
                    }
                    if (DEBUG_STORAGE) {
                        Log.d(TAG, "Done compressing PNG");
                    }
                }

                // Next, write metadata to help index the screenshot
@@ -181,7 +199,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
                        exif.setAttribute(ExifInterface.TAG_OFFSET_TIME_ORIGINAL,
                                DateTimeFormatter.ofPattern("XXX").format(time));
                    }

                    if (DEBUG_STORAGE) {
                        Log.d(TAG, "Writing EXIF metadata");
                    }
                    exif.saveAttributes();
                }

@@ -190,6 +210,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
                values.put(MediaColumns.IS_PENDING, 0);
                values.putNull(MediaColumns.DATE_EXPIRES);
                resolver.update(uri, values, null, null);
                if (DEBUG_STORAGE) {
                    Log.d(TAG, "Completed writing to ContentManager");
                }
            } catch (Exception e) {
                resolver.delete(uri, null);
                throw e;
@@ -215,15 +238,24 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
            mImageData.deleteAction = createDeleteAction(mContext, mContext.getResources(), uri);

            mParams.mActionsReadyListener.onActionsReady(mImageData);
            if (DEBUG_CALLBACK) {
                Log.d(TAG, "finished background processing, Calling (Consumer<Uri>) "
                        + "finisher.accept(\"" + mImageData.uri + "\"");
            }
            mParams.finisher.accept(mImageData.uri);
            mParams.image = null;
        } catch (Exception e) {
            // IOException/UnsupportedOperationException may be thrown if external storage is
            // not mounted
            Slog.e(TAG, "unable to save screenshot", e);
            if (DEBUG_STORAGE) {
                Log.d(TAG, "Failed to store screenshot", e);
            }
            mParams.clearImage();
            mImageData.reset();
            mParams.mActionsReadyListener.onActionsReady(mImageData);
            if (DEBUG_CALLBACK) {
                Log.d(TAG, "Calling (Consumer<Uri>) finisher.accept(null)");
            }
            mParams.finisher.accept(null);
        }

@@ -245,6 +277,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
        // params from the ctor in any case.
        mImageData.reset();
        mParams.mActionsReadyListener.onActionsReady(mImageData);
        if (DEBUG_CALLBACK) {
            Log.d(TAG, "onCancelled, calling (Consumer<Uri>) finisher.accept(null)");
        }
        mParams.finisher.accept(null);
        mParams.clearImage();
    }
@@ -380,7 +415,9 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
        try {
            return ActivityTaskManager.getService().getLastResumedActivityUserId();
        } catch (RemoteException e) {
            Slog.w(TAG, "getUserHandleOfForegroundApplication: ", e);
            if (DEBUG_ACTIONS) {
                Log.d(TAG, "Failed to get UserHandle of foreground app: ", e);
            }
            return context.getUserId();
        }
    }
@@ -421,6 +458,4 @@ class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> {
                .putExtra(ScreenshotController.EXTRA_ID, screenshotId)
                .putExtra(ScreenshotController.EXTRA_SMART_ACTIONS_ENABLED, smartActionsEnabled);
    }


}
+95 −52
Original line number Diff line number Diff line
@@ -21,6 +21,14 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.TYPE_SCREENSHOT;

import static com.android.systemui.screenshot.LogConfig.DEBUG_ANIM;
import static com.android.systemui.screenshot.LogConfig.DEBUG_CALLBACK;
import static com.android.systemui.screenshot.LogConfig.DEBUG_DISMISS;
import static com.android.systemui.screenshot.LogConfig.DEBUG_INPUT;
import static com.android.systemui.screenshot.LogConfig.DEBUG_UI;
import static com.android.systemui.screenshot.LogConfig.DEBUG_WINDOW;
import static com.android.systemui.screenshot.LogConfig.logTag;

import static java.util.Objects.requireNonNull;

import android.animation.Animator;
@@ -75,6 +83,7 @@ import javax.inject.Inject;
 * Controls the state and flow for screenshots.
 */
public class ScreenshotController {
    private static final String TAG = logTag(ScreenshotController.class);
    /**
     * POD used in the AsyncTask which saves an image in the background.
     */
@@ -110,12 +119,10 @@ public class ScreenshotController {
        }
    }

    abstract static class ActionsReadyListener {
        abstract void onActionsReady(ScreenshotController.SavedImageData imageData);
    interface ActionsReadyListener {
        void onActionsReady(ScreenshotController.SavedImageData imageData);
    }

    private static final String TAG = "ScreenshotController";

    // These strings are used for communicating the action invoked to
    // ScreenshotNotificationSmartActionsProvider.
    static final String EXTRA_ACTION_TYPE = "android:screenshot_action_type";
@@ -166,6 +173,9 @@ public class ScreenshotController {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_CORNER_TIMEOUT:
                    if (DEBUG_UI) {
                        Log.d(TAG, "Corner timeout hit");
                    }
                    mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_INTERACTION_TIMEOUT);
                    ScreenshotController.this.dismissScreenshot(false);
                    break;
@@ -292,13 +302,17 @@ public class ScreenshotController {
     * Clears current screenshot
     */
    void dismissScreenshot(boolean immediate) {
        if (DEBUG_DISMISS) {
            Log.d(TAG, "dismissScreenshot(immediate=" + immediate + ")");
        }
        // If we're already animating out, don't restart the animation
        // (but do obey an immediate dismissal)
        if (!immediate && mScreenshotView.isDismissing()) {
            if (DEBUG_DISMISS) {
                Log.v(TAG, "Already dismissing, ignoring duplicate command");
            }
            return;
        }
        Log.v(TAG, "Clearing screenshot");
        mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
        if (immediate) {
            resetScreenshotView();
@@ -308,12 +322,17 @@ public class ScreenshotController {
    }

    /**
     * Update assets (called when the dark theme status changes). We only need to update the dismiss
     * button and the actions container background, since the buttons are re-inflated on demand.
     * Update resources on configuration change. Reinflate for theme/color changes.
     */
    private void reloadAssets() {
        if (DEBUG_UI) {
            Log.d(TAG, "reloadAssets()");
        }
        boolean wasAttached = mDecorView.isAttachedToWindow();
        if (wasAttached) {
            if (DEBUG_WINDOW) {
                Log.d(TAG, "Removing screenshot window");
            }
            mWindowManager.removeView(mDecorView);
        }

@@ -336,6 +355,9 @@ public class ScreenshotController {
        // TODO(159460485): Remove this when focus is handled properly in the system
        mScreenshotView.setOnTouchListener((v, event) -> {
            if (event.getActionMasked() == MotionEvent.ACTION_OUTSIDE) {
                if (DEBUG_INPUT) {
                    Log.d(TAG, "onTouch: ACTION_OUTSIDE");
                }
                // Once the user touches outside, stop listening for input
                setWindowFocusable(false);
            }
@@ -344,6 +366,9 @@ public class ScreenshotController {

        mScreenshotView.setOnKeyListener((v, keyCode, event) -> {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                if (DEBUG_INPUT) {
                    Log.d(TAG, "onKeyEvent: KeyEvent.KEYCODE_BACK");
                }
                dismissScreenshot(false);
                return true;
            }
@@ -373,10 +398,16 @@ public class ScreenshotController {
        Bitmap screenshot = screenshotBuffer == null ? null : screenshotBuffer.asBitmap();

        if (screenshot == null) {
            Log.e(TAG, "Screenshot bitmap was null");
            Log.e(TAG, "takeScreenshotInternal: Screenshot bitmap was null");
            mNotificationsController.notifyScreenshotError(
                    R.string.screenshot_failed_to_capture_text);
            if (DEBUG_CALLBACK) {
                Log.d(TAG, "Supplying null to Consumer<Uri>");
            }
            finisher.accept(null);
            if (DEBUG_CALLBACK) {
                Log.d(TAG, "Calling mOnCompleteRunnable.run()");
            }
            mOnCompleteRunnable.run();
            return;
        }
@@ -399,12 +430,17 @@ public class ScreenshotController {
            if (!mScreenshotView.isDismissing()) {
                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_REENTERED);
            }
            if (DEBUG_WINDOW) {
                Log.d(TAG, "saveScreenshot: screenshotView is already attached, resetting. "
                        + "(dismissing=" + mScreenshotView.isDismissing()  + ")");
            }
            mScreenshotView.reset();
        }

        mScreenBitmap = screenshot;

        if (!isUserSetupComplete()) {
            Log.w(TAG, "User setup not complete, displaying toast only");
            // User setup isn't complete, so we don't want to show any UI beyond a toast, as editing
            // and sharing shouldn't be exposed to the user.
            saveScreenshotAndToast(finisher);
@@ -416,6 +452,9 @@ public class ScreenshotController {
        mScreenBitmap.prepareToDraw();

        if (mConfigChanges.applyNewConfig(mContext.getResources())) {
            if (DEBUG_UI) {
                Log.d(TAG, "saveScreenshot: reloading assets");
            }
            reloadAssets();
        }

@@ -450,10 +489,10 @@ public class ScreenshotController {
            mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
        });

        saveScreenshotInWorkerThread(finisher,
                new ScreenshotController.ActionsReadyListener() {
                    @Override
                    void onActionsReady(ScreenshotController.SavedImageData imageData) {
        saveScreenshotInWorkerThread(finisher, imageData -> {
            if (DEBUG_CALLBACK) {
                Log.d(TAG, "returning URI to finisher (Consumer<URI>): " + imageData.uri);
            }
            finisher.accept(imageData.uri);
            if (imageData.uri == null) {
                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_NOT_SAVED);
@@ -461,12 +500,8 @@ public class ScreenshotController {
                        R.string.screenshot_failed_to_save_text);
            } else {
                mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_SAVED);

                            mScreenshotHandler.post(() -> {
                                Toast.makeText(mContext, R.string.screenshot_saved_title,
                                        Toast.LENGTH_SHORT).show();
                            });
                        }
                mScreenshotHandler.post(() -> Toast.makeText(mContext,
                        R.string.screenshot_saved_title, Toast.LENGTH_SHORT).show());
            }
        });
    }
@@ -479,37 +514,46 @@ public class ScreenshotController {
        mScreenshotHandler.removeMessages(MESSAGE_CORNER_TIMEOUT);
        mScreenshotHandler.post(() -> {
            if (!mScreenshotView.isAttachedToWindow()) {
                if (DEBUG_WINDOW) {
                    Log.d(TAG, "Adding screenshot window");
                }
                mWindowManager.addView(mWindow.getDecorView(), mWindowLayoutParams);
            }

            mScreenshotView.prepareForAnimation(mScreenBitmap, screenInsets);

            mScreenshotHandler.post(() -> {
                if (DEBUG_WINDOW) {
                    Log.d(TAG, "adding OnComputeInternalInsetsListener");
                }
                mScreenshotView.getViewTreeObserver().addOnComputeInternalInsetsListener(
                        mScreenshotView);

                mScreenshotAnimation =
                        mScreenshotView.createScreenshotDropInAnimation(screenRect, showFlash);

                saveScreenshotInWorkerThread(finisher,
                        new ScreenshotController.ActionsReadyListener() {
                            @Override
                            void onActionsReady(
                                    ScreenshotController.SavedImageData imageData) {
                                showUiOnActionsReady(imageData);
                            }
                        });
                saveScreenshotInWorkerThread(finisher, this::showUiOnActionsReady);

                // Play the shutter sound to notify that we've taken a screenshot
                mCameraSound.play(MediaActionSound.SHUTTER_CLICK);

                if (DEBUG_ANIM) {
                    Log.d(TAG, "starting post-screenshot animation");
                }
                mScreenshotAnimation.start();
            });
        });
    }

    /** Reset screenshot view and then call onCompleteRunnable */
    private void resetScreenshotView() {
        if (DEBUG_UI) {
            Log.d(TAG, "resetScreenshotView");
        }
        if (mScreenshotView.isAttachedToWindow()) {
            if (DEBUG_WINDOW) {
                Log.d(TAG, "Removing screenshot window");
            }
            mWindowManager.removeView(mDecorView);
        }
        mScreenshotView.reset();
@@ -519,8 +563,7 @@ public class ScreenshotController {
    /**
     * Creates a new worker thread and saves the screenshot to the media store.
     */
    private void saveScreenshotInWorkerThread(
            Consumer<Uri> finisher,
    private void saveScreenshotInWorkerThread(Consumer<Uri> finisher,
            @Nullable ScreenshotController.ActionsReadyListener actionsReadyListener) {
        ScreenshotController.SaveImageInBackgroundData
                data = new ScreenshotController.SaveImageInBackgroundData();
@@ -530,13 +573,7 @@ public class ScreenshotController {

        if (mSaveInBgTask != null) {
            // just log success/failure for the pre-existing screenshot
            mSaveInBgTask.setActionsReadyListener(
                    new ScreenshotController.ActionsReadyListener() {
                        @Override
                        void onActionsReady(ScreenshotController.SavedImageData imageData) {
                            logSuccessOnActionsReady(imageData);
                        }
                    });
            mSaveInBgTask.setActionsReadyListener(this::logSuccessOnActionsReady);
        }

        mSaveInBgTask = new SaveImageInBackgroundTask(mContext, mScreenshotSmartActions, data);
@@ -555,6 +592,9 @@ public class ScreenshotController {
                SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS,
                AccessibilityManager.FLAG_CONTENT_CONTROLS);

        if (DEBUG_UI) {
            Log.d(TAG, "Showing UI actions, dismiss timeout: " + timeoutMs + " ms");
        }
        mScreenshotHandler.sendMessageDelayed(
                mScreenshotHandler.obtainMessage(MESSAGE_CORNER_TIMEOUT),
                timeoutMs);
@@ -600,6 +640,9 @@ public class ScreenshotController {
     * shown.
     */
    private void setWindowFocusable(boolean focusable) {
        if (DEBUG_WINDOW) {
            Log.d(TAG, "setWindowFocusable: " + focusable);
        }
        if (focusable) {
            mWindowLayoutParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        } else {
@@ -618,9 +661,10 @@ public class ScreenshotController {

        if (insettedHeight == 0 || insettedWidth == 0 || bitmap.getWidth() == 0
                || bitmap.getHeight() == 0) {
            Log.e(TAG, String.format(
                    "Provided bitmap and insets create degenerate region: %dx%d %s",
                    bitmap.getWidth(), bitmap.getHeight(), bitmapInsets));
            if (DEBUG_UI) {
                Log.e(TAG, "Provided bitmap and insets create degenerate region: "
                        + bitmap.getWidth() + "x" + bitmap.getHeight() + " " + bitmapInsets);
            }
            return false;
        }

@@ -628,11 +672,10 @@ public class ScreenshotController {
        float boundsAspect = ((float) screenBounds.width()) / screenBounds.height();

        boolean matchWithinTolerance = Math.abs(insettedBitmapAspect - boundsAspect) < 0.1f;
        if (!matchWithinTolerance) {
            Log.d(TAG, String.format("aspectRatiosMatch: don't match bitmap: %f, bounds: %f",
                    insettedBitmapAspect, boundsAspect));
        if (DEBUG_UI) {
            Log.d(TAG, "aspectRatiosMatch: don't match bitmap: " + insettedBitmapAspect
                    + ", bounds: " + boundsAspect);
        }

        return matchWithinTolerance;
    }
}
+22 −20
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.systemui.screenshot;

import static com.android.systemui.screenshot.LogConfig.DEBUG_ACTIONS;
import static com.android.systemui.screenshot.LogConfig.logTag;

import android.app.Notification;
import android.content.ComponentName;
import android.graphics.Bitmap;
@@ -32,6 +35,9 @@ import java.util.concurrent.CompletableFuture;
 * in order to provide smart actions in the screenshot notification.
 */
public class ScreenshotNotificationSmartActionsProvider {

    private static final String TAG = logTag(ScreenshotNotificationSmartActionsProvider.class);

    /* Key provided in the notification action to get the type of smart action. */
    public static final String ACTION_TYPE = "action_type";
    public static final String DEFAULT_ACTION_TYPE = "Smart Action";
@@ -51,29 +57,21 @@ public class ScreenshotNotificationSmartActionsProvider {
        ERROR,
        TIMEOUT
    }

    private static final String TAG = "ScreenshotActions";

    /**
     * Default implementation that returns an empty list.
     * This method is overridden in vendor-specific Sys UI implementation.
     *
     * @param screenshotId       A generated random unique id for the screenshot.
     * @param screenshotFileName name of the file where the screenshot will be written.
     * @param bitmap             The bitmap of the screenshot. The bitmap config must be {@link
     *                           HARDWARE}.
     * @param componentName      Contains package and activity class names where the screenshot was
     *                           taken. This is used as an additional signal to generate and rank
     *                           more relevant actions.
     * @param userHandle         The user handle of the app where the screenshot was taken.
     * @param screenshotId       a unique id for the screenshot
     * @param screenshotUri      uri where the screenshot has been stored
     * @param bitmap             the screenshot, config must be {@link Bitmap.Config#HARDWARE}
     * @param componentName      name of the foreground component when the screenshot was taken
     * @param userHandle         user handle of the foreground task owner
     */
    public CompletableFuture<List<Notification.Action>> getActions(
            String screenshotId,
            Uri screenshotUri,
            Bitmap bitmap,
            ComponentName componentName,
            UserHandle userHandle) {
    public CompletableFuture<List<Notification.Action>> getActions(String screenshotId,
            Uri screenshotUri, Bitmap bitmap, ComponentName componentName, UserHandle userHandle) {
        if (DEBUG_ACTIONS) {
            Log.d(TAG, "Returning empty smart action list.");
        }
        return CompletableFuture.completedFuture(Collections.emptyList());
    }

@@ -88,7 +86,9 @@ public class ScreenshotNotificationSmartActionsProvider {
     */
    public void notifyOp(String screenshotId, ScreenshotOp op, ScreenshotOpStatus status,
            long durationMs) {
        Log.d(TAG, "Return without notify.");
        if (DEBUG_ACTIONS) {
            Log.d(TAG, "SmartActions: notifyOp() - return without notify");
        }
    }

    /**
@@ -100,6 +100,8 @@ public class ScreenshotNotificationSmartActionsProvider {
     * @param isSmartAction whether action invoked was a smart action.
     */
    public void notifyAction(String screenshotId, String action, boolean isSmartAction) {
        Log.d(TAG, "Return without notify.");
        if (DEBUG_ACTIONS) {
            Log.d(TAG, "SmartActions: notifyAction: return without notify");
        }
    }
}
+42 −15

File changed.

Preview size limit exceeded, changes collapsed.

Loading