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

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

Merge "First pass at using hardware bitmaps" into ub-launcher3-master

parents 5f733574 9d32323c
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.launcher3.uioverrides;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.view.View.AccessibilityDelegate;
import android.widget.PopupMenu;
import android.widget.Toast;
@@ -24,11 +26,16 @@ import android.widget.Toast;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.BitmapRenderer;
import com.android.launcher3.util.TouchController;
import com.android.launcher3.widget.WidgetsFullSheet;
import com.android.systemui.shared.recents.view.RecentsTransition;

public class UiFactory {

    public static final boolean USE_HARDWARE_BITMAP = FeatureFlags.IS_DOGFOOD_BUILD;

    public static TouchController[] createTouchControllers(Launcher launcher) {

        if (launcher.getDeviceProfile().isVerticalBarLayout()) {
@@ -77,4 +84,15 @@ public class UiFactory {
        }
        menu.show();
    }

    public static Bitmap createFromRenderer(int width, int height, boolean forceSoftwareRenderer,
            BitmapRenderer renderer) {
        if (USE_HARDWARE_BITMAP && !forceSoftwareRenderer) {
            return RecentsTransition.createHardwareBitmap(width, height, renderer::render);
        } else {
            Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            renderer.render(new Canvas(result));
            return result;
        }
    }
}
+13 −2
Original line number Diff line number Diff line
@@ -41,17 +41,20 @@ import android.os.UserHandle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;

import com.android.launcher3.compat.LauncherAppsCompat;
import com.android.launcher3.compat.UserManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.LauncherIcons;
import com.android.launcher3.model.PackageItemInfo;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.InstantAppResolver;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.Provider;
import com.android.launcher3.util.SQLiteCacheHelper;
import com.android.launcher3.util.Thunk;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -102,6 +105,7 @@ public class IconCache {
    @Thunk final Handler mWorkerHandler;

    private final BitmapFactory.Options mLowResOptions;
    private final BitmapFactory.Options mHighResOptions;

    public IconCache(Context context, InvariantDeviceProfile inv) {
        mContext = context;
@@ -120,6 +124,13 @@ public class IconCache {
        // Always prefer RGB_565 config for low res. If the bitmap has transparency, it will
        // automatically be loaded as ALPHA_8888.
        mLowResOptions.inPreferredConfig = Bitmap.Config.RGB_565;

        if (UiFactory.USE_HARDWARE_BITMAP) {
            mHighResOptions = new BitmapFactory.Options();
            mHighResOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
        } else {
            mHighResOptions = null;
        }
    }

    private Drawable getFullResDefaultActivityIcon() {
@@ -625,7 +636,7 @@ public class IconCache {
                    Bitmap icon = LauncherIcons.createBadgedIconBitmap(
                            appInfo.loadIcon(mPackageManager), user, mContext, appInfo.targetSdkVersion);
                    if (mInstantAppResolver.isInstantApp(appInfo)) {
                        icon = LauncherIcons.badgeWithDrawable(icon,
                        LauncherIcons.badgeWithDrawable(icon,
                                mContext.getDrawable(R.drawable.ic_instant_app_badge), mContext);
                    }
                    Bitmap lowResIcon =  generateLowResIcon(icon);
@@ -665,7 +676,7 @@ public class IconCache {
                new String[]{cacheKey.componentName.flattenToString(),
                        Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
            if (c.moveToNext()) {
                entry.icon = loadIconNoResize(c, 0, lowRes ? mLowResOptions : null);
                entry.icon = loadIconNoResize(c, 0, lowRes ? mLowResOptions : mHighResOptions);
                entry.isLowResIcon = lowRes;
                entry.title = c.getString(1);
                if (entry.title == null) {
+21 −25
Original line number Diff line number Diff line
@@ -36,10 +36,9 @@ import com.android.launcher3.MainThreadExecutor;
import com.android.launcher3.R;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.folder.PreviewBackground;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.Preconditions;

import java.util.concurrent.Callable;

/**
 * {@link AdaptiveIconDrawable} representation of a {@link FolderIcon}
 */
@@ -66,7 +65,7 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
    }

    public static FolderAdaptiveIcon createFolderAdaptiveIcon(
            final Launcher launcher, final long folderId, Point dragViewSize) {
            Launcher launcher, long folderId, Point dragViewSize) {
        Preconditions.assertNonUiThread();
        int margin = launcher.getResources()
                .getDimensionPixelSize(R.dimen.blur_size_medium_outline);
@@ -75,21 +74,12 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
        final Bitmap badge = Bitmap.createBitmap(
                dragViewSize.x - margin, dragViewSize.y - margin, Bitmap.Config.ARGB_8888);

        // The bitmap for the preview is generated larger than needed to allow for the spring effect
        float sizeScaleFactor = 1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction();
        final Bitmap preview = Bitmap.createBitmap(
                (int) (dragViewSize.x * sizeScaleFactor), (int) (dragViewSize.y * sizeScaleFactor),
                Bitmap.Config.ARGB_8888);

        // Create the actual drawable on the UI thread to avoid race conditions with
        // FolderIcon draw pass
        try {
            return new MainThreadExecutor().submit(new Callable<FolderAdaptiveIcon>() {
                @Override
                public FolderAdaptiveIcon call() throws Exception {
            return new MainThreadExecutor().submit(() -> {
                FolderIcon icon = launcher.findFolderIcon(folderId);
                    return icon == null ? null : createDrawableOnUiThread(icon, badge, preview);
                }
                return icon == null ? null : createDrawableOnUiThread(icon, badge, dragViewSize);
            }).get();
        } catch (Exception e) {
            Log.e(TAG, "Unable to create folder icon", e);
@@ -101,7 +91,7 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
     * Initializes various bitmaps on the UI thread and returns the final drawable.
     */
    private static FolderAdaptiveIcon createDrawableOnUiThread(FolderIcon icon,
            Bitmap badgeBitmap, Bitmap previewBitmap) {
            Bitmap badgeBitmap, Point dragViewSize) {
        Preconditions.assertUIThread();
        float margin = icon.getResources().getDimension(R.dimen.blur_size_medium_outline) / 2;

@@ -115,15 +105,21 @@ public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
        icon.drawBadge(c);

        // Initialize preview
        float shiftFactor = AdaptiveIconDrawable.getExtraInsetFraction() /
                (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
        float previewShiftX = shiftFactor * previewBitmap.getWidth();
        float previewShiftY = shiftFactor * previewBitmap.getHeight();

        c.setBitmap(previewBitmap);
        c.translate(previewShiftX, previewShiftY);
        icon.getPreviewItemManager().draw(c);
        c.setBitmap(null);
        final float sizeScaleFactor = 1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction();
        final int previewWidth = (int) (dragViewSize.x * sizeScaleFactor);
        final int previewHeight = (int) (dragViewSize.y * sizeScaleFactor);

        final float shiftFactor = AdaptiveIconDrawable.getExtraInsetFraction() / sizeScaleFactor;
        final float previewShiftX = shiftFactor * previewWidth;
        final float previewShiftY = shiftFactor * previewHeight;

        Bitmap previewBitmap = UiFactory.createFromRenderer(previewWidth, previewHeight, false,
                (canvas) -> {
                    int count = canvas.save();
                    canvas.translate(previewShiftX, previewShiftY);
                    icon.getPreviewItemManager().draw(canvas);
                    canvas.restoreToCount(count);
                });

        // Initialize mask
        Path mask = new Path();
+23 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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.launcher3.graphics;

import android.graphics.Canvas;

public interface BitmapRenderer {

     void render(Canvas out);
}
+11 −13
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import com.android.launcher3.LauncherAppWidgetHostView;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
import com.android.launcher3.uioverrides.UiFactory;
import com.android.launcher3.util.UiThreadHelper;

import java.nio.ByteBuffer;
@@ -77,8 +78,10 @@ public class DragPreviewProvider {
    /**
     * Draws the {@link #mView} into the given {@param destCanvas}.
     */
    private void drawDragView(Canvas destCanvas) {
    private void drawDragView(Canvas destCanvas, float scale) {
        destCanvas.save();
        destCanvas.scale(scale, scale);

        if (mView instanceof BubbleTextView) {
            Drawable d = ((BubbleTextView) mView).getIcon();
            Rect bounds = getDrawableBounds(d);
@@ -120,6 +123,7 @@ public class DragPreviewProvider {
        int width = mView.getWidth();
        int height = mView.getHeight();

        boolean forceSoftwareRenderer = false;
        if (mView instanceof BubbleTextView) {
            Drawable d = ((BubbleTextView) mView).getIcon();
            Rect bounds = getDrawableBounds(d);
@@ -129,20 +133,14 @@ public class DragPreviewProvider {
            scale = ((LauncherAppWidgetHostView) mView).getScaleToFit();
            width = (int) (mView.getWidth() * scale);
            height = (int) (mView.getHeight() * scale);
        }

        Bitmap b = Bitmap.createBitmap(width + blurSizeOutline, height + blurSizeOutline,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(b);

        canvas.save();
        canvas.scale(scale, scale);
        drawDragView(canvas);
        canvas.restore();

        canvas.setBitmap(null);
            // Use software renderer for widgets as we know that they already work
            forceSoftwareRenderer = true;
        }

        return b;
        final float scaleFinal = scale;
        return UiFactory.createFromRenderer(width + blurSizeOutline, height + blurSizeOutline,
                forceSoftwareRenderer, (c) -> drawDragView(c, scaleFinal));
    }

    public final void generateDragOutline(Bitmap preview) {
Loading