Merge "Talkback: return correct row index inside AllApps b/27108673 b/26546781" into ub-launcher3-burnaby-nyc
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 990bde0..918ae52 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -127,13 +127,6 @@
android:process=":settings_process">
</activity>
- <receiver
- android:name="com.android.launcher3.WallpaperChangedReceiver">
- <intent-filter>
- <action android:name="android.intent.action.WALLPAPER_CHANGED" />
- </intent-filter>
- </receiver>
-
<!-- Intent received used to install shortcuts from other applications -->
<receiver
android:name="com.android.launcher3.InstallShortcutReceiver"
diff --git a/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml b/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml
index 8e349b7..2b39b09 100644
--- a/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml
+++ b/WallpaperPicker/res/layout/actionbar_set_wallpaper.xml
@@ -28,5 +28,6 @@
android:drawableLeft="@drawable/ic_actionbar_accept"
android:drawablePadding="8dp"
android:gravity="start|center_vertical"
- android:text="@string/wallpaper_instructions">
+ android:text="@string/wallpaper_instructions"
+ android:enabled="false">
</com.android.launcher3.AlphaDisableableButton>
diff --git a/WallpaperPicker/res/values/arrays.xml b/WallpaperPicker/res/values/arrays.xml
new file mode 100644
index 0000000..5c10b98
--- /dev/null
+++ b/WallpaperPicker/res/values/arrays.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 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.
+-->
+<resources>
+ <string-array name="which_wallpaper_options">
+ <item>@string/which_wallpaper_option_home_screen</item>
+ <item>@string/which_wallpaper_option_lock_screen</item>
+ <item>@string/which_wallpaper_option_home_screen_and_lock_screen</item>
+ </string-array>
+</resources>
\ No newline at end of file
diff --git a/WallpaperPicker/res/values/strings.xml b/WallpaperPicker/res/values/strings.xml
index 2bfd476..aef6a1a 100644
--- a/WallpaperPicker/res/values/strings.xml
+++ b/WallpaperPicker/res/values/strings.xml
@@ -53,4 +53,11 @@
<string name="pick_wallpaper">Wallpapers</string>
<!-- Title of activity for cropping wallpapers -->
<string name="crop_wallpaper">Crop wallpaper</string>
+
+ <!-- Option for setting the wallpaper only on the home screen. -->
+ <string name="which_wallpaper_option_home_screen">Home screen</string>
+ <!-- Option for setting the wallpaper only on the lock screen. -->
+ <string name="which_wallpaper_option_lock_screen">Lock screen</string>
+ <!-- Option for setting the wallpaper on both the home screen and lock screen. -->
+ <string name="which_wallpaper_option_home_screen_and_lock_screen">Home screen and lock screen</string>
</resources>
diff --git a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
index 8b51447..027e947 100644
--- a/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
+++ b/WallpaperPicker/src/com/android/gallery3d/common/BitmapCropTask.java
@@ -33,7 +33,9 @@
import android.util.Log;
import android.widget.Toast;
+import com.android.launcher3.NycWallpaperUtils;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
@@ -42,7 +44,7 @@
import java.io.IOException;
import java.io.InputStream;
-public class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
+public class BitmapCropTask extends AsyncTask<Integer, Void, Boolean> {
public interface OnBitmapCroppedHandler {
public void onBitmapCropped(byte[] imageBytes);
@@ -71,15 +73,6 @@
BitmapCropTask.OnBitmapCroppedHandler mOnBitmapCroppedHandler;
boolean mNoCrop;
- public BitmapCropTask(Context c, String filePath,
- RectF cropBounds, int rotation, int outWidth, int outHeight,
- boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
- mContext = c;
- mInFilePath = filePath;
- init(cropBounds, rotation,
- outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndCropHandler);
- }
-
public BitmapCropTask(byte[] imageBytes,
RectF cropBounds, int rotation, int outWidth, int outHeight,
boolean setWallpaper, boolean saveCroppedBitmap, OnEndCropHandler onEndCropHandler) {
@@ -175,7 +168,7 @@
public Bitmap getCroppedBitmap() {
return mCroppedBitmap;
}
- public boolean cropBitmap() {
+ public boolean cropBitmap(int whichWallpaper) {
boolean failure = false;
@@ -189,7 +182,11 @@
try {
InputStream is = regenerateInputStream();
if (is != null) {
- wallpaperManager.setStream(is);
+ if (!Utilities.isNycOrAbove()) {
+ wallpaperManager.setStream(is);
+ } else {
+ NycWallpaperUtils.setStream(mContext, is, null, true, whichWallpaper);
+ }
Utils.closeSilently(is);
}
} catch (IOException e) {
@@ -375,7 +372,13 @@
if (mSetWallpaper && wallpaperManager != null) {
try {
byte[] outByteArray = tmpOut.toByteArray();
- wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
+ if (!Utilities.isNycOrAbove()) {
+ wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
+ } else {
+ NycWallpaperUtils.setStream(mContext,
+ new ByteArrayInputStream(outByteArray), null, true,
+ whichWallpaper);
+ }
if (mOnBitmapCroppedHandler != null) {
mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
}
@@ -393,8 +396,8 @@
}
@Override
- protected Boolean doInBackground(Void... params) {
- return cropBitmap();
+ protected Boolean doInBackground(Integer... params) {
+ return cropBitmap(params.length == 0 ? NycWallpaperUtils.FLAG_SET_SYSTEM : params[0]);
}
@Override
diff --git a/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java b/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java
new file mode 100644
index 0000000..abac830
--- /dev/null
+++ b/WallpaperPicker/src/com/android/launcher3/NycWallpaperUtils.java
@@ -0,0 +1,79 @@
+package com.android.launcher3;
+
+import android.app.AlertDialog;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Rect;
+import android.os.AsyncTask;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Utility class used to help set lockscreen wallpapers on N+.
+ */
+public class NycWallpaperUtils {
+ public static final int FLAG_SET_SYSTEM = 1 << 0; // TODO: use WallpaperManager.FLAG_SET_SYSTEM
+ public static final int FLAG_SET_LOCK = 1 << 1; // TODO: use WallpaperManager.FLAG_SET_LOCK
+
+ /**
+ * Calls cropTask.execute(), once the user has selected which wallpaper to set. On pre-N
+ * devices, the prompt is not displayed since there is no API to set the lockscreen wallpaper.
+ */
+ public static void executeCropTaskAfterPrompt(
+ Context context, final AsyncTask<Integer, ?, ?> cropTask,
+ DialogInterface.OnCancelListener onCancelListener) {
+ if (Utilities.isNycOrAbove()) {
+ new AlertDialog.Builder(context)
+ .setTitle(R.string.wallpaper_instructions)
+ .setItems(R.array.which_wallpaper_options, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int selectedItemIndex) {
+ int whichWallpaper;
+ if (selectedItemIndex == 0) {
+ whichWallpaper = FLAG_SET_SYSTEM;
+ } else if (selectedItemIndex == 1) {
+ whichWallpaper = FLAG_SET_LOCK;
+ } else {
+ whichWallpaper = FLAG_SET_SYSTEM | FLAG_SET_LOCK;
+ }
+ cropTask.execute(whichWallpaper);
+ }
+ })
+ .setOnCancelListener(onCancelListener)
+ .show();
+ } else {
+ cropTask.execute(FLAG_SET_SYSTEM);
+ }
+ }
+
+ public static void setStream(Context context, final InputStream data, Rect visibleCropHint,
+ boolean allowBackup, int whichWallpaper) throws IOException {
+ WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
+ try {
+ // TODO: use mWallpaperManager.setStream(data, visibleCropHint, allowBackup, which)
+ // without needing reflection.
+ Method setStream = WallpaperManager.class.getMethod("setStream", InputStream.class,
+ Rect.class, boolean.class, int.class);
+ setStream.invoke(wallpaperManager, data, visibleCropHint, allowBackup, whichWallpaper);
+ } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
+ // Fall back to previous implementation (set system)
+ wallpaperManager.setStream(data);
+ }
+ }
+
+ public static void clear(Context context, int whichWallpaper) throws IOException {
+ WallpaperManager wallpaperManager = WallpaperManager.getInstance(context);
+ try {
+ // TODO: use mWallpaperManager.clear(whichWallpaper) without needing reflection.
+ Method clear = WallpaperManager.class.getMethod("clear", int.class);
+ clear.invoke(wallpaperManager, whichWallpaper);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ // Fall back to previous implementation (clear system)
+ wallpaperManager.clear();
+ }
+ }
+}
\ No newline at end of file
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index 75bdb8a..364cdb8 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -21,6 +21,7 @@
import android.app.Activity;
import android.app.WallpaperManager;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@@ -86,6 +87,18 @@
@Thunk Set<Bitmap> mReusableBitmaps =
Collections.newSetFromMap(new WeakHashMap<Bitmap, Boolean>());
+ private final DialogInterface.OnCancelListener mOnDialogCancelListener =
+ new DialogInterface.OnCancelListener() {
+ @Override
+ public void onCancel(DialogInterface dialog) {
+ getActionBar().show();
+ View wallpaperStrip = findViewById(R.id.wallpaper_strip);
+ if (wallpaperStrip != null) {
+ wallpaperStrip.setVisibility(View.VISIBLE);
+ }
+ }
+ };
+
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -242,6 +255,10 @@
}
}
+ public DialogInterface.OnCancelListener getOnDialogCancelListener() {
+ return mOnDialogCancelListener;
+ }
+
protected void onLoadRequestComplete(LoadRequest req, boolean success) {
mCurrentLoadRequest = null;
if (success) {
@@ -326,7 +343,7 @@
};
cropTask.setOnEndRunnable(onEndCrop);
cropTask.setNoCrop(true);
- cropTask.execute();
+ NycWallpaperUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener());
}
protected void cropImageAndSetWallpaper(Resources res, int resId,
@@ -335,8 +352,7 @@
// this device
int rotation = BitmapUtils.getRotationFromExif(res, resId);
Point inSize = mCropView.getSourceDimensions();
- Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(),
- getWindowManager());
+ Point outSize = WallpaperUtils.getDefaultWallpaperSize(getResources(), getWindowManager());
RectF crop = Utils.getMaxCropRect(
inSize.x, inSize.y, outSize.x, outSize.y, false);
BitmapCropTask.OnEndCropHandler onEndCrop = new BitmapCropTask.OnEndCropHandler() {
@@ -355,7 +371,7 @@
};
BitmapCropTask cropTask = new BitmapCropTask(getContext(), res, resId,
crop, rotation, outSize.x, outSize.y, true, false, onEndCrop);
- cropTask.execute();
+ NycWallpaperUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener());
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 4998bf4..5c6113f 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -44,6 +44,7 @@
import android.os.Bundle;
import android.os.Process;
import android.provider.MediaStore;
+import android.support.annotation.NonNull;
import android.util.Log;
import android.util.Pair;
import android.view.ActionMode;
@@ -77,13 +78,15 @@
import com.android.photos.BitmapRegionTileSource;
import com.android.photos.BitmapRegionTileSource.BitmapSource;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
public class WallpaperPickerActivity extends WallpaperCropActivity {
- static final String TAG = "Launcher.WallpaperPickerActivity";
+ static final String TAG = "WallpaperPickerActivity";
public static final int IMAGE_PICK = 5;
public static final int PICK_WALLPAPER_THIRD_PARTY_ACTIVITY = 6;
@@ -317,15 +320,75 @@
a.onLoadRequestComplete(req, true);
}
@Override
- public void onSave(WallpaperPickerActivity a) {
- try {
- WallpaperManager.getInstance(a.getContext()).clear();
- a.setResult(Activity.RESULT_OK);
- } catch (IOException e) {
- Log.w("Setting wallpaper to default threw exception", e);
+ public void onSave(final WallpaperPickerActivity a) {
+ if (!Utilities.isNycOrAbove()) {
+ try {
+ WallpaperManager.getInstance(a.getContext()).clear();
+ a.setResult(Activity.RESULT_OK);
+ } catch (IOException e) {
+ Log.e(TAG, "Setting wallpaper to default threw exception", e);
+ } catch (SecurityException e) {
+ Log.w(TAG, "Setting wallpaper to default threw exception", e);
+ // In this case, clearing worked; the exception was thrown afterwards.
+ a.setResult(Activity.RESULT_OK);
+ }
+ a.finish();
+ } else {
+ BitmapCropTask.OnEndCropHandler onEndCropHandler
+ = new BitmapCropTask.OnEndCropHandler() {
+ @Override
+ public void run(boolean cropSucceeded) {
+ if (cropSucceeded) {
+ a.setResult(Activity.RESULT_OK);
+ }
+ a.finish();
+ }
+ };
+ BitmapCropTask setWallpaperTask = getDefaultWallpaperCropTask(a, onEndCropHandler);
+
+ NycWallpaperUtils.executeCropTaskAfterPrompt(a, setWallpaperTask,
+ a.getOnDialogCancelListener());
}
- a.finish();
}
+
+ @NonNull
+ private BitmapCropTask getDefaultWallpaperCropTask(final WallpaperPickerActivity a,
+ final BitmapCropTask.OnEndCropHandler onEndCropHandler) {
+ return new BitmapCropTask(a, null, null, -1, -1, -1,
+ true, false, onEndCropHandler) {
+ @Override
+ protected Boolean doInBackground(Integer... params) {
+ int whichWallpaper = params[0];
+ boolean succeeded = true;
+ try {
+ if (whichWallpaper == NycWallpaperUtils.FLAG_SET_LOCK) {
+ Bitmap defaultWallpaper = ((BitmapDrawable) WallpaperManager
+ .getInstance(a.getApplicationContext()).getBuiltInDrawable())
+ .getBitmap();
+ ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
+ if (defaultWallpaper.compress(Bitmap.CompressFormat.PNG, 100,
+ tmpOut)) {
+ byte[] outByteArray = tmpOut.toByteArray();
+ NycWallpaperUtils.setStream(a.getApplicationContext(),
+ new ByteArrayInputStream(outByteArray), null, true,
+ NycWallpaperUtils.FLAG_SET_LOCK);
+ }
+ } else {
+ NycWallpaperUtils.clear(a, whichWallpaper);
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Setting wallpaper to default threw exception", e);
+ succeeded = false;
+ } catch (SecurityException e) {
+ Log.w(TAG, "Setting wallpaper to default threw exception", e);
+ // In this case, clearing worked; the exception was thrown afterwards.
+ succeeded = true;
+ }
+ return succeeded;
+ }
+ };
+ }
+
@Override
public boolean isSelectable() {
return true;
@@ -442,10 +505,10 @@
}
return;
}
- setWallpaperButtonEnabled(true);
WallpaperTileInfo info = (WallpaperTileInfo) v.getTag();
if (info.isSelectable() && v.getVisibility() == View.VISIBLE) {
selectTile(v);
+ setWallpaperButtonEnabled(true);
}
info.onClick(WallpaperPickerActivity.this);
}
@@ -561,7 +624,7 @@
new View.OnClickListener() {
@Override
public void onClick(View v) {
- // Ensure that a tile is slelected and loaded.
+ // Ensure that a tile is selected and loaded.
if (mSelectedTile != null && mCropView.getTileSource() != null) {
// Prevent user from selecting any new tile.
mWallpaperStrip.setVisibility(View.GONE);
@@ -570,9 +633,9 @@
WallpaperTileInfo info = (WallpaperTileInfo) mSelectedTile.getTag();
info.onSave(WallpaperPickerActivity.this);
} else {
- // no tile was selected, so we just finish the activity and go back
- setResult(Activity.RESULT_OK);
- finish();
+ // This case shouldn't be possible, since "Set wallpaper" is disabled
+ // until user clicks on a title.
+ Log.w(TAG, "\"Set wallpaper\" was clicked when no tile was selected");
}
}
});
@@ -849,7 +912,7 @@
(int) rotatedBounds[0], (int) rotatedBounds[1], width, height, leftAligned);
cropTask.setCropBounds(cropRect);
- if (cropTask.cropBitmap()) {
+ if (cropTask.cropBitmap(NycWallpaperUtils.FLAG_SET_SYSTEM)) {
return cropTask.getCroppedBitmap();
} else {
return null;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 704e001..ff120f7 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -939,6 +939,9 @@
protected void onStop() {
super.onStop();
FirstFrameAnimatorHelper.setIsVisible(false);
+ if (Utilities.isNycOrAbove()) {
+ mAppWidgetHost.stopListening();
+ }
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onStop();
@@ -949,6 +952,9 @@
protected void onStart() {
super.onStart();
FirstFrameAnimatorHelper.setIsVisible(true);
+ if (Utilities.isNycOrAbove()) {
+ mAppWidgetHost.startListening();
+ }
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onStart();
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 1f7bbe0..e1ade10 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -106,6 +106,9 @@
sContext.registerReceiver(mModel, filter);
UserManagerCompat.getInstance(sContext).enableAndResetCache();
new ConfigMonitor(sContext).register();
+
+ sContext.registerReceiver(
+ new WallpaperChangedReceiver(), new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
}
/**
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 8c23ff3..1510558 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -82,12 +82,6 @@
}
}
- @Override
- public void stopListening() {
- super.stopListening();
- clearViews();
- }
-
public void addProviderChangeListener(Runnable callback) {
mProviderChangeListeners.add(callback);
}