Fix crash in built-in wallpaper cropper
Also, sync to latest version of WallpaperCropActivity Bug: 10950237
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/wallpaper_cropper"
|
||||
android:id="@+id/wallpaper_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
<com.android.wallpapercropper.CropView
|
||||
|
||||
18
packages/WallpaperCropper/res/values-sw600dp/config.xml
Normal file
18
packages/WallpaperCropper/res/values-sw600dp/config.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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>
|
||||
<bool name="allow_rotation">true</bool>
|
||||
</resources>
|
||||
18
packages/WallpaperCropper/res/values/config.xml
Normal file
18
packages/WallpaperCropper/res/values/config.xml
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2013 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>
|
||||
<bool name="allow_rotation">false</bool>
|
||||
</resources>
|
||||
@@ -22,8 +22,8 @@ import android.graphics.RectF;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ScaleGestureDetector.OnScaleGestureListener;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||
|
||||
@@ -44,6 +44,7 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
|
||||
public interface TouchCallback {
|
||||
void onTouchDown();
|
||||
void onTap();
|
||||
void onTouchUp();
|
||||
}
|
||||
|
||||
public CropView(Context context) {
|
||||
@@ -140,12 +141,12 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
|
||||
public void onScaleEnd(ScaleGestureDetector detector) {
|
||||
}
|
||||
|
||||
public void moveToUpperLeft() {
|
||||
public void moveToLeft() {
|
||||
if (getWidth() == 0 || getHeight() == 0) {
|
||||
final ViewTreeObserver observer = getViewTreeObserver();
|
||||
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
|
||||
public void onGlobalLayout() {
|
||||
moveToUpperLeft();
|
||||
moveToLeft();
|
||||
getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||
}
|
||||
});
|
||||
@@ -154,7 +155,6 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
|
||||
getEdgesHelper(edges);
|
||||
final float scale = mRenderer.scale;
|
||||
mRenderer.centerX += Math.ceil(edges.left / scale);
|
||||
mRenderer.centerY += Math.ceil(edges.top / scale);
|
||||
}
|
||||
|
||||
public void setTouchEnabled(boolean enabled) {
|
||||
@@ -197,11 +197,13 @@ public class CropView extends TiledImageView implements OnScaleGestureListener {
|
||||
float squaredDist = (mFirstX - x) * (mFirstX - x) + (mFirstY - y) * (mFirstY - y);
|
||||
float slop = config.getScaledTouchSlop() * config.getScaledTouchSlop();
|
||||
long now = System.currentTimeMillis();
|
||||
// only do this if it's a small movement
|
||||
if (mTouchCallback != null &&
|
||||
squaredDist < slop &&
|
||||
if (mTouchCallback != null) {
|
||||
// only do this if it's a small movement
|
||||
if (squaredDist < slop &&
|
||||
now < mTouchDownTime + ViewConfiguration.getTapTimeout()) {
|
||||
mTouchCallback.onTap();
|
||||
mTouchCallback.onTap();
|
||||
}
|
||||
mTouchCallback.onTouchUp();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.
|
||||
*/
|
||||
/* Copied from Launcher3 */
|
||||
package com.android.wallpapercropper;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
public class TranslucentDecor {
|
||||
private static final int SYSTEM_UI_FLAG_TRANSPARENT_STATUS = 0x00001000;
|
||||
private static final int SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION = 0x00002000;
|
||||
|
||||
// Replace with SDK constants when available.
|
||||
public static final int FLAG_TRANSLUCENT_STATUS = 0x04000000;
|
||||
public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000;
|
||||
|
||||
// Behave properly on early K builds.
|
||||
public static final boolean SYSUI_SUPPORTED = !hasSystemUiFlag("ALLOW_TRANSIENT") &&
|
||||
hasSystemUiFlag("TRANSPARENT_STATUS") &&
|
||||
hasSystemUiFlag("TRANSPARENT_NAVIGATION");
|
||||
|
||||
public static final boolean WM_SUPPORTED =
|
||||
hasWindowManagerFlag("TRANSLUCENT_STATUS") &&
|
||||
hasWindowManagerFlag("TRANSLUCENT_NAVIGATION");
|
||||
|
||||
private final View mTarget;
|
||||
|
||||
public TranslucentDecor(View target) {
|
||||
mTarget = target;
|
||||
}
|
||||
|
||||
public void requestTranslucentDecor(boolean translucent) {
|
||||
int sysui = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
|
||||
if (WM_SUPPORTED && mTarget.getContext() instanceof Activity) {
|
||||
Window w = ((Activity) mTarget.getContext()).getWindow();
|
||||
int wmFlags = FLAG_TRANSLUCENT_STATUS | FLAG_TRANSLUCENT_NAVIGATION;
|
||||
if (translucent) {
|
||||
w.addFlags(wmFlags);
|
||||
} else {
|
||||
w.clearFlags(wmFlags);
|
||||
}
|
||||
} else if (SYSUI_SUPPORTED) { // Remove when droidfood platform is updated
|
||||
if (translucent) {
|
||||
sysui |= SYSTEM_UI_FLAG_TRANSPARENT_STATUS | SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION;
|
||||
}
|
||||
}
|
||||
mTarget.setSystemUiVisibility(sysui);
|
||||
}
|
||||
|
||||
private static boolean hasWindowManagerFlag(String name) {
|
||||
try {
|
||||
return WindowManager.LayoutParams.class.getField("FLAG_" + name) != null;
|
||||
} catch (NoSuchFieldException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasSystemUiFlag(String name) {
|
||||
try {
|
||||
return View.class.getField("SYSTEM_UI_FLAG_" + name) != null;
|
||||
} catch (NoSuchFieldException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,6 +75,9 @@ public class WallpaperCropActivity extends Activity {
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
init();
|
||||
if (!enableRotation()) {
|
||||
setRequestedOrientation(Configuration.ORIENTATION_PORTRAIT);
|
||||
}
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
@@ -99,6 +102,12 @@ public class WallpaperCropActivity extends Activity {
|
||||
cropImageAndSetWallpaper(imageUri, null, finishActivityWhenDone);
|
||||
}
|
||||
});
|
||||
TranslucentDecor transparentDecor = new TranslucentDecor(findViewById(R.id.wallpaper_root));
|
||||
transparentDecor.requestTranslucentDecor(true);
|
||||
}
|
||||
|
||||
public boolean enableRotation() {
|
||||
return getResources().getBoolean(R.bool.allow_rotation);
|
||||
}
|
||||
|
||||
public static String getSharedPreferencesKey() {
|
||||
@@ -162,7 +171,6 @@ public class WallpaperCropActivity extends Activity {
|
||||
}
|
||||
|
||||
protected void setWallpaper(String filePath, final boolean finishActivityWhenDone) {
|
||||
|
||||
BitmapCropTask cropTask = new BitmapCropTask(this,
|
||||
filePath, null, 0, 0, true, false, null);
|
||||
final Point bounds = cropTask.getImageBounds();
|
||||
@@ -200,7 +208,7 @@ public class WallpaperCropActivity extends Activity {
|
||||
}
|
||||
}
|
||||
};
|
||||
BitmapCropTask cropTask = new BitmapCropTask(res, resId,
|
||||
BitmapCropTask cropTask = new BitmapCropTask(this, res, resId,
|
||||
crop, outSize.x, outSize.y,
|
||||
true, false, onEndCrop);
|
||||
cropTask.execute();
|
||||
@@ -213,9 +221,11 @@ public class WallpaperCropActivity extends Activity {
|
||||
|
||||
protected void cropImageAndSetWallpaper(Uri uri,
|
||||
OnBitmapCroppedHandler onBitmapCroppedHandler, final boolean finishActivityWhenDone) {
|
||||
// Get the crop
|
||||
// Get the crop
|
||||
Point inSize = mCropView.getSourceDimensions();
|
||||
|
||||
boolean ltr = mCropView.getLayoutDirection() == View.LAYOUT_DIRECTION_LTR;
|
||||
|
||||
Point minDims = new Point();
|
||||
Point maxDims = new Point();
|
||||
Display d = getWindowManager().getDefaultDisplay();
|
||||
@@ -226,12 +236,12 @@ public class WallpaperCropActivity extends Activity {
|
||||
|
||||
int maxDim = Math.max(maxDims.x, maxDims.y);
|
||||
final int minDim = Math.min(minDims.x, minDims.y);
|
||||
int defaultWidth;
|
||||
int defaultWallpaperWidth;
|
||||
if (isScreenLarge(getResources())) {
|
||||
defaultWidth = (int) (maxDim *
|
||||
defaultWallpaperWidth = (int) (maxDim *
|
||||
wallpaperTravelToScreenWidthRatio(maxDim, minDim));
|
||||
} else {
|
||||
defaultWidth = Math.max((int)
|
||||
defaultWallpaperWidth = Math.max((int)
|
||||
(minDim * WALLPAPER_SCREENS_SPAN), maxDim);
|
||||
}
|
||||
|
||||
@@ -256,12 +266,17 @@ public class WallpaperCropActivity extends Activity {
|
||||
|
||||
// ADJUST CROP WIDTH
|
||||
// Extend the crop all the way to the right, for parallax
|
||||
float extraSpaceToRight = inSize.x - cropRect.right;
|
||||
// (or all the way to the left, in RTL)
|
||||
float extraSpace = ltr ? inSize.x - cropRect.right : cropRect.left;
|
||||
// Cap the amount of extra width
|
||||
float maxExtraSpace = defaultWidth / cropScale - cropRect.width();
|
||||
extraSpaceToRight = Math.min(extraSpaceToRight, maxExtraSpace);
|
||||
float maxExtraSpace = defaultWallpaperWidth / cropScale - cropRect.width();
|
||||
extraSpace = Math.min(extraSpace, maxExtraSpace);
|
||||
|
||||
cropRect.right += extraSpaceToRight;
|
||||
if (ltr) {
|
||||
cropRect.right += extraSpace;
|
||||
} else {
|
||||
cropRect.left -= extraSpace;
|
||||
}
|
||||
|
||||
// ADJUST CROP HEIGHT
|
||||
if (isPortrait) {
|
||||
@@ -287,7 +302,7 @@ public class WallpaperCropActivity extends Activity {
|
||||
}
|
||||
}
|
||||
};
|
||||
BitmapCropTask cropTask = new BitmapCropTask(uri,
|
||||
BitmapCropTask cropTask = new BitmapCropTask(this, uri,
|
||||
cropRect, outWidth, outHeight, true, false, onEndCrop);
|
||||
if (onBitmapCroppedHandler != null) {
|
||||
cropTask.setOnBitmapCropped(onBitmapCroppedHandler);
|
||||
@@ -299,7 +314,7 @@ public class WallpaperCropActivity extends Activity {
|
||||
public void onBitmapCropped(byte[] imageBytes);
|
||||
}
|
||||
|
||||
protected class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
|
||||
protected static class BitmapCropTask extends AsyncTask<Void, Void, Boolean> {
|
||||
Uri mInUri = null;
|
||||
Context mContext;
|
||||
String mInFilePath;
|
||||
@@ -309,7 +324,6 @@ public class WallpaperCropActivity extends Activity {
|
||||
RectF mCropBounds = null;
|
||||
int mOutWidth, mOutHeight;
|
||||
int mRotation = 0; // for now
|
||||
protected final WallpaperManager mWPManager;
|
||||
String mOutputFormat = "jpg"; // for now
|
||||
boolean mSetWallpaper;
|
||||
boolean mSaveCroppedBitmap;
|
||||
@@ -324,7 +338,6 @@ public class WallpaperCropActivity extends Activity {
|
||||
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
|
||||
mContext = c;
|
||||
mInFilePath = filePath;
|
||||
mWPManager = WallpaperManager.getInstance(getApplicationContext());
|
||||
init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
|
||||
}
|
||||
|
||||
@@ -332,24 +345,23 @@ public class WallpaperCropActivity extends Activity {
|
||||
RectF cropBounds, int outWidth, int outHeight,
|
||||
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
|
||||
mInImageBytes = imageBytes;
|
||||
mWPManager = WallpaperManager.getInstance(getApplicationContext());
|
||||
init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
|
||||
}
|
||||
|
||||
public BitmapCropTask(Uri inUri,
|
||||
public BitmapCropTask(Context c, Uri inUri,
|
||||
RectF cropBounds, int outWidth, int outHeight,
|
||||
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
|
||||
mContext = c;
|
||||
mInUri = inUri;
|
||||
mWPManager = WallpaperManager.getInstance(getApplicationContext());
|
||||
init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
|
||||
}
|
||||
|
||||
public BitmapCropTask(Resources res, int inResId,
|
||||
public BitmapCropTask(Context c, Resources res, int inResId,
|
||||
RectF cropBounds, int outWidth, int outHeight,
|
||||
boolean setWallpaper, boolean saveCroppedBitmap, Runnable onEndRunnable) {
|
||||
mContext = c;
|
||||
mInResId = inResId;
|
||||
mResources = res;
|
||||
mWPManager = WallpaperManager.getInstance(getApplicationContext());
|
||||
init(cropBounds, outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);
|
||||
}
|
||||
|
||||
@@ -385,7 +397,7 @@ public class WallpaperCropActivity extends Activity {
|
||||
try {
|
||||
if (mInUri != null) {
|
||||
mInStream = new BufferedInputStream(
|
||||
getContentResolver().openInputStream(mInUri));
|
||||
mContext.getContentResolver().openInputStream(mInUri));
|
||||
} else if (mInFilePath != null) {
|
||||
mInStream = mContext.openFileInput(mInFilePath);
|
||||
} else if (mInImageBytes != null) {
|
||||
@@ -426,16 +438,17 @@ public class WallpaperCropActivity extends Activity {
|
||||
|
||||
regenerateInputStream();
|
||||
|
||||
if (mNoCrop && mInStream != null) {
|
||||
WallpaperManager wallpaperManager = null;
|
||||
if (mSetWallpaper) {
|
||||
wallpaperManager = WallpaperManager.getInstance(mContext.getApplicationContext());
|
||||
}
|
||||
if (mSetWallpaper && mNoCrop && mInStream != null) {
|
||||
try {
|
||||
mWPManager.setStream(mInStream);
|
||||
wallpaperManager.setStream(mInStream);
|
||||
} catch (IOException e) {
|
||||
Log.w(LOGTAG, "cannot write stream to wallpaper", e);
|
||||
failure = true;
|
||||
}
|
||||
if (mOnEndRunnable != null) {
|
||||
mOnEndRunnable.run();
|
||||
}
|
||||
return !failure;
|
||||
}
|
||||
if (mInStream != null) {
|
||||
@@ -509,7 +522,9 @@ public class WallpaperCropActivity extends Activity {
|
||||
(int) returnRect.height(), Bitmap.Config.ARGB_8888);
|
||||
if (tmp != null) {
|
||||
Canvas c = new Canvas(tmp);
|
||||
c.drawBitmap(crop, m, new Paint());
|
||||
Paint p = new Paint();
|
||||
p.setFilterBitmap(true);
|
||||
c.drawBitmap(crop, m, p);
|
||||
crop = tmp;
|
||||
}
|
||||
} else if (mRotation > 0) {
|
||||
@@ -534,26 +549,18 @@ public class WallpaperCropActivity extends Activity {
|
||||
ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(2048);
|
||||
if (crop.compress(cf, DEFAULT_COMPRESS_QUALITY, tmpOut)) {
|
||||
// If we need to set to the wallpaper, set it
|
||||
if (mSetWallpaper && mWPManager != null) {
|
||||
if (mWPManager == null) {
|
||||
Log.w(LOGTAG, "no wallpaper manager");
|
||||
failure = true;
|
||||
} else {
|
||||
try {
|
||||
byte[] outByteArray = tmpOut.toByteArray();
|
||||
mWPManager.setStream(new ByteArrayInputStream(outByteArray));
|
||||
if (mOnBitmapCroppedHandler != null) {
|
||||
mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(LOGTAG, "cannot write stream to wallpaper", e);
|
||||
failure = true;
|
||||
if (mSetWallpaper && wallpaperManager != null) {
|
||||
try {
|
||||
byte[] outByteArray = tmpOut.toByteArray();
|
||||
wallpaperManager.setStream(new ByteArrayInputStream(outByteArray));
|
||||
if (mOnBitmapCroppedHandler != null) {
|
||||
mOnBitmapCroppedHandler.onBitmapCropped(outByteArray);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(LOGTAG, "cannot write stream to wallpaper", e);
|
||||
failure = true;
|
||||
}
|
||||
}
|
||||
if (mOnEndRunnable != null) {
|
||||
mOnEndRunnable.run();
|
||||
}
|
||||
} else {
|
||||
Log.w(LOGTAG, "cannot compress bitmap");
|
||||
failure = true;
|
||||
@@ -569,8 +576,9 @@ public class WallpaperCropActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
setResult(Activity.RESULT_OK);
|
||||
finish();
|
||||
if (mOnEndRunnable != null) {
|
||||
mOnEndRunnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user