Search in sources :

Example 16 with Widget

use of com.android.launcher3.tapl.Widget in project android_packages_apps_Launcher3 by crdroidandroid.

the class WidgetsDiffReporter method process.

/**
 * Notifies the difference between {@code currentEntries} & {@code newEntries} by calling the
 * relevant {@link androidx.recyclerview.widget.RecyclerView.RecyclerViewDataObserver} methods.
 */
public void process(ArrayList<WidgetsListBaseEntry> currentEntries, List<WidgetsListBaseEntry> newEntries, WidgetListBaseRowEntryComparator comparator) {
    if (DEBUG) {
        Log.d(TAG, "process oldEntries#=" + currentEntries.size() + " newEntries#=" + newEntries.size());
    }
    // Early exit if either of the list is empty
    if (currentEntries.isEmpty() || newEntries.isEmpty()) {
        // when the bind actually completes.
        if (currentEntries.size() != newEntries.size()) {
            currentEntries.clear();
            currentEntries.addAll(newEntries);
            mListener.notifyDataSetChanged();
        }
        return;
    }
    ArrayList<WidgetsListBaseEntry> orgEntries = (ArrayList<WidgetsListBaseEntry>) currentEntries.clone();
    Iterator<WidgetsListBaseEntry> orgIter = orgEntries.iterator();
    Iterator<WidgetsListBaseEntry> newIter = newEntries.iterator();
    WidgetsListBaseEntry orgRowEntry = orgIter.next();
    WidgetsListBaseEntry newRowEntry = newIter.next();
    do {
        int diff = compareAppNameAndType(orgRowEntry, newRowEntry, comparator);
        if (DEBUG) {
            Log.d(TAG, String.format("diff=%d orgRowEntry (%s) newRowEntry (%s)", diff, orgRowEntry != null ? orgRowEntry.toString() : null, newRowEntry != null ? newRowEntry.toString() : null));
        }
        int index = -1;
        if (diff < 0) {
            index = currentEntries.indexOf(orgRowEntry);
            mListener.notifyItemRemoved(index);
            if (DEBUG) {
                Log.d(TAG, String.format("notifyItemRemoved called (%d)%s", index, orgRowEntry.mTitleSectionName));
            }
            currentEntries.remove(index);
            orgRowEntry = orgIter.hasNext() ? orgIter.next() : null;
        } else if (diff > 0) {
            index = orgRowEntry != null ? currentEntries.indexOf(orgRowEntry) : currentEntries.size();
            currentEntries.add(index, newRowEntry);
            if (DEBUG) {
                Log.d(TAG, String.format("notifyItemInserted called (%d)%s", index, newRowEntry.mTitleSectionName));
            }
            newRowEntry = newIter.hasNext() ? newIter.next() : null;
            mListener.notifyItemInserted(index);
        } else {
            // or did the widget size and desc, span, etc change?
            if (!isSamePackageItemInfo(orgRowEntry.mPkgItem, newRowEntry.mPkgItem) || hasHeaderUpdated(orgRowEntry, newRowEntry) || hasWidgetsListContentChanged(orgRowEntry, newRowEntry)) {
                index = currentEntries.indexOf(orgRowEntry);
                currentEntries.set(index, newRowEntry);
                mListener.notifyItemChanged(index);
                if (DEBUG) {
                    Log.d(TAG, String.format("notifyItemChanged called (%d)%s", index, newRowEntry.mTitleSectionName));
                }
            }
            orgRowEntry = orgIter.hasNext() ? orgIter.next() : null;
            newRowEntry = newIter.hasNext() ? newIter.next() : null;
        }
    } while (orgRowEntry != null || newRowEntry != null);
}
Also used : WidgetsListBaseEntry(com.android.launcher3.widget.model.WidgetsListBaseEntry) ArrayList(java.util.ArrayList)

Example 17 with Widget

use of com.android.launcher3.tapl.Widget in project android_packages_apps_Launcher3 by crdroidandroid.

the class WidgetsListAdapter method ensureAllPreviewsReady.

/**
 * Checks that all preview images are loaded and starts loading for those that aren't ready.
 *
 * @return true if all previews are ready and the data can be updated, false otherwise.
 */
