diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index d5bcb0cbcb..a8546e8448 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -43,6 +43,8 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; +import android.util.Size; +import android.util.SparseArray; import android.util.SparseIntArray; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -53,6 +55,8 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.widget.TextClock; +import androidx.annotation.Nullable; + import com.android.launcher3.BubbleTextView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; @@ -177,10 +181,12 @@ public class LauncherPreviewRenderer extends ContextWrapper private final Map mWorkspaceScreens = new HashMap<>(); private final AppWidgetHost mAppWidgetHost; private final SparseIntArray mWallpaperColorResources; + private final SparseArray mLauncherWidgetSpanInfo; public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp, - WallpaperColors wallpaperColorsOverride) { + WallpaperColors wallpaperColorsOverride, + @Nullable final SparseArray launcherWidgetSpanInfo) { super(context); mUiHandler = new Handler(Looper.getMainLooper()); @@ -224,6 +230,9 @@ public class LauncherPreviewRenderer extends ContextWrapper mHotseat = mRootView.findViewById(R.id.hotseat); mHotseat.resetLayout(false); + mLauncherWidgetSpanInfo = launcherWidgetSpanInfo == null ? new SparseArray<>() : + launcherWidgetSpanInfo; + CellLayout firstScreen = mRootView.findViewById(R.id.workspace); firstScreen.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingPx.left, mDp.workspacePadding.top + mDp.cellLayoutPaddingPx.top, diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java index fd11b37795..287b9760fe 100644 --- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java +++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java @@ -22,10 +22,13 @@ import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import android.app.WallpaperColors; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; +import android.database.Cursor; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; +import android.util.Size; +import android.util.SparseArray; import android.view.ContextThemeWrapper; import android.view.Display; import android.view.SurfaceControlViewHost; @@ -34,6 +37,8 @@ import android.view.View; import android.view.WindowManager.LayoutParams; import android.view.animation.AccelerateDecelerateInterpolator; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.annotation.WorkerThread; @@ -123,6 +128,45 @@ public class PreviewSurfaceRenderer { mOnDestroyCallbacks.executeAllAndDestroy(); } + /** + * A function that queries for the launcher app widget span info + * + * @param context The context to get the content resolver from, should be related to launcher + * @return A SparseArray with the app widget id being the key and the span info being the values + */ + @WorkerThread + @Nullable + public SparseArray getLoadedLauncherWidgetInfo( + @NonNull final Context context) { + final SparseArray widgetInfo = new SparseArray<>(); + final String query = LauncherSettings.Favorites.ITEM_TYPE + " = " + + LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET; + + try (Cursor c = context.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI, + new String[] { + LauncherSettings.Favorites.APPWIDGET_ID, + LauncherSettings.Favorites.SPANX, + LauncherSettings.Favorites.SPANY + }, query, null, null)) { + final int appWidgetIdIndex = c.getColumnIndexOrThrow( + LauncherSettings.Favorites.APPWIDGET_ID); + final int spanXIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANX); + final int spanYIndex = c.getColumnIndexOrThrow(LauncherSettings.Favorites.SPANY); + while (c.moveToNext()) { + final int appWidgetId = c.getInt(appWidgetIdIndex); + final int spanX = c.getInt(spanXIndex); + final int spanY = c.getInt(spanYIndex); + + widgetInfo.append(appWidgetId, new Size(spanX, spanY)); + } + } catch (Exception e) { + Log.e(TAG, "Error querying for launcher widget info", e); + return null; + } + + return widgetInfo; + } + /** * Generates the preview in background */ @@ -174,8 +218,11 @@ public class PreviewSurfaceRenderer { loadWorkspace(new ArrayList<>(), LauncherSettings.Favorites.PREVIEW_CONTENT_URI, query); + final SparseArray spanInfo = + getLoadedLauncherWidgetInfo(previewContext.getBaseContext()); + MAIN_EXECUTOR.execute(() -> { - renderView(previewContext, mBgDataModel, mWidgetProvidersMap); + renderView(previewContext, mBgDataModel, mWidgetProvidersMap, spanInfo); mOnDestroyCallbacks.add(previewContext::onDestroy); }); } @@ -183,7 +230,8 @@ public class PreviewSurfaceRenderer { } else { LauncherAppState.getInstance(inflationContext).getModel().loadAsync(dataModel -> { if (dataModel != null) { - MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null)); + MAIN_EXECUTOR.execute(() -> renderView(inflationContext, dataModel, null, + null)); } else { Log.e(TAG, "Model loading failed"); } @@ -201,12 +249,13 @@ public class PreviewSurfaceRenderer { @UiThread private void renderView(Context inflationContext, BgDataModel dataModel, - Map widgetProviderInfoMap) { + Map widgetProviderInfoMap, + @Nullable final SparseArray launcherWidgetSpanInfo) { if (mDestroyed) { return; } - View view = new LauncherPreviewRenderer(inflationContext, mIdp, mWallpaperColors) - .getRenderedView(dataModel, widgetProviderInfoMap); + View view = new LauncherPreviewRenderer(inflationContext, mIdp, mWallpaperColors, + launcherWidgetSpanInfo).getRenderedView(dataModel, widgetProviderInfoMap); // This aspect scales the view to fit in the surface and centers it final float scale = Math.min(mWidth / (float) view.getMeasuredWidth(), mHeight / (float) view.getMeasuredHeight());