Moving some utilities methods to separate class
Change-Id: I5094b22ddc77c45590cea1a5f5dead0dc7580abf
This commit is contained in:
parent
273c079761
commit
9dbb27c09c
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.util;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
/**
|
||||
* Robolectric unit tests for {@link IntArray}
|
||||
*/
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class IntArrayTest {
|
||||
|
||||
@Test
|
||||
public void concatAndParseString() {
|
||||
int[] array = new int[] {0, 2, 3, 9};
|
||||
String concat = IntArray.wrap(array).toConcatString();
|
||||
|
||||
int[] parsed = IntArray.fromConcatString(concat).toArray();
|
||||
assertThat(array).isEqualTo(parsed);
|
||||
}
|
||||
}
|
|
@ -21,7 +21,6 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
|
|
@ -43,6 +43,7 @@ import com.android.launcher3.LauncherSettings.Favorites;
|
|||
import com.android.launcher3.icons.GraphicsUtils;
|
||||
import com.android.launcher3.icons.LauncherIcons;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
@ -72,7 +73,7 @@ public class AutoInstallsLayout {
|
|||
|
||||
static AutoInstallsLayout get(Context context, AppWidgetHost appWidgetHost,
|
||||
LayoutParserCallback callback) {
|
||||
Pair<String, Resources> customizationApkInfo = Utilities.findSystemApk(
|
||||
Pair<String, Resources> customizationApkInfo = PackageManagerHelper.findSystemApk(
|
||||
ACTION_LAUNCHER_CUSTOMIZATION, context.getPackageManager());
|
||||
if (customizationApkInfo == null) {
|
||||
return null;
|
||||
|
|
|
@ -34,9 +34,9 @@ import com.android.launcher3.LauncherSettings.Favorites;
|
|||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
import com.android.launcher3.model.AppLaunchTracker;
|
||||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.testing.TestProtocol;
|
||||
import com.android.launcher3.uioverrides.DisplayRotationListener;
|
||||
import com.android.launcher3.uioverrides.WallpaperColorInfo;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.Themes;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
@ -135,7 +135,7 @@ public abstract class BaseDraggingActivity extends BaseActivity
|
|||
|
||||
public boolean startActivitySafely(View v, Intent intent, @Nullable ItemInfo item,
|
||||
@Nullable String sourceContainer) {
|
||||
if (mIsSafeModeEnabled && !Utilities.isSystemApp(this, intent)) {
|
||||
if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) {
|
||||
Toast.makeText(this, R.string.safemode_shortcut_error, Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -612,7 +612,7 @@ public class InstallShortcutReceiver extends BroadcastReceiver {
|
|||
// Already an activity target
|
||||
return original;
|
||||
}
|
||||
if (!Utilities.isLauncherAppTarget(original.launchIntent)) {
|
||||
if (!PackageManagerHelper.isLauncherAppTarget(original.launchIntent)) {
|
||||
return original;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.OperationApplicationException;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ProviderInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.database.Cursor;
|
||||
|
@ -50,7 +49,6 @@ import android.os.Handler;
|
|||
import android.os.Message;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.BaseColumns;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
|
@ -70,6 +68,7 @@ import com.android.launcher3.util.IOUtils;
|
|||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.launcher3.util.NoLocaleSQLiteHelper;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
import com.android.launcher3.util.Thunk;
|
||||
|
||||
|
@ -77,7 +76,6 @@ import org.xmlpull.v1.XmlPullParser;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringReader;
|
||||
|
@ -873,7 +871,7 @@ public class LauncherProvider extends ContentProvider {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!Utilities.isLauncherAppTarget(intent)) {
|
||||
if (!PackageManagerHelper.isLauncherAppTarget(intent)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.util.PackageManagerHelper.findSystemApk;
|
||||
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.util.DisplayMetrics;
|
||||
|
@ -59,7 +61,7 @@ public class Partner {
|
|||
*/
|
||||
public static synchronized Partner get(PackageManager pm) {
|
||||
if (!sSearched) {
|
||||
Pair<String, Resources> apkInfo = Utilities.findSystemApk(ACTION_PARTNER_CUSTOMIZATION, pm);
|
||||
Pair<String, Resources> apkInfo = findSystemApk(ACTION_PARTNER_CUSTOMIZATION, pm);
|
||||
if (apkInfo != null) {
|
||||
sPartner = new Partner(apkInfo.first, apkInfo.second);
|
||||
}
|
||||
|
|
|
@ -16,20 +16,16 @@
|
|||
|
||||
package com.android.launcher3;
|
||||
|
||||
import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED;
|
||||
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.res.Resources;
|
||||
|
@ -44,7 +40,6 @@ import android.graphics.drawable.ColorDrawable;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.DeadObjectException;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
@ -57,7 +52,6 @@ import android.text.TextUtils;
|
|||
import android.text.style.TtsSpan;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.util.TypedValue;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -66,7 +60,6 @@ import android.view.animation.Interpolator;
|
|||
|
||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
import com.android.launcher3.compat.ShortcutConfigActivityInfo;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
|
||||
import com.android.launcher3.graphics.RotationMode;
|
||||
import com.android.launcher3.graphics.TintedDrawableSpan;
|
||||
|
@ -78,13 +71,10 @@ import com.android.launcher3.util.PackageManagerHelper;
|
|||
import com.android.launcher3.views.Transposable;
|
||||
import com.android.launcher3.widget.PendingAddShortcutInfo;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
@ -92,8 +82,6 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.android.launcher3.ItemInfoWithIcon.FLAG_ICON_BADGED;
|
||||
|
||||
/**
|
||||
* Various utilities shared amongst the Launcher's classes.
|
||||
*/
|
||||
|
@ -253,7 +241,6 @@ public final class Utilities {
|
|||
return scale;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, float[], boolean)}.
|
||||
*/
|
||||
|
@ -389,53 +376,6 @@ public final class Utilities {
|
|||
return min + (value * (max - min));
|
||||
}
|
||||
|
||||
public static boolean isSystemApp(Context context, Intent intent) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ComponentName cn = intent.getComponent();
|
||||
String packageName = null;
|
||||
if (cn == null) {
|
||||
ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if ((info != null) && (info.activityInfo != null)) {
|
||||
packageName = info.activityInfo.packageName;
|
||||
}
|
||||
} else {
|
||||
packageName = cn.getPackageName();
|
||||
}
|
||||
if (packageName != null) {
|
||||
try {
|
||||
PackageInfo info = pm.getPackageInfo(packageName, 0);
|
||||
return (info != null) && (info.applicationInfo != null) &&
|
||||
((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds a system apk which had a broadcast receiver listening to a particular action.
|
||||
* @param action intent action used to find the apk
|
||||
* @return a pair of apk package name and the resources.
|
||||
*/
|
||||
static Pair<String, Resources> findSystemApk(String action, PackageManager pm) {
|
||||
final Intent intent = new Intent(action);
|
||||
for (ResolveInfo info : pm.queryBroadcastReceivers(intent, 0)) {
|
||||
if (info.activityInfo != null &&
|
||||
(info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
final String packageName = info.activityInfo.packageName;
|
||||
try {
|
||||
final Resources res = pm.getResourcesForApplication(packageName);
|
||||
return Pair.create(packageName, res);
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.w(TAG, "Failed to find resources for " + packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trims the string, removing all whitespace at the beginning and end of the string.
|
||||
* Non-breaking whitespaces are also removed.
|
||||
|
@ -460,51 +400,10 @@ public final class Utilities {
|
|||
return (int) Math.ceil(fm.bottom - fm.top);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience println with multiple args.
|
||||
*/
|
||||
public static void println(String key, Object... args) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(key);
|
||||
b.append(": ");
|
||||
boolean isFirstArgument = true;
|
||||
for (Object arg : args) {
|
||||
if (isFirstArgument) {
|
||||
isFirstArgument = false;
|
||||
} else {
|
||||
b.append(", ");
|
||||
}
|
||||
b.append(arg);
|
||||
}
|
||||
System.out.println(b.toString());
|
||||
}
|
||||
|
||||
public static boolean isRtl(Resources res) {
|
||||
return res.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the intent is a valid launch intent for a launcher activity of an app.
|
||||
* This is used to identify shortcuts which are different from the ones exposed by the
|
||||
* applications' manifest file.
|
||||
*
|
||||
* @param launchIntent The intent that will be launched when the shortcut is clicked.
|
||||
*/
|
||||
public static boolean isLauncherAppTarget(Intent launchIntent) {
|
||||
if (launchIntent != null
|
||||
&& Intent.ACTION_MAIN.equals(launchIntent.getAction())
|
||||
&& launchIntent.getComponent() != null
|
||||
&& launchIntent.getCategories() != null
|
||||
&& launchIntent.getCategories().size() == 1
|
||||
&& launchIntent.hasCategory(Intent.CATEGORY_LAUNCHER)
|
||||
&& TextUtils.isEmpty(launchIntent.getDataString())) {
|
||||
// An app target can either have no extra or have ItemInfo.EXTRA_PROFILE.
|
||||
Bundle extras = launchIntent.getExtras();
|
||||
return extras == null || extras.keySet().isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static float dpiFromPx(int size, DisplayMetrics metrics){
|
||||
float densityRatio = (float) metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT;
|
||||
return (size / densityRatio);
|
||||
|
@ -607,18 +506,6 @@ public final class Utilities {
|
|||
return context.getSystemService(WallpaperManager.class).isSetWallpaperAllowed();
|
||||
}
|
||||
|
||||
public static void closeSilently(Closeable c) {
|
||||
if (c != null) {
|
||||
try {
|
||||
c.close();
|
||||
} catch (IOException e) {
|
||||
if (FeatureFlags.IS_DOGFOOD_BUILD) {
|
||||
Log.d(TAG, "Error closing", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isBinderSizeError(Exception e) {
|
||||
return e.getCause() instanceof TransactionTooLargeException
|
||||
|| e.getCause() instanceof DeadObjectException;
|
||||
|
@ -733,25 +620,6 @@ public final class Utilities {
|
|||
}
|
||||
}
|
||||
|
||||
public static int[] getIntArrayFromString(String tokenized) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(tokenized, ",");
|
||||
int[] array = new int[tokenizer.countTokens()];
|
||||
int count = 0;
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
array[count] = Integer.parseInt(tokenizer.nextToken());
|
||||
count++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public static String getStringFromIntArray(int[] array) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (int value : array) {
|
||||
str.append(value).append(",");
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public static float squaredHypot(float x, float y) {
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import android.util.Pair;
|
|||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.util.IOUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
|
@ -131,7 +132,7 @@ public final class FileLog {
|
|||
private PrintWriter mCurrentWriter = null;
|
||||
|
||||
private void closeWriter() {
|
||||
Utilities.closeSilently(mCurrentWriter);
|
||||
IOUtils.closeSilently(mCurrentWriter);
|
||||
mCurrentWriter = null;
|
||||
}
|
||||
|
||||
|
@ -219,7 +220,7 @@ public final class FileLog {
|
|||
} catch (Exception e) {
|
||||
// ignore
|
||||
} finally {
|
||||
Utilities.closeSilently(in);
|
||||
IOUtils.closeSilently(in);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ import com.android.launcher3.LauncherModel.CallbackTask;
|
|||
import com.android.launcher3.LauncherModel.Callbacks;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.WorkspaceItemInfo;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.util.GridOccupancy;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -162,7 +162,7 @@ public class AddWorkspaceItemsTask extends BaseModelUpdateTask {
|
|||
intentWithoutPkg = intent.toUri(0);
|
||||
}
|
||||
|
||||
boolean isLauncherAppTarget = Utilities.isLauncherAppTarget(intent);
|
||||
boolean isLauncherAppTarget = PackageManagerHelper.isLauncherAppTarget(intent);
|
||||
synchronized (dataModel) {
|
||||
for (ItemInfo item : dataModel.itemsIdMap) {
|
||||
if (item instanceof WorkspaceItemInfo) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
|
|||
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
|
||||
import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
|
||||
import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems;
|
||||
import static com.android.launcher3.util.PackageManagerHelper.isSystemApp;
|
||||
|
||||
import android.appwidget.AppWidgetProviderInfo;
|
||||
import android.content.ComponentName;
|
||||
|
@ -69,6 +70,7 @@ import com.android.launcher3.provider.ImportDataTask;
|
|||
import com.android.launcher3.shortcuts.DeepShortcutManager;
|
||||
import com.android.launcher3.shortcuts.ShortcutKey;
|
||||
import com.android.launcher3.util.ComponentKey;
|
||||
import com.android.launcher3.util.IOUtils;
|
||||
import com.android.launcher3.util.LooperIdleLock;
|
||||
import com.android.launcher3.util.MultiHashMap;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
@ -531,7 +533,7 @@ public class LoaderTask implements Runnable {
|
|||
info.spanX = 1;
|
||||
info.spanY = 1;
|
||||
info.runtimeStatusFlags |= disabledState;
|
||||
if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
|
||||
if (isSafeMode && !isSystemApp(context, intent)) {
|
||||
info.runtimeStatusFlags |= FLAG_DISABLED_SAFEMODE;
|
||||
}
|
||||
|
||||
|
@ -703,7 +705,7 @@ public class LoaderTask implements Runnable {
|
|||
}
|
||||
}
|
||||
} finally {
|
||||
Utilities.closeSilently(c);
|
||||
IOUtils.closeSilently(c);
|
||||
}
|
||||
|
||||
// Break early if we've stopped loading
|
||||
|
|
|
@ -42,7 +42,6 @@ import com.android.launcher3.LauncherProvider;
|
|||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.LauncherSettings.Favorites;
|
||||
import com.android.launcher3.LauncherSettings.Settings;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.Workspace;
|
||||
import com.android.launcher3.compat.UserManagerCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
|
@ -50,6 +49,7 @@ import com.android.launcher3.logging.FileLog;
|
|||
import com.android.launcher3.model.GridSizeMigrationTask;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSparseArrayMap;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -223,7 +223,7 @@ public class ImportDataTask {
|
|||
case Favorites.ITEM_TYPE_SHORTCUT:
|
||||
case Favorites.ITEM_TYPE_APPLICATION: {
|
||||
intent = Intent.parseUri(c.getString(intentIndex), 0);
|
||||
if (Utilities.isLauncherAppTarget(intent)) {
|
||||
if (PackageManagerHelper.isLauncherAppTarget(intent)) {
|
||||
type = Favorites.ITEM_TYPE_APPLICATION;
|
||||
} else {
|
||||
values.put(Favorites.ICON_PACKAGE, c.getString(iconPackageIndex));
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
|
||||
package com.android.launcher3.provider;
|
||||
|
||||
import static com.android.launcher3.Utilities.getIntArrayFromString;
|
||||
import static com.android.launcher3.Utilities.getStringFromIntArray;
|
||||
import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
|
||||
|
||||
import android.app.backup.BackupManager;
|
||||
|
@ -40,6 +38,7 @@ import com.android.launcher3.WorkspaceItemInfo;
|
|||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.logging.FileLog;
|
||||
import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.LogConfig;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
|
@ -246,8 +245,8 @@ public class RestoreDbTask {
|
|||
SharedPreferences prefs = Utilities.getPrefs(context);
|
||||
if (prefs.contains(APPWIDGET_OLD_IDS) && prefs.contains(APPWIDGET_IDS)) {
|
||||
AppWidgetsRestoredReceiver.restoreAppWidgetIds(context,
|
||||
getIntArrayFromString(prefs.getString(APPWIDGET_OLD_IDS, "")),
|
||||
getIntArrayFromString(prefs.getString(APPWIDGET_IDS, "")));
|
||||
IntArray.fromConcatString(prefs.getString(APPWIDGET_OLD_IDS, "")).toArray(),
|
||||
IntArray.fromConcatString(prefs.getString(APPWIDGET_IDS, "")).toArray());
|
||||
} else {
|
||||
FileLog.d(TAG, "No app widget ids to restore.");
|
||||
}
|
||||
|
@ -259,8 +258,8 @@ public class RestoreDbTask {
|
|||
public static void setRestoredAppWidgetIds(Context context, @NonNull int[] oldIds,
|
||||
@NonNull int[] newIds) {
|
||||
Utilities.getPrefs(context).edit()
|
||||
.putString(APPWIDGET_OLD_IDS, getStringFromIntArray(oldIds))
|
||||
.putString(APPWIDGET_IDS, getStringFromIntArray(newIds))
|
||||
.putString(APPWIDGET_OLD_IDS, IntArray.wrap(oldIds).toConcatString())
|
||||
.putString(APPWIDGET_IDS, IntArray.wrap(newIds).toConcatString())
|
||||
.commit();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,10 +17,13 @@
|
|||
package com.android.launcher3.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
|
@ -35,6 +38,7 @@ import java.util.UUID;
|
|||
public class IOUtils {
|
||||
|
||||
private static final int BUF_SIZE = 0x1000; // 4K
|
||||
private static final String TAG = "IOUtils";
|
||||
|
||||
public static byte[] toByteArray(File file) throws IOException {
|
||||
try (InputStream in = new FileInputStream(file)) {
|
||||
|
@ -77,4 +81,16 @@ public class IOUtils {
|
|||
}
|
||||
return file.getAbsolutePath();
|
||||
}
|
||||
|
||||
public static void closeSilently(Closeable c) {
|
||||
if (c != null) {
|
||||
try {
|
||||
c.close();
|
||||
} catch (IOException e) {
|
||||
if (FeatureFlags.IS_DOGFOOD_BUILD) {
|
||||
Log.d(TAG, "Error closing", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package com.android.launcher3.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Copy of the platform hidden implementation of android.util.IntArray.
|
||||
|
@ -248,6 +249,17 @@ public class IntArray implements Cloneable {
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
public static IntArray fromConcatString(String concatString) {
|
||||
StringTokenizer tokenizer = new StringTokenizer(concatString, ",");
|
||||
int[] array = new int[tokenizer.countTokens()];
|
||||
int count = 0;
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
array[count] = Integer.parseInt(tokenizer.nextToken().trim());
|
||||
count++;
|
||||
}
|
||||
return new IntArray(array, array.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws {@link ArrayIndexOutOfBoundsException} if the index is out of bounds.
|
||||
*
|
||||
|
|
|
@ -24,9 +24,11 @@ import android.content.Intent;
|
|||
import android.content.IntentFilter;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.LauncherActivityInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Rect;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
@ -35,6 +37,7 @@ import android.os.PatternMatcher;
|
|||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.launcher3.AppInfo;
|
||||
|
@ -220,4 +223,73 @@ public class PackageManagerHelper {
|
|||
packageFilter.addDataSchemeSpecificPart(pkg, PatternMatcher.PATTERN_LITERAL);
|
||||
return packageFilter;
|
||||
}
|
||||
|
||||
public static boolean isSystemApp(Context context, Intent intent) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
ComponentName cn = intent.getComponent();
|
||||
String packageName = null;
|
||||
if (cn == null) {
|
||||
ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if ((info != null) && (info.activityInfo != null)) {
|
||||
packageName = info.activityInfo.packageName;
|
||||
}
|
||||
} else {
|
||||
packageName = cn.getPackageName();
|
||||
}
|
||||
if (packageName != null) {
|
||||
try {
|
||||
PackageInfo info = pm.getPackageInfo(packageName, 0);
|
||||
return (info != null) && (info.applicationInfo != null) &&
|
||||
((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
|
||||
} catch (NameNotFoundException e) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a system apk which had a broadcast receiver listening to a particular action.
|
||||
* @param action intent action used to find the apk
|
||||
* @return a pair of apk package name and the resources.
|
||||
*/
|
||||
public static Pair<String, Resources> findSystemApk(String action, PackageManager pm) {
|
||||
final Intent intent = new Intent(action);
|
||||
for (ResolveInfo info : pm.queryBroadcastReceivers(intent, 0)) {
|
||||
if (info.activityInfo != null &&
|
||||
(info.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
final String packageName = info.activityInfo.packageName;
|
||||
try {
|
||||
final Resources res = pm.getResourcesForApplication(packageName);
|
||||
return Pair.create(packageName, res);
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.w(TAG, "Failed to find resources for " + packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the intent is a valid launch intent for a launcher activity of an app.
|
||||
* This is used to identify shortcuts which are different from the ones exposed by the
|
||||
* applications' manifest file.
|
||||
*
|
||||
* @param launchIntent The intent that will be launched when the shortcut is clicked.
|
||||
*/
|
||||
public static boolean isLauncherAppTarget(Intent launchIntent) {
|
||||
if (launchIntent != null
|
||||
&& Intent.ACTION_MAIN.equals(launchIntent.getAction())
|
||||
&& launchIntent.getComponent() != null
|
||||
&& launchIntent.getCategories() != null
|
||||
&& launchIntent.getCategories().size() == 1
|
||||
&& launchIntent.hasCategory(Intent.CATEGORY_LAUNCHER)
|
||||
&& TextUtils.isEmpty(launchIntent.getDataString())) {
|
||||
// An app target can either have no extra or have ItemInfo.EXTRA_PROFILE.
|
||||
Bundle extras = launchIntent.getExtras();
|
||||
return extras == null || extras.keySet().isEmpty();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import com.android.launcher3.icons.IconCache;
|
|||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.ItemInfo;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.compat.LauncherAppsCompat;
|
||||
import com.android.launcher3.icons.BitmapInfo;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -115,7 +115,7 @@ public class LoaderCursorTest {
|
|||
WorkspaceItemInfo info = mLoaderCursor.getAppShortcutInfo(
|
||||
new Intent().setComponent(cn), false /* allowMissingTarget */, true);
|
||||
assertNotNull(info);
|
||||
assertTrue(Utilities.isLauncherAppTarget(info.intent));
|
||||
assertTrue(PackageManagerHelper.isLauncherAppTarget(info.intent));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -127,7 +127,7 @@ public class LoaderCursorTest {
|
|||
WorkspaceItemInfo info = mLoaderCursor.getAppShortcutInfo(
|
||||
new Intent().setComponent(cn), true /* allowMissingTarget */, true);
|
||||
assertNotNull(info);
|
||||
assertTrue(Utilities.isLauncherAppTarget(info.intent));
|
||||
assertTrue(PackageManagerHelper.isLauncherAppTarget(info.intent));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue