Merge "Fixing restored icons sometimes dissapers." into ub-now-master
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 49efc5d..f391a19 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -50,11 +50,13 @@
android:protectionLevel="signatureOrSystem"
android:label="@string/permlab_write_settings"
android:description="@string/permdesc_write_settings"/>
-
<permission
android:name="com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS"
android:protectionLevel="signature"
/>
+ <permission
+ android:name="com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST"
+ android:protectionLevel="signatureOrSystem" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
diff --git a/WallpaperPicker/src/com/android/launcher3/Partner.java b/WallpaperPicker/src/com/android/launcher3/Partner.java
index d3c825d..d172ce9 100644
--- a/WallpaperPicker/src/com/android/launcher3/Partner.java
+++ b/WallpaperPicker/src/com/android/launcher3/Partner.java
@@ -24,6 +24,8 @@
import android.content.res.Resources;
import android.util.Log;
+import java.io.File;
+
/**
* Utilities to discover and interact with partner customizations. There can
* only be one set of customizations on a device, and it must be bundled with
@@ -40,6 +42,9 @@
public static final String RESOURCE_WALLPAPERS = "partner_wallpapers";
public static final String RESOURCE_DEFAULT_LAYOUT = "partner_default_layout";
+ public static final String RESOURCE_DEFAULT_WALLPAPER_HIDDEN = "default_wallpapper_hidden";
+ public static final String RESOURCE_SYSTEM_WALLPAPER_DIR = "system_wallpaper_directory";
+
private static boolean sSearched = false;
private static Partner sPartner;
@@ -94,4 +99,16 @@
"xml", getPackageName());
return folder != 0;
}
+
+ public boolean hideDefaultWallpaper() {
+ int resId = getResources().getIdentifier(RESOURCE_DEFAULT_WALLPAPER_HIDDEN, "bool",
+ getPackageName());
+ return resId != 0 && getResources().getBoolean(resId);
+ }
+
+ public File getWallpaperDirectory() {
+ int resId = getResources().getIdentifier(RESOURCE_SYSTEM_WALLPAPER_DIR, "string",
+ getPackageName());
+ return (resId != 0) ? new File(getResources().getString(resId)) : null;
+ }
}
diff --git a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
index 44bfdf1..2bdf8f1 100644
--- a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
@@ -34,8 +34,6 @@
import android.widget.BaseAdapter;
import android.widget.ListAdapter;
-import com.android.photos.BitmapRegionTileSource;
-
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -49,39 +47,17 @@
Context mContext;
LayoutInflater mLayoutInflater;
- public static class SavedWallpaperTile extends WallpaperPickerActivity.WallpaperTileInfo {
+ public static class SavedWallpaperTile extends WallpaperPickerActivity.FileWallpaperInfo {
private int mDbId;
- private Drawable mThumb;
- public SavedWallpaperTile(int dbId, Drawable thumb) {
+ public SavedWallpaperTile(int dbId, File target, Drawable thumb) {
+ super(target, thumb);
mDbId = dbId;
- mThumb = thumb;
}
- @Override
- public void onClick(WallpaperPickerActivity a) {
- String imageFilename = a.getSavedImages().getImageFilename(mDbId);
- File file = new File(a.getFilesDir(), imageFilename);
- BitmapRegionTileSource.FilePathBitmapSource bitmapSource =
- new BitmapRegionTileSource.FilePathBitmapSource(file.getAbsolutePath(), 1024);
- a.setCropViewTileSource(bitmapSource, false, true, null);
- }
- @Override
- public void onSave(WallpaperPickerActivity a) {
- boolean finishActivityWhenDone = true;
- String imageFilename = a.getSavedImages().getImageFilename(mDbId);
- a.setWallpaper(imageFilename, finishActivityWhenDone);
- }
+
@Override
public void onDelete(WallpaperPickerActivity a) {
a.getSavedImages().deleteImage(mDbId);
}
- @Override
- public boolean isSelectable() {
- return true;
- }
- @Override
- public boolean isNamelessWallpaper() {
- return true;
- }
}
public SavedWallpaperImages(Activity context) {
@@ -98,7 +74,8 @@
SQLiteDatabase db = mDb.getReadableDatabase();
Cursor result = db.query(ImageDb.TABLE_NAME,
new String[] { ImageDb.COLUMN_ID,
- ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME }, // cols to return
+ ImageDb.COLUMN_IMAGE_THUMBNAIL_FILENAME,
+ ImageDb.COLUMN_IMAGE_FILENAME}, // cols to return
null, // select query
null, // args to select query
null,
@@ -112,7 +89,9 @@
Bitmap thumb = BitmapFactory.decodeFile(file.getAbsolutePath());
if (thumb != null) {
- mImages.add(new SavedWallpaperTile(result.getInt(0), new BitmapDrawable(thumb)));
+ mImages.add(new SavedWallpaperTile(result.getInt(0),
+ new File(mContext.getFilesDir(), result.getString(2)),
+ new BitmapDrawable(thumb)));
}
}
result.close();
@@ -136,15 +115,7 @@
Log.e(TAG, "Error decoding thumbnail for wallpaper #" + position);
}
return WallpaperPickerActivity.createImageTileView(
- mLayoutInflater, position, convertView, parent, thumbDrawable);
- }
-
- public String getImageFilename(int id) {
- Pair<String, String> filenames = getImageFilenames(id);
- if (filenames != null) {
- return filenames.second;
- }
- return null;
+ mLayoutInflater, convertView, parent, thumbDrawable);
}
private Pair<String, String> getImageFilenames(int id) {
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 8652d85..d5c7cd9 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -308,10 +308,10 @@
return 0;
}
- protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
- int rotation = getRotationFromExif(filePath);
+ protected void setWallpaper(Uri uri, final boolean finishActivityWhenDone) {
+ int rotation = getRotationFromExif(this, uri);
BitmapCropTask cropTask = new BitmapCropTask(
- this, filePath, null, rotation, 0, 0, true, false, null);
+ this, uri, null, rotation, 0, 0, true, false, null);
final Point bounds = cropTask.getImageBounds();
Runnable onEndCrop = new Runnable() {
public void run() {
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index b5e34cf..95b19ce 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -17,6 +17,7 @@
package com.android.launcher3;
import android.animation.LayoutTransition;
+import android.annotation.TargetApi;
import android.app.ActionBar;
import android.app.Activity;
import android.app.WallpaperInfo;
@@ -61,12 +62,12 @@
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
+import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.ListAdapter;
import android.widget.Toast;
import com.android.photos.BitmapRegionTileSource;
@@ -109,6 +110,8 @@
public static abstract class WallpaperTileInfo {
protected View mView;
+ public Drawable mThumb;
+
public void setView(View v) {
mView = v;
}
@@ -194,10 +197,36 @@
}
}
+ public static class FileWallpaperInfo extends WallpaperTileInfo {
+ private File mFile;
+
+ public FileWallpaperInfo(File target, Drawable thumb) {
+ mFile = target;
+ mThumb = thumb;
+ }
+ @Override
+ public void onClick(WallpaperPickerActivity a) {
+ BitmapRegionTileSource.UriBitmapSource bitmapSource =
+ new BitmapRegionTileSource.UriBitmapSource(a, Uri.fromFile(mFile), 1024);
+ a.setCropViewTileSource(bitmapSource, false, true, null);
+ }
+ @Override
+ public void onSave(WallpaperPickerActivity a) {
+ a.setWallpaper(Uri.fromFile(mFile), true);
+ }
+ @Override
+ public boolean isSelectable() {
+ return true;
+ }
+ @Override
+ public boolean isNamelessWallpaper() {
+ return true;
+ }
+ }
+
public static class ResourceWallpaperInfo extends WallpaperTileInfo {
private Resources mResources;
private int mResId;
- private Drawable mThumb;
public ResourceWallpaperInfo(Resources res, int resId, Drawable thumb) {
mResources = res;
@@ -237,8 +266,8 @@
}
}
+ @TargetApi(Build.VERSION_CODES.KITKAT)
public static class DefaultWallpaperInfo extends WallpaperTileInfo {
- public Drawable mThumb;
public DefaultWallpaperInfo(Drawable thumb) {
mThumb = thumb;
}
@@ -431,9 +460,9 @@
};
// Populate the built-in wallpapers
- ArrayList<ResourceWallpaperInfo> wallpapers = findBundledWallpapers();
+ ArrayList<WallpaperTileInfo> wallpapers = findBundledWallpapers();
mWallpapersView = (LinearLayout) findViewById(R.id.wallpaper_list);
- BuiltInWallpapersAdapter ia = new BuiltInWallpapersAdapter(this, wallpapers);
+ SimpleWallpapersAdapter ia = new SimpleWallpapersAdapter(this, wallpapers);
populateWallpapersFromAdapter(mWallpapersView, ia, false);
// Populate the saved wallpapers
@@ -484,20 +513,6 @@
pickImageInfo.setView(pickImageTile);
pickImageTile.setOnClickListener(mThumbnailOnClickListener);
- // Add a tile for the default wallpaper
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
- DefaultWallpaperInfo defaultWallpaperInfo = getDefaultWallpaper();
- if (defaultWallpaperInfo != null) {
- FrameLayout defaultWallpaperTile = (FrameLayout) createImageTileView(
- getLayoutInflater(), 0, null, mWallpapersView, defaultWallpaperInfo.mThumb);
- setWallpaperItemPaddingToZero(defaultWallpaperTile);
- defaultWallpaperTile.setTag(defaultWallpaperInfo);
- mWallpapersView.addView(defaultWallpaperTile, 0);
- defaultWallpaperTile.setOnClickListener(mThumbnailOnClickListener);
- defaultWallpaperInfo.setView(defaultWallpaperTile);
- }
- }
-
// Select the first item; wait for a layout pass so that we initialize the dimensions of
// cropView or the defaultWallpaperView first
mCropView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@@ -825,12 +840,26 @@
final Context context = this;
new AsyncTask<Void, Bitmap, Bitmap>() {
protected Bitmap doInBackground(Void...args) {
- int rotation = WallpaperCropActivity.getRotationFromExif(context, uri);
- return createThumbnail(defaultSize, context, uri, null, null, 0, rotation, false);
-
+ try {
+ int rotation = WallpaperCropActivity.getRotationFromExif(context, uri);
+ return createThumbnail(defaultSize, context, uri, null, null, 0, rotation, false);
+ } catch (SecurityException securityException) {
+ if (isDestroyed()) {
+ // Temporarily granted permissions are revoked when the activity
+ // finishes, potentially resulting in a SecurityException here.
+ // Even though {@link #isDestroyed} might also return true in different
+ // situations where the configuration changes, we are fine with
+ // catching these cases here as well.
+ cancel(false);
+ } else {
+ // otherwise it had a different cause and we throw it further
+ throw securityException;
+ }
+ return null;
+ }
}
protected void onPostExecute(Bitmap thumb) {
- if (thumb != null) {
+ if (!isCancelled() && thumb != null) {
image.setImageBitmap(thumb);
Drawable thumbDrawable = image.getDrawable();
thumbDrawable.setDither(true);
@@ -889,9 +918,9 @@
v.setOnLongClickListener(mLongClickListener);
}
- private ArrayList<ResourceWallpaperInfo> findBundledWallpapers() {
+ private ArrayList<WallpaperTileInfo> findBundledWallpapers() {
final PackageManager pm = getPackageManager();
- final ArrayList<ResourceWallpaperInfo> bundled = new ArrayList<ResourceWallpaperInfo>(24);
+ final ArrayList<WallpaperTileInfo> bundled = new ArrayList<WallpaperTileInfo>(24);
Partner partner = Partner.get(pm);
if (partner != null) {
@@ -901,6 +930,34 @@
if (resId != 0) {
addWallpapers(bundled, partnerRes, partner.getPackageName(), resId);
}
+
+ // Add system wallpapers
+ File systemDir = partner.getWallpaperDirectory();
+ if (systemDir != null && systemDir.isDirectory()) {
+ for (File file : systemDir.listFiles()) {
+ if (!file.isFile()) {
+ continue;
+ }
+ String name = file.getName();
+ int dotPos = name.lastIndexOf('.');
+ String extension = "";
+ if (dotPos >= -1) {
+ extension = name.substring(dotPos);
+ name = name.substring(0, dotPos);
+ }
+
+ if (name.endsWith("_small")) {
+ // it is a thumbnail
+ continue;
+ }
+
+ File thumbnail = new File(systemDir, name + "_small" + extension);
+ Bitmap thumb = BitmapFactory.decodeFile(thumbnail.getAbsolutePath());
+ if (thumb != null) {
+ bundled.add(new FileWallpaperInfo(file, new BitmapDrawable(thumb)));
+ }
+ }
+ }
}
Pair<ApplicationInfo, Integer> r = getWallpaperArrayResourceId();
@@ -912,9 +969,12 @@
}
}
- // Add an entry for the default wallpaper (stored in system resources)
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
- ResourceWallpaperInfo defaultWallpaperInfo = getPreKKDefaultWallpaperInfo();
+ if (partner == null || !partner.hideDefaultWallpaper()) {
+ // Add an entry for the default wallpaper (stored in system resources)
+ WallpaperTileInfo defaultWallpaperInfo =
+ (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT)
+ ? getPreKKDefaultWallpaperInfo()
+ : getDefaultWallpaper();
if (defaultWallpaperInfo != null) {
bundled.add(0, defaultWallpaperInfo);
}
@@ -963,6 +1023,7 @@
return null;
}
+ @TargetApi(Build.VERSION_CODES.KITKAT)
private DefaultWallpaperInfo getDefaultWallpaper() {
File defaultThumbFile = new File(getFilesDir(), DEFAULT_WALLPAPER_THUMBNAIL_FILENAME);
Bitmap thumb = null;
@@ -1011,7 +1072,7 @@
}
}
- private void addWallpapers(ArrayList<ResourceWallpaperInfo> known, Resources res,
+ private void addWallpapers(ArrayList<WallpaperTileInfo> known, Resources res,
String packageName, int listResId) {
final String[] extras = res.getStringArray(listResId);
for (String extra : extras) {
@@ -1058,37 +1119,24 @@
}
}
- private static class BuiltInWallpapersAdapter extends BaseAdapter implements ListAdapter {
- private LayoutInflater mLayoutInflater;
- private ArrayList<ResourceWallpaperInfo> mWallpapers;
+ private static class SimpleWallpapersAdapter extends ArrayAdapter<WallpaperTileInfo> {
+ private final LayoutInflater mLayoutInflater;
- BuiltInWallpapersAdapter(Activity activity, ArrayList<ResourceWallpaperInfo> wallpapers) {
+ SimpleWallpapersAdapter(Activity activity, ArrayList<WallpaperTileInfo> wallpapers) {
+ super(activity, R.layout.wallpaper_picker_item, wallpapers);
mLayoutInflater = activity.getLayoutInflater();
- mWallpapers = wallpapers;
- }
-
- public int getCount() {
- return mWallpapers.size();
- }
-
- public ResourceWallpaperInfo getItem(int position) {
- return mWallpapers.get(position);
- }
-
- public long getItemId(int position) {
- return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
- Drawable thumb = mWallpapers.get(position).mThumb;
+ Drawable thumb = getItem(position).mThumb;
if (thumb == null) {
Log.e(TAG, "Error decoding thumbnail for wallpaper #" + position);
}
- return createImageTileView(mLayoutInflater, position, convertView, parent, thumb);
+ return createImageTileView(mLayoutInflater, convertView, parent, thumb);
}
}
- public static View createImageTileView(LayoutInflater layoutInflater, int position,
+ public static View createImageTileView(LayoutInflater layoutInflater,
View convertView, ViewGroup parent, Drawable thumb) {
View view;
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ee1be6..780dcd2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -27,6 +27,9 @@
<!-- Permission to receive the com.android.launcher3.action.LAUNCH intent -->
<string name="receive_launch_broadcasts_permission" translatable="false">com.android.launcher3.permission.RECEIVE_LAUNCH_BROADCASTS</string>
+ <!-- Permission to receive the com.android.launcher3.action.FIRST_LOAD_COMPLETE intent -->
+ <string name="receive_first_load_broadcast_permission" translatable="false">com.android.launcher3.permission.RECEIVE_FIRST_LOAD_BROADCAST</string>
+
<!-- Application name -->
<string name="application_name">Launcher3</string>
<!-- Accessibility-facing application name -->
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
index 334d8b6..283f4ed 100644
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher3/AppsCustomizeTabHost.java
@@ -150,7 +150,7 @@
}
@Override
- public View getContent() {
+ public ViewGroup getContent() {
return mPagedView;
}
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 8ca8d91..1073764 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -30,8 +30,6 @@
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -169,8 +167,6 @@
private Rect mTempRect = new Rect();
- private final static PorterDuffXfermode sAddBlendMode =
- new PorterDuffXfermode(PorterDuff.Mode.ADD);
private final static Paint sPaint = new Paint();
public CellLayout(Context context) {
@@ -579,7 +575,15 @@
}
public void restoreInstanceState(SparseArray<Parcelable> states) {
- dispatchRestoreInstanceState(states);
+ try {
+ dispatchRestoreInstanceState(states);
+ } catch (IllegalArgumentException ex) {
+ if (LauncherAppState.isDogfoodBuild()) {
+ throw ex;
+ }
+ // Mismatched viewId / viewType preventing restore. Skip restore on production builds.
+ Log.e(TAG, "Ignoring an error while restoring a view instance state", ex);
+ }
}
@Override
@@ -700,9 +704,6 @@
// First we clear the tag to ensure that on every touch down we start with a fresh slate,
// even in the case where we return early. Not clearing here was causing bugs whereby on
// long-press we'd end up picking up an item from a previous drag operation.
- final int action = ev.getAction();
-
-
if (mInterceptTouchListener != null && mInterceptTouchListener.onTouch(this, ev)) {
return true;
}
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index bb62bac..b1250ce 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -71,20 +71,20 @@
/**
* Private helper to get the parent TabHost in the view hiearchy.
*/
- private static TabHost findTabHostParent(View v) {
+ private static AppsCustomizeTabHost findTabHostParent(View v) {
ViewParent p = v.getParent();
- while (p != null && !(p instanceof TabHost)) {
+ while (p != null && !(p instanceof AppsCustomizeTabHost)) {
p = p.getParent();
}
- return (TabHost) p;
+ return (AppsCustomizeTabHost) p;
}
/**
* Handles key events in a AppsCustomize tab between the last tab view and the shop button.
*/
static boolean handleAppsCustomizeTabKeyEvent(View v, int keyCode, KeyEvent e) {
- final TabHost tabHost = findTabHostParent(v);
- final ViewGroup contents = tabHost.getTabContentView();
+ final AppsCustomizeTabHost tabHost = findTabHostParent(v);
+ final ViewGroup contents = tabHost.getContent();
final View shop = tabHost.findViewById(R.id.market_button);
final int action = e.getAction();
@@ -134,8 +134,7 @@
final PagedViewGridLayout parent = (PagedViewGridLayout) w.getParent();
final PagedView container = (PagedView) parent.getParent();
- final TabHost tabHost = findTabHostParent(container);
- final TabWidget tabs = tabHost.getTabWidget();
+ final AppsCustomizeTabHost tabHost = findTabHostParent(container);
final int widgetIndex = parent.indexOfChild(w);
final int widgetCount = parent.getChildCount();
final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parent));
@@ -194,8 +193,6 @@
int newWidgetIndex = ((y - 1) * cellCountX) + x;
child = parent.getChildAt(newWidgetIndex);
if (child != null) child.requestFocus();
- } else {
- tabs.requestFocus();
}
}
wasHandled = true;
@@ -294,8 +291,7 @@
// Note we have an extra parent because of the
// PagedViewCellLayout/PagedViewCellLayoutChildren relationship
final PagedView container = (PagedView) parentLayout.getParent();
- final TabHost tabHost = findTabHostParent(container);
- final TabWidget tabs = tabHost.getTabWidget();
+ final AppsCustomizeTabHost tabHost = findTabHostParent(container);
final int iconIndex = itemContainer.indexOfChild(v);
final int itemCount = itemContainer.getChildCount();
final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parentLayout));
@@ -354,8 +350,6 @@
if (y > 0) {
int newiconIndex = ((y - 1) * countX) + x;
itemContainer.getChildAt(newiconIndex).requestFocus();
- } else {
- tabs.requestFocus();
}
}
wasHandled = true;
@@ -439,8 +433,8 @@
if (!LauncherAppState.getInstance().isScreenLarge()) return false;
final FocusOnlyTabWidget parent = (FocusOnlyTabWidget) v.getParent();
- final TabHost tabHost = findTabHostParent(parent);
- final ViewGroup contents = tabHost.getTabContentView();
+ final AppsCustomizeTabHost tabHost = findTabHostParent(parent);
+ final ViewGroup contents = tabHost.getContent();
final int tabCount = parent.getTabCount();
final int tabIndex = parent.getChildTabIndex(v);
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 7d8628d..221df58 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -64,8 +64,8 @@
private static class CacheEntry {
public Bitmap icon;
- public String title;
- public String contentDescription;
+ public CharSequence title;
+ public CharSequence contentDescription;
}
private static class CacheKey {
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index fe03017..c726fb4 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -110,7 +110,7 @@
/**
* Content description of the item.
*/
- String contentDescription;
+ CharSequence contentDescription;
/**
* The position of the item in a drag-and-drop operation.
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 65f9cbe..3cbe1c1 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -209,6 +209,10 @@
static final String INTRO_SCREEN_DISMISSED = "launcher.intro_screen_dismissed";
static final String FIRST_RUN_ACTIVITY_DISPLAYED = "launcher.first_run_activity_displayed";
+ static final String FIRST_LOAD_COMPLETE = "launcher.first_load_complete";
+ static final String ACTION_FIRST_LOAD_COMPLETE =
+ "com.android.launcher3.action.FIRST_LOAD_COMPLETE";
+
private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =
"com.android.launcher.toolbar_search_icon";
@@ -4454,6 +4458,7 @@
}
setWorkspaceLoading(false);
+ sendLoadingCompleteBroadcastIfNecessary();
// If we received the result of any pending adds while the loader was running (e.g. the
// widget configuration forced an orientation change), process them now.
@@ -4478,6 +4483,18 @@
}
}
+ private void sendLoadingCompleteBroadcastIfNecessary() {
+ if (!mSharedPrefs.getBoolean(FIRST_LOAD_COMPLETE, false)) {
+ String permission =
+ getResources().getString(R.string.receive_first_load_broadcast_permission);
+ Intent intent = new Intent(ACTION_FIRST_LOAD_COMPLETE);
+ sendBroadcast(intent, permission);
+ SharedPreferences.Editor editor = mSharedPrefs.edit();
+ editor.putBoolean(FIRST_LOAD_COMPLETE, true);
+ editor.apply();
+ }
+ }
+
public boolean isAllAppsButtonRank(int rank) {
if (mHotseat != null) {
return mHotseat.isAllAppsButtonRank(rank);
@@ -4912,7 +4929,7 @@
public ItemInfo createShortcutDragInfo(Intent shortcutIntent, CharSequence caption,
Bitmap icon, UserHandleCompat user) {
UserManagerCompat userManager = UserManagerCompat.getInstance(this);
- String contentDescription = userManager.getBadgedLabelForUser(caption.toString(), user);
+ CharSequence contentDescription = userManager.getBadgedLabelForUser(caption, user);
return new ShortcutInfo(shortcutIntent, caption, contentDescription, icon, user);
}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 2256179..ac4a206 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -99,6 +99,8 @@
private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE =
"com.android.launcher.action.APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE";
+ private static final String URI_PARAM_IS_EXTERNAL_ADD = "isExternalAdd";
+
private LauncherProviderChangeListener mListener;
/**
@@ -175,6 +177,14 @@
public Uri insert(Uri uri, ContentValues initialValues) {
SqlArguments args = new SqlArguments(uri);
+ // In very limited cases, we support system|signature permission apps to add to the db
+ String externalAdd = uri.getQueryParameter(URI_PARAM_IS_EXTERNAL_ADD);
+ if (externalAdd != null && "true".equals(externalAdd)) {
+ if (!mOpenHelper.initializeExternalAdd(initialValues)) {
+ return null;
+ }
+ }
+
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
addModifiedTime(initialValues);
final long rowId = dbInsertAndCheck(mOpenHelper, db, args.table, null, initialValues);
@@ -186,6 +196,7 @@
return uri;
}
+
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
SqlArguments args = new SqlArguments(uri);
@@ -1245,6 +1256,38 @@
if (LOGD) Log.d(TAG, "mMaxItemId: " + mMaxItemId);
}
+ private boolean initializeExternalAdd(ContentValues values) {
+ // 1. Ensure that externally added items have a valid item id
+ long id = generateNewItemId();
+ values.put(LauncherSettings.Favorites._ID, id);
+
+ // 2. In the case of an app widget, and if no app widget id is specified, we
+ // attempt allocate and bind the widget.
+ Integer itemType = values.getAsInteger(LauncherSettings.Favorites.ITEM_TYPE);
+ if (itemType != null &&
+ itemType.intValue() == LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET &&
+ !values.containsKey(LauncherSettings.Favorites.APPWIDGET_ID)) {
+
+ final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
+ ComponentName cn = ComponentName.unflattenFromString(
+ values.getAsString(Favorites.APPWIDGET_PROVIDER));
+
+ if (cn != null) {
+ try {
+ int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
+ values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId);
+ if (appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,cn)) {
+ return true;
+ }
+ } catch (RuntimeException e) {
+ Log.e(TAG, "Failed to initialize external widget", e);
+ }
+ }
+ return false;
+ }
+ return true;
+ }
+
private static final void beginDocument(XmlPullParser parser, String firstElementName)
throws XmlPullParserException, IOException {
int type;
@@ -1752,6 +1795,7 @@
return false;
}
+
private boolean addAppWidget(SQLiteDatabase db, ContentValues values, ComponentName cn,
Bundle extras) {
boolean allocatedAppWidgets = false;
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 087c3c5..dc019b2 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -126,7 +126,7 @@
}
}
- ShortcutInfo(Intent intent, CharSequence title, String contentDescription,
+ ShortcutInfo(Intent intent, CharSequence title, CharSequence contentDescription,
Bitmap icon, UserHandleCompat user) {
this();
this.intent = intent;
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index c10a743..8effb81 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -41,5 +41,5 @@
public abstract long getSerialNumberForUser(UserHandleCompat user);
public abstract UserHandleCompat getUserForSerialNumber(long serialNumber);
public abstract Drawable getBadgedDrawableForUser(Drawable unbadged, UserHandleCompat user);
- public abstract String getBadgedLabelForUser(String label, UserHandleCompat user);
+ public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user);
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatV16.java b/src/com/android/launcher3/compat/UserManagerCompatV16.java
index 03dd097..32f972e 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatV16.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatV16.java
@@ -45,7 +45,7 @@
return 0;
}
- public String getBadgedLabelForUser(String label, UserHandleCompat user) {
+ public CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user) {
return label;
}
}
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index e071a8f..da7b116 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -49,11 +49,12 @@
return mUserManager.getBadgedDrawableForUser(unbadged, user.getUser());
}
- public String getBadgedLabelForUser(String label, UserHandleCompat user) {
+ public CharSequence getBadgedLabelForUser(CharSequence label, UserHandleCompat user) {
if (user == null) {
return label;
}
- return mUserManager.getBadgedLabelForUser(label, user.getUser());
+ // TODO Remove casts when API has made it from lmp-dev -> sdk
+ return (CharSequence) mUserManager.getBadgedLabelForUser((String) label, user.getUser());
}
}