Merge "Add meta data to indicate launcher_dump provider name" into ub-launcher3-dorval
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index 826235b..c2270d2 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -19,7 +19,6 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingStart="16dp"
android:paddingTop="28dp"
android:background="?android:attr/colorPrimary"
android:elevation="@dimen/deep_shortcuts_elevation"
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 34adf47..0608fdd 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -19,6 +19,8 @@
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
+import android.graphics.Rect;
+import android.os.Bundle;
import android.provider.Settings;
import android.util.AttributeSet;
import android.util.Log;
@@ -60,6 +62,11 @@
*/
public static boolean startDetailsActivityForInfo(
ItemInfo info, Launcher launcher, DropTargetResultCallback callback) {
+ return startDetailsActivityForInfo(info, launcher, callback, null, null);
+ }
+
+ public static boolean startDetailsActivityForInfo(ItemInfo info, Launcher launcher,
+ DropTargetResultCallback callback, Rect sourceBounds, Bundle opts) {
boolean result = false;
ComponentName componentName = null;
if (info instanceof AppInfo) {
@@ -74,7 +81,7 @@
if (componentName != null) {
try {
LauncherAppsCompat.getInstance(launcher)
- .showAppDetailsForProfile(componentName, info.user);
+ .showAppDetailsForProfile(componentName, info.user, sourceBounds, opts);
result = true;
} catch (SecurityException | ActivityNotFoundException e) {
Toast.makeText(launcher, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3c29f5e..eef578d 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2555,6 +2555,7 @@
Intent intent = new Intent(Intent.ACTION_APPLICATION_PREFERENCES)
.setPackage(getPackageName());
intent.setSourceBounds(getViewBounds(v));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent, getActivityLaunchOptions(v));
}
@@ -2668,7 +2669,7 @@
}
@TargetApi(Build.VERSION_CODES.M)
- private Bundle getActivityLaunchOptions(View v) {
+ public Bundle getActivityLaunchOptions(View v) {
if (Utilities.ATLEAST_MARSHMALLOW) {
int left = 0, top = 0;
int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
@@ -2694,7 +2695,7 @@
return null;
}
- private Rect getViewBounds(View v) {
+ public Rect getViewBounds(View v) {
int[] pos = new int[2];
v.getLocationOnScreen(pos);
return new Rect(pos[0], pos[1], pos[0] + v.getWidth(), pos[1] + v.getHeight());
@@ -3902,6 +3903,7 @@
// Update AllApps
if (mAppsView != null) {
mAppsView.removeApps(appInfos);
+ tryAndUpdatePredictedApps();
}
}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 5bde839..e68e637 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1062,7 +1062,8 @@
info = c.loadSimpleShortcut();
// Shortcuts are only available on the primary profile
- if (pmHelper.isAppSuspended(targetPkg, c.user)) {
+ if (!TextUtils.isEmpty(targetPkg)
+ && pmHelper.isAppSuspended(targetPkg, c.user)) {
disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 7d85ac1..d4e3171 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -124,6 +124,7 @@
// always available in the main process.
FileLog.setDir(getContext().getApplicationContext().getFilesDir());
IconShapeOverride.apply(getContext());
+ SessionCommitReceiver.applyDefaultUserPrefs(getContext());
return true;
}
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 203bc25..61bcc17 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -16,6 +16,7 @@
package com.android.launcher3;
+import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -23,39 +24,51 @@
import android.content.pm.LauncherActivityInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageInstaller.SessionInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
import android.os.Process;
import android.os.UserHandle;
+import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.UserManagerCompat;
import java.util.List;
/**
* BroadcastReceiver to handle session commit intent.
*/
+@TargetApi(Build.VERSION_CODES.O)
public class SessionCommitReceiver extends BroadcastReceiver {
- private static final long SESSION_IGNORE_DURATION = 3 * 60 * 60 * 1000; // 3 hours
+ private static final String TAG = "SessionCommitReceiver";
+
+ // The content provider for the add to home screen setting. It should be of the format:
+ // <package name>.addtohomescreen
+ private static final String MARKER_PROVIDER_PREFIX = ".addtohomescreen";
// Preference key for automatically adding icon to homescreen.
public static final String ADD_ICON_PREFERENCE_KEY = "pref_add_icon_to_home";
-
- private static final String KEY_FIRST_TIME = "first_session_broadcast_time";
+ public static final String ADD_ICON_PREFERENCE_INITIALIZED_KEY =
+ "pref_add_icon_to_home_initialized";
@Override
public void onReceive(Context context, Intent intent) {
- if (!isEnabled(context)) {
+ if (!isEnabled(context) || !Utilities.isAtLeastO()) {
// User has decided to not add icons on homescreen.
return;
}
SessionInfo info = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
- // TODO: Verify install reason
- if (TextUtils.isEmpty(info.getAppPackageName())) {
+
+ if (TextUtils.isEmpty(info.getAppPackageName()) ||
+ info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
return;
}
@@ -64,17 +77,6 @@
return;
}
- // STOPSHIP: Remove this workaround when we start getting proper install reason
- SharedPreferences prefs = context
- .getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0);
- long now = System.currentTimeMillis();
- long firstTime = prefs.getLong(KEY_FIRST_TIME, now);
- prefs.edit().putLong(KEY_FIRST_TIME, firstTime).apply();
- if ((now - firstTime) < SESSION_IGNORE_DURATION) {
- Log.d("SessionCommitReceiver", "Temporarily ignoring session broadcast");
- return;
- }
-
List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
.getActivityList(info.getAppPackageName(), user);
if (activities == null || activities.isEmpty()) {
@@ -87,4 +89,68 @@
public static boolean isEnabled(Context context) {
return Utilities.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true);
}
+
+ public static void applyDefaultUserPrefs(final Context context) {
+ if (!Utilities.isAtLeastO()) {
+ return;
+ }
+ SharedPreferences prefs = Utilities.getPrefs(context);
+ if (prefs.getAll().isEmpty()) {
+ // This logic assumes that the code is the first thing that is executed (before any
+ // shared preference is written).
+ // TODO: Move this logic to DB upgrade once we have proper support for db downgrade
+ // If it is a fresh start, just apply the default value. We use prefs.isEmpty() to infer
+ // a fresh start as put preferences always contain some values corresponding to current
+ // grid.
+ prefs.edit().putBoolean(ADD_ICON_PREFERENCE_KEY, true).apply();
+ } else if (!prefs.contains(ADD_ICON_PREFERENCE_INITIALIZED_KEY)) {
+ new PrefInitTask(context).executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
+ }
+ }
+
+ private static class PrefInitTask extends AsyncTask<Void, Void, Void> {
+ private final Context mContext;
+
+ PrefInitTask(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ protected Void doInBackground(Void... voids) {
+ boolean addIconToHomeScreenEnabled = readValueFromMarketApp();
+ Utilities.getPrefs(mContext).edit()
+ .putBoolean(ADD_ICON_PREFERENCE_KEY, addIconToHomeScreenEnabled)
+ .putBoolean(ADD_ICON_PREFERENCE_INITIALIZED_KEY, true)
+ .apply();
+ return null;
+ }
+
+ public boolean readValueFromMarketApp() {
+ // Get the marget package
+ ResolveInfo ri = mContext.getPackageManager().resolveActivity(
+ new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_APP_MARKET),
+ PackageManager.MATCH_DEFAULT_ONLY | PackageManager.MATCH_SYSTEM_ONLY);
+ if (ri == null) {
+ return true;
+ }
+
+ Cursor c = null;
+ try {
+ c = mContext.getContentResolver().query(
+ Uri.parse("content://" + ri.activityInfo.packageName
+ + MARKER_PROVIDER_PREFIX),
+ null, null, null, null);
+ if (c.moveToNext()) {
+ return c.getInt(c.getColumnIndexOrThrow(Settings.NameValueTable.VALUE)) != 0;
+ }
+ } catch (Exception e) {
+ Log.d(TAG, "Error reading add to homescreen preference", e);
+ } finally {
+ if (c != null) {
+ c.close();
+ }
+ }
+ return true;
+ }
+ }
}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index f17d8de..e997a99 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -78,7 +78,8 @@
Rect sourceBounds, Bundle opts);
public abstract ApplicationInfo getApplicationInfo(
String packageName, int flags, UserHandle user);
- public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user);
+ public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user,
+ Rect sourceBounds, Bundle opts);
public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
public abstract boolean isPackageEnabledForProfile(String packageName, UserHandle user);
@@ -142,4 +143,8 @@
return null;
}
}
+
+ public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
+ showAppDetailsForProfile(component, user, null, null);
+ }
}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 58683db..647c315 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -95,8 +95,9 @@
}
@Override
- public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
- mLauncherApps.startAppDetailsActivity(component, user, null, null);
+ public void showAppDetailsForProfile(ComponentName component, UserHandle user,
+ Rect sourceBounds, Bundle opts) {
+ mLauncherApps.startAppDetailsActivity(component, user, sourceBounds, opts);
}
@Override
diff --git a/src/com/android/launcher3/graphics/LauncherIcons.java b/src/com/android/launcher3/graphics/LauncherIcons.java
index 746a639..53521f2 100644
--- a/src/com/android/launcher3/graphics/LauncherIcons.java
+++ b/src/com/android/launcher3/graphics/LauncherIcons.java
@@ -265,7 +265,7 @@
final int top = (textureHeight-height) / 2;
sOldBounds.set(icon.getBounds());
- if (icon instanceof AdaptiveIconDrawable) {
+ if (Utilities.isAtLeastO() && icon instanceof AdaptiveIconDrawable) {
int offset = Math.min(left, top);
int size = Math.max(width, height);
icon.setBounds(offset, offset, offset + size, offset + size);
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index 81460e4..f158f71 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -1,7 +1,9 @@
package com.android.launcher3.popup;
import android.content.Context;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
import android.view.View;
import com.android.launcher3.AbstractFloatingView;
@@ -82,7 +84,9 @@
return new View.OnClickListener() {
@Override
public void onClick(View view) {
- InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, null);
+ Rect sourceBounds = launcher.getViewBounds(view);
+ Bundle opts = launcher.getActivityLaunchOptions(view);
+ InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, null, sourceBounds, opts);
}
};
}
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index a423154..5fe00c2 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -133,10 +133,19 @@
}
}
- // If there is only one widget, we want to center it instead of left-align.
- WidgetsBottomSheet.LayoutParams params = (WidgetsBottomSheet.LayoutParams)
- widgetRow.getLayoutParams();
- params.gravity = widgets.size() == 1 ? Gravity.CENTER_HORIZONTAL : Gravity.START;
+ if (widgets.size() == 1) {
+ // If there is only one widget, we want to center it instead of left-align.
+ WidgetsBottomSheet.LayoutParams params = (WidgetsBottomSheet.LayoutParams)
+ widgetRow.getLayoutParams();
+ params.gravity = Gravity.CENTER_HORIZONTAL;
+ } else {
+ // Otherwise, add an empty view to the start as padding (but still scroll edge to edge).
+ View leftPaddingView = LayoutInflater.from(getContext()).inflate(
+ R.layout.widget_list_divider, widgetRow, false);
+ leftPaddingView.getLayoutParams().width = Utilities.pxFromDp(
+ 16, getResources().getDisplayMetrics());
+ widgetCells.addView(leftPaddingView, 0);
+ }
}
private void addDivider(ViewGroup parent) {