private boolean ensureAllPreviewsReady() {
    boolean allReady = true;
    BaseActivity activity = BaseActivity.fromContext(mContext);
    for (WidgetsListBaseEntry entry : mAllEntries) {
        if (!(entry instanceof WidgetsListContentEntry))
            continue;
        WidgetsListContentEntry contentEntry = (WidgetsListContentEntry) entry;
        if (!matchesKey(entry, mWidgetsContentVisiblePackageUserKey)) {
            // If the entry isn't visible, clear any loaded previews.
            mCachingPreviewLoader.clearPreviews(contentEntry.mWidgets);
            continue;
        }
        for (int i = 0; i < entry.mWidgets.size(); i++) {
            WidgetItem widgetItem = entry.mWidgets.get(i);
            DeviceProfile deviceProfile = activity.getDeviceProfile();
            Size widgetSize = WidgetSizes.getWidgetItemSizePx(mContext, deviceProfile, widgetItem);
            if (widgetItem.isShortcut()) {
                widgetSize = new Size(widgetSize.getWidth() + mShortcutPreviewPadding, widgetSize.getHeight() + mShortcutPreviewPadding);
            }
            if (widgetItem.hasPreviewLayout() || mCachingPreviewLoader.isPreviewLoaded(widgetItem, widgetSize)) {
                // preview bitmap is in the cache.
                continue;
            }
            // If we've reached this point, we should load the preview for the widget.
            allReady = false;
            mCachingPreviewLoader.loadPreview(activity, widgetItem, widgetSize, mPreviewLoadedCallback);
        }
    }
    return allReady;
}
Also used : DeviceProfile(com.android.launcher3.DeviceProfile) Size(android.util.Size) WidgetsListBaseEntry(com.android.launcher3.widget.model.WidgetsListBaseEntry) BaseActivity(com.android.launcher3.BaseActivity) WidgetsListContentEntry(com.android.launcher3.widget.model.WidgetsListContentEntry) WidgetItem(com.android.launcher3.model.WidgetItem)

Example 18 with Widget

use of com.android.launcher3.tapl.Widget in project android_packages_apps_Launcher3 by crdroidandroid.

the class DatabaseWidgetPreviewLoader method removeObsoletePreviews.

/**
 * Updates the persistent DB:
 *   1. Any preview generated for an old package version is removed
 *   2. Any preview for an absent package is removed
 * This ensures that we remove entries for packages which changed while the launcher was dead.
 *
 * @param packageUser if provided, specifies that list only contains previews for the
 *                    given package/user, otherwise the list contains all previews
 */
public void removeObsoletePreviews(ArrayList<? extends ComponentKey> list, @Nullable PackageUserKey packageUser) {
    Preconditions.assertWorkerThread();
    LongSparseArray<HashSet<String>> validPackages = new LongSparseArray<>();
    for (ComponentKey key : list) {
        final long userId = mUserCache.getSerialNumberForUser(key.user);
        HashSet<String> packages = validPackages.get(userId);
        if (packages == null) {
            packages = new HashSet<>();
            validPackages.put(userId, packages);
        }
        packages.add(key.componentName.getPackageName());
    }
    LongSparseArray<HashSet<String>> packagesToDelete = new LongSparseArray<>();
    long passedUserId = packageUser == null ? 0 : mUserCache.getSerialNumberForUser(packageUser.mUser);
    Cursor c = null;
    try {
        c = mDb.query(new String[] { CacheDb.COLUMN_USER, CacheDb.COLUMN_PACKAGE, CacheDb.COLUMN_LAST_UPDATED, CacheDb.COLUMN_VERSION }, null, null);
        while (c.moveToNext()) {
            long userId = c.getLong(0);
            String pkg = c.getString(1);
            long lastUpdated = c.getLong(2);
            long version = c.getLong(3);
            if (packageUser != null && (!pkg.equals(packageUser.mPackageName) || userId != passedUserId)) {
                // This preview is associated with a different package/user, no need to remove.
                continue;
            }
            HashSet<String> packages = validPackages.get(userId);
            if (packages != null && packages.contains(pkg)) {
                long[] versions = getPackageVersion(pkg);
                if (versions[0] == version && versions[1] == lastUpdated) {
                    // Every thing checks out
                    continue;
                }
            }
            // We need to delete this package.
            packages = packagesToDelete.get(userId);
            if (packages == null) {
                packages = new HashSet<>();
                packagesToDelete.put(userId, packages);
            }
            packages.add(pkg);
        }
        for (int i = 0; i < packagesToDelete.size(); i++) {
            long userId = packagesToDelete.keyAt(i);
            UserHandle user = mUserCache.getUserForSerialNumber(userId);
            for (String pkg : packagesToDelete.valueAt(i)) {
                removePackage(pkg, user, userId);
            }
        }
    } catch (SQLException e) {
        Log.e(TAG, "Error updating widget previews", e);
    } finally {
        if (c != null) {
            c.close();
        }
    }
}
Also used : LongSparseArray(android.util.LongSparseArray) SQLException(android.database.SQLException) ComponentKey(com.android.launcher3.util.ComponentKey) Cursor(android.database.Cursor) Paint(android.graphics.Paint) UserHandle(android.os.UserHandle) HashSet(java.util.HashSet)

