diff options
| author | 2018-11-29 20:44:13 +0000 | |
|---|---|---|
| committer | 2018-11-29 20:44:13 +0000 | |
| commit | 54ff93c6b285927f6912fdfa871da15271b1ff25 (patch) | |
| tree | cecf2457197ad769c993bd298f7b75aad45faa4b | |
| parent | f8d769ef29b4f49087a7f8136e44c1ab366d8bfa (diff) | |
| parent | 4c8c3274dae088923fe3f7db60c5ab6ac25285b6 (diff) | |
Merge "Ambient wallpaper API feedback"
14 files changed, 96 insertions, 44 deletions
diff --git a/api/current.txt b/api/current.txt index eb441523165a..1b5b3ee26a9f 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1316,7 +1316,6 @@ package android { field public static final int summaryColumn = 16843426; // 0x10102a2 field public static final int summaryOff = 16843248; // 0x10101f0 field public static final int summaryOn = 16843247; // 0x10101ef - field public static final int supportsAmbientMode = 16844173; // 0x101058d field public static final int supportsAssist = 16844016; // 0x10104f0 field public static final int supportsLaunchVoiceAssistFromKeyguard = 16844017; // 0x10104f1 field public static final int supportsLocalInteraction = 16844047; // 0x101050f @@ -6359,7 +6358,6 @@ package android.app { method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager); method public java.lang.CharSequence loadLabel(android.content.pm.PackageManager); method public android.graphics.drawable.Drawable loadThumbnail(android.content.pm.PackageManager); - method public boolean supportsAmbientMode(); method public boolean supportsMultipleDisplays(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.app.WallpaperInfo> CREATOR; @@ -40930,11 +40928,9 @@ package android.service.wallpaper { method public int getDesiredMinimumHeight(); method public int getDesiredMinimumWidth(); method public android.view.SurfaceHolder getSurfaceHolder(); - method public boolean isInAmbientMode(); method public boolean isPreview(); method public boolean isVisible(); method public void notifyColorsChanged(); - method public void onAmbientModeChanged(boolean, boolean); method public void onApplyWindowInsets(android.view.WindowInsets); method public android.os.Bundle onCommand(java.lang.String, int, int, int, android.os.Bundle, boolean); method public android.app.WallpaperColors onComputeColors(); diff --git a/api/system-current.txt b/api/system-current.txt index 37d581b1c729..b4c73362d7cc 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -17,6 +17,7 @@ package android { field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE"; field public static final java.lang.String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; + field public static final java.lang.String AMBIENT_WALLPAPER = "android.permission.AMBIENT_WALLPAPER"; field public static final java.lang.String BACKUP = "android.permission.BACKUP"; field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; @@ -224,6 +225,7 @@ package android { field public static final int isVrOnly = 16844152; // 0x1010578 field public static final int requiredSystemPropertyName = 16844133; // 0x1010565 field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566 + field public static final int supportsAmbientMode = 16844173; // 0x101058d field public static final int userRestriction = 16844164; // 0x1010584 } @@ -555,6 +557,10 @@ package android.app { method public void onVrStateChanged(boolean); } + public final class WallpaperInfo implements android.os.Parcelable { + method public boolean supportsAmbientMode(); + } + public class WallpaperManager { method public void clearWallpaper(int, int); method public void setDisplayOffset(android.os.IBinder, int, int); @@ -5339,6 +5345,15 @@ package android.service.trust { } +package android.service.wallpaper { + + public class WallpaperService.Engine { + method public boolean isInAmbientMode(); + method public void onAmbientModeChanged(boolean, long); + } + +} + package android.telecom { public deprecated class AudioState implements android.os.Parcelable { diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl index 00547b4a5ce4..3a2038d40952 100644 --- a/core/java/android/app/IWallpaperManager.aidl +++ b/core/java/android/app/IWallpaperManager.aidl @@ -159,5 +159,5 @@ interface IWallpaperManager { /** * Called from SystemUI when it shows the AoD UI. */ - oneway void setInAmbientMode(boolean inAmbientMode, boolean animated); + oneway void setInAmbientMode(boolean inAmbientMode, long animationDuration); } diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java index 3ea3da25e2fc..f0f7d899ff07 100644 --- a/core/java/android/app/WallpaperInfo.java +++ b/core/java/android/app/WallpaperInfo.java @@ -16,6 +16,7 @@ package android.app; +import android.annotation.SystemApi; import android.app.slice.Slice; import android.content.ComponentName; import android.content.Context; @@ -330,7 +331,9 @@ public final class WallpaperInfo implements Parcelable { * @see WallpaperService.Engine#onAmbientModeChanged(boolean, boolean) * @see WallpaperService.Engine#isInAmbientMode() * @return {@code true} if wallpaper can draw when in ambient mode. + * @hide */ + @SystemApi public boolean supportsAmbientMode() { return mSupportsAmbientMode; } diff --git a/core/java/android/service/wallpaper/IWallpaperEngine.aidl b/core/java/android/service/wallpaper/IWallpaperEngine.aidl index dccce406e32c..ebce4846c16b 100644 --- a/core/java/android/service/wallpaper/IWallpaperEngine.aidl +++ b/core/java/android/service/wallpaper/IWallpaperEngine.aidl @@ -27,7 +27,7 @@ oneway interface IWallpaperEngine { void setDesiredSize(int width, int height); void setDisplayPadding(in Rect padding); void setVisibility(boolean visible); - void setInAmbientMode(boolean inAmbientDisplay, boolean animated); + void setInAmbientMode(boolean inAmbientDisplay, long animationDuration); void dispatchPointer(in MotionEvent event); void dispatchWallpaperCommand(String action, int x, int y, int z, in Bundle extras); diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 45d53f340f35..a095b0d8b239 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -19,6 +19,7 @@ package android.service.wallpaper; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; +import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.app.Service; import android.app.WallpaperColors; @@ -442,7 +443,9 @@ public abstract class WallpaperService extends Service { /** * Returns true if this engine is running in ambient mode -- that is, * it is being shown in low power mode, on always on display. + * @hide */ + @SystemApi public boolean isInAmbientMode() { return mIsInAmbientMode; } @@ -568,14 +571,16 @@ public abstract class WallpaperService extends Service { * Called when the device enters or exits ambient mode. * * @param inAmbientMode {@code true} if in ambient mode. - * @param animated {@code true} if you'll have the opportunity of animating your transition - * {@code false} when the wallpaper should present its ambient version - * immediately. + * @param animationDuration How long the transition animation to change the ambient state + * should run, in milliseconds. If 0 is passed as the argument + * here, the state should be switched immediately. * * @see #isInAmbientMode() * @see WallpaperInfo#supportsAmbientMode() + * @hide */ - public void onAmbientModeChanged(boolean inAmbientMode, boolean animated) { + @SystemApi + public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) { } /** @@ -1049,19 +1054,19 @@ public abstract class WallpaperService extends Service { * message sent from handler. * * @param inAmbientMode {@code true} if in ambient mode. - * @param animated {@code true} if the transition will be animated. + * @param animationDuration For how long the transition will last, in ms. * @hide */ @VisibleForTesting - public void doAmbientModeChanged(boolean inAmbientMode, boolean animated) { + public void doAmbientModeChanged(boolean inAmbientMode, long animationDuration) { if (!mDestroyed) { if (DEBUG) { Log.v(TAG, "onAmbientModeChanged(" + inAmbientMode + ", " - + animated + "): " + this); + + animationDuration + "): " + this); } mIsInAmbientMode = inAmbientMode; if (mCreated) { - onAmbientModeChanged(inAmbientMode, animated); + onAmbientModeChanged(inAmbientMode, animationDuration); } } } @@ -1320,10 +1325,10 @@ public abstract class WallpaperService extends Service { } @Override - public void setInAmbientMode(boolean inAmbientDisplay, boolean animated) + public void setInAmbientMode(boolean inAmbientDisplay, long animationDuration) throws RemoteException { - Message msg = mCaller.obtainMessageII(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0, - animated ? 1 : 0); + Message msg = mCaller.obtainMessageIO(DO_IN_AMBIENT_MODE, inAmbientDisplay ? 1 : 0, + animationDuration); mCaller.sendMessage(msg); } @@ -1394,7 +1399,7 @@ public abstract class WallpaperService extends Service { return; } case DO_IN_AMBIENT_MODE: { - mEngine.doAmbientModeChanged(message.arg1 != 0, message.arg2 != 0); + mEngine.doAmbientModeChanged(message.arg1 != 0, (Long) message.obj); return; } case MSG_UPDATE_SURFACE: diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 6c3085ff2919..8b66be310abc 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -4217,6 +4217,10 @@ @hide --> <permission android:name="android.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY" android:protectionLevel="signature|preinstalled" /> + <!-- @SystemApi Allows wallpaper to be rendered in ambient mode. + @hide --> + <permission android:name="android.permission.AMBIENT_WALLPAPER" + android:protectionLevel="signature|preinstalled" /> <application android:process="system" android:persistent="true" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 470e1ccf36e8..918070cbf829 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7935,7 +7935,9 @@ wallpaper. --> <attr name="showMetadataInPreview" format="boolean" /> - <!-- Wallpapers optimized and capable of drawing in ambient mode will return true. --> + <!-- Wallpapers optimized and capable of drawing in ambient mode will return true. + This feature requires the android.permission.AMBIENT_WALLPAPER permission. + @hide @SystemApi --> <attr name="supportsAmbientMode" format="boolean" /> <!-- Uri that specifies a settings Slice for this wallpaper. --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 7fac4e439bcf..feefcad3f56f 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2909,6 +2909,7 @@ <public name="opticalInsetRight" /> <public name="opticalInsetBottom" /> <public name="forceDarkAllowed" /> + <!-- @hide @SystemApi --> <public name="supportsAmbientMode" /> <!-- @hide For use by platform and tools only. Developers should not specify this value. --> <public name="usesNonSdkApi" /> diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java index 9a5a5b855999..be504ef5eb9c 100644 --- a/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java +++ b/packages/SystemUI/src/com/android/systemui/doze/DozeWallpaperState.java @@ -23,6 +23,7 @@ import android.os.ServiceManager; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; +import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.DozeParameters; import java.io.PrintWriter; @@ -80,11 +81,12 @@ public class DozeWallpaperState implements DozeMachine.Part { if (isAmbientMode != mIsAmbientMode) { mIsAmbientMode = isAmbientMode; try { + long duration = animated ? StackStateAnimator.ANIMATION_DURATION_WAKEUP : 0L; if (DEBUG) { Log.i(TAG, "AOD wallpaper state changed to: " + mIsAmbientMode - + ", animated: " + animated); + + ", animationDuration: " + duration); } - mWallpaperManagerService.setInAmbientMode(mIsAmbientMode, animated); + mWallpaperManagerService.setInAmbientMode(mIsAmbientMode, duration); } catch (RemoteException e) { // Cannot notify wallpaper manager service, but it's fine, let's just skip it. Log.w(TAG, "Cannot notify state to WallpaperManagerService: " + mIsAmbientMode); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 2fc3adc4c98f..408ab42a6f06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -721,7 +721,7 @@ public class StatusBar extends SystemUI implements DemoMode, IWallpaperManager wallpaperManager = IWallpaperManager.Stub.asInterface( ServiceManager.getService(Context.WALLPAPER_SERVICE)); try { - wallpaperManager.setInAmbientMode(false /* ambientMode */, false /* animated */); + wallpaperManager.setInAmbientMode(false /* ambientMode */, 0L /* duration */); } catch (RemoteException e) { // Just pass, nothing critical. } diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java index 6ac44628b52f..ec2319d80194 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeWallpaperStateTest.java @@ -16,9 +16,8 @@ package com.android.systemui.doze; -import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -27,8 +26,8 @@ import android.app.IWallpaperManager; import android.os.RemoteException; import android.support.test.filters.SmallTest; -import com.android.keyguard.KeyguardUpdateMonitor; import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.notification.stack.StackStateAnimator; import com.android.systemui.statusbar.phone.DozeParameters; import org.junit.Before; @@ -59,14 +58,14 @@ public class DozeWallpaperStateTest extends SysuiTestCase { mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.DOZE_AOD); - verify(mIWallpaperManager).setInAmbientMode(eq(true), anyBoolean()); + verify(mIWallpaperManager).setInAmbientMode(eq(true), anyLong()); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH); - verify(mIWallpaperManager).setInAmbientMode(eq(false), anyBoolean()); + verify(mIWallpaperManager).setInAmbientMode(eq(false), anyLong()); // Make sure we're sending false when AoD is off reset(mDozeParameters); mDozeWallpaperState.transitionTo(DozeMachine.State.FINISH, DozeMachine.State.DOZE_AOD); - verify(mIWallpaperManager).setInAmbientMode(eq(false), anyBoolean()); + verify(mIWallpaperManager).setInAmbientMode(eq(false), anyLong()); } @Test @@ -78,10 +77,12 @@ public class DozeWallpaperStateTest extends SysuiTestCase { mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.DOZE_AOD); - verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(true)); + verify(mIWallpaperManager).setInAmbientMode(eq(true), + eq((long) StackStateAnimator.ANIMATION_DURATION_WAKEUP)); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH); - verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(true)); + verify(mIWallpaperManager).setInAmbientMode(eq(false), + eq((long) StackStateAnimator.ANIMATION_DURATION_WAKEUP)); } @Test @@ -93,24 +94,24 @@ public class DozeWallpaperStateTest extends SysuiTestCase { mDozeWallpaperState.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.DOZE_AOD); - verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(false)); + verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(0L)); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_AOD, DozeMachine.State.FINISH); - verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(false)); + verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(0L)); } @Test public void testTransitionTo_requestPulseIsAmbientMode() throws RemoteException { mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.DOZE_REQUEST_PULSE); - verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(false)); + verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(0L)); } @Test public void testTransitionTo_pulseIsAmbientMode() throws RemoteException { mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_REQUEST_PULSE, DozeMachine.State.DOZE_PULSING); - verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(false)); + verify(mIWallpaperManager).setInAmbientMode(eq(true), eq(0L)); } @Test @@ -120,6 +121,7 @@ public class DozeWallpaperStateTest extends SysuiTestCase { reset(mIWallpaperManager); mDozeWallpaperState.transitionTo(DozeMachine.State.DOZE_PULSING, DozeMachine.State.FINISH); - verify(mIWallpaperManager).setInAmbientMode(eq(false), eq(true)); + verify(mIWallpaperManager).setInAmbientMode(eq(false), + eq((long) StackStateAnimator.ANIMATION_DURATION_WAKEUP)); } } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index 6ede423f63c8..cfec8effeede 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -1181,7 +1181,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub // TODO(multi-display) TBD. if (mInfo != null && mInfo.supportsAmbientMode() && displayId == DEFAULT_DISPLAY) { try { - connector.mEngine.setInAmbientMode(mInAmbientMode, false /* animated */); + connector.mEngine.setInAmbientMode(mInAmbientMode, 0L /* duration */); } catch (RemoteException e) { Slog.w(TAG, "Failed to set ambient mode state", e); } @@ -2023,11 +2023,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } - // TODO(b/115486823) Extends this method with specific display. - public void setInAmbientMode(boolean inAmbienMode, boolean animated) { + /** + * TODO(b/115486823) Extends this method with specific display. + * Propagate ambient state to wallpaper engine. + * + * @param inAmbientMode {@code true} when in ambient mode, {@code false} otherwise. + * @param animationDuration Duration of the animation, or 0 when immediate. + */ + public void setInAmbientMode(boolean inAmbientMode, long animationDuration) { final IWallpaperEngine engine; synchronized (mLock) { - mInAmbientMode = inAmbienMode; + mInAmbientMode = inAmbientMode; final WallpaperData data = mWallpaperMap.get(mCurrentUserId); if (data != null && data.connection != null && data.connection.mInfo != null && data.connection.mInfo.supportsAmbientMode()) { @@ -2040,7 +2046,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub if (engine != null) { try { - engine.setInAmbientMode(inAmbienMode, animated); + engine.setInAmbientMode(inAmbientMode, animationDuration); } catch (RemoteException e) { // Cannot talk to wallpaper engine. } @@ -2344,7 +2350,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub return false; } if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) { - String msg = "Selected service does not require " + String msg = "Selected service does not have " + android.Manifest.permission.BIND_WALLPAPER + ": " + componentName; if (fromUser) { @@ -2396,6 +2402,22 @@ public class WallpaperManagerService extends IWallpaperManager.Stub } } + if (wi != null && wi.supportsAmbientMode()) { + final int hasPrivilege = mIPackageManager.checkPermission( + android.Manifest.permission.AMBIENT_WALLPAPER, wi.getPackageName(), + serviceUserId); + if (hasPrivilege != PackageManager.PERMISSION_GRANTED) { + String msg = "Selected service does not have " + + android.Manifest.permission.AMBIENT_WALLPAPER + + ": " + componentName; + if (fromUser) { + throw new SecurityException(msg); + } + Slog.w(TAG, msg); + return false; + } + } + // Bind the service! if (DEBUG) Slog.v(TAG, "Binding to:" + componentName); final int componentUid = mIPackageManager.getPackageUid(componentName.getPackageName(), diff --git a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java index 8d8fc84126ec..b9e282ebdfef 100644 --- a/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java +++ b/tests/Internal/src/android/service/wallpaper/WallpaperServiceTest.java @@ -38,7 +38,7 @@ public class WallpaperServiceTest { public Engine onCreateEngine() { return new Engine() { @Override - public void onAmbientModeChanged(boolean inAmbientMode, boolean animated) { + public void onAmbientModeChanged(boolean inAmbientMode, long duration) { ambientModeChangedCount[0]++; } }; @@ -47,12 +47,12 @@ public class WallpaperServiceTest { WallpaperService.Engine engine = service.onCreateEngine(); engine.setCreated(true); - engine.doAmbientModeChanged(false, false); + engine.doAmbientModeChanged(false, 0); assertFalse("ambient mode should be false", engine.isInAmbientMode()); assertEquals("onAmbientModeChanged should have been called", ambientModeChangedCount[0], 1); - engine.doAmbientModeChanged(true, false); + engine.doAmbientModeChanged(true, 0); assertTrue("ambient mode should be false", engine.isInAmbientMode()); assertEquals("onAmbientModeChanged should have been called", ambientModeChangedCount[0], 2); |