Replace the launcher telephony apps with the default work profile one
when using AutoInstalls or when restoring, and when work telephony is
enabled.
Test: atest RestoreDbTaskTest
Bug: 258631628
Change-Id: I3e699e5c34c09daf60e29724eda04282493673e7
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 55ede6c..27c41c2 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -16,11 +16,14 @@
package com.android.launcher3;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.sqlite.SQLiteDatabase;
@@ -40,9 +43,12 @@
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.qsb.QsbContainerView;
+import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Partner;
import com.android.launcher3.util.Thunk;
@@ -53,6 +59,7 @@
import java.io.IOException;
import java.util.Locale;
+import java.util.Map;
import java.util.function.Supplier;
/**
@@ -162,7 +169,7 @@
private final InvariantDeviceProfile mIdp;
private final int mRowCount;
private final int mColumnCount;
-
+ private final Map<String, LauncherActivityInfo> mActivityOverride;
private final int[] mTemp = new int[2];
@Thunk
final ContentValues mValues;
@@ -193,6 +200,7 @@
mIdp = LauncherAppState.getIDP(context);
mRowCount = mIdp.numRows;
mColumnCount = mIdp.numColumns;
+ mActivityOverride = ApiWrapper.getActivityOverrides(context);
}
/**
@@ -299,6 +307,9 @@
mValues.put(Favorites.SPANX, 1);
mValues.put(Favorites.SPANY, 1);
mValues.put(Favorites._ID, id);
+
+ maybeReplaceShortcut(intent.getComponent().getPackageName(), type);
+
if (mCallback.insertAndCheck(mDb, mValues) < 0) {
return -1;
} else {
@@ -364,7 +375,7 @@
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
return addShortcut(info.loadLabel(mPackageManager).toString(),
- intent, Favorites.ITEM_TYPE_APPLICATION);
+ intent, ITEM_TYPE_APPLICATION);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Favorite not found: " + packageName + "/" + className);
}
@@ -404,7 +415,7 @@
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
return addShortcut(mContext.getString(R.string.package_state_unknown), intent,
- Favorites.ITEM_TYPE_APPLICATION);
+ ITEM_TYPE_APPLICATION);
}
}
@@ -573,8 +584,7 @@
}
@Override
- public int parseAndAdd(XmlPullParser parser)
- throws XmlPullParserException, IOException {
+ public int parseAndAdd(XmlPullParser parser) throws XmlPullParserException, IOException {
final String title;
final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
if (titleResId != 0) {
@@ -717,4 +727,13 @@
static void copyInteger(ContentValues from, ContentValues to, String key) {
to.put(key, from.getAsInteger(key));
}
+
+ private void maybeReplaceShortcut(String packageName, int type) {
+ if (mActivityOverride.containsKey(packageName) && type == ITEM_TYPE_APPLICATION) {
+ LauncherActivityInfo replacementInfo = mActivityOverride.get(packageName);
+ mValues.put(Favorites.PROFILE_ID, UserCache.INSTANCE.get(mContext)
+ .getSerialNumberForUser(replacementInfo.getUser()));
+ mValues.put(Favorites.INTENT, AppInfo.makeLaunchIntent(replacementInfo).toUri(0));
+ }
+ }
}
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 2a452be..5789a6c 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -20,15 +20,19 @@
import static com.android.launcher3.LauncherPrefs.APP_WIDGET_IDS;
import static com.android.launcher3.LauncherPrefs.OLD_APP_WIDGET_IDS;
import static com.android.launcher3.LauncherPrefs.RESTORE_DEVICE;
+import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
import android.app.backup.BackupManager;
import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseLongArray;
@@ -44,15 +48,21 @@
import com.android.launcher3.logging.FileLog;
import com.android.launcher3.model.DeviceGridState;
import com.android.launcher3.model.GridBackupTable;
+import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
+import com.android.launcher3.uioverrides.ApiWrapper;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.LogConfig;
import com.android.launcher3.widget.LauncherWidgetHolder;
import java.io.InvalidObjectException;
import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.stream.Collectors;
/**
* Utility class to update DB schema after it has been restored.
@@ -159,6 +169,7 @@
* 3. If the user serial for any restored profile is different than that of the previous
* device, update the entries to the new profile id.
* 4. If restored from a single display backup, remove gaps between screenIds
+ * 5. Override shortcuts that need to be replaced.
*
* @return number of items deleted.
*/
@@ -245,6 +256,9 @@
removeScreenIdGaps(db);
}
+ // Override shortcuts
+ maybeOverrideShortcuts(context, db, myProfileId);
+
return itemsDeleted;
}
@@ -374,4 +388,48 @@
APP_WIDGET_IDS.to(IntArray.wrap(newIds).toConcatString()));
}
+ protected static void maybeOverrideShortcuts(Context context, SQLiteDatabase db,
+ long currentUser) {
+ Map<String, LauncherActivityInfo> activityOverrides = ApiWrapper.getActivityOverrides(
+ context);
+
+ if (activityOverrides == null || activityOverrides.isEmpty()) {
+ return;
+ }
+
+ try (Cursor c = db.query(Favorites.TABLE_NAME,
+ new String[]{Favorites._ID, Favorites.INTENT},
+ String.format("%s=? AND %s=? AND ( %s )", Favorites.ITEM_TYPE, Favorites.PROFILE_ID,
+ getTelephonyIntentSQLLiteSelection(activityOverrides.keySet())),
+ new String[]{String.valueOf(ITEM_TYPE_APPLICATION), String.valueOf(currentUser)},
+ null, null, null);
+ SQLiteTransaction t = new SQLiteTransaction(db)) {
+ final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
+ final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);
+ while (c.moveToNext()) {
+ LauncherActivityInfo override = activityOverrides.get(Intent.parseUri(
+ c.getString(intentIndex), 0).getComponent().getPackageName());
+ if (override != null) {
+ ContentValues values = new ContentValues();
+ values.put(Favorites.PROFILE_ID,
+ UserCache.INSTANCE.get(context).getSerialNumberForUser(
+ override.getUser()));
+ values.put(Favorites.INTENT, AppInfo.makeLaunchIntent(override).toUri(0));
+ db.update(Favorites.TABLE_NAME, values, String.format("%s=?", Favorites._ID),
+ new String[]{String.valueOf(c.getInt(idIndex))});
+ }
+ }
+ t.commit();
+ } catch (Exception ex) {
+ Log.e(TAG, "Error while overriding shortcuts", ex);
+ }
+ }
+
+ private static String getTelephonyIntentSQLLiteSelection(Collection<String> packages) {
+ return packages.stream().map(
+ packageToChange -> String.format("intent LIKE '%%' || '%s' || '%%' ",
+ packageToChange)).collect(
+ Collectors.joining(" OR "));
+ }
+
}