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);
}
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;
}
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();
}
}
}
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);
}
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;
}
Aggregations