Example 19 with Widget

use of com.android.launcher3.tapl.Widget in project android_packages_apps_Launcher3 by crdroidandroid.

the class LauncherAppWidgetProviderInfo method initSpans.

public void initSpans(Context context, InvariantDeviceProfile idp) {
    int minSpanX = 0;
    int minSpanY = 0;
    int maxSpanX = idp.numColumns;
    int maxSpanY = idp.numRows;
    int spanX = 0;
    int spanY = 0;
    Rect widgetPadding = new Rect();
    Rect localPadding = new Rect();
    AppWidgetHostView.getDefaultPaddingForWidget(context, provider, widgetPadding);
    Point cellSize = new Point();
    for (DeviceProfile dp : idp.supportedProfiles) {
        dp.getCellSize(cellSize);
        // If grids supports insetting widgets, we do not account for widget padding.
        if (dp.shouldInsetWidgets()) {
            localPadding.setEmpty();
        } else {
            localPadding.set(widgetPadding);
        }
        minSpanX = Math.max(minSpanX, getSpanX(localPadding, minResizeWidth, dp.cellLayoutBorderSpacingPx, cellSize.x));
        minSpanY = Math.max(minSpanY, getSpanY(localPadding, minResizeHeight, dp.cellLayoutBorderSpacingPx, cellSize.y));
        if (ATLEAST_S) {
            if (maxResizeWidth > 0) {
                maxSpanX = Math.min(maxSpanX, getSpanX(localPadding, maxResizeWidth, dp.cellLayoutBorderSpacingPx, cellSize.x));
            }
            if (maxResizeHeight > 0) {
                maxSpanY = Math.min(maxSpanY, getSpanY(localPadding, maxResizeHeight, dp.cellLayoutBorderSpacingPx, cellSize.y));
            }
        }
        spanX = Math.max(spanX, getSpanX(localPadding, minWidth, dp.cellLayoutBorderSpacingPx, cellSize.x));
        spanY = Math.max(spanY, getSpanY(localPadding, minHeight, dp.cellLayoutBorderSpacingPx, cellSize.y));
    }
    if (ATLEAST_S) {
        // Ensures maxSpan >= minSpan
        maxSpanX = Math.max(maxSpanX, minSpanX);
        maxSpanY = Math.max(maxSpanY, minSpanY);
        // Otherwise, use the span of minWidth/Height.
        if (targetCellWidth >= minSpanX && targetCellWidth <= maxSpanX && targetCellHeight >= minSpanY && targetCellHeight <= maxSpanY) {
            spanX = targetCellWidth;
            spanY = targetCellHeight;
        }
    }
    // If minSpanX/Y > spanX/Y, ignore the minSpanX/Y to match the behavior described in
    // minResizeWidth & minResizeHeight Android documentation. See
    // https://developer.android.com/reference/android/appwidget/AppWidgetProviderInfo
    this.minSpanX = Math.min(spanX, minSpanX);
    this.minSpanY = Math.min(spanY, minSpanY);
    this.maxSpanX = maxSpanX;
    this.maxSpanY = maxSpanY;
    this.mIsMinSizeFulfilled = Math.min(spanX, minSpanX) <= idp.numColumns && Math.min(spanY, minSpanY) <= idp.numRows;
    // Ensures the default span X and span Y will not exceed the current grid size.
    this.spanX = Math.min(spanX, idp.numColumns);
    this.spanY = Math.min(spanY, idp.numRows);
}
Also used : DeviceProfile(com.android.launcher3.DeviceProfile) InvariantDeviceProfile(com.android.launcher3.InvariantDeviceProfile) Rect(android.graphics.Rect) Point(android.graphics.Point) Point(android.graphics.Point)

