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

Commit 319e63bc authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Misc cleanups and simplifications"

parents ddf3f6a1 6a928c65
Loading
Loading
Loading
Loading
+28 −80
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.systemui.screenshot;

import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
@@ -27,11 +26,10 @@ import static java.util.Objects.requireNonNull;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Configuration;
import android.content.pm.ActivityInfo;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.PixelFormat;
@@ -64,6 +62,7 @@ import android.widget.Toast;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.policy.PhoneWindow;
import com.android.settingslib.applications.InterestingConfigChanges;
import com.android.systemui.R;
import com.android.systemui.util.DeviceConfigProxy;

@@ -145,7 +144,6 @@ public class ScreenshotController {

    private final WindowManager mWindowManager;
    private final WindowManager.LayoutParams mWindowLayoutParams;
    private final Display mDisplay;
    private final DisplayMetrics mDisplayMetrics;
    private final AccessibilityManager mAccessibilityManager;
    private final MediaActionSound mCameraSound;
@@ -162,9 +160,6 @@ public class ScreenshotController {
    private Animator mScreenshotAnimation;

    private Runnable mOnCompleteRunnable;
    private boolean mInDarkMode;
    private boolean mDirectionLTR;
    private boolean mOrientationPortrait;

    private final Handler mScreenshotHandler = new Handler(Looper.getMainLooper()) {
        @Override
@@ -180,6 +175,15 @@ public class ScreenshotController {
        }
    };

    /** Tracks config changes that require re-creating UI */
    private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
            ActivityInfo.CONFIG_ORIENTATION
                    | ActivityInfo.CONFIG_LAYOUT_DIRECTION
                    | ActivityInfo.CONFIG_LOCALE
                    | ActivityInfo.CONFIG_UI_MODE
                    | ActivityInfo.CONFIG_SCREEN_LAYOUT
                    | ActivityInfo.CONFIG_ASSETS_PATHS);

    @Inject
    ScreenshotController(
            Context context,
@@ -194,23 +198,20 @@ public class ScreenshotController {
        mUiEventLogger = uiEventLogger;

        final DisplayManager dm = requireNonNull(context.getSystemService(DisplayManager.class));
        mDisplay = dm.getDisplay(DEFAULT_DISPLAY);
        mContext = context.createWindowContext(TYPE_SCREENSHOT, null);
        final Display display = dm.getDisplay(DEFAULT_DISPLAY);
        final Context displayContext = context.createDisplayContext(display);
        mContext = displayContext.createWindowContext(TYPE_SCREENSHOT, null);
        mWindowManager = mContext.getSystemService(WindowManager.class);

        mAccessibilityManager = AccessibilityManager.getInstance(mContext);
        mConfigProxy = configProxy;

        Configuration config = mContext.getResources().getConfiguration();
        mInDarkMode = config.isNightModeActive();
        mDirectionLTR = config.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
        mOrientationPortrait = config.orientation == ORIENTATION_PORTRAIT;
        mWindowToken = new Binder("ScreenshotController");
        mScrollCaptureClient.setHostWindowToken(mWindowToken);

        // Setup the window that we are going to use
        mWindowLayoutParams = new WindowManager.LayoutParams(MATCH_PARENT, MATCH_PARENT, 0, 0,
                TYPE_SCREENSHOT,
        mWindowLayoutParams = new WindowManager.LayoutParams(
                MATCH_PARENT, MATCH_PARENT, /* xpos */ 0, /* ypos */ 0, TYPE_SCREENSHOT,
                WindowManager.LayoutParams.FLAG_FULLSCREEN
                        | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
@@ -235,7 +236,7 @@ public class ScreenshotController {
        reloadAssets();

        mDisplayMetrics = new DisplayMetrics();
        mDisplay.getRealMetrics(mDisplayMetrics);
        display.getRealMetrics(mDisplayMetrics);

        // Setup the Camera shutter sound
        mCameraSound = new MediaActionSound();
@@ -245,7 +246,6 @@ public class ScreenshotController {
    void takeScreenshotFullscreen(Consumer<Uri> finisher, Runnable onComplete) {
        mOnCompleteRunnable = onComplete;

        mDisplay.getRealMetrics(mDisplayMetrics);
        takeScreenshotInternal(
                finisher,
                new Rect(0, 0, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
@@ -266,19 +266,18 @@ public class ScreenshotController {
            return;
        }

        if (aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) {
            saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, false);
        } else {
            saveScreenshot(screenshot, finisher,
                    new Rect(0, 0, screenshot.getWidth(), screenshot.getHeight()), Insets.NONE,
                    true);
        boolean showFlash = false;
        if (!aspectRatiosMatch(screenshot, visibleInsets, screenshotScreenBounds)) {
            showFlash = true;
            visibleInsets = Insets.NONE;
            screenshotScreenBounds.set(0, 0, screenshot.getWidth(), screenshot.getHeight());
        }
        saveScreenshot(screenshot, finisher, screenshotScreenBounds, visibleInsets, showFlash);
    }

    /**
     * Displays a screenshot selector
     */
    @SuppressLint("ClickableViewAccessibility")
    void takeScreenshotPartial(final Consumer<Uri> finisher, Runnable onComplete) {
        dismissScreenshot(true);
        mOnCompleteRunnable = onComplete;
@@ -308,60 +307,6 @@ public class ScreenshotController {
        }
    }

    private void onConfigChanged(Configuration newConfig) {
        boolean needsUpdate = false;
        // dark mode
        if (newConfig.isNightModeActive()) {
            // Night mode is active, we're using dark theme
            if (!mInDarkMode) {
                mInDarkMode = true;
                needsUpdate = true;
            }
        } else {
            // Night mode is not active, we're using the light theme
            if (mInDarkMode) {
                mInDarkMode = false;
                needsUpdate = true;
            }
        }

        // RTL configuration
        switch (newConfig.getLayoutDirection()) {
            case View.LAYOUT_DIRECTION_LTR:
                if (!mDirectionLTR) {
                    mDirectionLTR = true;
                    needsUpdate = true;
                }
                break;
            case View.LAYOUT_DIRECTION_RTL:
                if (mDirectionLTR) {
                    mDirectionLTR = false;
                    needsUpdate = true;
                }
                break;
        }

        // portrait/landscape orientation
        switch (newConfig.orientation) {
            case ORIENTATION_PORTRAIT:
                if (!mOrientationPortrait) {
                    mOrientationPortrait = true;
                    needsUpdate = true;
                }
                break;
            case ORIENTATION_LANDSCAPE:
                if (mOrientationPortrait) {
                    mOrientationPortrait = false;
                    needsUpdate = true;
                }
                break;
        }

        if (needsUpdate) {
            reloadAssets();
        }
    }

    /**
     * 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.
@@ -373,8 +318,9 @@ public class ScreenshotController {
        }

        // respect the display cutout in landscape (since we'd otherwise overlap) but not portrait
        int orientation = mContext.getResources().getConfiguration().orientation;
        mWindowLayoutParams.setFitInsetsTypes(
                mOrientationPortrait ? 0 : WindowInsets.Type.displayCutout());
                orientation == ORIENTATION_PORTRAIT ? 0 : WindowInsets.Type.displayCutout());

        // ignore system bar insets for the purpose of window layout
        mDecorView.setOnApplyWindowInsetsListener((v, insets) -> v.onApplyWindowInsets(
@@ -469,7 +415,9 @@ public class ScreenshotController {
        mScreenBitmap.setHasAlpha(false);
        mScreenBitmap.prepareToDraw();

        onConfigChanged(mContext.getResources().getConfiguration());
        if (mConfigChanges.applyNewConfig(mContext.getResources())) {
            reloadAssets();
        }

        // The window is focusable by default
        setWindowFocusable(true);
+75 −73
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ import android.os.UserManager;
import android.util.Log;
import android.view.WindowManager;

import androidx.annotation.NonNull;

import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.R;
@@ -57,9 +59,8 @@ public class TakeScreenshotService extends Service {
    private final UserManager mUserManager;
    private final UiEventLogger mUiEventLogger;
    private final ScreenshotNotificationsController mNotificationsController;

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {

    private final Handler mHandler;
    private final BroadcastReceiver mCloseSystemDialogs = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction()) && mScreenshot != null) {
@@ -68,24 +69,37 @@ public class TakeScreenshotService extends Service {
        }
    };

    private Handler mHandler = new Handler(Looper.myLooper()) {
    @Inject
    public TakeScreenshotService(ScreenshotController screenshotController, UserManager userManager,
            UiEventLogger uiEventLogger,
            ScreenshotNotificationsController notificationsController) {
        mHandler = new Handler(Looper.getMainLooper(), this::handleMessage);
        mScreenshot = screenshotController;
        mUserManager = userManager;
        mUiEventLogger = uiEventLogger;
        mNotificationsController = notificationsController;
    }

    @Override
        public void handleMessage(Message msg) {
            final Messenger callback = msg.replyTo;
            Consumer<Uri> uriConsumer = uri -> {
                Message reply = Message.obtain(null, SCREENSHOT_MSG_URI, uri);
                try {
                    callback.send(reply);
                } catch (RemoteException e) {
    public IBinder onBind(@NonNull Intent intent) {
        registerReceiver(mCloseSystemDialogs, new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS));
        return new Messenger(mHandler).getBinder();
    }
            };
            Runnable onComplete = () -> {
                Message reply = Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE);
                try {
                    callback.send(reply);
                } catch (RemoteException e) {

    @Override
    public boolean onUnbind(Intent intent) {
        if (mScreenshot != null) {
            mScreenshot.dismissScreenshot(true);
        }
        unregisterReceiver(mCloseSystemDialogs);
        return false;
    }
            };

    /** Respond to incoming Message via Binder (Messenger) */
    private boolean handleMessage(Message msg) {
        final Messenger replyTo = msg.replyTo;
        final Runnable onComplete = () -> sendComplete(replyTo);
        final Consumer<Uri> uriConsumer = (uri) -> reportUri(replyTo, uri);

        // If the storage for this user is locked, we have no place to store
        // the screenshot, so skip taking it instead of showing a misleading
@@ -94,9 +108,9 @@ public class TakeScreenshotService extends Service {
            Log.w(TAG, "Skipping screenshot because storage is locked!");
            mNotificationsController.notifyScreenshotError(
                    R.string.screenshot_failed_to_save_user_locked_text);
                post(() -> uriConsumer.accept(null));
                post(onComplete);
                return;
            uriConsumer.accept(null);
            onComplete.run();
            return true;
        }

        ScreenshotHelper.ScreenshotRequest screenshotRequest =
@@ -123,39 +137,27 @@ public class TakeScreenshotService extends Service {
                        taskId, userId, topComponent, uriConsumer, onComplete);
                break;
            default:
                    Log.d(TAG, "Invalid screenshot option: " + msg.what);
            }
                Log.w(TAG, "Invalid screenshot option: " + msg.what);
                return false;
        }
        return true;
    };

    @Inject
    public TakeScreenshotService(
            ScreenshotController screenshotController,
            UserManager userManager,
            UiEventLogger uiEventLogger,
            ScreenshotNotificationsController notificationsController) {
        mScreenshot = screenshotController;
        mUserManager = userManager;
        mUiEventLogger = uiEventLogger;
        mNotificationsController = notificationsController;
    private void sendComplete(Messenger target) {
        try {
            Log.d(TAG, "sendComplete: " + target);
            target.send(Message.obtain(null, SCREENSHOT_MSG_PROCESS_COMPLETE));
        } catch (RemoteException e) {
            Log.d(TAG, "ignored remote exception", e);
        }

    @Override
    public IBinder onBind(Intent intent) {
        // register broadcast receiver
        IntentFilter filter = new IntentFilter(ACTION_CLOSE_SYSTEM_DIALOGS);
        registerReceiver(mBroadcastReceiver, filter);

        return new Messenger(mHandler).getBinder();

    }

    @Override
    public boolean onUnbind(Intent intent) {
        if (mScreenshot != null) {
            mScreenshot.dismissScreenshot(true);
    private void reportUri(Messenger target, Uri uri) {
        try {
            Log.d(TAG, "reportUri: " + target + " -> " + uri);
            target.send(Message.obtain(null, SCREENSHOT_MSG_URI, uri));
        } catch (RemoteException e) {
            Log.d(TAG, "ignored remote exception", e);
        }
        unregisterReceiver(mBroadcastReceiver);
        return true;
    }
}