diff options
3 files changed, 172 insertions, 10 deletions
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 28467303df14..febdb83f0af3 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -45,6 +45,7 @@ import android.util.Log; import android.util.MergedConfiguration; import android.view.Display; import android.view.DisplayCutout; +import android.view.DisplayInfo; import android.view.Gravity; import android.view.IWindowSession; import android.view.InputChannel; @@ -163,7 +164,8 @@ public abstract class WallpaperService extends Service { int mType; int mCurWidth; int mCurHeight; - int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; + int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_SCALED; int mWindowPrivateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS; int mCurWindowFlags = mWindowFlags; @@ -763,9 +765,19 @@ public abstract class WallpaperService extends Service { mLayout.x = 0; mLayout.y = 0; - mLayout.width = myWidth; - mLayout.height = myHeight; - + + if (!fixedSize) { + mLayout.width = myWidth; + mLayout.height = myHeight; + } else { + // Force the wallpaper to cover the screen in both dimensions + // only internal implementations like ImageWallpaper + DisplayInfo displayInfo = new DisplayInfo(); + mDisplay.getDisplayInfo(displayInfo); + mLayout.width = Math.max(displayInfo.logicalWidth, myWidth); + mLayout.height = Math.max(displayInfo.logicalHeight, myHeight); + } + mLayout.format = mFormat; mCurWindowFlags = mWindowFlags; @@ -773,7 +785,8 @@ public abstract class WallpaperService extends Service { | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_SCALED; mCurWindowPrivateFlags = mWindowPrivateFlags; mLayout.privateFlags = mWindowPrivateFlags; @@ -847,6 +860,9 @@ public abstract class WallpaperService extends Service { mStableInsets.bottom += padding.bottom; mDisplayCutout.set(mDisplayCutout.get().inset(-padding.left, -padding.top, -padding.right, -padding.bottom)); + } else { + w = myWidth; + h = myHeight; } if (mCurWidth != w) { diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java index acc7b49d9c35..77f4bf529f21 100644 --- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java @@ -35,6 +35,8 @@ import android.view.Surface; import android.view.SurfaceHolder; import android.view.WindowManager; +import com.android.internal.annotations.VisibleForTesting; + import java.io.FileDescriptor; import java.io.IOException; import java.io.PrintWriter; @@ -77,6 +79,13 @@ public class ImageWallpaper extends WallpaperService { unloadWallpaper(false /* forgetSize */); }; + // Surface is rejected if size below a threshold on some devices (ie. 8px on elfin) + // set min to 64 px (CTS covers this) + @VisibleForTesting + static final int MIN_BACKGROUND_WIDTH = 64; + @VisibleForTesting + static final int MIN_BACKGROUND_HEIGHT = 64; + Bitmap mBackground; int mBackgroundWidth = -1, mBackgroundHeight = -1; int mLastSurfaceWidth = -1, mLastSurfaceHeight = -1; @@ -156,9 +165,9 @@ public class ImageWallpaper extends WallpaperService { hasWallpaper = false; } - // Force the wallpaper to cover the screen in both dimensions - int surfaceWidth = Math.max(displayInfo.logicalWidth, mBackgroundWidth); - int surfaceHeight = Math.max(displayInfo.logicalHeight, mBackgroundHeight); + // Set surface size equal to bitmap size, prevent memory waste + int surfaceWidth = Math.max(MIN_BACKGROUND_WIDTH, mBackgroundWidth); + int surfaceHeight = Math.max(MIN_BACKGROUND_HEIGHT, mBackgroundHeight); // Used a fixed size surface, because we are special. We can do // this because we know the current design of window animations doesn't @@ -257,7 +266,8 @@ public class ImageWallpaper extends WallpaperService { drawFrame(); } - private DisplayInfo getDefaultDisplayInfo() { + @VisibleForTesting + DisplayInfo getDefaultDisplayInfo() { mDefaultDisplay.getDisplayInfo(mTmpDisplayInfo); return mTmpDisplayInfo; } @@ -420,7 +430,8 @@ public class ImageWallpaper extends WallpaperService { }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } - private void updateBitmap(Bitmap bitmap) { + @VisibleForTesting + void updateBitmap(Bitmap bitmap) { mBackground = null; mBackgroundWidth = -1; mBackgroundHeight = -1; diff --git a/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java new file mode 100644 index 000000000000..521d5d10a621 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/ImageWallpaperTest.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2018 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.systemui; + + +import static org.junit.Assert.assertNotNull; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; + +import android.graphics.Bitmap; +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.DisplayInfo; +import android.view.SurfaceHolder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.concurrent.CountDownLatch; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class ImageWallpaperTest extends SysuiTestCase { + + private static final int BMP_WIDTH = 128; + private static final int BMP_HEIGHT = 128; + + private static final int INVALID_BMP_WIDTH = 1; + private static final int INVALID_BMP_HEIGHT = 1; + + private ImageWallpaper mImageWallpaper; + + @Mock private SurfaceHolder mSurfaceHolder; + @Mock private DisplayInfo mDisplayInfo; + + CountDownLatch mEventCountdown; + + @Before + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mEventCountdown = new CountDownLatch(1); + + mImageWallpaper = new ImageWallpaper() { + @Override + public Engine onCreateEngine() { + return new DrawableEngine() { + @Override + DisplayInfo getDefaultDisplayInfo() { + return mDisplayInfo; + } + + @Override + public SurfaceHolder getSurfaceHolder() { + return mSurfaceHolder; + } + + @Override + public void setFixedSizeAllowed(boolean allowed) { + super.setFixedSizeAllowed(allowed); + assertTrue("mFixedSizeAllowed should be true", allowed); + mEventCountdown.countDown(); + } + }; + } + }; + } + + @Test + public void testSetValidBitmapWallpaper() { + ImageWallpaper.DrawableEngine wallpaperEngine = + (ImageWallpaper.DrawableEngine) mImageWallpaper.onCreateEngine(); + + assertEquals("setFixedSizeAllowed should have been called.", + 0, mEventCountdown.getCount()); + + Bitmap mockedBitmap = mock(Bitmap.class); + when(mockedBitmap.getWidth()).thenReturn(BMP_WIDTH); + when(mockedBitmap.getHeight()).thenReturn(BMP_HEIGHT); + + wallpaperEngine.updateBitmap(mockedBitmap); + + assertEquals(BMP_WIDTH, wallpaperEngine.mBackgroundWidth); + assertEquals(BMP_HEIGHT, wallpaperEngine.mBackgroundHeight); + + verify(mSurfaceHolder, times(1)).setFixedSize(BMP_WIDTH, BMP_HEIGHT); + + } + + @Test + public void testSetTooSmallBitmapWallpaper() { + ImageWallpaper.DrawableEngine wallpaperEngine = + (ImageWallpaper.DrawableEngine) mImageWallpaper.onCreateEngine(); + + assertEquals("setFixedSizeAllowed should have been called.", + 0, mEventCountdown.getCount()); + + Bitmap mockedBitmap = mock(Bitmap.class); + when(mockedBitmap.getWidth()).thenReturn(INVALID_BMP_WIDTH); + when(mockedBitmap.getHeight()).thenReturn(INVALID_BMP_HEIGHT); + + wallpaperEngine.updateBitmap(mockedBitmap); + + assertEquals(INVALID_BMP_WIDTH, wallpaperEngine.mBackgroundWidth); + assertEquals(INVALID_BMP_HEIGHT, wallpaperEngine.mBackgroundHeight); + + verify(mSurfaceHolder, times(1)).setFixedSize(ImageWallpaper.DrawableEngine.MIN_BACKGROUND_WIDTH, ImageWallpaper.DrawableEngine.MIN_BACKGROUND_HEIGHT); + } + +} |