update:2021.03.15
fix:修改首页图标位置 add:在桌面隐藏自己的图标和搜索
@@ -181,26 +181,26 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<!-- <activity android:name=".Launcher"-->
|
<activity android:name=".Launcher"
|
||||||
<!-- android:launchMode="singleTask"-->
|
android:launchMode="singleTask"
|
||||||
<!-- android:clearTaskOnLaunch="true"-->
|
android:clearTaskOnLaunch="true"
|
||||||
<!-- android:stateNotNeeded="true"-->
|
android:stateNotNeeded="true"
|
||||||
<!-- android:windowSoftInputMode="adjustPan"-->
|
android:windowSoftInputMode="adjustPan"
|
||||||
<!-- android:screenOrientation="unspecified"-->
|
android:screenOrientation="unspecified"
|
||||||
<!-- android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"-->
|
android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
|
||||||
<!-- android:resizeableActivity="true"-->
|
android:resizeableActivity="true"
|
||||||
<!-- android:resumeWhilePausing="true"-->
|
android:resumeWhilePausing="true"
|
||||||
<!-- android:taskAffinity=""-->
|
android:taskAffinity=""
|
||||||
<!-- android:enabled="true">-->
|
android:enabled="true">
|
||||||
<!-- <intent-filter>-->
|
<intent-filter>
|
||||||
<!-- <action android:name="android.intent.action.MAIN" />-->
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<!-- <category android:name="android.intent.category.HOME" />-->
|
<category android:name="android.intent.category.HOME" />
|
||||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<!-- <category android:name="android.intent.category.MONKEY"/>-->
|
<category android:name="android.intent.category.MONKEY"/>
|
||||||
<!-- <category android:name="android.intent.category.LAUNCHER_APP" />-->
|
<category android:name="android.intent.category.LAUNCHER_APP" />
|
||||||
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
<!-- </intent-filter>-->
|
</intent-filter>
|
||||||
<!-- </activity>-->
|
</activity>
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="com.android.uiuios.testing.TestInformationProvider"
|
android:name="com.android.uiuios.testing.TestInformationProvider"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.5 MiB After Width: | Height: | Size: 311 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -102,4 +102,16 @@
|
|||||||
<!-- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />-->
|
<!-- <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />-->
|
||||||
<!-- <favorite launcher:uri="market://details?id=com.android.launcher" />-->
|
<!-- <favorite launcher:uri="market://details?id=com.android.launcher" />-->
|
||||||
<!-- </resolve>-->
|
<!-- </resolve>-->
|
||||||
|
<favorite
|
||||||
|
launcher:className="com.info.sn.activity.MainActivity"
|
||||||
|
launcher:packageName="com.info.sn"
|
||||||
|
launcher:screen="0"
|
||||||
|
launcher:x="0"
|
||||||
|
launcher:y="0" />
|
||||||
|
<favorite
|
||||||
|
launcher:className="com.jiaoguanyi.sysc.activity.MainActivity"
|
||||||
|
launcher:packageName="com.jiaoguanyi.sysc"
|
||||||
|
launcher:screen="0"
|
||||||
|
launcher:x="1"
|
||||||
|
launcher:y="0" />
|
||||||
</favorites>
|
</favorites>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import android.util.Pair;
|
|||||||
|
|
||||||
import com.android.uiuios.AllAppsList;
|
import com.android.uiuios.AllAppsList;
|
||||||
import com.android.uiuios.AppInfo;
|
import com.android.uiuios.AppInfo;
|
||||||
|
import com.android.uiuios.BuildConfig;
|
||||||
import com.android.uiuios.FolderInfo;
|
import com.android.uiuios.FolderInfo;
|
||||||
import com.android.uiuios.InstallShortcutReceiver;
|
import com.android.uiuios.InstallShortcutReceiver;
|
||||||
import com.android.uiuios.ItemInfo;
|
import com.android.uiuios.ItemInfo;
|
||||||
@@ -86,10 +87,10 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Runnable for the thread that loads the contents of the launcher:
|
* Runnable for the thread that loads the contents of the launcher:
|
||||||
* - workspace icons
|
* - workspace icons
|
||||||
* - widgets
|
* - widgets
|
||||||
* - all apps icons
|
* - all apps icons
|
||||||
* - deep shortcuts within apps
|
* - deep shortcuts within apps
|
||||||
*/
|
*/
|
||||||
public class LoaderTask implements Runnable {
|
public class LoaderTask implements Runnable {
|
||||||
private static final String TAG = "LoaderTask";
|
private static final String TAG = "LoaderTask";
|
||||||
@@ -112,7 +113,7 @@ public class LoaderTask implements Runnable {
|
|||||||
private boolean mStopped;
|
private boolean mStopped;
|
||||||
|
|
||||||
public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
|
public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
|
||||||
LoaderResults results) {
|
LoaderResults results) {
|
||||||
mApp = app;
|
mApp = app;
|
||||||
mBgAllAppsList = bgAllAppsList;
|
mBgAllAppsList = bgAllAppsList;
|
||||||
mBgDataModel = dataModel;
|
mBgDataModel = dataModel;
|
||||||
@@ -133,7 +134,7 @@ public class LoaderTask implements Runnable {
|
|||||||
LooperIdleLock idleLock = mResults.newIdleLock(this);
|
LooperIdleLock idleLock = mResults.newIdleLock(this);
|
||||||
// Just in case mFlushingWorkerThread changes but we aren't woken up,
|
// Just in case mFlushingWorkerThread changes but we aren't woken up,
|
||||||
// wait no longer than 1sec at a time
|
// wait no longer than 1sec at a time
|
||||||
while (!mStopped && idleLock.awaitLocked(1000));
|
while (!mStopped && idleLock.awaitLocked(1000)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void verifyNotStopped() throws CancellationException {
|
private synchronized void verifyNotStopped() throws CancellationException {
|
||||||
@@ -245,6 +246,11 @@ public class LoaderTask implements Runnable {
|
|||||||
TraceHelper.endSection(TAG);
|
TraceHelper.endSection(TAG);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<String> hideApp = new ArrayList<String>() {{
|
||||||
|
this.add(BuildConfig.APPLICATION_ID);
|
||||||
|
this.add("com.android.quicksearchbox");
|
||||||
|
}};
|
||||||
|
|
||||||
//add for load all app on workspace
|
//add for load all app on workspace
|
||||||
private void verifyApplications() {
|
private void verifyApplications() {
|
||||||
final Context context = mApp.getContext();
|
final Context context = mApp.getContext();
|
||||||
@@ -255,6 +261,9 @@ public class LoaderTask implements Runnable {
|
|||||||
ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> added = new ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo>();
|
ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo> added = new ArrayList<InstallShortcutReceiver.PendingInstallShortcutInfo>();
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
for (LauncherActivityInfo app : apps) {
|
for (LauncherActivityInfo app : apps) {
|
||||||
|
if (hideApp.contains(app.getApplicationInfo().packageName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
InstallShortcutReceiver.PendingInstallShortcutInfo pendingInstallShortcutInfo = new InstallShortcutReceiver.PendingInstallShortcutInfo(app, context);
|
InstallShortcutReceiver.PendingInstallShortcutInfo pendingInstallShortcutInfo = new InstallShortcutReceiver.PendingInstallShortcutInfo(app, context);
|
||||||
added.add(pendingInstallShortcutInfo);
|
added.add(pendingInstallShortcutInfo);
|
||||||
installQueue.add(pendingInstallShortcutInfo.getItemInfo());
|
installQueue.add(pendingInstallShortcutInfo.getItemInfo());
|
||||||
@@ -373,354 +382,354 @@ public class LoaderTask implements Runnable {
|
|||||||
|
|
||||||
boolean allowMissingTarget = false;
|
boolean allowMissingTarget = false;
|
||||||
switch (c.itemType) {
|
switch (c.itemType) {
|
||||||
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
|
||||||
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
|
||||||
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
|
case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
|
||||||
intent = c.parseIntent();
|
intent = c.parseIntent();
|
||||||
if (intent == null) {
|
if (intent == null) {
|
||||||
c.markDeleted("Invalid or null intent");
|
c.markDeleted("Invalid or null intent");
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int disabledState = quietMode.get(c.serialNumber) ?
|
|
||||||
WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
|
|
||||||
ComponentName cn = intent.getComponent();
|
|
||||||
targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
|
|
||||||
|
|
||||||
if (allUsers.indexOfValue(c.user) < 0) {
|
|
||||||
if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
|
||||||
c.markDeleted("Legacy shortcuts are only allowed for current users");
|
|
||||||
continue;
|
|
||||||
} else if (c.restoreFlag != 0) {
|
|
||||||
// Don't restore items for other profiles.
|
|
||||||
c.markDeleted("Restore from other profiles not supported");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (TextUtils.isEmpty(targetPkg) &&
|
|
||||||
c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
|
||||||
c.markDeleted("Only legacy shortcuts can have null package");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there is no target package, its an implicit intent
|
int disabledState = quietMode.get(c.serialNumber) ?
|
||||||
// (legacy shortcut) which is always valid
|
WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
|
||||||
boolean validTarget = TextUtils.isEmpty(targetPkg) ||
|
ComponentName cn = intent.getComponent();
|
||||||
mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user);
|
targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
|
||||||
|
|
||||||
if (cn != null && validTarget) {
|
if (allUsers.indexOfValue(c.user) < 0) {
|
||||||
// If the apk is present and the shortcut points to a specific
|
if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||||
// component.
|
c.markDeleted("Legacy shortcuts are only allowed for current users");
|
||||||
|
continue;
|
||||||
// If the component is already present
|
} else if (c.restoreFlag != 0) {
|
||||||
if (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) {
|
// Don't restore items for other profiles.
|
||||||
// no special handling necessary for this item
|
c.markDeleted("Restore from other profiles not supported");
|
||||||
c.markRestored();
|
|
||||||
} else {
|
|
||||||
// Gracefully try to find a fallback activity.
|
|
||||||
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
|
|
||||||
if (intent != null) {
|
|
||||||
c.restoreFlag = 0;
|
|
||||||
c.updater().put(
|
|
||||||
LauncherSettings.Favorites.INTENT,
|
|
||||||
intent.toUri(0)).commit();
|
|
||||||
cn = intent.getComponent();
|
|
||||||
} else {
|
|
||||||
c.markDeleted("Unable to find a launch target");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (TextUtils.isEmpty(targetPkg) &&
|
||||||
// else if cn == null => can't infer much, leave it
|
c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
|
||||||
// else if !validPkg => could be restored icon or missing sd-card
|
c.markDeleted("Only legacy shortcuts can have null package");
|
||||||
|
|
||||||
if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
|
|
||||||
// Points to a valid app (superset of cn != null) but the apk
|
|
||||||
// is not available.
|
|
||||||
|
|
||||||
if (c.restoreFlag != 0) {
|
|
||||||
// Package is not yet available but might be
|
|
||||||
// installed later.
|
|
||||||
FileLog.d(TAG, "package not yet restored: " + targetPkg);
|
|
||||||
|
|
||||||
if (c.hasRestoreFlag(WorkspaceItemInfo.FLAG_RESTORE_STARTED)) {
|
|
||||||
// Restore has started once.
|
|
||||||
} else if (installingPkgs.containsKey(targetPkg)) {
|
|
||||||
// App restore has started. Update the flag
|
|
||||||
c.restoreFlag |= WorkspaceItemInfo.FLAG_RESTORE_STARTED;
|
|
||||||
c.updater().put(LauncherSettings.Favorites.RESTORED,
|
|
||||||
c.restoreFlag).commit();
|
|
||||||
} else {
|
|
||||||
c.markDeleted("Unrestored app removed: " + targetPkg);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
|
|
||||||
// Package is present but not available.
|
|
||||||
disabledState |= WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE;
|
|
||||||
// Add the icon on the workspace anyway.
|
|
||||||
allowMissingTarget = true;
|
|
||||||
} else if (!isSdCardReady) {
|
|
||||||
// SdCard is not ready yet. Package might get available,
|
|
||||||
// once it is ready.
|
|
||||||
Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
|
|
||||||
pendingPackages.addToList(c.user, targetPkg);
|
|
||||||
// Add the icon on the workspace anyway.
|
|
||||||
allowMissingTarget = true;
|
|
||||||
} else {
|
|
||||||
// Do not wait for external media load anymore.
|
|
||||||
c.markDeleted("Invalid package removed: " + targetPkg);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((c.restoreFlag & WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI) != 0) {
|
// If there is no target package, its an implicit intent
|
||||||
validTarget = false;
|
// (legacy shortcut) which is always valid
|
||||||
}
|
boolean validTarget = TextUtils.isEmpty(targetPkg) ||
|
||||||
|
mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user);
|
||||||
|
|
||||||
if (validTarget) {
|
if (cn != null && validTarget) {
|
||||||
// The shortcut points to a valid target (either no target
|
// If the apk is present and the shortcut points to a specific
|
||||||
// or something which is ready to be used)
|
// component.
|
||||||
c.markRestored();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean useLowResIcon = !c.isOnWorkspaceOrHotseat();
|
// If the component is already present
|
||||||
|
if (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) {
|
||||||
if (c.restoreFlag != 0) {
|
// no special handling necessary for this item
|
||||||
// Already verified above that user is same as default user
|
c.markRestored();
|
||||||
info = c.getRestoredItemInfo(intent);
|
|
||||||
} else if (c.itemType ==
|
|
||||||
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
|
||||||
info = c.getAppShortcutInfo(
|
|
||||||
intent, allowMissingTarget, useLowResIcon);
|
|
||||||
} else if (c.itemType ==
|
|
||||||
LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
|
||||||
|
|
||||||
ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
|
|
||||||
if (unlockedUsers.get(c.serialNumber)) {
|
|
||||||
ShortcutInfo pinnedShortcut =
|
|
||||||
shortcutKeyToPinnedShortcuts.get(key);
|
|
||||||
if (pinnedShortcut == null) {
|
|
||||||
// The shortcut is no longer valid.
|
|
||||||
c.markDeleted("Pinned shortcut not found");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
info = new WorkspaceItemInfo(pinnedShortcut, context);
|
|
||||||
final WorkspaceItemInfo finalInfo = info;
|
|
||||||
|
|
||||||
LauncherIcons li = LauncherIcons.obtain(context);
|
|
||||||
// If the pinned deep shortcut is no longer published,
|
|
||||||
// use the last saved icon instead of the default.
|
|
||||||
Supplier<ItemInfoWithIcon> fallbackIconProvider = () ->
|
|
||||||
c.loadIcon(finalInfo, li) ? finalInfo : null;
|
|
||||||
info.applyFrom(li.createShortcutIcon(pinnedShortcut,
|
|
||||||
true /* badged */, fallbackIconProvider));
|
|
||||||
li.recycle();
|
|
||||||
if (pmHelper.isAppSuspended(
|
|
||||||
pinnedShortcut.getPackage(), info.user)) {
|
|
||||||
info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
|
|
||||||
}
|
|
||||||
intent = info.intent;
|
|
||||||
} else {
|
|
||||||
// Create a shortcut info in disabled mode for now.
|
|
||||||
info = c.loadSimpleWorkspaceItem();
|
|
||||||
info.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
|
|
||||||
}
|
|
||||||
} else { // item type == ITEM_TYPE_SHORTCUT
|
|
||||||
info = c.loadSimpleWorkspaceItem();
|
|
||||||
|
|
||||||
// Shortcuts are only available on the primary profile
|
|
||||||
if (!TextUtils.isEmpty(targetPkg)
|
|
||||||
&& pmHelper.isAppSuspended(targetPkg, c.user)) {
|
|
||||||
disabledState |= FLAG_DISABLED_SUSPENDED;
|
|
||||||
}
|
|
||||||
|
|
||||||
// App shortcuts that used to be automatically added to Launcher
|
|
||||||
// didn't always have the correct intent flags set, so do that
|
|
||||||
// here
|
|
||||||
if (intent.getAction() != null &&
|
|
||||||
intent.getCategories() != null &&
|
|
||||||
intent.getAction().equals(Intent.ACTION_MAIN) &&
|
|
||||||
intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
|
|
||||||
intent.addFlags(
|
|
||||||
Intent.FLAG_ACTIVITY_NEW_TASK |
|
|
||||||
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (info != null) {
|
|
||||||
c.applyCommonProperties(info);
|
|
||||||
|
|
||||||
info.intent = intent;
|
|
||||||
info.rank = c.getInt(rankIndex);
|
|
||||||
info.spanX = 1;
|
|
||||||
info.spanY = 1;
|
|
||||||
info.runtimeStatusFlags |= disabledState;
|
|
||||||
if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
|
|
||||||
info.runtimeStatusFlags |= FLAG_DISABLED_SAFEMODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
|
|
||||||
SessionInfo si = installingPkgs.get(targetPkg);
|
|
||||||
if (si == null) {
|
|
||||||
info.status &= ~WorkspaceItemInfo.FLAG_INSTALL_SESSION_ACTIVE;
|
|
||||||
} else {
|
} else {
|
||||||
info.setInstallProgress((int) (si.getProgress() * 100));
|
// Gracefully try to find a fallback activity.
|
||||||
}
|
intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
|
||||||
}
|
if (intent != null) {
|
||||||
|
c.restoreFlag = 0;
|
||||||
c.checkAndAddItem(info, mBgDataModel);
|
c.updater().put(
|
||||||
} else {
|
LauncherSettings.Favorites.INTENT,
|
||||||
throw new RuntimeException("Unexpected null WorkspaceItemInfo");
|
intent.toUri(0)).commit();
|
||||||
}
|
cn = intent.getComponent();
|
||||||
break;
|
} else {
|
||||||
|
c.markDeleted("Unable to find a launch target");
|
||||||
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
continue;
|
||||||
FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id);
|
|
||||||
c.applyCommonProperties(folderInfo);
|
|
||||||
|
|
||||||
// Do not trim the folder label, as is was set by the user.
|
|
||||||
folderInfo.title = c.getString(c.titleIndex);
|
|
||||||
folderInfo.spanX = 1;
|
|
||||||
folderInfo.spanY = 1;
|
|
||||||
folderInfo.options = c.getInt(optionsIndex);
|
|
||||||
|
|
||||||
// no special handling required for restored folders
|
|
||||||
c.markRestored();
|
|
||||||
|
|
||||||
c.checkAndAddItem(folderInfo, mBgDataModel);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
|
|
||||||
if (FeatureFlags.GO_DISABLE_WIDGETS) {
|
|
||||||
c.markDeleted("Only legacy shortcuts can have null package");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Follow through
|
|
||||||
case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
|
|
||||||
// Read all Launcher-specific widget details
|
|
||||||
boolean customWidget = c.itemType ==
|
|
||||||
LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
|
|
||||||
|
|
||||||
int appWidgetId = c.getInt(appWidgetIdIndex);
|
|
||||||
String savedProvider = c.getString(appWidgetProviderIndex);
|
|
||||||
|
|
||||||
final ComponentName component =
|
|
||||||
ComponentName.unflattenFromString(savedProvider);
|
|
||||||
|
|
||||||
final boolean isIdValid = !c.hasRestoreFlag(
|
|
||||||
LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
|
|
||||||
final boolean wasProviderReady = !c.hasRestoreFlag(
|
|
||||||
LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
|
|
||||||
|
|
||||||
if (widgetProvidersMap == null) {
|
|
||||||
widgetProvidersMap = mAppWidgetManager.getAllProvidersMap();
|
|
||||||
}
|
|
||||||
final AppWidgetProviderInfo provider = widgetProvidersMap.get(
|
|
||||||
new ComponentKey(
|
|
||||||
ComponentName.unflattenFromString(savedProvider),
|
|
||||||
c.user));
|
|
||||||
|
|
||||||
final boolean isProviderReady = isValidProvider(provider);
|
|
||||||
if (!isSafeMode && !customWidget &&
|
|
||||||
wasProviderReady && !isProviderReady) {
|
|
||||||
c.markDeleted(
|
|
||||||
"Deleting widget that isn't installed anymore: "
|
|
||||||
+ provider);
|
|
||||||
} else {
|
|
||||||
if (isProviderReady) {
|
|
||||||
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
|
|
||||||
provider.provider);
|
|
||||||
|
|
||||||
// The provider is available. So the widget is either
|
|
||||||
// available or not available. We do not need to track
|
|
||||||
// any future restore updates.
|
|
||||||
int status = c.restoreFlag &
|
|
||||||
~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED &
|
|
||||||
~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
|
|
||||||
if (!wasProviderReady) {
|
|
||||||
// If provider was not previously ready, update the
|
|
||||||
// status and UI flag.
|
|
||||||
|
|
||||||
// Id would be valid only if the widget restore broadcast was received.
|
|
||||||
if (isIdValid) {
|
|
||||||
status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
appWidgetInfo.restoreStatus = status;
|
}
|
||||||
} else {
|
// else if cn == null => can't infer much, leave it
|
||||||
Log.v(TAG, "Widget restore pending id=" + c.id
|
// else if !validPkg => could be restored icon or missing sd-card
|
||||||
+ " appWidgetId=" + appWidgetId
|
|
||||||
+ " status =" + c.restoreFlag);
|
|
||||||
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
|
|
||||||
component);
|
|
||||||
appWidgetInfo.restoreStatus = c.restoreFlag;
|
|
||||||
SessionInfo si =
|
|
||||||
installingPkgs.get(component.getPackageName());
|
|
||||||
Integer installProgress = si == null
|
|
||||||
? null
|
|
||||||
: (int) (si.getProgress() * 100);
|
|
||||||
|
|
||||||
if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
|
if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
|
||||||
// Restore has started once.
|
// Points to a valid app (superset of cn != null) but the apk
|
||||||
} else if (installProgress != null) {
|
// is not available.
|
||||||
// App restore has started. Update the flag
|
|
||||||
appWidgetInfo.restoreStatus |=
|
if (c.restoreFlag != 0) {
|
||||||
LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
|
// Package is not yet available but might be
|
||||||
} else if (!isSafeMode) {
|
// installed later.
|
||||||
c.markDeleted("Unrestored widget removed: " + component);
|
FileLog.d(TAG, "package not yet restored: " + targetPkg);
|
||||||
|
|
||||||
|
if (c.hasRestoreFlag(WorkspaceItemInfo.FLAG_RESTORE_STARTED)) {
|
||||||
|
// Restore has started once.
|
||||||
|
} else if (installingPkgs.containsKey(targetPkg)) {
|
||||||
|
// App restore has started. Update the flag
|
||||||
|
c.restoreFlag |= WorkspaceItemInfo.FLAG_RESTORE_STARTED;
|
||||||
|
c.updater().put(LauncherSettings.Favorites.RESTORED,
|
||||||
|
c.restoreFlag).commit();
|
||||||
|
} else {
|
||||||
|
c.markDeleted("Unrestored app removed: " + targetPkg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
|
||||||
|
// Package is present but not available.
|
||||||
|
disabledState |= WorkspaceItemInfo.FLAG_DISABLED_NOT_AVAILABLE;
|
||||||
|
// Add the icon on the workspace anyway.
|
||||||
|
allowMissingTarget = true;
|
||||||
|
} else if (!isSdCardReady) {
|
||||||
|
// SdCard is not ready yet. Package might get available,
|
||||||
|
// once it is ready.
|
||||||
|
Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
|
||||||
|
pendingPackages.addToList(c.user, targetPkg);
|
||||||
|
// Add the icon on the workspace anyway.
|
||||||
|
allowMissingTarget = true;
|
||||||
|
} else {
|
||||||
|
// Do not wait for external media load anymore.
|
||||||
|
c.markDeleted("Invalid package removed: " + targetPkg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c.restoreFlag & WorkspaceItemInfo.FLAG_SUPPORTS_WEB_UI) != 0) {
|
||||||
|
validTarget = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validTarget) {
|
||||||
|
// The shortcut points to a valid target (either no target
|
||||||
|
// or something which is ready to be used)
|
||||||
|
c.markRestored();
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean useLowResIcon = !c.isOnWorkspaceOrHotseat();
|
||||||
|
|
||||||
|
if (c.restoreFlag != 0) {
|
||||||
|
// Already verified above that user is same as default user
|
||||||
|
info = c.getRestoredItemInfo(intent);
|
||||||
|
} else if (c.itemType ==
|
||||||
|
LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
|
||||||
|
info = c.getAppShortcutInfo(
|
||||||
|
intent, allowMissingTarget, useLowResIcon);
|
||||||
|
} else if (c.itemType ==
|
||||||
|
LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
|
||||||
|
|
||||||
|
ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
|
||||||
|
if (unlockedUsers.get(c.serialNumber)) {
|
||||||
|
ShortcutInfo pinnedShortcut =
|
||||||
|
shortcutKeyToPinnedShortcuts.get(key);
|
||||||
|
if (pinnedShortcut == null) {
|
||||||
|
// The shortcut is no longer valid.
|
||||||
|
c.markDeleted("Pinned shortcut not found");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
info = new WorkspaceItemInfo(pinnedShortcut, context);
|
||||||
|
final WorkspaceItemInfo finalInfo = info;
|
||||||
|
|
||||||
|
LauncherIcons li = LauncherIcons.obtain(context);
|
||||||
|
// If the pinned deep shortcut is no longer published,
|
||||||
|
// use the last saved icon instead of the default.
|
||||||
|
Supplier<ItemInfoWithIcon> fallbackIconProvider = () ->
|
||||||
|
c.loadIcon(finalInfo, li) ? finalInfo : null;
|
||||||
|
info.applyFrom(li.createShortcutIcon(pinnedShortcut,
|
||||||
|
true /* badged */, fallbackIconProvider));
|
||||||
|
li.recycle();
|
||||||
|
if (pmHelper.isAppSuspended(
|
||||||
|
pinnedShortcut.getPackage(), info.user)) {
|
||||||
|
info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
|
||||||
|
}
|
||||||
|
intent = info.intent;
|
||||||
|
} else {
|
||||||
|
// Create a shortcut info in disabled mode for now.
|
||||||
|
info = c.loadSimpleWorkspaceItem();
|
||||||
|
info.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
|
||||||
|
}
|
||||||
|
} else { // item type == ITEM_TYPE_SHORTCUT
|
||||||
|
info = c.loadSimpleWorkspaceItem();
|
||||||
|
|
||||||
|
// Shortcuts are only available on the primary profile
|
||||||
|
if (!TextUtils.isEmpty(targetPkg)
|
||||||
|
&& pmHelper.isAppSuspended(targetPkg, c.user)) {
|
||||||
|
disabledState |= FLAG_DISABLED_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// App shortcuts that used to be automatically added to Launcher
|
||||||
|
// didn't always have the correct intent flags set, so do that
|
||||||
|
// here
|
||||||
|
if (intent.getAction() != null &&
|
||||||
|
intent.getCategories() != null &&
|
||||||
|
intent.getAction().equals(Intent.ACTION_MAIN) &&
|
||||||
|
intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
|
||||||
|
intent.addFlags(
|
||||||
|
Intent.FLAG_ACTIVITY_NEW_TASK |
|
||||||
|
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info != null) {
|
||||||
|
c.applyCommonProperties(info);
|
||||||
|
|
||||||
|
info.intent = intent;
|
||||||
|
info.rank = c.getInt(rankIndex);
|
||||||
|
info.spanX = 1;
|
||||||
|
info.spanY = 1;
|
||||||
|
info.runtimeStatusFlags |= disabledState;
|
||||||
|
if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
|
||||||
|
info.runtimeStatusFlags |= FLAG_DISABLED_SAFEMODE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
|
||||||
|
SessionInfo si = installingPkgs.get(targetPkg);
|
||||||
|
if (si == null) {
|
||||||
|
info.status &= ~WorkspaceItemInfo.FLAG_INSTALL_SESSION_ACTIVE;
|
||||||
|
} else {
|
||||||
|
info.setInstallProgress((int) (si.getProgress() * 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c.checkAndAddItem(info, mBgDataModel);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Unexpected null WorkspaceItemInfo");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
|
||||||
|
FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id);
|
||||||
|
c.applyCommonProperties(folderInfo);
|
||||||
|
|
||||||
|
// Do not trim the folder label, as is was set by the user.
|
||||||
|
folderInfo.title = c.getString(c.titleIndex);
|
||||||
|
folderInfo.spanX = 1;
|
||||||
|
folderInfo.spanY = 1;
|
||||||
|
folderInfo.options = c.getInt(optionsIndex);
|
||||||
|
|
||||||
|
// no special handling required for restored folders
|
||||||
|
c.markRestored();
|
||||||
|
|
||||||
|
c.checkAndAddItem(folderInfo, mBgDataModel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
|
||||||
|
if (FeatureFlags.GO_DISABLE_WIDGETS) {
|
||||||
|
c.markDeleted("Only legacy shortcuts can have null package");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Follow through
|
||||||
|
case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
|
||||||
|
// Read all Launcher-specific widget details
|
||||||
|
boolean customWidget = c.itemType ==
|
||||||
|
LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
|
||||||
|
|
||||||
|
int appWidgetId = c.getInt(appWidgetIdIndex);
|
||||||
|
String savedProvider = c.getString(appWidgetProviderIndex);
|
||||||
|
|
||||||
|
final ComponentName component =
|
||||||
|
ComponentName.unflattenFromString(savedProvider);
|
||||||
|
|
||||||
|
final boolean isIdValid = !c.hasRestoreFlag(
|
||||||
|
LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
|
||||||
|
final boolean wasProviderReady = !c.hasRestoreFlag(
|
||||||
|
LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
|
||||||
|
|
||||||
|
if (widgetProvidersMap == null) {
|
||||||
|
widgetProvidersMap = mAppWidgetManager.getAllProvidersMap();
|
||||||
|
}
|
||||||
|
final AppWidgetProviderInfo provider = widgetProvidersMap.get(
|
||||||
|
new ComponentKey(
|
||||||
|
ComponentName.unflattenFromString(savedProvider),
|
||||||
|
c.user));
|
||||||
|
|
||||||
|
final boolean isProviderReady = isValidProvider(provider);
|
||||||
|
if (!isSafeMode && !customWidget &&
|
||||||
|
wasProviderReady && !isProviderReady) {
|
||||||
|
c.markDeleted(
|
||||||
|
"Deleting widget that isn't installed anymore: "
|
||||||
|
+ provider);
|
||||||
|
} else {
|
||||||
|
if (isProviderReady) {
|
||||||
|
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
|
||||||
|
provider.provider);
|
||||||
|
|
||||||
|
// The provider is available. So the widget is either
|
||||||
|
// available or not available. We do not need to track
|
||||||
|
// any future restore updates.
|
||||||
|
int status = c.restoreFlag &
|
||||||
|
~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED &
|
||||||
|
~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
|
||||||
|
if (!wasProviderReady) {
|
||||||
|
// If provider was not previously ready, update the
|
||||||
|
// status and UI flag.
|
||||||
|
|
||||||
|
// Id would be valid only if the widget restore broadcast was received.
|
||||||
|
if (isIdValid) {
|
||||||
|
status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appWidgetInfo.restoreStatus = status;
|
||||||
|
} else {
|
||||||
|
Log.v(TAG, "Widget restore pending id=" + c.id
|
||||||
|
+ " appWidgetId=" + appWidgetId
|
||||||
|
+ " status =" + c.restoreFlag);
|
||||||
|
appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
|
||||||
|
component);
|
||||||
|
appWidgetInfo.restoreStatus = c.restoreFlag;
|
||||||
|
SessionInfo si =
|
||||||
|
installingPkgs.get(component.getPackageName());
|
||||||
|
Integer installProgress = si == null
|
||||||
|
? null
|
||||||
|
: (int) (si.getProgress() * 100);
|
||||||
|
|
||||||
|
if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
|
||||||
|
// Restore has started once.
|
||||||
|
} else if (installProgress != null) {
|
||||||
|
// App restore has started. Update the flag
|
||||||
|
appWidgetInfo.restoreStatus |=
|
||||||
|
LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
|
||||||
|
} else if (!isSafeMode) {
|
||||||
|
c.markDeleted("Unrestored widget removed: " + component);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
appWidgetInfo.installProgress =
|
||||||
|
installProgress == null ? 0 : installProgress;
|
||||||
|
}
|
||||||
|
if (appWidgetInfo.hasRestoreFlag(
|
||||||
|
LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
|
||||||
|
appWidgetInfo.bindOptions = c.parseIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
c.applyCommonProperties(appWidgetInfo);
|
||||||
|
appWidgetInfo.spanX = c.getInt(spanXIndex);
|
||||||
|
appWidgetInfo.spanY = c.getInt(spanYIndex);
|
||||||
|
appWidgetInfo.user = c.user;
|
||||||
|
|
||||||
|
if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
|
||||||
|
c.markDeleted("Widget has invalid size: "
|
||||||
|
+ appWidgetInfo.spanX + "x" + appWidgetInfo.spanY);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!c.isOnWorkspaceOrHotseat()) {
|
||||||
|
c.markDeleted("Widget found where container != " +
|
||||||
|
"CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
appWidgetInfo.installProgress =
|
if (!customWidget) {
|
||||||
installProgress == null ? 0 : installProgress;
|
String providerName =
|
||||||
}
|
appWidgetInfo.providerName.flattenToString();
|
||||||
if (appWidgetInfo.hasRestoreFlag(
|
if (!providerName.equals(savedProvider) ||
|
||||||
LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
|
(appWidgetInfo.restoreStatus != c.restoreFlag)) {
|
||||||
appWidgetInfo.bindOptions = c.parseIntent();
|
c.updater()
|
||||||
}
|
.put(LauncherSettings.Favorites.APPWIDGET_PROVIDER,
|
||||||
|
providerName)
|
||||||
c.applyCommonProperties(appWidgetInfo);
|
.put(LauncherSettings.Favorites.RESTORED,
|
||||||
appWidgetInfo.spanX = c.getInt(spanXIndex);
|
appWidgetInfo.restoreStatus)
|
||||||
appWidgetInfo.spanY = c.getInt(spanYIndex);
|
.commit();
|
||||||
appWidgetInfo.user = c.user;
|
}
|
||||||
|
|
||||||
if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
|
|
||||||
c.markDeleted("Widget has invalid size: "
|
|
||||||
+ appWidgetInfo.spanX + "x" + appWidgetInfo.spanY);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!c.isOnWorkspaceOrHotseat()) {
|
|
||||||
c.markDeleted("Widget found where container != " +
|
|
||||||
"CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!customWidget) {
|
|
||||||
String providerName =
|
|
||||||
appWidgetInfo.providerName.flattenToString();
|
|
||||||
if (!providerName.equals(savedProvider) ||
|
|
||||||
(appWidgetInfo.restoreStatus != c.restoreFlag)) {
|
|
||||||
c.updater()
|
|
||||||
.put(LauncherSettings.Favorites.APPWIDGET_PROVIDER,
|
|
||||||
providerName)
|
|
||||||
.put(LauncherSettings.Favorites.RESTORED,
|
|
||||||
appWidgetInfo.restoreStatus)
|
|
||||||
.commit();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (appWidgetInfo.restoreStatus !=
|
if (appWidgetInfo.restoreStatus !=
|
||||||
LauncherAppWidgetInfo.RESTORE_COMPLETED) {
|
LauncherAppWidgetInfo.RESTORE_COMPLETED) {
|
||||||
String pkg = appWidgetInfo.providerName.getPackageName();
|
String pkg = appWidgetInfo.providerName.getPackageName();
|
||||||
appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg);
|
appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg);
|
||||||
appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
|
appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
|
||||||
mIconCache.getTitleAndIconForApp(
|
mIconCache.getTitleAndIconForApp(
|
||||||
appWidgetInfo.pendingItemInfo, false);
|
appWidgetInfo.pendingItemInfo, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
c.checkAndAddItem(appWidgetInfo, mBgDataModel);
|
c.checkAndAddItem(appWidgetInfo, mBgDataModel);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "Desktop items loading interrupted", e);
|
Log.e(TAG, "Desktop items loading interrupted", e);
|
||||||
|
|||||||