Example 20 with Widget

use of com.android.launcher3.tapl.Widget in project android_packages_apps_Launcher3 by crdroidandroid.

the class WidgetHostViewLoader method preloadWidget.

/**
 * Start preloading the widget.
 */
private boolean preloadWidget() {
    final LauncherAppWidgetProviderInfo pInfo = mInfo.info;
    if (pInfo.isCustomWidget()) {
        return false;
    }
    final Bundle options = mInfo.getDefaultSizeOptions(mLauncher);
    // If there is a configuration activity, do not follow thru bound and inflate.
    if (mInfo.getHandler().needsConfigure()) {
        mInfo.bindOptions = options;
        return false;
    }
    mBindWidgetRunnable = new Runnable() {

        @Override
        public void run() {
            mWidgetLoadingId = mLauncher.getAppWidgetHost().allocateAppWidgetId();
            if (LOGD) {
                Log.d(TAG, "Binding widget, id: " + mWidgetLoadingId);
            }
            if (new WidgetManagerHelper(mLauncher).bindAppWidgetIdIfAllowed(mWidgetLoadingId, pInfo, options)) {
                // Widget id bound. Inflate the widget.
                mHandler.post(mInflateWidgetRunnable);
            }
        }
    };
    mInflateWidgetRunnable = new Runnable() {

        @Override
        public void run() {
            if (LOGD) {
                Log.d(TAG, "Inflating widget, id: " + mWidgetLoadingId);
            }
            if (mWidgetLoadingId == -1) {
                return;
            }
            AppWidgetHostView hostView = mLauncher.getAppWidgetHost().createView((Context) mLauncher, mWidgetLoadingId, pInfo);
            mInfo.boundWidget = hostView;
            // We used up the widget Id in binding the above view.
            mWidgetLoadingId = -1;
            hostView.setVisibility(View.INVISIBLE);
            int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(mInfo);
            // We want the first widget layout to be the correct size. This will be important
            // for width size reporting to the AppWidgetManager.
            DragLayer.LayoutParams lp = new DragLayer.LayoutParams(unScaledSize[0], unScaledSize[1]);
            lp.x = lp.y = 0;
            lp.customPosition = true;
            hostView.setLayoutParams(lp);
            if (LOGD) {
                Log.d(TAG, "Adding host view to drag layer");
            }
            mLauncher.getDragLayer().addView(hostView);
            mView.setTag(mInfo);
        }
    };
    if (LOGD) {
        Log.d(TAG, "About to bind/inflate widget");
    }
    mHandler.post(mBindWidgetRunnable);
    return true;
}
Also used : Context(android.content.Context) AppWidgetHostView(android.appwidget.AppWidgetHostView) DragLayer(com.android.launcher3.dragndrop.DragLayer) Bundle(android.os.Bundle)

Aggregations

LauncherAppWidgetInfo (com.android.launcher3.model.data.LauncherAppWidgetInfo)105 Test (org.junit.Test)87 LauncherAppWidgetProviderInfo (com.android.launcher3.widget.LauncherAppWidgetProviderInfo)71 LauncherAppWidgetHostView (com.android.launcher3.widget.LauncherAppWidgetHostView)66 Point (android.graphics.Point)62 ArrayList (java.util.ArrayList)60 AppWidgetProviderInfo (android.appwidget.AppWidgetProviderInfo)56 View (android.view.View)55 LargeTest (androidx.test.filters.LargeTest)55 ComponentName (android.content.ComponentName)53 AppWidgetHostView (android.appwidget.AppWidgetHostView)52 Bundle (android.os.Bundle)50 WidgetItem (com.android.launcher3.model.WidgetItem)49 AbstractLauncherUiTest (com.android.launcher3.ui.AbstractLauncherUiTest)49 PendingAppWidgetHostView (com.android.launcher3.widget.PendingAppWidgetHostView)47 ItemInfo (com.android.launcher3.model.data.ItemInfo)44 PackageUserKey (com.android.launcher3.util.PackageUserKey)41 PendingAddWidgetInfo (com.android.launcher3.widget.PendingAddWidgetInfo)41 Context (android.content.Context)31 WidgetManagerHelper (com.android.launcher3.widget.WidgetManagerHelper)31