Merge "Resize image wallpaper surface to match bitmap size in order to optimize memory (on AndroidTV there is no need for wallpaper and RAM is wasted)"

This commit is contained in:
Iavor-Valentin Iftime
2018-09-03 07:30:37 +00:00
committed by Android (Google) Code Review
3 changed files with 172 additions and 10 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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);
}
}