diff options
Diffstat (limited to 'src/com/android/wallpaper/module')
15 files changed, 499 insertions, 1875 deletions
diff --git a/src/com/android/wallpaper/module/BaseWallpaperInjector.java b/src/com/android/wallpaper/module/BaseWallpaperInjector.java index f8191fc..de9ddb1 100755 --- a/src/com/android/wallpaper/module/BaseWallpaperInjector.java +++ b/src/com/android/wallpaper/module/BaseWallpaperInjector.java @@ -34,12 +34,10 @@ public abstract class BaseWallpaperInjector implements Injector { private Requester mRequester; private WallpaperManagerCompat mWallpaperManagerCompat; private CurrentWallpaperInfoFactory mCurrentWallpaperFactory; - private LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; private NetworkStatusNotifier mNetworkStatusNotifier; private AlarmManagerWrapper mAlarmManagerWrapper; private ExploreIntentChecker mExploreIntentChecker; private SystemFeatureChecker mSystemFeatureChecker; - private RotatingWallpaperComponentChecker mRotatingWallpaperComponentChecker; private FormFactorChecker mFormFactorChecker; private PackageStatusNotifier mPackageStatusNotifier; private LiveWallpaperInfoFactory mLiveWallpaperInfoFactory; @@ -111,15 +109,6 @@ public abstract class BaseWallpaperInjector implements Injector { } @Override - public synchronized LiveWallpaperStatusChecker getLiveWallpaperStatusChecker(Context context) { - if (mLiveWallpaperStatusChecker == null) { - mLiveWallpaperStatusChecker = - new DefaultLiveWallpaperStatusChecker(context.getApplicationContext()); - } - return mLiveWallpaperStatusChecker; - } - - @Override public synchronized NetworkStatusNotifier getNetworkStatusNotifier(Context context) { if (mNetworkStatusNotifier == null) { mNetworkStatusNotifier = new DefaultNetworkStatusNotifier(context.getApplicationContext()); @@ -161,14 +150,6 @@ public abstract class BaseWallpaperInjector implements Injector { } @Override - public synchronized RotatingWallpaperComponentChecker getRotatingWallpaperComponentChecker() { - if (mRotatingWallpaperComponentChecker == null) { - mRotatingWallpaperComponentChecker = new DefaultRotatingWallpaperComponentChecker(); - } - return mRotatingWallpaperComponentChecker; - } - - @Override public synchronized FormFactorChecker getFormFactorChecker(Context context) { if (mFormFactorChecker == null) { mFormFactorChecker = new DefaultFormFactorChecker(context.getApplicationContext()); diff --git a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java index c74f9b2..dbe3722 100755 --- a/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java +++ b/src/com/android/wallpaper/module/DefaultCurrentWallpaperInfoFactory.java @@ -17,16 +17,13 @@ package com.android.wallpaper.module; import android.content.Context; -import com.android.wallpaper.compat.BuildCompat; +import androidx.annotation.Nullable; + import com.android.wallpaper.compat.WallpaperManagerCompat; -import com.android.wallpaper.model.CurrentWallpaperInfoV16; import com.android.wallpaper.model.CurrentWallpaperInfoVN; -import com.android.wallpaper.model.LiveWallpaperInfo; import com.android.wallpaper.model.WallpaperInfo; import com.android.wallpaper.module.WallpaperPreferences.PresentationMode; -import androidx.annotation.Nullable; - /** * Default implementation of {@link CurrentWallpaperInfoFactory} which actually constructs * {@link WallpaperInfo} instances representing the wallpapers currently set to the device. @@ -35,7 +32,6 @@ public class DefaultCurrentWallpaperInfoFactory implements CurrentWallpaperInfoF private final Context mAppContext; private final WallpaperRefresher mWallpaperRefresher; - private final LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; private final LiveWallpaperInfoFactory mLiveWallpaperInfoFactory; // Cached copies of the currently-set WallpaperInfo(s) and presentation mode. @@ -49,8 +45,6 @@ public class DefaultCurrentWallpaperInfoFactory implements CurrentWallpaperInfoF mAppContext = context.getApplicationContext(); Injector injector = InjectorProvider.getInjector(); mWallpaperRefresher = injector.getWallpaperRefresher(mAppContext); - mLiveWallpaperStatusChecker = - injector.getLiveWallpaperStatusChecker(mAppContext); mLiveWallpaperInfoFactory = injector.getLiveWallpaperInfoFactory(mAppContext); } @@ -72,29 +66,16 @@ public class DefaultCurrentWallpaperInfoFactory implements CurrentWallpaperInfoF mWallpaperRefresher.refresh( (homeWallpaperMetadata, lockWallpaperMetadata, presentationMode) -> { - WallpaperInfo homeWallpaper; - - if (homeWallpaperMetadata.getWallpaperComponent() == null - || mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) { - // Image wallpaper - if (BuildCompat.isAtLeastN()) { - homeWallpaper = new CurrentWallpaperInfoVN( - homeWallpaperMetadata.getAttributions(), - homeWallpaperMetadata.getActionUrl(), - homeWallpaperMetadata.getActionLabelRes(), - homeWallpaperMetadata.getActionIconRes(), - homeWallpaperMetadata.getCollectionId(), - WallpaperManagerCompat.FLAG_SYSTEM); - } else { - homeWallpaper = new CurrentWallpaperInfoV16( - homeWallpaperMetadata.getAttributions(), - homeWallpaperMetadata.getActionUrl(), - homeWallpaperMetadata.getActionLabelRes(), - homeWallpaperMetadata.getActionIconRes(), - homeWallpaperMetadata.getCollectionId()); - } - } else { // Live wallpaper + if (homeWallpaperMetadata.getWallpaperComponent() == null) { + homeWallpaper = new CurrentWallpaperInfoVN( + homeWallpaperMetadata.getAttributions(), + homeWallpaperMetadata.getActionUrl(), + homeWallpaperMetadata.getActionLabelRes(), + homeWallpaperMetadata.getActionIconRes(), + homeWallpaperMetadata.getCollectionId(), + WallpaperManagerCompat.FLAG_SYSTEM); + } else { homeWallpaper = mLiveWallpaperInfoFactory.getLiveWallpaperInfo( homeWallpaperMetadata.getWallpaperComponent()); } diff --git a/src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java b/src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java deleted file mode 100755 index 003a06b..0000000 --- a/src/com/android/wallpaper/module/DefaultLiveWallpaperStatusChecker.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2017 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.wallpaper.module; - -import android.annotation.SuppressLint; -import android.app.WallpaperManager; -import android.content.Context; - -/** - * Default implementation of {@link LiveWallpaperStatusChecker}. - */ -@SuppressLint("ServiceCast") -public class DefaultLiveWallpaperStatusChecker implements LiveWallpaperStatusChecker { - - private WallpaperManager mWallpaperManager; - - public DefaultLiveWallpaperStatusChecker(Context context) { - // Retrieve WallpaperManager using Context#getSystemService instead of - // WallpaperManager#getInstance so it can be mocked out in test. - mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); - } - - @Override - public boolean isNoBackupImageWallpaperSet() { - android.app.WallpaperInfo liveWallpaper = mWallpaperManager.getWallpaperInfo(); - return liveWallpaper != null - && liveWallpaper.getServiceName().equals(NoBackupImageWallpaper.class.getName()); - } -} diff --git a/src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java b/src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java deleted file mode 100755 index eddb6bf..0000000 --- a/src/com/android/wallpaper/module/DefaultRotatingWallpaperComponentChecker.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2017 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.wallpaper.module; - -import android.content.Context; -import android.content.pm.PackageManager; - -/** - * Default implementation of {@link RotatingWallpaperComponentChecker}. - */ -public class DefaultRotatingWallpaperComponentChecker implements RotatingWallpaperComponentChecker { - - private static boolean isLiveWallpaperSupported(Context context) { - return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LIVE_WALLPAPER); - } - - @Override - @RotatingWallpaperComponent - public int getCurrentRotatingWallpaperComponent(Context context) { - if (!isLiveWallpaperSupported(context)) { - return ROTATING_WALLPAPER_COMPONENT_STATIC; - } - - // If presentation mode is ROTATING but the live wallpaper is not set, then "legacy" rotation - // from older APKs is in effect and the current rotating wallpaper component is a static WP. - Injector injector = InjectorProvider.getInjector(); - WallpaperPreferences preferences = injector.getPreferences(context); - LiveWallpaperStatusChecker liveWallpaperStatusChecker = injector - .getLiveWallpaperStatusChecker(context); - if (preferences.getWallpaperPresentationMode() - == WallpaperPreferences.PRESENTATION_MODE_ROTATING - && !liveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) { - return ROTATING_WALLPAPER_COMPONENT_STATIC; - } - - return ROTATING_WALLPAPER_COMPONENT_LIVE; - } - - @Override - @RotatingWallpaperComponent - public int getNextRotatingWallpaperComponent(Context context) { - if (!isLiveWallpaperSupported(context)) { - return ROTATING_WALLPAPER_COMPONENT_STATIC; - } - - return ROTATING_WALLPAPER_COMPONENT_LIVE; - } - - @Override - @RotatingWallpaperSupport - public int getRotatingWallpaperSupport(Context context) { - FormFactorChecker formFactorChecker = - InjectorProvider.getInjector().getFormFactorChecker(context); - - if (formFactorChecker.getFormFactor() == FormFactorChecker.FORM_FACTOR_DESKTOP) { - return ROTATING_WALLPAPER_SUPPORT_SUPPORTED; - } - - // While static daily rotation is supported on desktops, it isn't (yet?) supported on phones. - // For phones which don't support live wallpapers thus we disallow daily rotation altogether. - return isLiveWallpaperSupported(context) ? ROTATING_WALLPAPER_SUPPORT_SUPPORTED - : ROTATING_WALLPAPER_SUPPORT_NOT_SUPPORTED; - } -} diff --git a/src/com/android/wallpaper/module/DefaultWallpaperPersister.java b/src/com/android/wallpaper/module/DefaultWallpaperPersister.java index e2c968c..27e4491 100755 --- a/src/com/android/wallpaper/module/DefaultWallpaperPersister.java +++ b/src/com/android/wallpaper/module/DefaultWallpaperPersister.java @@ -19,7 +19,6 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.WallpaperManager; import android.content.Context; -import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; @@ -32,6 +31,8 @@ import android.util.Log; import android.view.Display; import android.view.WindowManager; +import androidx.annotation.Nullable; + import com.android.wallpaper.asset.Asset; import com.android.wallpaper.asset.Asset.BitmapReceiver; import com.android.wallpaper.asset.Asset.DimensionsReceiver; @@ -42,24 +43,16 @@ import com.android.wallpaper.compat.BuildCompat; import com.android.wallpaper.compat.WallpaperManagerCompat; import com.android.wallpaper.model.WallpaperInfo; import com.android.wallpaper.module.BitmapCropper.Callback; -import com.android.wallpaper.module.RotatingWallpaperComponentChecker.RotatingWallpaperComponent; import com.android.wallpaper.util.BitmapTransformer; -import com.android.wallpaper.util.DiskBasedLogger; -import com.android.wallpaper.util.FileMover; import com.android.wallpaper.util.ScreenSizeCalculator; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; -import androidx.annotation.Nullable; - /** * Concrete implementation of WallpaperPersister which actually sets wallpapers to the system via * the WallpaperManager. @@ -71,11 +64,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { private final Context mAppContext; // The application's context. // Context that accesses files in device protected storage - private final Context mDeviceProtectedContext; private final WallpaperManager mWallpaperManager; private final WallpaperManagerCompat mWallpaperManagerCompat; private final WallpaperPreferences mWallpaperPreferences; - private final RotatingWallpaperComponentChecker mRotatingWallpaperComponentChecker; private final WallpaperChangedNotifier mWallpaperChangedNotifier; private WallpaperInfo mWallpaperInfoInPreview; @@ -83,21 +74,19 @@ public class DefaultWallpaperPersister implements WallpaperPersister { @SuppressLint("ServiceCast") public DefaultWallpaperPersister(Context context) { mAppContext = context.getApplicationContext(); - mDeviceProtectedContext = mAppContext.createDeviceProtectedStorageContext(); // Retrieve WallpaperManager using Context#getSystemService instead of // WallpaperManager#getInstance so it can be mocked out in test. Injector injector = InjectorProvider.getInjector(); mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); mWallpaperManagerCompat = injector.getWallpaperManagerCompat(context); mWallpaperPreferences = injector.getPreferences(context); - mRotatingWallpaperComponentChecker = injector.getRotatingWallpaperComponentChecker(); mWallpaperChangedNotifier = WallpaperChangedNotifier.getInstance(); } @Override public void setIndividualWallpaper(final WallpaperInfo wallpaper, Asset asset, - @Nullable Rect cropRect, float scale, @Destination final int destination, - final SetWallpaperCallback callback) { + @Nullable Rect cropRect, float scale, @Destination final int destination, + final SetWallpaperCallback callback) { // Set wallpaper without downscaling directly from an input stream if there's no crop rect // specified by the caller and the asset is streamable. if (cropRect == null && asset instanceof StreamableAsset) { @@ -149,7 +138,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { @Override public void setIndividualWallpaperWithPosition(Activity activity, WallpaperInfo wallpaper, - @WallpaperPosition int wallpaperPosition, SetWallpaperCallback callback) { + @WallpaperPosition int wallpaperPosition, SetWallpaperCallback callback) { Display display = ((WindowManager) mAppContext.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display); @@ -164,9 +153,10 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } switch (wallpaperPosition) { - // Crop out screen-sized center portion of the source image if it's larger than the screen - // in both dimensions. Otherwise, decode the entire bitmap and fill the space around it to - // fill a new screen-sized bitmap with plain black pixels. + // Crop out screen-sized center portion of the source image if it's larger + // than the screen + // in both dimensions. Otherwise, decode the entire bitmap and fill the space + // around it to fill a new screen-sized bitmap with plain black pixels. case WALLPAPER_POSITION_CENTER: setIndividualWallpaperWithCenterPosition( wallpaper, asset, dimensions, screenSize, callback); @@ -178,19 +168,22 @@ public class DefaultWallpaperPersister implements WallpaperPersister { wallpaper, asset, dimensions, screenSize, callback); break; - // Decode full bitmap sized for screen and stretch it to fill the screen dimensions. + // Decode full bitmap sized for screen and stretch it to fill the screen + // dimensions. case WALLPAPER_POSITION_STRETCH: asset.decodeBitmap(screenSize.x, screenSize.y, new BitmapReceiver() { @Override public void onBitmapDecoded(@Nullable Bitmap bitmap) { - setIndividualWallpaperStretch(wallpaper, bitmap, screenSize /* stretchSize */, + setIndividualWallpaperStretch(wallpaper, bitmap, + screenSize /* stretchSize */, WallpaperPersister.DEST_BOTH, callback); } }); break; default: - Log.e(TAG, "Unsupported wallpaper position option specified: " + wallpaperPosition); + Log.e(TAG, "Unsupported wallpaper position option specified: " + + wallpaperPosition); callback.onError(null); } } @@ -208,7 +201,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Callback used to notify original caller of wallpaper set operation result. */ private void setIndividualWallpaperWithCenterPosition(WallpaperInfo wallpaper, Asset asset, - Point dimensions, Point screenSize, SetWallpaperCallback callback) { + Point dimensions, Point screenSize, SetWallpaperCallback callback) { if (dimensions.x >= screenSize.x && dimensions.y >= screenSize.y) { Rect cropRect = new Rect( (dimensions.x - screenSize.x) / 2, @@ -218,7 +211,8 @@ public class DefaultWallpaperPersister implements WallpaperPersister { asset.decodeBitmapRegion(cropRect, screenSize.x, screenSize.y, new BitmapReceiver() { @Override public void onBitmapDecoded(@Nullable Bitmap bitmap) { - setIndividualWallpaper(wallpaper, bitmap, WallpaperPersister.DEST_BOTH, callback); + setIndividualWallpaper(wallpaper, bitmap, WallpaperPersister.DEST_BOTH, + callback); } }); } else { @@ -249,7 +243,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Callback used to notify original caller of wallpaper set operation result. */ private void setIndividualWallpaperWithCenterCropPosition(WallpaperInfo wallpaper, Asset asset, - Point dimensions, Point screenSize, SetWallpaperCallback callback) { + Point dimensions, Point screenSize, SetWallpaperCallback callback) { float scale = Math.max((float) screenSize.x / dimensions.x, (float) screenSize.y / dimensions.y); @@ -276,7 +270,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaper(WallpaperInfo wallpaper, Bitmap croppedBitmap, - @Destination int destination, SetWallpaperCallback callback) { + @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, croppedBitmap, destination, callback); setWallpaperTask.execute(); @@ -287,15 +281,16 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * * @param wallpaper Wallpaper model object. * @param croppedBitmap Bitmap representing the individual wallpaper image. - * @param fillSize Specifies the final bitmap size that should be set to WallpaperManager. This - * final bitmap will show the visible area of the provided bitmap after applying a mask with - * black background the source bitmap and centering. There may be black borders around the - * original bitmap if it's smaller than the fillSize in one or both dimensions. + * @param fillSize Specifies the final bitmap size that should be set to WallpaperManager. + * This final bitmap will show the visible area of the provided bitmap + * after applying a mask with black background the source bitmap and + * centering. There may be black borders around the original bitmap if + * it's smaller than the fillSize in one or both dimensions. * @param destination The destination - where to set the wallpaper to. * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaperFill(WallpaperInfo wallpaper, Bitmap croppedBitmap, - Point fillSize, @Destination int destination, SetWallpaperCallback callback) { + Point fillSize, @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, croppedBitmap, destination, callback); setWallpaperTask.setFillSize(fillSize); @@ -308,13 +303,14 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * * @param wallpaper Wallpaper model object. * @param croppedBitmap Bitmap representing the individual wallpaper image. - * @param stretchSize Specifies the final size to which the the bitmap should be stretched prior + * @param stretchSize Specifies the final size to which the bitmap should be stretched + * prior * to being set to the device. * @param destination The destination - where to set the wallpaper to. * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaperStretch(WallpaperInfo wallpaper, Bitmap croppedBitmap, - Point stretchSize, @Destination int destination, SetWallpaperCallback callback) { + Point stretchSize, @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, croppedBitmap, destination, callback); setWallpaperTask.setStretchSize(stretchSize); @@ -330,7 +326,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * @param callback Called once the wallpaper was set or if an error occurred. */ private void setIndividualWallpaper(WallpaperInfo wallpaper, InputStream inputStream, - @Destination int destination, SetWallpaperCallback callback) { + @Destination int destination, SetWallpaperCallback callback) { SetWallpaperTask setWallpaperTask = new SetWallpaperTask(wallpaper, inputStream, destination, callback); setWallpaperTask.execute(); @@ -338,58 +334,31 @@ public class DefaultWallpaperPersister implements WallpaperPersister { @Override public boolean setWallpaperInRotation(Bitmap wallpaperBitmap, List<String> attributions, - int actionLabelRes, int actionIconRes, - String actionUrl, String collectionId) { - @RotatingWallpaperComponent int rotatingWallpaperComponent = mRotatingWallpaperComponentChecker - .getCurrentRotatingWallpaperComponent(mAppContext); - - switch (rotatingWallpaperComponent) { - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC: - return setWallpaperInRotationStatic(wallpaperBitmap, attributions, actionUrl, - actionLabelRes, actionIconRes, collectionId); - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_LIVE: - return setWallpaperInRotationLive(wallpaperBitmap, attributions, actionUrl, - actionLabelRes, actionIconRes, collectionId); - default: - Log.e(TAG, "Unknown rotating wallpaper component: " + rotatingWallpaperComponent); - return false; - } + int actionLabelRes, int actionIconRes, String actionUrl, String collectionId) { + + return setWallpaperInRotationStatic(wallpaperBitmap, attributions, actionUrl, + actionLabelRes, actionIconRes, collectionId); } @Override public int setWallpaperBitmapInNextRotation(Bitmap wallpaperBitmap) { - @RotatingWallpaperComponent int rotatingWallpaperComponent = mRotatingWallpaperComponentChecker - .getNextRotatingWallpaperComponent(mAppContext); - - switch (rotatingWallpaperComponent) { - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC: - return setWallpaperBitmapInRotationStatic(wallpaperBitmap); - case RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_LIVE: - boolean isSuccess = setWallpaperBitmapInRotationLive(wallpaperBitmap, true /* isPreview */); - return isSuccess ? 1 : 0; - default: - Log.e(TAG, "Unknown rotating wallpaper component: " + rotatingWallpaperComponent); - return 0; - } + return setWallpaperBitmapInRotationStatic(wallpaperBitmap); } @Override public boolean finalizeWallpaperForNextRotation(List<String> attributions, String actionUrl, - int actionLabelRes, int actionIconRes, - String collectionId, int wallpaperId) { - @RotatingWallpaperComponent int rotatingWallpaperComponent = - mRotatingWallpaperComponentChecker.getNextRotatingWallpaperComponent(mAppContext); + int actionLabelRes, int actionIconRes, String collectionId, int wallpaperId) { return finalizeWallpaperForRotatingComponent(attributions, actionUrl, actionLabelRes, - actionIconRes, collectionId, wallpaperId, rotatingWallpaperComponent); + actionIconRes, collectionId, wallpaperId); } /** - * Sets wallpaper image and attributions when a static wallpaper is responsible for presenting the + * Sets wallpaper image and attributions when a static wallpaper is responsible for presenting + * the * current "daily wallpaper". */ private boolean setWallpaperInRotationStatic(Bitmap wallpaperBitmap, List<String> attributions, - String actionUrl, int actionLabelRes, - int actionIconRes, String collectionId) { + String actionUrl, int actionLabelRes, int actionIconRes, String collectionId) { final int wallpaperId = setWallpaperBitmapInRotationStatic(wallpaperBitmap); if (wallpaperId == 0) { @@ -397,8 +366,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } return finalizeWallpaperForRotatingComponent(attributions, actionUrl, actionLabelRes, - actionIconRes, collectionId, wallpaperId, - RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC); + actionIconRes, collectionId, wallpaperId); } /** @@ -413,83 +381,21 @@ public class DefaultWallpaperPersister implements WallpaperPersister { int actionLabelRes, int actionIconRes, String collectionId, - int wallpaperId, - @RotatingWallpaperComponent int rotatingWallpaperComponent) { + int wallpaperId) { mWallpaperPreferences.clearHomeWallpaperMetadata(); boolean isLockWallpaperSet = isSeparateLockScreenWallpaperSet(); - // Persist wallpaper IDs if the rotating wallpaper component is static and this device is - // running Android N or later. - if (rotatingWallpaperComponent - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC) { - if (BuildCompat.isAtLeastN()) { - mWallpaperPreferences.setHomeWallpaperManagerId(wallpaperId); + // Persist wallpaper IDs if the rotating wallpaper component + mWallpaperPreferences.setHomeWallpaperManagerId(wallpaperId); - // Only copy over wallpaper ID to lock wallpaper if no explicit lock wallpaper is set (so - // metadata isn't lost if a user explicitly sets a home-only wallpaper). - if (!isLockWallpaperSet) { - mWallpaperPreferences.setLockWallpaperId(wallpaperId); - } - } else { // Pre-N but using static component - // Compute bitmap hash code after setting the wallpaper because JPEG compression has likely - // changed many pixels' color values. Forget the previously loaded wallpaper bitmap so that - // WallpaperManager doesn't return the old wallpaper drawable. - mWallpaperManager.forgetLoadedWallpaper(); - Bitmap bitmap = ((BitmapDrawable) mWallpaperManagerCompat.getDrawable()).getBitmap(); - long bitmapHash = BitmapUtils.generateHashCode(bitmap); - - mWallpaperPreferences.setHomeWallpaperHashCode(bitmapHash); - } - } else { // Live wallpaper rotating component. - - // Copy "preview" JPEG to "rotating" JPEG if the preview file exists. - File rotatingWallpaper; - try { - rotatingWallpaper = moveToDeviceProtectedStorage( - NoBackupImageWallpaper.PREVIEW_WALLPAPER_FILE_PATH, - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - } catch (Exception e) { - DiskBasedLogger.e( - TAG, - "Unable to move preview to final file for rotating wallpaper " + - "file (exception)" + e.toString(), - mAppContext); - return false; - } - if (rotatingWallpaper == null) { - rotatingWallpaper = mDeviceProtectedContext.getFileStreamPath( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - } - try { - FileInputStream fis = new FileInputStream(rotatingWallpaper.getAbsolutePath()); - Bitmap bitmap = BitmapFactory.decodeStream(fis); - fis.close(); - - if (bitmap != null) { - long bitmapHash = BitmapUtils.generateHashCode(bitmap); - mWallpaperPreferences.setHomeWallpaperHashCode(bitmapHash); - } else { - Log.e(TAG, "Unable to decode rotating wallpaper file"); - return false; - } - } catch (FileNotFoundException e) { - Log.e(TAG, "Rotating wallpaper file not found at path: " - + rotatingWallpaper.getAbsolutePath()); - e.printStackTrace(); - return false; - } catch (IOException e) { - Log.e(TAG, "IOException when closing FileInputStream " + e); - return false; - } - - mWallpaperChangedNotifier.notifyWallpaperChanged(); - - // Send a broadcast to {@link RotatingWallpaperChangedReceiver} in the :live_wallpaper - // process so the currently displayed wallpaper updates. - notifyLiveWallpaperBitmapChanged(); + // Only copy over wallpaper ID to lock wallpaper if no explicit lock wallpaper is set + // (so metadata isn't lost if a user explicitly sets a home-only wallpaper). + if (!isLockWallpaperSet) { + mWallpaperPreferences.setLockWallpaperId(wallpaperId); } + mWallpaperPreferences.setHomeWallpaperAttributions(attributions); mWallpaperPreferences.setHomeWallpaperActionUrl(actionUrl); mWallpaperPreferences.setHomeWallpaperActionLabelRes(actionLabelRes); @@ -498,11 +404,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.setHomeWallpaperBaseImageUrl(null); mWallpaperPreferences.setHomeWallpaperCollectionId(collectionId); - // Set metadata to lock screen also when the rotating wallpaper is a static one so if user sets - // a home screen-only wallpaper later, these attributions will still be available. - if (rotatingWallpaperComponent - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC - && !isLockWallpaperSet) { + // Set metadata to lock screen also when the rotating wallpaper so if user sets a home + // screen-only wallpaper later, these attributions will still be available. + if (!isLockWallpaperSet) { mWallpaperPreferences.setLockWallpaperAttributions(attributions); mWallpaperPreferences.setLockWallpaperActionUrl(actionUrl); mWallpaperPreferences.setLockWallpaperActionLabelRes(actionLabelRes); @@ -514,26 +418,6 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } /** - * Sets wallpaper image and attributions when a live wallpaper is responsible for presenting the - * current "daily wallpaper". - */ - private boolean setWallpaperInRotationLive(Bitmap wallpaperBitmap, List<String> attributions, - String actionUrl, int actionLabelRes, - int actionIconRes, String collectionId) { - - synchronized (RotatingWallpaperLockProvider.getInstance()) { - if (!setWallpaperBitmapInRotationLive(wallpaperBitmap, false /* isPreview */)) { - return false; - } - - return finalizeWallpaperForRotatingComponent(attributions, actionUrl, actionLabelRes, - actionIconRes, collectionId, - 0 /* wallpaperId */, - RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_LIVE); - } - } - - /** * Sets a wallpaper in rotation as a static wallpaper to the {@link WallpaperManager} with the * option allowBackup=false to save user data. * @@ -553,84 +437,6 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } /** - * Sets a wallpaper in rotation as a live wallpaper. Writes wallpaper bitmap to a file in internal - * storage and sends a broadcast to the live wallpaper notifying it that rotating wallpaper image - * data changed. - * - * @return whether the set wallpaper operation was successful. - */ - private boolean setWallpaperBitmapInRotationLive(Bitmap wallpaperBitmap, boolean isPreview) { - File pendingFile; - try { - pendingFile = File.createTempFile("rotating_pending", ".jpg", mAppContext.getFilesDir()); - } catch (IOException e) { - Log.e(TAG, "Unable to create temp file for rotating wallpaper"); - return false; - } - - FileOutputStream fos; - try { - fos = mAppContext.openFileOutput(pendingFile.getName(), Context.MODE_PRIVATE); - } catch (FileNotFoundException e) { - Log.e(TAG, "Unable to open file output stream for pending rotating wallpaper file"); - return false; - } - - boolean compressedSuccessfully = - wallpaperBitmap.compress(CompressFormat.JPEG, DEFAULT_COMPRESS_QUALITY, fos); - - // Close the file stream. - try { - fos.flush(); - fos.close(); - } catch (IOException e) { - Log.e(TAG, "Unable to close FileOutputStream for pending rotating wallpaper file" - + " (compress succeeded"); - return false; - } - - if (compressedSuccessfully) { - // Compressing/writing to disk succeeded, so move the pending file to the final location. - try { - if (isPreview) { - if (!pendingFile.renameTo(mAppContext.getFileStreamPath( - NoBackupImageWallpaper.PREVIEW_WALLPAPER_FILE_PATH))) { - return false; - } - } else { - moveToDeviceProtectedStorage(pendingFile.getName(), - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - } - } catch (Exception e) { - Log.e(TAG, "Unable to rename pending to final file for rotating wallpaper file" - + " (exception)" + e.toString()); - return false; - } - } else { - Log.e(TAG, "Unable to compress the wallpaper bitmap"); - - // Delete the pending file since compressing/writing the image to disk failed. - try { - pendingFile.delete(); - } catch (SecurityException e) { - Log.e(TAG, "Unable to delete pending rotating wallpaper file"); - return false; - } - - return false; - } - - mWallpaperChangedNotifier.notifyWallpaperChanged(); - - // Send a broadcast to {@link RotatingWallpaperChangedReceiver} in the :live_wallpaper - // process so the currently displayed wallpaper updates if the live wallpaper is set to the - // device. - notifyLiveWallpaperBitmapChanged(); - - return true; - } - - /** * Sets a wallpaper bitmap to the {@link WallpaperManagerCompat}. * * @return an integer wallpaper ID. This is an actual wallpaper ID on N and later versions of @@ -638,7 +444,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * operation was successful and zero if the operation encountered an error. */ private int setBitmapToWallpaperManagerCompat(Bitmap wallpaperBitmap, boolean allowBackup, - int whichWallpaper) { + int whichWallpaper) { ByteArrayOutputStream tmpOut = new ByteArrayOutputStream(); if (wallpaperBitmap.compress(CompressFormat.JPEG, DEFAULT_COMPRESS_QUALITY, tmpOut)) { try { @@ -668,9 +474,10 @@ public class DefaultWallpaperPersister implements WallpaperPersister { } private int setStreamToWallpaperManagerCompat(InputStream inputStream, boolean allowBackup, - int whichWallpaper) { + int whichWallpaper) { try { - return mWallpaperManagerCompat.setStream(inputStream, null, allowBackup, whichWallpaper); + return mWallpaperManagerCompat.setStream(inputStream, null, allowBackup, + whichWallpaper); } catch (IOException e) { return 0; } @@ -688,7 +495,8 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperInfoInPreview.getWallpaperComponent(); // If there is no live wallpaper set on the WallpaperManager or it doesn't match the - // WallpaperInfo which was last previewed, then do nothing and nullify last previewed wallpaper. + // WallpaperInfo which was last previewed, then do nothing and nullify last previewed + // wallpaper. if (currentWallpaperComponent == null || previewedWallpaperComponent == null || !currentWallpaperComponent.getPackageName() .equals(previewedWallpaperComponent.getPackageName())) { @@ -729,9 +537,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperInfoInPreview.getWallpaperComponent(); mWallpaperPreferences.clearHomeWallpaperMetadata(); - // NOTE: We explicitly do not also clear the lock wallpaper metadata. Since the user may have - // set the live wallpaper on the home screen only, we leave the lock wallpaper metadata intact. - // If the user has set the live wallpaper for both home and lock screens, then the + // NOTE: We explicitly do not also clear the lock wallpaper metadata. Since the user may + // have set the live wallpaper on the home screen only, we leave the lock wallpaper metadata + // intact. If the user has set the live wallpaper for both home and lock screens, then the // WallpaperRefresher will pick up on that and update the preferences later. mWallpaperPreferences .setHomeWallpaperAttributions(mWallpaperInfoInPreview.getAttributions(mAppContext)); @@ -744,36 +552,6 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.clearDailyRotations(); } - /** - * Notifies the :live_wallpaper process that the contents of the rotating live wallpaper bitmap - * changed. - */ - private void notifyLiveWallpaperBitmapChanged() { - Intent intent = new Intent(mAppContext.getPackageName() - + NoBackupImageWallpaper.ACTION_ROTATING_WALLPAPER_CHANGED); - // Handled by a runtime-registered receiver in NoBackupImageWallpaper. - intent.setPackage(mAppContext.getPackageName()); - mAppContext.sendBroadcast(intent); - } - - /** - * Moves a file from the app's files directory to the device content protected storage - * directory. - * @param srcFileName Name of the source file (just the name, no path). It's expected to be - * located in {@link Context#getFilesDir()} for {@link #mAppContext} - * @param dstFileName Name of the destination file (just the name, no path), which will be - * located in {@link Context#getFilesDir()} - * for {@link #mDeviceProtectedContext} - * @return a {@link File} corresponding to the moved file in its new location, or null if - * nothing was moved (because srcFileName didn't exist). - */ - @Nullable - private File moveToDeviceProtectedStorage(String srcFileName, String dstFileName) - throws IOException { - return FileMover.moveFileBetweenContexts(mAppContext, srcFileName, mDeviceProtectedContext, - dstFileName); - } - private class SetWallpaperTask extends AsyncTask<Void, Void, Boolean> { private final WallpaperInfo mWallpaper; @@ -793,7 +571,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { private Point mStretchSize; SetWallpaperTask(WallpaperInfo wallpaper, Bitmap bitmap, @Destination int destination, - WallpaperPersister.SetWallpaperCallback callback) { + WallpaperPersister.SetWallpaperCallback callback) { super(); mWallpaper = wallpaper; mBitmap = bitmap; @@ -806,7 +584,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * will close the InputStream once it is done with it. */ SetWallpaperTask(WallpaperInfo wallpaper, InputStream stream, - @Destination int destination, WallpaperPersister.SetWallpaperCallback callback) { + @Destination int destination, WallpaperPersister.SetWallpaperCallback callback) { mWallpaper = wallpaper; mInputStream = stream; mDestination = destination; @@ -815,16 +593,18 @@ public class DefaultWallpaperPersister implements WallpaperPersister { void setFillSize(Point fillSize) { if (mStretchSize != null) { - throw new IllegalArgumentException("Can't pass a fill size option if a stretch size is " - + "already set."); + throw new IllegalArgumentException( + "Can't pass a fill size option if a stretch size is " + + "already set."); } mFillSize = fillSize; } void setStretchSize(Point stretchSize) { if (mFillSize != null) { - throw new IllegalArgumentException("Can't pass a stretch size option if a fill size is " - + "already set."); + throw new IllegalArgumentException( + "Can't pass a stretch size option if a fill size is " + + "already set."); } mStretchSize = stretchSize; } @@ -841,16 +621,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { | WallpaperManagerCompat.FLAG_LOCK; } - // NOTE: The rotating wallpaper component must be determined here, _before_ actually setting - // the bitmap/stream on WallpaperManagerCompat, to ensure that the - // RotatingWallpaperComponentChecker is doing its check while rotation is still enabled. - // E.g., if "live wallpaper" is the component, then it needs to check while live wallpaper is - // still set as the active wallpaper on the device. Otherwise, the checker would see a static - // wallpaper is currently set and it would return the wrong value. - @RotatingWallpaperComponent int currentRotatingWallpaperComponent = - mRotatingWallpaperComponentChecker.getCurrentRotatingWallpaperComponent(mAppContext); - boolean wasLockWallpaperSet = LockWallpaperStatusChecker.isLockWallpaperSet(mAppContext); + boolean wasLockWallpaperSet = LockWallpaperStatusChecker.isLockWallpaperSet( + mAppContext); boolean allowBackup = mWallpaper.getBackupPermission() == WallpaperInfo.BACKUP_ALLOWED; final int wallpaperId; @@ -860,15 +633,20 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mBitmap = BitmapTransformer.applyFillTransformation(mBitmap, mFillSize); } if (mStretchSize != null) { - mBitmap = Bitmap.createScaledBitmap(mBitmap, mStretchSize.x, mStretchSize.y, true); + mBitmap = Bitmap.createScaledBitmap(mBitmap, mStretchSize.x, mStretchSize.y, + true); } - wallpaperId = setBitmapToWallpaperManagerCompat(mBitmap, allowBackup, whichWallpaper); + wallpaperId = setBitmapToWallpaperManagerCompat(mBitmap, allowBackup, + whichWallpaper); } else if (mInputStream != null) { - wallpaperId = setStreamToWallpaperManagerCompat(mInputStream, allowBackup, whichWallpaper); + wallpaperId = setStreamToWallpaperManagerCompat(mInputStream, allowBackup, + whichWallpaper); } else { - Log.e(TAG, "Both the wallpaper bitmap and input stream are null so we're unable to set any " - + "kind of wallpaper here."); + Log.e(TAG, + "Both the wallpaper bitmap and input stream are null so we're unable to " + + "set any " + + "kind of wallpaper here."); wallpaperId = 0; } @@ -878,7 +656,7 @@ public class DefaultWallpaperPersister implements WallpaperPersister { == WallpaperPreferences.PRESENTATION_MODE_ROTATING && !wasLockWallpaperSet && BuildCompat.isAtLeastN()) { - copyRotatingWallpaperToLock(currentRotatingWallpaperComponent); + copyRotatingWallpaperToLock(); } setImageWallpaperMetadata(mDestination, wallpaperId); return true; @@ -914,12 +692,8 @@ public class DefaultWallpaperPersister implements WallpaperPersister { * Used to accommodate the case where a user had gone from a home+lock daily rotation to * selecting a static wallpaper on home-only. The image and metadata that was previously * rotating is now copied to the lock screen. - * - * @param currentRotatingWallpaperComponent The component in which rotating wallpapers were - * presented. */ - private void copyRotatingWallpaperToLock( - @RotatingWallpaperComponent int currentRotatingWallpaperComponent) { + private void copyRotatingWallpaperToLock() { mWallpaperPreferences.setLockWallpaperAttributions( mWallpaperPreferences.getHomeWallpaperAttributions()); @@ -935,41 +709,28 @@ public class DefaultWallpaperPersister implements WallpaperPersister { // Set the lock wallpaper ID to what Android set it to, following its having // copied the system wallpaper over to the lock screen when we changed from // "both" to distinct system and lock screen wallpapers. - if (currentRotatingWallpaperComponent - == RotatingWallpaperComponentChecker.ROTATING_WALLPAPER_COMPONENT_STATIC) { - mWallpaperPreferences.setLockWallpaperId( - mWallpaperManagerCompat.getWallpaperId(WallpaperManagerCompat.FLAG_LOCK)); - } else { - try { - FileInputStream fileInputStream = mDeviceProtectedContext.openFileInput( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - int lockWallpaperId = setStreamToWallpaperManagerCompat( - fileInputStream, false /* allowBackup */, WallpaperManagerCompat.FLAG_LOCK); - fileInputStream.close(); - mWallpaperPreferences.setLockWallpaperId(lockWallpaperId); - } catch (FileNotFoundException e) { - Log.e(TAG, "Couldn't copy over previously rotating wallpaper to lock screen."); - } catch (IOException e) { - Log.e(TAG, "IOException when closing the file input stream " + e); - } - } + mWallpaperPreferences.setLockWallpaperId( + mWallpaperManagerCompat.getWallpaperId(WallpaperManagerCompat.FLAG_LOCK)); + } /** - * Sets the image wallpaper's metadata on SharedPreferences. This method is called after the set - * wallpaper operation is successful. + * Sets the image wallpaper's metadata on SharedPreferences. This method is called after the + * set wallpaper operation is successful. * - * @param destination Which destination of wallpaper the metadata corresponds to (home screen, - * lock screen, or both). - * @param wallpaperId The ID of the static wallpaper returned by WallpaperManager, which on N - * and later versions of Android uniquely identifies a wallpaper image. + * @param destination Which destination of wallpaper the metadata corresponds to (home + * screen, lock screen, or both). + * @param wallpaperId The ID of the static wallpaper returned by WallpaperManager, which + * on N and later versions of Android uniquely identifies a wallpaper + * image. */ private void setImageWallpaperMetadata(@Destination int destination, int wallpaperId) { if (destination == DEST_HOME_SCREEN || destination == DEST_BOTH) { mWallpaperPreferences.clearHomeWallpaperMetadata(); setImageWallpaperHomeMetadata(wallpaperId); - // Reset presentation mode to STATIC if an individual wallpaper is set to the home screen + // Reset presentation mode to STATIC if an individual wallpaper is set to the + // home screen // because rotation always affects at least the home screen. mWallpaperPreferences.setWallpaperPresentationMode( WallpaperPreferences.PRESENTATION_MODE_STATIC); @@ -988,10 +749,11 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.setHomeWallpaperManagerId(homeWallpaperId); } - // Compute bitmap hash code after setting the wallpaper because JPEG compression has likely - // changed many pixels' color values. Forget the previously loaded wallpaper bitmap so that - // WallpaperManager doesn't return the old wallpaper drawable. Do this on N+ devices in - // addition to saving the wallpaper ID for the purpose of backup & restore. + // Compute bitmap hash code after setting the wallpaper because JPEG compression has + // likely changed many pixels' color values. Forget the previously loaded wallpaper + // bitmap so that WallpaperManager doesn't return the old wallpaper drawable. Do this + // on N+ devices in addition to saving the wallpaper ID for the purpose of backup & + // restore. mWallpaperManager.forgetLoadedWallpaper(); mBitmap = ((BitmapDrawable) mWallpaperManagerCompat.getDrawable()).getBitmap(); long bitmapHash = BitmapUtils.generateHashCode(mBitmap); @@ -1023,9 +785,10 @@ public class DefaultWallpaperPersister implements WallpaperPersister { mWallpaperPreferences.setLockWallpaperCollectionId( mWallpaper.getCollectionId(mAppContext)); - // Save the lock wallpaper image's hash code as well for the sake of backup & restore because - // WallpaperManager-generated IDs are specific to a physical device and cannot be used to - // identify a wallpaper image on another device after restore is complete. + // Save the lock wallpaper image's hash code as well for the sake of backup & restore + // because WallpaperManager-generated IDs are specific to a physical device and + // cannot be used to identify a wallpaper image on another device after restore is + // complete. saveLockWallpaperHashCode(); } @@ -1051,7 +814,9 @@ public class DefaultWallpaperPersister implements WallpaperPersister { try { fileStream.close(); } catch (IOException e) { - Log.e(TAG, "IO exception when closing the input stream for the lock screen WP."); + Log.e(TAG, + "IO exception when closing the input stream for the lock screen " + + "WP."); } } } diff --git a/src/com/android/wallpaper/module/DefaultWallpaperPreferences.java b/src/com/android/wallpaper/module/DefaultWallpaperPreferences.java index 319276b..b040ebb 100755 --- a/src/com/android/wallpaper/module/DefaultWallpaperPreferences.java +++ b/src/com/android/wallpaper/module/DefaultWallpaperPreferences.java @@ -24,6 +24,8 @@ import android.util.Log; import androidx.annotation.Nullable; +import com.android.wallpaper.module.WallpaperPreferenceKeys.NoBackupKeys; + import org.json.JSONArray; import org.json.JSONException; @@ -39,10 +41,12 @@ import java.util.List; */ public class DefaultWallpaperPreferences implements WallpaperPreferences { public static final String PREFS_NAME = "wallpaper"; + public static final String NO_BACKUP_PREFS_NAME = "wallpaper-nobackup"; private static final String TAG = "DefaultWPPreferences"; protected SharedPreferences mSharedPrefs; + protected SharedPreferences mNoBackupPrefs; protected Context mContext; // Keep a strong reference to this OnSharedPreferenceChangeListener to prevent the listener from @@ -51,19 +55,106 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { public DefaultWallpaperPreferences(Context context) { mSharedPrefs = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE); + mNoBackupPrefs = context.getSharedPreferences(NO_BACKUP_PREFS_NAME, Context.MODE_PRIVATE); + if (mNoBackupPrefs.getAll().isEmpty() && !mSharedPrefs.getAll().isEmpty()) { + upgradePrefs(); + } mContext = context.getApplicationContext(); // Register a prefs changed listener so that all prefs changes trigger a backup event. final BackupManager backupManager = new BackupManager(context); - mSharedPrefsChangedListener = new OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - backupManager.dataChanged(); - } - }; + mSharedPrefsChangedListener = (sharedPreferences, key) -> backupManager.dataChanged(); mSharedPrefs.registerOnSharedPreferenceChangeListener(mSharedPrefsChangedListener); } + /** + * Move {@link NoBackupKeys} preferences that might have been in mSharedPrefs from previous + * versions of the app into mNoBackupPrefs. + */ + private void upgradePrefs() { + SharedPreferences.Editor editor = mNoBackupPrefs.edit(); + if (mSharedPrefs.contains( + NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, null)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID)) { + editor.putInt(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, + mSharedPrefs.getInt(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, null)); + } + if (mSharedPrefs.contains( + NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, null)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID)) { + editor.putInt(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, + mSharedPrefs.getInt(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, 0)); + } + if (mSharedPrefs.contains( + NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE)) { + editor.putString(NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, + mSharedPrefs.getString(NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, null)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS)) { + editor.putString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, + mSharedPrefs.getString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, null)); + } + if (mSharedPrefs.contains( + NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, -1)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_ROTATION_STATUS)) { + editor.putInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, + mSharedPrefs.getInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, -1)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP)) { + editor.putLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, + mSharedPrefs.getLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS)) { + editor.putInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + mSharedPrefs.getInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + WALLPAPER_SET_NOT_PENDING)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS)) { + editor.putInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + mSharedPrefs.getInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + DAILY_WALLPAPER_UPDATE_NOT_PENDING)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED)) { + editor.putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, + mSharedPrefs.getInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED)) { + editor.putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, + mSharedPrefs.getInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0)); + } + if (mSharedPrefs.contains(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME)) { + editor.putString(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, + mSharedPrefs.getString(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, null)); + } + + editor.apply(); + } + private int getResIdPersistedByName(String key, String type) { String resName = mSharedPrefs.getString(key, null); if (resName == null) { @@ -106,13 +197,16 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { public void setHomeWallpaperAttributions(List<String> attributions) { SharedPreferences.Editor editor = mSharedPrefs.edit(); if (attributions.size() > 0) { - editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_1, attributions.get(0)); + editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_1, + attributions.get(0)); } if (attributions.size() > 1) { - editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_2, attributions.get(1)); + editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_2, + attributions.get(1)); } if (attributions.size() > 2) { - editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_3, attributions.get(2)); + editor.putString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ATTRIB_3, + attributions.get(2)); } editor.apply(); } @@ -155,19 +249,22 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override public String getHomeWallpaperBaseImageUrl() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, null); } @Override public void setHomeWallpaperBaseImageUrl(String baseImageUrl) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, baseImageUrl).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL, baseImageUrl) + .apply(); } @Override @Nullable public String getHomeWallpaperCollectionId() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_COLLECTION_ID, null); + return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_COLLECTION_ID, + null); } @Override @@ -179,14 +276,14 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override @Nullable public String getHomeWallpaperBackingFileName() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BACKING_FILE, - null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, null); } @Override public void setHomeWallpaperBackingFileName(String fileName) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BACKING_FILE, fileName).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE, fileName).apply(); } @Override @@ -213,47 +310,56 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ACTION_URL) .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ACTION_LABEL_RES) .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_ACTION_ICON_RES) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL) .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_HASH_CODE) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_MANAGER_ID) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_REMOTE_ID) - .remove(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_BACKING_FILE) + .apply(); + + mNoBackupPrefs.edit() + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_BASE_IMAGE_URL) + .remove(NoBackupKeys.KEY_HOME_WALLPAPER_BACKING_FILE) .apply(); } @Override public String getHomeWallpaperPackageName() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, null); } @Override public void setHomeWallpaperPackageName(String packageName) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, packageName).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_PACKAGE_NAME, packageName) + .apply(); } @Override public int getHomeWallpaperManagerId() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_MANAGER_ID, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, 0); } @Override public void setHomeWallpaperManagerId(int homeWallpaperId) { - mSharedPrefs.edit().putInt( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_MANAGER_ID, homeWallpaperId).apply(); + mNoBackupPrefs.edit().putInt( + NoBackupKeys.KEY_HOME_WALLPAPER_MANAGER_ID, homeWallpaperId) + .apply(); } @Nullable @Override public String getHomeWallpaperRemoteId() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_REMOTE_ID, null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, null); } @Override public void setHomeWallpaperRemoteId(@Nullable String wallpaperRemoteId) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_HOME_WALLPAPER_REMOTE_ID, wallpaperRemoteId).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_HOME_WALLPAPER_REMOTE_ID, wallpaperRemoteId) + .apply(); } @Override @@ -269,13 +375,16 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { public void setLockWallpaperAttributions(List<String> attributions) { SharedPreferences.Editor editor = mSharedPrefs.edit(); if (attributions.size() > 0) { - editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_1, attributions.get(0)); + editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_1, + attributions.get(0)); } if (attributions.size() > 1) { - editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_2, attributions.get(1)); + editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_2, + attributions.get(1)); } if (attributions.size() > 2) { - editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_3, attributions.get(2)); + editor.putString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ATTRIB_3, + attributions.get(2)); } editor.apply(); } @@ -319,7 +428,8 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override @Nullable public String getLockWallpaperCollectionId() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_COLLECTION_ID, null); + return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_COLLECTION_ID, + null); } @Override @@ -331,25 +441,27 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override @Nullable public String getLockWallpaperBackingFileName() { - return mSharedPrefs.getString(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, - null); + return mNoBackupPrefs.getString( + NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, null); } @Override public void setLockWallpaperBackingFileName(String fileName) { - mSharedPrefs.edit().putString( - WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, fileName).apply(); + mNoBackupPrefs.edit().putString( + NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE, fileName).apply(); } @Override public int getLockWallpaperId() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, 0); } @Override public void setLockWallpaperId(int lockWallpaperId) { - mSharedPrefs.edit().putInt( - WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, lockWallpaperId).apply(); + mNoBackupPrefs.edit().putInt( + NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID, lockWallpaperId) + .apply(); } @Override @@ -378,21 +490,25 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ACTION_LABEL_RES) .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_ACTION_ICON_RES) .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_HASH_CODE) - .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_MANAGER_ID) - .remove(WallpaperPreferenceKeys.KEY_LOCK_WALLPAPER_BACKING_FILE) + .apply(); + + mNoBackupPrefs.edit() + .remove(NoBackupKeys.KEY_LOCK_WALLPAPER_MANAGER_ID) + .remove(NoBackupKeys.KEY_LOCK_WALLPAPER_BACKING_FILE) .apply(); } @Override public void addDailyRotation(long timestamp) { - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); jsonArray.put(timestamp); - mSharedPrefs.edit() - .putString(WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, jsonArray.toString()) + mNoBackupPrefs.edit() + .putString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, + jsonArray.toString()) .apply(); } catch (JSONException e) { Log.e(TAG, "Failed to add a daily rotation timestamp due to a JSON parse exception"); @@ -401,8 +517,8 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override public long getLastDailyRotationTimestamp() { - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); @@ -428,15 +544,15 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { oneWeekAgo.add(Calendar.WEEK_OF_YEAR, -1); long oneWeekAgoTimestamp = oneWeekAgo.getTimeInMillis(); - // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled earlier - // than one week ago. + // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled + // less than one week ago. if (enabledTimestamp == -1 || enabledTimestamp > oneWeekAgoTimestamp) { return null; } List<Long> timestamps = new ArrayList<>(); - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); @@ -451,8 +567,9 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { } jsonArray = new JSONArray(timestamps); - mSharedPrefs.edit() - .putString(WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, jsonArray.toString()) + mNoBackupPrefs.edit() + .putString(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, + jsonArray.toString()) .apply(); } catch (JSONException e) { Log.e(TAG, "Failed to get daily rotation timestamps due to a JSON parse exception"); @@ -479,21 +596,21 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { midnightToday.set(Calendar.MINUTE, 0); long midnightTodayTimestamp = midnightToday.getTimeInMillis(); - // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled earlier - // than midnight yesterday. + // Return null if daily rotation wasn't enabled (timestamp value of -1) or was enabled + // less than midnight yesterday. if (enabledTimestamp == -1 || enabledTimestamp > midnightYesterdayTimestamp) { return null; } List<Long> timestamps = new ArrayList<>(); - String jsonString = mSharedPrefs.getString( - WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); + String jsonString = mNoBackupPrefs.getString( + NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS, "[]"); try { JSONArray jsonArray = new JSONArray(jsonString); - // Filter the timestamps (which cover up to one week of data) to only include those between - // midnight yesterday and midnight today. + // Filter the timestamps (which cover up to one week of data) to only include those + // between midnight yesterday and midnight today. for (int i = 0; i < jsonArray.length(); i++) { long timestamp = jsonArray.getLong(i); if (timestamp >= midnightYesterdayTimestamp && timestamp < midnightTodayTimestamp) { @@ -510,160 +627,175 @@ public class DefaultWallpaperPreferences implements WallpaperPreferences { @Override public long getDailyWallpaperEnabledTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, -1); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, -1); } @Override public void setDailyWallpaperEnabledTimestamp(long timestamp) { - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP, + timestamp) .apply(); } @Override public void clearDailyRotations() { - mSharedPrefs.edit() - .remove(WallpaperPreferenceKeys.KEY_DAILY_ROTATION_TIMESTAMPS) - .remove(WallpaperPreferenceKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP) + mNoBackupPrefs.edit() + .remove(NoBackupKeys.KEY_DAILY_ROTATION_TIMESTAMPS) + .remove(NoBackupKeys.KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP) .apply(); } @Override public long getLastDailyLogTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, 0); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, 0); } @Override public void setLastDailyLogTimestamp(long timestamp) { - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_LAST_DAILY_LOG_TIMESTAMP, timestamp) .apply(); } @Override public long getLastAppActiveTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, 0); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, 0); } @Override public void setLastAppActiveTimestamp(long timestamp) { - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_LAST_APP_ACTIVE_TIMESTAMP, timestamp) .apply(); } @Override public void setDailyWallpaperRotationStatus(int status, long timestamp) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS, status) - .putLong(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, timestamp) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, status) + .putLong(NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, + timestamp) .apply(); } @Override public int getDailyWallpaperLastRotationStatus() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS, -1); + return mNoBackupPrefs.getInt(NoBackupKeys.KEY_LAST_ROTATION_STATUS, -1); } @Override public long getDailyWallpaperLastRotationStatusTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, 0); + return mNoBackupPrefs.getLong( + NoBackupKeys.KEY_LAST_ROTATION_STATUS_TIMESTAMP, 0); } @Override public long getLastSyncTimestamp() { - return mSharedPrefs.getLong(WallpaperPreferenceKeys.KEY_LAST_SYNC_TIMESTAMP, 0); + return mNoBackupPrefs.getLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, 0); } @Override public void setLastSyncTimestamp(long timestamp) { - // Write synchronously via commit() to ensure this timetsamp gets written to disk immediately. - mSharedPrefs.edit() - .putLong(WallpaperPreferenceKeys.KEY_LAST_SYNC_TIMESTAMP, timestamp) + // Write synchronously via commit() to ensure this timetsamp gets written to disk + // immediately. + mNoBackupPrefs.edit() + .putLong(NoBackupKeys.KEY_LAST_SYNC_TIMESTAMP, timestamp) .commit(); } @Override public void setPendingWallpaperSetStatusSync(@PendingWallpaperSetStatus int setStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_WALLPAPER_SET_STATUS, setStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + setStatus) .commit(); } @Override public int getPendingWallpaperSetStatus() { //noinspection ResourceType - return mSharedPrefs.getInt( - WallpaperPreferenceKeys.KEY_PENDING_WALLPAPER_SET_STATUS, WALLPAPER_SET_NOT_PENDING); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + WALLPAPER_SET_NOT_PENDING); } @Override public void setPendingWallpaperSetStatus(@PendingWallpaperSetStatus int setStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_WALLPAPER_SET_STATUS, setStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_WALLPAPER_SET_STATUS, + setStatus) .apply(); } @Override public void setPendingDailyWallpaperUpdateStatusSync( @PendingDailyWallpaperUpdateStatus int updateStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, updateStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + updateStatus) .commit(); } @Override public int getPendingDailyWallpaperUpdateStatus() { //noinspection ResourceType - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, DAILY_WALLPAPER_UPDATE_NOT_PENDING); } @Override public void setPendingDailyWallpaperUpdateStatus( @PendingDailyWallpaperUpdateStatus int updateStatus) { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, updateStatus) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS, + updateStatus) .apply(); } @Override public void incrementNumDaysDailyRotationFailed() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, getNumDaysDailyRotationFailed() + 1) .apply(); } @Override public int getNumDaysDailyRotationFailed() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0); } @Override public void resetNumDaysDailyRotationFailed() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_FAILED, 0) .apply(); } @Override public void incrementNumDaysDailyRotationNotAttempted() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, getNumDaysDailyRotationNotAttempted() + 1) .apply(); } @Override public int getNumDaysDailyRotationNotAttempted() { - return mSharedPrefs.getInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0); + return mNoBackupPrefs.getInt( + NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0); } @Override public void resetNumDaysDailyRotationNotAttempted() { - mSharedPrefs.edit() - .putInt(WallpaperPreferenceKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0) + mNoBackupPrefs.edit() + .putInt(NoBackupKeys.KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED, 0) .apply(); } } diff --git a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java index c97d2b9..d85e04e 100755 --- a/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java +++ b/src/com/android/wallpaper/module/DefaultWallpaperRefresher.java @@ -32,7 +32,6 @@ import com.android.wallpaper.compat.WallpaperManagerCompat; import com.android.wallpaper.model.WallpaperMetadata; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -50,9 +49,6 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { private final Context mAppContext; private final WallpaperPreferences mWallpaperPreferences; private final WallpaperManager mWallpaperManager; - private final LiveWallpaperStatusChecker mLiveWallpaperStatusChecker; - private final UserEventLogger mUserEventLogger; - private final Context mDeviceProtectedContext; /** * @param context The application's context. @@ -62,13 +58,10 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { Injector injector = InjectorProvider.getInjector(); mWallpaperPreferences = injector.getPreferences(mAppContext); - mLiveWallpaperStatusChecker = injector.getLiveWallpaperStatusChecker(mAppContext); - mUserEventLogger = injector.getUserEventLogger(mAppContext); // Retrieve WallpaperManager using Context#getSystemService instead of // WallpaperManager#getInstance so it can be mocked out in test. mWallpaperManager = (WallpaperManager) context.getSystemService(Context.WALLPAPER_SERVICE); - mDeviceProtectedContext = mAppContext.createDeviceProtectedStorageContext(); } @Override @@ -203,8 +196,7 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { * current system wallpaper. */ private boolean isHomeScreenMetadataCurrent() { - return (mWallpaperManager.getWallpaperInfo() == null - || mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) + return (mWallpaperManager.getWallpaperInfo() == null) ? isHomeScreenImageWallpaperCurrent() : isHomeScreenLiveWallpaperCurrent(); } @@ -221,36 +213,6 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { private long getCurrentHomeWallpaperHashCode() { if (mCurrentHomeWallpaperHashCode == 0) { - if (mLiveWallpaperStatusChecker.isNoBackupImageWallpaperSet()) { - - synchronized (RotatingWallpaperLockProvider.getInstance()) { - Bitmap bitmap = null; - try { - FileInputStream fis = - mDeviceProtectedContext.openFileInput( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - bitmap = BitmapFactory.decodeStream(fis); - fis.close(); - } catch (FileNotFoundException e) { - Log.e(TAG, "Rotating wallpaper file not found at path: " - + mDeviceProtectedContext.getFileStreamPath( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH), - e); - } catch (IOException e) { - Log.e(TAG, "IOException when closing FileInputStream " + e); - } - - if (bitmap != null) { - mCurrentHomeWallpaperHashCode = BitmapUtils.generateHashCode(bitmap); - mUserEventLogger.logDailyWallpaperDecodes(true); - } else { - // If an error occurred decoding the stream then we should just assume the current - // home wallpaper remained intact. - mCurrentHomeWallpaperHashCode = mWallpaperPreferences.getHomeWallpaperHashCode(); - mUserEventLogger.logDailyWallpaperDecodes(false); - } - } - } else { BitmapDrawable wallpaperDrawable = (BitmapDrawable) mWallpaperManagerCompat.getDrawable(); Bitmap wallpaperBitmap = wallpaperDrawable.getBitmap(); mCurrentHomeWallpaperHashCode = BitmapUtils.generateHashCode(wallpaperBitmap); @@ -258,7 +220,6 @@ public class DefaultWallpaperRefresher implements WallpaperRefresher { // Manually request that WallpaperManager loses its reference to the current wallpaper // bitmap, which can occupy a large memory allocation for the lifetime of the app. mWallpaperManager.forgetLoadedWallpaper(); - } } return mCurrentHomeWallpaperHashCode; } diff --git a/src/com/android/wallpaper/module/Injector.java b/src/com/android/wallpaper/module/Injector.java index 3afaeb4..ca64b9d 100755 --- a/src/com/android/wallpaper/module/Injector.java +++ b/src/com/android/wallpaper/module/Injector.java @@ -44,8 +44,6 @@ public interface Injector { FormFactorChecker getFormFactorChecker(Context context); - LiveWallpaperStatusChecker getLiveWallpaperStatusChecker(Context context); - LoggingOptInStatusProvider getLoggingOptInStatusProvider(Context context); NetworkStatusNotifier getNetworkStatusNotifier(Context context); @@ -56,8 +54,6 @@ public interface Injector { Requester getRequester(Context context); - RotatingWallpaperComponentChecker getRotatingWallpaperComponentChecker(); - SystemFeatureChecker getSystemFeatureChecker(); UserEventLogger getUserEventLogger(Context context); diff --git a/src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java b/src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java deleted file mode 100755 index 67d87f8..0000000 --- a/src/com/android/wallpaper/module/LiveWallpaperStatusChecker.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2017 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.wallpaper.module; - -/** - * Reads whether the application's live wallpaper service is set to the device. - */ -public interface LiveWallpaperStatusChecker { - - /** - * Returns whether the live wallpaper for daily wallpapers is set to the device. - */ - boolean isNoBackupImageWallpaperSet(); -} diff --git a/src/com/android/wallpaper/module/NoBackupImageWallpaper.java b/src/com/android/wallpaper/module/NoBackupImageWallpaper.java deleted file mode 100755 index a76d881..0000000 --- a/src/com/android/wallpaper/module/NoBackupImageWallpaper.java +++ /dev/null @@ -1,1018 +0,0 @@ -/* - * Copyright (C) 2017 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.wallpaper.module; - -import static javax.microedition.khronos.egl.EGL10.EGL_NO_CONTEXT; -import static javax.microedition.khronos.egl.EGL10.EGL_NO_SURFACE; - -import android.annotation.SuppressLint; -import android.app.WallpaperColors; -import android.app.WallpaperManager; -import android.content.BroadcastReceiver; -import android.content.ComponentCallbacks2; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Point; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.BitmapDrawable; -import android.graphics.drawable.Drawable; -import android.opengl.GLES20; -import android.opengl.GLUtils; -import android.os.AsyncTask; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; -import android.os.Handler; -import android.renderscript.Matrix4f; -import android.service.wallpaper.WallpaperService; -import android.util.Log; -import android.view.Display; -import android.view.MotionEvent; -import android.view.SurfaceHolder; -import android.view.WindowManager; - -import com.android.wallpaper.util.ScreenSizeCalculator; - -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.nio.FloatBuffer; - -import javax.microedition.khronos.egl.EGL10; -import javax.microedition.khronos.egl.EGLConfig; -import javax.microedition.khronos.egl.EGLContext; -import javax.microedition.khronos.egl.EGLDisplay; -import javax.microedition.khronos.egl.EGLSurface; - -import androidx.annotation.RequiresApi; - -/** - * Live wallpaper service which simply renders a wallpaper from internal storage. Designed as a - * workaround to WallpaperManager not having an allowBackup=false option on pre-N builds of Android. - * <p> - * Adapted from {@code com.android.systemui.ImageWallpaper}. - */ -@SuppressLint("ServiceCast") -public class NoBackupImageWallpaper extends WallpaperService { - - public static final String ACTION_ROTATING_WALLPAPER_CHANGED = - ".ACTION_ROTATING_WALLPAPER_CHANGED"; - public static final String PERMISSION_NOTIFY_ROTATING_WALLPAPER_CHANGED = - ".NOTIFY_ROTATING_WALLPAPER_CHANGED"; - public static final String PREVIEW_WALLPAPER_FILE_PATH = "preview_wallpaper.jpg"; - public static final String ROTATING_WALLPAPER_FILE_PATH = "rotating_wallpaper.jpg"; - - private static final String TAG = "NoBackupImageWallpaper"; - private static final String GL_LOG_TAG = "ImageWallpaperGL"; - private static final boolean DEBUG = false; - private static final boolean FIXED_SIZED_SURFACE = false; - - private final Handler mHandler = new Handler(); - - private int mOpenGlContextCounter; - private WallpaperManager mWallpaperManager; - private DrawableEngine mEngine; - private boolean mIsHardwareAccelerated; - - @Override - public void onCreate() { - super.onCreate(); - - mOpenGlContextCounter = 0; - mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE); - - // By default, use OpenGL for drawing the static wallpaper image. - mIsHardwareAccelerated = true; - } - - @Override - public void onTrimMemory(int level) { - if (mEngine != null) { - mEngine.trimMemory(level); - } - } - - @Override - public Engine onCreateEngine() { - mEngine = new DrawableEngine(); - return mEngine; - } - - private class DrawableEngine extends Engine { - static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; - static final int EGL_OPENGL_ES2_BIT = 4; - private static final String S_SIMPLE_VS = - "attribute vec4 position;\n" - + "attribute vec2 texCoords;\n" - + "varying vec2 outTexCoords;\n" - + "uniform mat4 projection;\n" - + "\nvoid main(void) {\n" - + " outTexCoords = texCoords;\n" - + " gl_Position = projection * position;\n" - + "}\n\n"; - private static final String S_SIMPLE_FS = - "precision mediump float;\n\n" - + "varying vec2 outTexCoords;\n" - + "uniform sampler2D texture;\n" - + "\nvoid main(void) {\n" - + " gl_FragColor = texture2D(texture, outTexCoords);\n" - + "}\n\n"; - private static final int FLOAT_SIZE_BYTES = 4; - private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; - private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; - private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; - Bitmap mBackground; - WallpaperColors mCachedWallpaperColors; - int mBackgroundWidth = -1, mBackgroundHeight = -1; - int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; - int mLastRotation = -1; - float mXOffset = 0.5f; - float mYOffset = 0.5f; - float mScale = 1f; - boolean mVisible = true; - boolean mOffsetsChanged; - int mLastXTranslation; - int mLastYTranslation; - private Display mDefaultDisplay; - private EGL10 mEgl; - private EGLDisplay mEglDisplay; - private EGLConfig mEglConfig; - private EGLContext mEglContext; - private EGLSurface mEglSurface; - private int mTexture; - private int mProgram; - private boolean mIsOpenGlTextureLoaded; - private int mRotationAtLastSurfaceSizeUpdate = -1; - private int mDisplayWidthAtLastSurfaceSizeUpdate = -1; - private int mDisplayHeightAtLastSurfaceSizeUpdate = -1; - - private int mLastRequestedWidth = -1; - private int mLastRequestedHeight = -1; - private AsyncTask<Void, Void, Bitmap> mLoader; - private boolean mNeedsDrawAfterLoadingWallpaper; - private boolean mSurfaceValid; - - private BroadcastReceiver mReceiver; - - public DrawableEngine() { - super(); - } - - public void trimMemory(int level) { - if (level >= ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW - && mBackground != null) { - if (DEBUG) { - Log.d(TAG, "trimMemory"); - } - mBackground.recycle(); - mBackground = null; - mBackgroundWidth = -1; - mBackgroundHeight = -1; - } - } - - @Override - public void onCreate(SurfaceHolder surfaceHolder) { - if (DEBUG) { - Log.d(TAG, "onCreate"); - } - - super.onCreate(surfaceHolder); - - mIsOpenGlTextureLoaded = false; - - mDefaultDisplay = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)) - .getDefaultDisplay(); - - updateSurfaceSize(surfaceHolder, mDefaultDisplay, false /* forDraw */); - - // Enable offset notifications to pan wallpaper for parallax effect. - setOffsetNotificationsEnabled(true); - - // If not a preview, then register a local broadcast receiver for listening to changes in the - // rotating wallpaper file. - if (!isPreview()) { - IntentFilter filter = new IntentFilter(); - filter.addAction(getPackageName() + ACTION_ROTATING_WALLPAPER_CHANGED); - - mReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (DEBUG) { - Log.i(TAG, "Broadcast received with intent: " + intent); - } - - String action = intent.getAction(); - if (action.equals(getPackageName() + ACTION_ROTATING_WALLPAPER_CHANGED)) { - DrawableEngine.this.invalidateAndRedrawWallpaper(); - } - } - }; - - registerReceiver(mReceiver, filter, getPackageName() - + PERMISSION_NOTIFY_ROTATING_WALLPAPER_CHANGED, null /* handler */); - } - } - - @Override - public void onDestroy() { - super.onDestroy(); - mBackground = null; - mWallpaperManager.forgetLoadedWallpaper(); - - if (!isPreview() && mReceiver != null) { - unregisterReceiver(mReceiver); - } - } - - boolean updateSurfaceSize(SurfaceHolder surfaceHolder, Display display, boolean forDraw) { - boolean hasWallpaper = true; - Point displaySize = ScreenSizeCalculator.getInstance().getScreenSize(display); - - // Load background image dimensions, if we haven't saved them yet - if (mBackgroundWidth <= 0 || mBackgroundHeight <= 0) { - // Need to load the image to get dimensions - loadWallpaper(forDraw); - if (DEBUG) { - Log.d(TAG, "Reloading, redoing updateSurfaceSize later."); - } - hasWallpaper = false; - } - - // Force the wallpaper to cover the screen in both dimensions - int surfaceWidth = Math.max(displaySize.x, mBackgroundWidth); - int surfaceHeight = Math.max(displaySize.y, mBackgroundHeight); - - if (FIXED_SIZED_SURFACE) { - // Used a fixed size surface, because we are special. We can do - // this because we know the current design of window animations doesn't - // cause this to break. - surfaceHolder.setFixedSize(surfaceWidth, surfaceHeight); - mLastRequestedWidth = surfaceWidth; - mLastRequestedHeight = surfaceHeight; - } else { - surfaceHolder.setSizeFromLayout(); - } - return hasWallpaper; - } - - @Override - public void onVisibilityChanged(boolean visible) { - if (DEBUG) { - Log.d(TAG, "onVisibilityChanged: mVisible, visible=" + mVisible + ", " + visible); - } - - if (mVisible != visible) { - if (DEBUG) { - Log.d(TAG, "Visibility changed to visible=" + visible); - } - mVisible = visible; - drawFrame(false /* forceRedraw */); - } - } - - @Override - public void onTouchEvent(MotionEvent event) { - super.onTouchEvent(event); - } - - @Override - public void onOffsetsChanged(float xOffset, float yOffset, - float xOffsetStep, float yOffsetStep, - int xPixels, int yPixels) { - if (DEBUG) { - Log.d(TAG, "onOffsetsChanged: xOffset=" + xOffset + ", yOffset=" + yOffset - + ", xOffsetStep=" + xOffsetStep + ", yOffsetStep=" + yOffsetStep - + ", xPixels=" + xPixels + ", yPixels=" + yPixels); - } - - if (mXOffset != xOffset || mYOffset != yOffset) { - if (DEBUG) { - Log.d(TAG, "Offsets changed to (" + xOffset + "," + yOffset + ")."); - } - mXOffset = xOffset; - mYOffset = yOffset; - mOffsetsChanged = true; - } - mHandler.post(new Runnable() { - @Override - public void run() { - drawFrame(false /* forceRedraw */); - } - }); - } - - @Override - public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { - if (DEBUG) { - Log.d(TAG, "onSurfaceChanged: width=" + width + ", height=" + height); - } - - super.onSurfaceChanged(holder, format, width, height); - - // Retrieve buffer in new size. - if (mEgl != null) { - mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); - } - drawFrame(false /* forceRedraw */); - } - - @Override - public void onSurfaceDestroyed(SurfaceHolder holder) { - super.onSurfaceDestroyed(holder); - if (DEBUG) { - Log.d(TAG, "onSurfaceDestroyed"); - } - mLastSurfaceWidth = mLastSurfaceHeight = -1; - mSurfaceValid = false; - - if (mIsHardwareAccelerated) { - finishGL(mTexture, mProgram); - } - } - - @Override - public void onSurfaceCreated(SurfaceHolder holder) { - super.onSurfaceCreated(holder); - if (DEBUG) { - Log.d(TAG, "onSurfaceCreated"); - } - mLastSurfaceWidth = mLastSurfaceHeight = -1; - mSurfaceValid = true; - - if (mIsHardwareAccelerated) { - if (!initGL(holder)) { - // Fall back to canvas drawing if initializing OpenGL failed. - mIsHardwareAccelerated = false; - mEgl = null; - } - } - } - - @Override - public void onSurfaceRedrawNeeded(SurfaceHolder holder) { - if (DEBUG) { - Log.d(TAG, "onSurfaceRedrawNeeded"); - } - super.onSurfaceRedrawNeeded(holder); - - drawFrame(true /* forceRedraw */); - } - - @RequiresApi(VERSION_CODES.O_MR1) - @Override - public WallpaperColors onComputeColors() { - // It's OK to return null here. - return mCachedWallpaperColors; - } - - /** - * Invalidates the currently-drawn wallpaper image, causing the engine to reload the image from - * disk and draw the new wallpaper image. - */ - public void invalidateAndRedrawWallpaper() { - // If a wallpaper load was already in flight, cancel it and restart a load in order to decode - // the new image. - if (mLoader != null) { - mLoader.cancel(true /* mayInterruptIfRunning */); - mLoader = null; - } - - loadWallpaper(true /* needsDraw */); - } - - void drawFrame(boolean forceRedraw) { - if (!mSurfaceValid) { - return; - } - - Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(mDefaultDisplay); - int newRotation = mDefaultDisplay.getRotation(); - - // Sometimes a wallpaper is not large enough to cover the screen in one dimension. - // Call updateSurfaceSize -- it will only actually do the update if the dimensions - // should change - if (newRotation != mLastRotation) { - // Update surface size (if necessary) - if (!updateSurfaceSize(getSurfaceHolder(), mDefaultDisplay, true /* forDraw */)) { - return; - } - mRotationAtLastSurfaceSizeUpdate = newRotation; - mDisplayWidthAtLastSurfaceSizeUpdate = screenSize.x; - mDisplayHeightAtLastSurfaceSizeUpdate = screenSize.y; - } - SurfaceHolder sh = getSurfaceHolder(); - final Rect frame = sh.getSurfaceFrame(); - final int dw = frame.width(); - final int dh = frame.height(); - boolean surfaceDimensionsChanged = dw != mLastSurfaceWidth - || dh != mLastSurfaceHeight; - - boolean redrawNeeded = surfaceDimensionsChanged || newRotation != mLastRotation - || forceRedraw; - if (!redrawNeeded && !mOffsetsChanged) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since redraw is not needed " - + "and offsets have not changed."); - } - return; - } - mLastRotation = newRotation; - - // Load bitmap if its null and we're not using hardware acceleration. - if ((mIsHardwareAccelerated && !mIsOpenGlTextureLoaded) // Using OpenGL but texture not loaded - || (!mIsHardwareAccelerated && mBackground == null)) { // Draw with Canvas but no bitmap - if (DEBUG) { - Log.d(TAG, "Reloading bitmap: mBackground, bgw, bgh, dw, dh = " - + mBackground + ", " + ((mBackground == null) ? 0 : mBackground.getWidth()) + ", " - + ((mBackground == null) ? 0 : mBackground.getHeight()) + ", " + dw + ", " + dh); - } - loadWallpaper(true /* needDraw */); - if (DEBUG) { - Log.d(TAG, "Reloading, resuming draw later"); - } - return; - } - - // Center the scaled image - mScale = Math.max(1f, Math.max(dw / (float) mBackgroundWidth, - dh / (float) mBackgroundHeight)); - final int availw = dw - (int) (mBackgroundWidth * mScale); - final int availh = dh - (int) (mBackgroundHeight * mScale); - int xPixels = availw / 2; - int yPixels = availh / 2; - - // Adjust the image for xOffset/yOffset values. If window manager is handling offsets, - // mXOffset and mYOffset are set to 0.5f by default and therefore xPixels and yPixels - // will remain unchanged - final int availwUnscaled = dw - mBackgroundWidth; - final int availhUnscaled = dh - mBackgroundHeight; - if (availwUnscaled < 0) { - xPixels += (int) (availwUnscaled * (mXOffset - .5f) + .5f); - } - if (availhUnscaled < 0) { - yPixels += (int) (availhUnscaled * (mYOffset - .5f) + .5f); - } - - mOffsetsChanged = false; - if (surfaceDimensionsChanged) { - mLastSurfaceWidth = dw; - mLastSurfaceHeight = dh; - } - if (!redrawNeeded && xPixels == mLastXTranslation && yPixels == mLastYTranslation) { - if (DEBUG) { - Log.d(TAG, "Suppressed drawFrame since the image has not " - + "actually moved an integral number of pixels."); - } - return; - } - mLastXTranslation = xPixels; - mLastYTranslation = yPixels; - - if (DEBUG) { - Log.d(TAG, "Redrawing wallpaper"); - } - - if (mIsHardwareAccelerated) { - if (!drawWallpaperWithOpenGL(sh, availw, availh, xPixels, yPixels)) { - drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); - } else { - // If OpenGL drawing was successful, then we can safely discard a reference to the - // wallpaper bitmap to save memory (since a copy has already been loaded into an OpenGL - // texture). - mBackground = null; - } - } else { - drawWallpaperWithCanvas(sh, availw, availh, xPixels, yPixels); - } - } - - /** - * Loads the wallpaper on background thread and schedules updating the surface frame, - * and if {@param needsDraw} is set also draws a frame. - * <p> - * If loading is already in-flight, subsequent loads are ignored (but needDraw is or-ed to - * the active request). - * <p> - * If {@param needsReset} is set also clears the cache in WallpaperManager first. - */ - private void loadWallpaper(boolean needsDraw) { - mNeedsDrawAfterLoadingWallpaper |= needsDraw; - if (mLoader != null) { - if (DEBUG) { - Log.d(TAG, "Skipping loadWallpaper, already in flight "); - } - return; - } - mLoader = new AsyncTask<Void, Void, Bitmap>() { - @Override - protected Bitmap doInBackground(Void... params) { - Throwable exception = null; - try { - // Decode bitmap of rotating image wallpaper. - String wallpaperFilePath = isPreview() - ? PREVIEW_WALLPAPER_FILE_PATH : ROTATING_WALLPAPER_FILE_PATH; - Context context = isPreview() ? getApplicationContext() - : getApplicationContext().createDeviceProtectedStorageContext(); - FileInputStream fileInputStream = context.openFileInput(wallpaperFilePath); - Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream); - fileInputStream.close(); - return bitmap; - } catch (RuntimeException | FileNotFoundException | OutOfMemoryError e) { - Log.i(TAG, "couldn't decode stream: ", e); - exception = e; - } catch (IOException e) { - Log.i(TAG, "couldn't close stream: ", e); - exception = e; - } - - if (isCancelled()) { - return null; - } - - if (exception != null) { - // Note that if we do fail at this, and the default wallpaper can't - // be loaded, we will go into a cycle. Don't do a build where the - // default wallpaper can't be loaded. - Log.w(TAG, "Unable to load wallpaper!", exception); - try { - return ((BitmapDrawable) getFallbackDrawable()).getBitmap(); - } catch (OutOfMemoryError ex) { - // now we're really screwed. - Log.w(TAG, "Unable reset to default wallpaper!", ex); - } - - if (isCancelled()) { - return null; - } - } - return null; - } - - @Override - protected void onPostExecute(Bitmap b) { - mBackground = null; - mBackgroundWidth = -1; - mBackgroundHeight = -1; - - if (b != null) { - mBackground = b; - mBackgroundWidth = mBackground.getWidth(); - mBackgroundHeight = mBackground.getHeight(); - - if (VERSION.SDK_INT >= VERSION_CODES.O_MR1) { - mCachedWallpaperColors = WallpaperColors.fromBitmap(mBackground); - notifyColorsChanged(); - } - } - - if (DEBUG) { - Log.d(TAG, "Wallpaper loaded: " + mBackground); - } - updateSurfaceSize(getSurfaceHolder(), mDefaultDisplay, - false /* forDraw */); - if (mTexture != 0 && mEgl != null) { - deleteTexture(mTexture); - } - // If background is absent (due to an error decoding the bitmap) then don't try to load - // a texture. - if (mEgl != null && mBackground != null) { - mTexture = loadTexture(mBackground); - } - if (mNeedsDrawAfterLoadingWallpaper) { - drawFrame(true /* forceRedraw */); - } - - mLoader = null; - mNeedsDrawAfterLoadingWallpaper = false; - } - }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); - } - - private Drawable getFallbackDrawable() { - Drawable drawable; - try { - drawable = mWallpaperManager.getDrawable(); - } catch (java.lang.Exception e) { - // Work around Samsung bug where SecurityException is thrown if device is still using its - // default wallpaper, and around Android 7.0 bug where SELinux issues can cause a perfectly - // valid access of the current wallpaper to cause a failed Binder transaction manifest here - // as a RuntimeException. - drawable = mWallpaperManager.getBuiltInDrawable(); - } - return drawable; - } - - @Override - protected void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) { - super.dump(prefix, fd, out, args); - - out.print(prefix); - out.println("ImageWallpaper.DrawableEngine:"); - out.print(prefix); - out.print(" mBackground="); - out.print(mBackground); - out.print(" mBackgroundWidth="); - out.print(mBackgroundWidth); - out.print(" mBackgroundHeight="); - out.println(mBackgroundHeight); - - out.print(prefix); - out.print(" mLastRotation="); - out.print(mLastRotation); - out.print(" mLastSurfaceWidth="); - out.print(mLastSurfaceWidth); - out.print(" mLastSurfaceHeight="); - out.println(mLastSurfaceHeight); - - out.print(prefix); - out.print(" mXOffset="); - out.print(mXOffset); - out.print(" mYOffset="); - out.println(mYOffset); - - out.print(prefix); - out.print(" mVisible="); - out.print(mVisible); - out.print(" mOffsetsChanged="); - out.println(mOffsetsChanged); - - out.print(prefix); - out.print(" mLastXTranslation="); - out.print(mLastXTranslation); - out.print(" mLastYTranslation="); - out.print(mLastYTranslation); - out.print(" mScale="); - out.println(mScale); - - out.print(prefix); - out.print(" mLastRequestedWidth="); - out.print(mLastRequestedWidth); - out.print(" mLastRequestedHeight="); - out.println(mLastRequestedHeight); - - out.print(prefix); - out.println(" DisplayInfo at last updateSurfaceSize:"); - out.print(prefix); - out.print(" rotation="); - out.print(mRotationAtLastSurfaceSizeUpdate); - out.print(" width="); - out.print(mDisplayWidthAtLastSurfaceSizeUpdate); - out.print(" height="); - out.println(mDisplayHeightAtLastSurfaceSizeUpdate); - } - - private void drawWallpaperWithCanvas(SurfaceHolder sh, int w, int h, int left, int top) { - Canvas c = sh.lockCanvas(); - if (c != null) { - try { - if (DEBUG) { - Log.d(TAG, "Redrawing: left=" + left + ", top=" + top); - } - - final float right = left + mBackgroundWidth * mScale; - final float bottom = top + mBackgroundHeight * mScale; - if (w < 0 || h < 0) { - c.save(); - c.clipOutRect(left, top, right, bottom); - c.drawColor(0xff000000); - c.restore(); - } - if (mBackground != null) { - RectF dest = new RectF(left, top, right, bottom); - // add a filter bitmap? - c.drawBitmap(mBackground, null, dest, null); - } - } finally { - sh.unlockCanvasAndPost(c); - } - } - } - - private boolean drawWallpaperWithOpenGL(SurfaceHolder sh, int w, int h, int left, int top) { - - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - - final float right = left + mBackgroundWidth * mScale; - final float bottom = top + mBackgroundHeight * mScale; - - final Rect frame = sh.getSurfaceFrame(); - final Matrix4f ortho = new Matrix4f(); - ortho.loadOrtho(0.0f, frame.width(), frame.height(), 0.0f, -1.0f, 1.0f); - - final FloatBuffer triangleVertices = createMesh(left, top, right, bottom); - - final int attribPosition = GLES20.glGetAttribLocation(mProgram, "position"); - final int attribTexCoords = GLES20.glGetAttribLocation(mProgram, "texCoords"); - final int uniformTexture = GLES20.glGetUniformLocation(mProgram, "texture"); - final int uniformProjection = GLES20.glGetUniformLocation(mProgram, "projection"); - - checkGlError(); - - GLES20.glViewport(0, 0, frame.width(), frame.height()); - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture); - - GLES20.glUseProgram(mProgram); - GLES20.glEnableVertexAttribArray(attribPosition); - GLES20.glEnableVertexAttribArray(attribTexCoords); - GLES20.glUniform1i(uniformTexture, 0); - GLES20.glUniformMatrix4fv(uniformProjection, 1, false, ortho.getArray(), 0); - - checkGlError(); - - if (w > 0 || h > 0) { - GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); - } - - // drawQuad - triangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); - GLES20.glVertexAttribPointer(attribPosition, 3, GLES20.GL_FLOAT, false, - TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); - - triangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); - GLES20.glVertexAttribPointer(attribTexCoords, 3, GLES20.GL_FLOAT, false, - TRIANGLE_VERTICES_DATA_STRIDE_BYTES, triangleVertices); - - GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); - - boolean status = mEgl.eglSwapBuffers(mEglDisplay, mEglSurface); - checkEglError(); - - return status; - } - - private FloatBuffer createMesh(int left, int top, float right, float bottom) { - final float[] verticesData = { - // X, Y, Z, U, V - left, bottom, 0.0f, 0.0f, 1.0f, - right, bottom, 0.0f, 1.0f, 1.0f, - left, top, 0.0f, 0.0f, 0.0f, - right, top, 0.0f, 1.0f, 0.0f, - }; - - final int bytes = verticesData.length * FLOAT_SIZE_BYTES; - final FloatBuffer triangleVertices = ByteBuffer.allocateDirect(bytes).order( - ByteOrder.nativeOrder()).asFloatBuffer(); - triangleVertices.put(verticesData).position(0); - return triangleVertices; - } - - private int loadTexture(Bitmap bitmap) { - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - - int[] textures = new int[1]; - - GLES20.glActiveTexture(GLES20.GL_TEXTURE0); - GLES20.glGenTextures(1, textures, 0); - checkGlError(); - - int texture = textures[0]; - GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); - checkGlError(); - - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); - GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); - - GLES20.glTexParameteri( - GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); - GLES20.glTexParameteri( - GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); - - GLUtils.texImage2D( - GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap, GLES20.GL_UNSIGNED_BYTE, 0); - checkGlError(); - - mIsOpenGlTextureLoaded = true; - - return texture; - } - - private int buildProgram(String vertex, String fragment) { - int vertexShader = buildShader(vertex, GLES20.GL_VERTEX_SHADER); - if (vertexShader == 0) { - return 0; - } - - int fragmentShader = buildShader(fragment, GLES20.GL_FRAGMENT_SHADER); - if (fragmentShader == 0) { - return 0; - } - - int program = GLES20.glCreateProgram(); - GLES20.glAttachShader(program, vertexShader); - GLES20.glAttachShader(program, fragmentShader); - GLES20.glLinkProgram(program); - checkGlError(); - - GLES20.glDeleteShader(vertexShader); - GLES20.glDeleteShader(fragmentShader); - - int[] status = new int[1]; - GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0); - if (status[0] != GLES20.GL_TRUE) { - String error = GLES20.glGetProgramInfoLog(program); - Log.d(GL_LOG_TAG, "Error while linking program:\n" + error); - GLES20.glDeleteProgram(program); - return 0; - } - - return program; - } - - private int buildShader(String source, int type) { - int shader = GLES20.glCreateShader(type); - - GLES20.glShaderSource(shader, source); - checkGlError(); - - GLES20.glCompileShader(shader); - checkGlError(); - - int[] status = new int[1]; - GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, status, 0); - if (status[0] != GLES20.GL_TRUE) { - String error = GLES20.glGetShaderInfoLog(shader); - Log.d(GL_LOG_TAG, "Error while compiling shader:\n" + error); - GLES20.glDeleteShader(shader); - return 0; - } - - return shader; - } - - private void checkEglError() { - int error = mEgl.eglGetError(); - if (error != EGL10.EGL_SUCCESS) { - Log.w(GL_LOG_TAG, "EGL error = " + GLUtils.getEGLErrorString(error)); - } - } - - private void checkGlError() { - int error = GLES20.glGetError(); - if (error != GLES20.GL_NO_ERROR) { - Log.w(GL_LOG_TAG, "GL error = 0x" + Integer.toHexString(error), new Throwable()); - } - } - - private void deleteTexture(int texture) { - int[] textures = new int[1]; - textures[0] = texture; - - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - GLES20.glDeleteTextures(1, textures, 0); - mTexture = 0; - } - - private void finishGL(int texture, int program) { - if (mEgl == null) { - return; - } - - mOpenGlContextCounter--; - - mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); - deleteTexture(mTexture); - GLES20.glDeleteProgram(program); - mEgl.eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - mEgl.eglDestroySurface(mEglDisplay, mEglSurface); - mEgl.eglDestroyContext(mEglDisplay, mEglContext); - if (mOpenGlContextCounter == 0) { - mEgl.eglTerminate(mEglDisplay); - } - - mEgl = null; - } - - private boolean initGL(SurfaceHolder surfaceHolder) { - mEgl = (EGL10) EGLContext.getEGL(); - - mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); - if (mEglDisplay == EGL10.EGL_NO_DISPLAY) { - throw new RuntimeException("eglGetDisplay failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - int[] version = new int[2]; - if (!mEgl.eglInitialize(mEglDisplay, version)) { - throw new RuntimeException("eglInitialize failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - mOpenGlContextCounter++; - - mEglConfig = chooseEglConfig(); - if (mEglConfig == null) { - throw new RuntimeException("eglConfig not initialized"); - } - - mEglContext = createContext(mEgl, mEglDisplay, mEglConfig); - if (mEglContext == EGL_NO_CONTEXT) { - throw new RuntimeException("createContext failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - int attribs[] = { - EGL10.EGL_WIDTH, 1, - EGL10.EGL_HEIGHT, 1, - EGL10.EGL_NONE - }; - EGLSurface tmpSurface = mEgl.eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs); - mEgl.eglMakeCurrent(mEglDisplay, tmpSurface, tmpSurface, mEglContext); - - int[] maxSize = new int[1]; - Rect frame = surfaceHolder.getSurfaceFrame(); - GLES20.glGetIntegerv(GLES20.GL_MAX_TEXTURE_SIZE, maxSize, 0); - - mEgl.eglMakeCurrent( - mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - mEgl.eglDestroySurface(mEglDisplay, tmpSurface); - - if (frame.width() > maxSize[0] || frame.height() > maxSize[0]) { - mEgl.eglDestroyContext(mEglDisplay, mEglContext); - mEgl.eglTerminate(mEglDisplay); - Log.e(GL_LOG_TAG, "requested texture size " + frame.width() + "x" + frame.height() - + " exceeds the support maximum of " + maxSize[0] + "x" + maxSize[0]); - return false; - } - - mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surfaceHolder, null); - if (mEglSurface == null || mEglSurface == EGL_NO_SURFACE) { - int error = mEgl.eglGetError(); - if (error == EGL10.EGL_BAD_NATIVE_WINDOW || error == EGL10.EGL_BAD_ALLOC) { - Log.e(GL_LOG_TAG, "createWindowSurface returned " + GLUtils.getEGLErrorString(error) - + "."); - return false; - } - throw new RuntimeException("createWindowSurface failed " - + GLUtils.getEGLErrorString(error)); - } - - if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { - throw new RuntimeException("eglMakeCurrent failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } - - mProgram = buildProgram(S_SIMPLE_VS, S_SIMPLE_FS); - if (mBackground != null) { - mTexture = loadTexture(mBackground); - } - - return true; - } - - - EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) { - int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE}; - return egl.eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, attribList); - } - - private EGLConfig chooseEglConfig() { - int[] configsCount = new int[1]; - EGLConfig[] configs = new EGLConfig[1]; - int[] configSpec = getConfig(); - if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) { - throw new IllegalArgumentException("eglChooseConfig failed " - + GLUtils.getEGLErrorString(mEgl.eglGetError())); - } else if (configsCount[0] > 0) { - return configs[0]; - } - return null; - } - - private int[] getConfig() { - return new int[]{ - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL10.EGL_RED_SIZE, 8, - EGL10.EGL_GREEN_SIZE, 8, - EGL10.EGL_BLUE_SIZE, 8, - EGL10.EGL_ALPHA_SIZE, 0, - EGL10.EGL_DEPTH_SIZE, 0, - EGL10.EGL_STENCIL_SIZE, 0, - EGL10.EGL_CONFIG_CAVEAT, EGL10.EGL_NONE, - EGL10.EGL_NONE - }; - } - } -} diff --git a/src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java b/src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java deleted file mode 100755 index 8a2908a..0000000 --- a/src/com/android/wallpaper/module/RotatingWallpaperComponentChecker.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2017 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.wallpaper.module; - -import android.content.Context; - -import androidx.annotation.IntDef; - -/** - * Checks what component is responsible for presenting the rotating wallpaper image under the - * device's launcher or keyguard for current and future rotations. - */ -public interface RotatingWallpaperComponentChecker { - - int ROTATING_WALLPAPER_COMPONENT_LIVE = 1; - int ROTATING_WALLPAPER_COMPONENT_STATIC = 2; - - int ROTATING_WALLPAPER_SUPPORT_NOT_SUPPORTED = 0; - int ROTATING_WALLPAPER_SUPPORT_SUPPORTED = 1; - - /** - * Returns the rotating wallpaper component for the current wallpaper rotation. - */ - @RotatingWallpaperComponent - int getCurrentRotatingWallpaperComponent(Context context); - - /** - * Returns the rotating wallpaper component for future wallpaper rotations. - */ - @RotatingWallpaperComponent - int getNextRotatingWallpaperComponent(Context context); - - /** - * Returns the support level for rotating wallpaper. - */ - @RotatingWallpaperSupport - int getRotatingWallpaperSupport(Context context); - - /** - * Possible components for presenting the rotating wallpaper image. - */ - @IntDef({ - ROTATING_WALLPAPER_COMPONENT_LIVE, - ROTATING_WALLPAPER_COMPONENT_STATIC}) - @interface RotatingWallpaperComponent { - } - - /** - * Possible support levels for rotating wallpaper. - */ - @IntDef({ - ROTATING_WALLPAPER_SUPPORT_NOT_SUPPORTED, - ROTATING_WALLPAPER_SUPPORT_SUPPORTED}) - @interface RotatingWallpaperSupport { - } -} diff --git a/src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java b/src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java deleted file mode 100644 index 975b0db..0000000 --- a/src/com/android/wallpaper/module/RotationWallpaperMoveReceiver.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.android.wallpaper.module; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; - -import com.android.wallpaper.compat.BuildCompat; -import com.android.wallpaper.util.DiskBasedLogger; -import com.android.wallpaper.util.FileMover; - -import java.io.File; -import java.io.IOException; - -/** - * Receiver to run when the app was updated or on first boot to migrate previously existing rotating - * wallpaper file to device protected storage so it can be read in direct-boot. - * This is basically a no-op if there's no file in - * {@link NoBackupImageWallpaper#ROTATING_WALLPAPER_FILE_PATH}. - */ -public class RotationWallpaperMoveReceiver extends BroadcastReceiver { - - private static final String TAG = "RotationWallpaperMoveReceiver"; - - @Override - public void onReceive(Context context, Intent intent) { - // This receiver is a no-op on pre-N Android and should only respond to a - // MY_PACKAGE_REPLACED intent. - if (intent.getAction() == null - || !(intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED) - || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) - || !BuildCompat.isAtLeastN()) { - DiskBasedLogger.e( - TAG, - "Unexpected action or Android version!", - context); - throw new IllegalStateException( - "Unexpected broadcast action or unsupported Android version"); - } - - // This is a no-op if there is no rotating wallpaper file in the files directory. - if (!context.getFileStreamPath( - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH).exists()) { - return; - } - - PendingResult broadcastResult = goAsync(); - new Thread(() -> { - Context appContext = context.getApplicationContext(); - Context deviceProtectedContext = appContext.createDeviceProtectedStorageContext(); - try { - File movedFile = FileMover.moveFileBetweenContexts(appContext, - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH, - deviceProtectedContext, - NoBackupImageWallpaper.ROTATING_WALLPAPER_FILE_PATH); - - if (movedFile != null) { - // Notify NoBackupImageWallpaper of the change in case that's the currently - // set wallpaper - Intent intent1 = new Intent(appContext.getPackageName() - + NoBackupImageWallpaper.ACTION_ROTATING_WALLPAPER_CHANGED); - // Handled by a runtime-registered receiver in NoBackupImageWallpaper. - intent1.setPackage(appContext.getPackageName()); - appContext.sendBroadcast(intent1); - } - } catch (IOException e) { - DiskBasedLogger.e( - TAG, - "Failed to move rotating wallpaper file to device protected storage: " - + e.getMessage(), - appContext); - } finally { - broadcastResult.finish(); - } - }).start(); - - } -} diff --git a/src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java b/src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java new file mode 100644 index 0000000..4fbc20d --- /dev/null +++ b/src/com/android/wallpaper/module/RotationWallpaperUpdateReceiver.java @@ -0,0 +1,111 @@ +/* + * 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.wallpaper.module; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; + +import com.android.wallpaper.compat.BuildCompat; +import com.android.wallpaper.util.DiskBasedLogger; +import com.android.wallpaper.util.FileMover; + +import java.io.File; + +/** + * Receiver to run when the app was updated or on first boot to switch from live rotating wallpaper + * to static rotating wallpaper. + */ +public class RotationWallpaperUpdateReceiver extends BroadcastReceiver { + + + // Earlier versions of rotating wallpaper save the current rotation image as a file. + // We can infer from the extistance of this file whether or not user had rotating live wallpaper + private static final String ROTATING_WALLPAPER_FILE_PATH = "rotating_wallpaper.jpg"; + private static final String TAG = "RotationWallpaperUpdateReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + // This receiver is a no-op on pre-N Android and should only respond to a + // MY_PACKAGE_REPLACED intent. + if (intent.getAction() == null + || !(intent.getAction().equals(Intent.ACTION_MY_PACKAGE_REPLACED) + || intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) + || !BuildCompat.isAtLeastN()) { + DiskBasedLogger.e( + TAG, + "Unexpected action or Android version!", + context); + throw new IllegalStateException( + "Unexpected broadcast action or unsupported Android version"); + } + + PendingResult broadcastResult = goAsync(); + new Thread(() -> { + Context appContext = context.getApplicationContext(); + Context deviceProtectedContext = appContext.createDeviceProtectedStorageContext(); + + if (context.getFileStreamPath(ROTATING_WALLPAPER_FILE_PATH).exists()) { + moveFileToProtectedStorage(appContext, deviceProtectedContext); + } + + File wallpaperFile = deviceProtectedContext.getFileStreamPath( + ROTATING_WALLPAPER_FILE_PATH); + if (wallpaperFile.exists()) { + switchToStaticWallpaper(appContext, wallpaperFile); + } + broadcastResult.finish(); + }).start(); + } + + private void moveFileToProtectedStorage(Context context, Context deviceProtectedContext) { + try { + FileMover.moveFileBetweenContexts(context, ROTATING_WALLPAPER_FILE_PATH, + deviceProtectedContext, ROTATING_WALLPAPER_FILE_PATH); + } catch (Exception ex) { + DiskBasedLogger.e( + TAG, + "Failed to move rotating wallpaper file to device protected storage: " + + ex.getMessage(), + context); + } + } + + private void switchToStaticWallpaper(Context appContext, File wallpaperFile) { + try { + Injector injector = InjectorProvider.getInjector(); + WallpaperPreferences wallpaperPreferences = injector.getPreferences(appContext); + if (wallpaperPreferences.getWallpaperPresentationMode() + != WallpaperPreferences.PRESENTATION_MODE_ROTATING) { + return; + } + Bitmap bitmap = BitmapFactory.decodeFile(wallpaperFile.getAbsolutePath()); + + injector.getWallpaperPersister(appContext).setWallpaperInRotation(bitmap, + wallpaperPreferences.getHomeWallpaperAttributions(), + wallpaperPreferences.getHomeWallpaperActionLabelRes(), + wallpaperPreferences.getHomeWallpaperActionIconRes(), + wallpaperPreferences.getHomeWallpaperActionUrl(), + wallpaperPreferences.getHomeWallpaperCollectionId()); + wallpaperFile.delete(); + + } catch (Exception ex) { + DiskBasedLogger.e(TAG, "Unable to set static wallpaper", appContext); + } + } +} diff --git a/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java b/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java index f63506f..e4c6588 100755 --- a/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java +++ b/src/com/android/wallpaper/module/WallpaperPreferenceKeys.java @@ -28,12 +28,7 @@ public class WallpaperPreferenceKeys { public static final String KEY_HOME_WALLPAPER_ACTION_LABEL_RES = "home_wallpaper_action_label"; public static final String KEY_HOME_WALLPAPER_ACTION_ICON_RES = "home_wallpaper_action_icon"; public static final String KEY_HOME_WALLPAPER_COLLECTION_ID = "home_wallpaper_collection_id"; - public static final String KEY_HOME_WALLPAPER_BASE_IMAGE_URL = "home_wallpaper_base_image_url"; public static final String KEY_HOME_WALLPAPER_HASH_CODE = "home_wallpaper_hash_code"; - public static final String KEY_HOME_WALLPAPER_MANAGER_ID = "home_wallpaper_id"; - public static final String KEY_HOME_WALLPAPER_PACKAGE_NAME = "home_wallpaper_package_name"; - public static final String KEY_HOME_WALLPAPER_REMOTE_ID = "home_wallpaper_remote_id"; - public static final String KEY_HOME_WALLPAPER_BACKING_FILE = "home_wallpaper_backing_file"; public static final String KEY_LOCK_WALLPAPER_ATTRIB_1 = "lock_wallpaper_attribution_line_1"; public static final String KEY_LOCK_WALLPAPER_ATTRIB_2 = "lock_wallpaper_attribution_line_2"; @@ -43,24 +38,35 @@ public class WallpaperPreferenceKeys { public static final String KEY_LOCK_WALLPAPER_ACTION_ICON_RES = "lock_wallpaper_action_icon"; public static final String KEY_LOCK_WALLPAPER_HASH_CODE = "lock_wallpaper_hash_code"; public static final String KEY_LOCK_WALLPAPER_COLLECTION_ID = "lock_wallpaper_collection_id"; - public static final String KEY_LOCK_WALLPAPER_MANAGER_ID = "lock_wallpaper_id"; - public static final String KEY_LOCK_WALLPAPER_BACKING_FILE = "lock_wallpaper_backing_file"; - public static final String KEY_DAILY_ROTATION_TIMESTAMPS = "daily_rotation_timestamps"; - public static final String KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP = - "daily_wallpaper_enabled_timestamp"; - - public static final String KEY_LAST_DAILY_LOG_TIMESTAMP = "last_daily_log_timestamp"; - public static final String KEY_LAST_APP_ACTIVE_TIMESTAMP = "last_app_active_timestamp"; - public static final String KEY_LAST_ROTATION_STATUS = "last_rotation_status"; - public static final String KEY_LAST_ROTATION_STATUS_TIMESTAMP = "last_rotation_status_timestamp"; - public static final String KEY_LAST_SYNC_TIMESTAMP = "last_sync_timestamp"; - - public static final String KEY_PENDING_WALLPAPER_SET_STATUS = "pending_wallpaper_set_status"; - public static final String KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS = - "pending_daily_wallpaper_update_status"; - - public static final String KEY_NUM_DAYS_DAILY_ROTATION_FAILED = "num_days_daily_rotation_failed"; - public static final String KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED = - "num_days_daily_rotation_not_attempted"; + /** + * Preferences with these keys should not be backed up + */ + public interface NoBackupKeys { + public static final String KEY_HOME_WALLPAPER_BASE_IMAGE_URL = + "home_wallpaper_base_image_url"; + public static final String KEY_HOME_WALLPAPER_MANAGER_ID = "home_wallpaper_id"; + public static final String KEY_HOME_WALLPAPER_REMOTE_ID = "home_wallpaper_remote_id"; + public static final String KEY_HOME_WALLPAPER_BACKING_FILE = "home_wallpaper_backing_file"; + public static final String KEY_LOCK_WALLPAPER_MANAGER_ID = "lock_wallpaper_id"; + public static final String KEY_LOCK_WALLPAPER_BACKING_FILE = "lock_wallpaper_backing_file"; + public static final String KEY_DAILY_ROTATION_TIMESTAMPS = "daily_rotation_timestamps"; + public static final String KEY_DAILY_WALLPAPER_ENABLED_TIMESTAMP = + "daily_wallpaper_enabled_timestamp"; + public static final String KEY_LAST_DAILY_LOG_TIMESTAMP = "last_daily_log_timestamp"; + public static final String KEY_LAST_APP_ACTIVE_TIMESTAMP = "last_app_active_timestamp"; + public static final String KEY_LAST_ROTATION_STATUS = "last_rotation_status"; + public static final String KEY_LAST_ROTATION_STATUS_TIMESTAMP = + "last_rotation_status_timestamp"; + public static final String KEY_LAST_SYNC_TIMESTAMP = "last_sync_timestamp"; + public static final String KEY_PENDING_WALLPAPER_SET_STATUS = + "pending_wallpaper_set_status"; + public static final String KEY_PENDING_DAILY_WALLPAPER_UPDATE_STATUS = + "pending_daily_wallpaper_update_status"; + public static final String KEY_NUM_DAYS_DAILY_ROTATION_FAILED = + "num_days_daily_rotation_failed"; + public static final String KEY_NUM_DAYS_DAILY_ROTATION_NOT_ATTEMPTED = + "num_days_daily_rotation_not_attempted"; + public static final String KEY_HOME_WALLPAPER_PACKAGE_NAME = "home_wallpaper_package_name"; + } } diff --git a/src/com/android/wallpaper/module/WallpaperSetter.java b/src/com/android/wallpaper/module/WallpaperSetter.java index 830d914..a33a5f1 100644 --- a/src/com/android/wallpaper/module/WallpaperSetter.java +++ b/src/com/android/wallpaper/module/WallpaperSetter.java @@ -72,8 +72,9 @@ public class WallpaperSetter { * @param callback optional callback to be notified when the wallpaper is set. */ public void setCurrentWallpaper(Activity containerActivity, WallpaperInfo wallpaper, - Asset wallpaperAsset, @Destination final int destination, float wallpaperScale, - @Nullable Rect cropRect, @Nullable SetWallpaperCallback callback) { + @Nullable Asset wallpaperAsset, @Destination final int destination, + float wallpaperScale, @Nullable Rect cropRect, + @Nullable SetWallpaperCallback callback) { if (wallpaper instanceof LiveWallpaperInfo) { setCurrentLiveWallpaper(containerActivity, (LiveWallpaperInfo) wallpaper, destination, callback); |