Loading quickstep/src/com/android/launcher3/uioverrides/UiFactory.java +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()) { Loading Loading @@ -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; } } } src/com/android/launcher3/IconCache.java +13 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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) { Loading src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java +21 −25 Original line number Diff line number Diff line Loading @@ -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} */ Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading @@ -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(); Loading src/com/android/launcher3/graphics/BitmapRenderer.java 0 → 100644 +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); } src/com/android/launcher3/graphics/DragPreviewProvider.java +11 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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 Loading
quickstep/src/com/android/launcher3/uioverrides/UiFactory.java +18 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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()) { Loading Loading @@ -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; } } }
src/com/android/launcher3/IconCache.java +13 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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() { Loading Loading @@ -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); Loading Loading @@ -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) { Loading
src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java +21 −25 Original line number Diff line number Diff line Loading @@ -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} */ Loading @@ -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); Loading @@ -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); Loading @@ -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; Loading @@ -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(); Loading
src/com/android/launcher3/graphics/BitmapRenderer.java 0 → 100644 +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); }
src/com/android/launcher3/graphics/DragPreviewProvider.java +11 −13 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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